globalThis.isItemAccessible = (function() { return { array: array, entry: entry, }; /** * Checks whether an item is accessible * @param {string} string Name of wearable item * @param {string} [category="clothing"] that item is in clothing, collar, etc * @param {App.Entity.SlaveState} [slave] * @returns {boolean|string} Returns true if item is accessible, and false if it is not. If the slave param is set, it may sometimes return a string instead of false, explaining why the item can't be used with that slave. */ function entry(string, category = "clothing", slave) { if (V.cheatMode === 1) { return true; } let selectedDB; switch (category) { case "clothing": case "clothes": selectedDB = App.Data.clothes; break; case "collar": selectedDB = App.Data.slaveWear.collars; break; case "bellyAccessory": selectedDB = App.Data.slaveWear.bellyAccessories; break; case "buttplug": selectedDB = App.Data.slaveWear.buttplugs; break; case "buttplugAttachment": selectedDB = App.Data.slaveWear.buttplugAttachments; break; case "vaginalAccessory": selectedDB = App.Data.slaveWear.vaginalAccessories; break; case "vaginalAttachment": selectedDB = App.Data.slaveWear.vaginalAttachments; break; case "dickAccessory": selectedDB = App.Data.slaveWear.dickAccessories; break; case "shoes": selectedDB = App.Data.slaveWear.shoes; break; case "chastity": selectedDB = App.Data.slaveWear.chastityDevices; break; default: console.log(`made a category for ${category} automatically, may need to define this by hand`); selectedDB = App.Data.slaveWear[category]; break; } const item = selectedDB.get(string); if (!item) { console.log(`${string} is not a registered piece of clothing! Check App.Data.slaveWear.${category}`); return false; /* couldn't be found */ } return isAvailable(item, category, slave); } /** * Returns array of wearable clothing in format [name, value], basically player facing / game data. * @param {Map} map Map to look in (such as App.Data.clothes) * @param {string} [filter] * @param {any} [filterValue] * @returns {Array} */ function array(map, filter, filterValue) { const array = []; for (const [key, obj] of map) { if (filter && filterValue !== (obj[filter] || false)) { continue; } if (V.cheatMode || isAvailable(obj)) { const name = (obj.fs) ? `${obj.name} (FS)` : obj.name; array.push([name, obj.value]); } } return array; } /** * @param {object} item * @param {string} [category="clothing"] that item is in clothing, collar, etc * @param {App.Entity.SlaveState} [slave] * @returns {boolean|string} Returns true if item is accessible, and false if it is not. If the slave param is set, it may sometimes return a string instead of false, explaining why the item can't be used with that slave. */ function isAvailable(item, category, slave) { let slaveResults; if (slave) { slaveResults = isAvailableForSlave(item, category, slave); if (slaveResults === false) { return slaveResults; } } if (!(item.hasOwnProperty("fs")) && !(item.hasOwnProperty("requirements"))) { // No restriction, this clothing item is available to everyone return true; } if (item.hasOwnProperty("requirements")) { if (item.requirements === true) { return true; } } if (item.hasOwnProperty("fs")) { if (V.arcologies[0][item.fs] > 0) { return true; } } if (slaveResults && slaveResults !== true) { // If we still haven't returned true or false, then we display why this particular slave can't use the item. return slaveResults; } return false; } /** * @param {object} item * @param {string} [category="clothing"] that item is in clothing, collar, etc * @param {App.Entity.SlaveState} [slave] * @returns {boolean|string} Returns true if item is accessible, and false if it is not. If the slave param is set, it may sometimes return a string instead of false, explaining why the item can't be used with that slave. */ function isAvailableForSlave(item, category, slave) { switch (category) { case "clothing": case "clothes": break; case "collar": break; case "bellyAccessory": { switch (item.value) { case "a support band": { if (slave.belly > 10000) { return true; } else { return `Slave belly too small for this`; } } case "a small empathy belly": case "a medium empathy belly": case "a large empathy belly": case "a huge empathy belly": { if (slave.belly < 1500 && slave.weight < 130) { return true; } else { return `Slave belly too big for this`; } } default: return true; } } case "buttplug": { switch (item.value) { case "huge plug": { if (slave.anus < 2) { return `Slave's anus is too small for this right now`; } else { return true; } } case "long plug": case "long, large plug": { if (!(slave.breedingMark !== 1 || V.propOutcome === 0 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) { return "Elites frown on this"; } else { return true; } } case "long, huge plug": { if (slave.anus < 2) { return `Slave's anus is too small for this right now`; } else if (!(slave.breedingMark !== 1 || V.propOutcome === 0 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) { return "Elites frown on this"; } else { return true; } } default: return true; } } case "buttplugAttachment": break; case "vaginalAccessory": { if (slave.vagina < 0) { return false; } switch (item.value) { case "huge dildo": { if (slave.vagina < 2) { return `Slave's vagina is too small for this right now`; } else { return true; } } case "long dildo": case "long, large dildo": { if (!(slave.breedingMark !== 1 || V.propOutcome === 0 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) { return "Elites frown on this"; } else { return true; } } case "long, huge dildo": { if (slave.vagina < 2) { return `Slave's vagina is too small for this right now`; } else if (!(slave.breedingMark !== 1 || V.propOutcome === 0 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) { return "Elites frown on this"; } else { return true; } } default: return true; } } case "vaginalAttachment": { if (slave.vagina < 0) { return false; } switch (item.value) { case "vibrator": if (slave.vaginalAccessory === "none") { return "No vaginal accessory to attach it to"; } else if (slave.vaginalAccessory === "bullet vibrator" || slave.vaginalAccessory === "smart bullet vibrator") { return "Vaginal accessory already vibrates"; } else { return true; } } break; } case "dickAccessory": return (slave.dick >= 1); case "shoes": break; case "chastity": { switch (item.value) { case "chastity belt": case "combined chastity belt": return (slave.vagina > -1); case "chastity cage": case "combined chastity cage": return (slave.dick > 0); case "genital chastity": case "full chastity": return (slave.vagina > -1 && slave.dick > 0); case "choose own chastity": return (slave.choosesOwnChastity !== 1 && slave.devotion > 20 && slave.trust > 0); case "revoke choosing own chastity": return (slave.choosesOwnChastity > 0); default: return true; } } default: break; } return true; } })(); /** * @param {App.Entity.SlaveState} slave * @param {string} prosthetic * @returns {boolean} */ globalThis.isProstheticAvailable = function(slave, prosthetic) { return slave.readyProsthetics.findIndex(function(p) { return p.id === prosthetic; }) !== -1; }; /** * @param {App.Entity.SlaveState} slave * @param {string} prosthetic */ globalThis.addProsthetic = function(slave, prosthetic) { if (!isProstheticAvailable(slave, prosthetic)) { let limb = prostheticToLimb(prosthetic); if (limb > 0) { let p = { id: prosthetic, arm: {left: new App.Entity.LimbState(), right: new App.Entity.LimbState()}, leg: {left: new App.Entity.LimbState(), right: new App.Entity.LimbState()} }; p.arm.left.type = limb; p.arm.right.type = limb; p.leg.left.type = limb; p.leg.right.type = limb; slave.readyProsthetics.push(p); } else { slave.readyProsthetics.push({id: prosthetic}); } } }; /** * @param {App.Entity.SlaveState} slave * @param {string} prosthetic * @returns {{}} */ globalThis.findProsthetic = function(slave, prosthetic) { return slave.readyProsthetics.find(p => p.id === prosthetic); }; /** * @param {string} prosthetic * @returns {number} */ globalThis.prostheticToLimb = function(prosthetic) { switch (prosthetic) { case "basicL": return 2; case "sexL": return 3; case "beautyL": return 4; case "combatL": return 5; case "cyberneticL": return 6; default: return 0; } }; /** * * @param {number} limb * @returns {string} */ globalThis.limbToProsthetic = function(limb) { switch (limb) { case 2: return "basicL"; case 3: return "sexL"; case 4: return "beautyL"; case 5: return "combatL"; case 6: return "cyberneticL"; default: return ""; } };