diff --git a/src/002-config/fc-js-init.js b/src/002-config/fc-js-init.js index 517904199992fed31214d0232ae6b06012c84736..6cef7885cde6fba1ec48f5e7d36bf1bf59a48e53 100644 --- a/src/002-config/fc-js-init.js +++ b/src/002-config/fc-js-init.js @@ -6,7 +6,7 @@ */ window.App = { }; // the same declaration for code parsers that don't like the line above -var App = window.App || {}; +var App = window.App || {}; /* eslint-disable-line no-var*/ App.Data = {}; App.Debug = {}; @@ -32,4 +32,5 @@ App.Facilities = { Arcade: {}, HGSuite: {} }; +App.RA = {}; App.SF = {}; diff --git a/src/002-config/fc-version.js b/src/002-config/fc-version.js index 7f70287c5d2a2dc34c604e5cbce01cc4054adea8..97ac65b22ba62b7cf8a8c187e3d2704ca1e7de47 100644 --- a/src/002-config/fc-version.js +++ b/src/002-config/fc-version.js @@ -1,7 +1,7 @@ App.Version = { base: "0.10.7", pmod: "2.4.X", - release: 1045, + release: 1046, }; /* Use release as save version */ diff --git a/src/init/setupVars.tw b/src/init/setupVars.tw index 2738bce06c3983eab06170f32f6472eb4e71043a..8cce9b6d62ad0353af91f31c1e4d46633efa23d4 100644 --- a/src/init/setupVars.tw +++ b/src/init/setupVars.tw @@ -2082,7 +2082,6 @@ Then pick _namePool.random(), or display those names as possible choices, or do ]>> <<set setup.shoes = [ - {name: "No default footwear setting", value: "no default setting"}, {name: "Barefoot", value: "none"}, {name: "Flats", value: "flats"}, {name: "Heels", value: "heels"}, @@ -2092,7 +2091,6 @@ Then pick _namePool.random(), or display those names as possible choices, or do ]>> <<set setup.bellyAccessories = [ - {name: "No default setting", value: "no default setting"}, {name: "None", value: "none"}, {name: "Tight corset", value: "a corset"}, {name: "Extreme corset", value: "an extreme corset"}, @@ -2104,7 +2102,6 @@ Then pick _namePool.random(), or display those names as possible choices, or do ]>> <<set setup.vaginalAccessories = [ - {name: "No default setting", value: "no default setting"}, {name: "None", value: "none"}, {name: "Bullet vibrator", value: "bullet vibrator"}, {name: "Smart bullet vibrator", value: "smart bullet vibrator"}, @@ -2116,16 +2113,13 @@ Then pick _namePool.random(), or display those names as possible choices, or do {name: "Long, huge dildo", value: "long, huge dildo", rs: "buyBigDildos"}]>> <<set setup.vaginalAttachments = [ - {name: "No default setting", value: "no default setting"}, {name: "None", value: "none"}, {name: "Vibrating attachment", value: "vibrator"}]>> <<set setup.dickAccessories = [ - {name: "No default setting", value: "no default setting"}, {name: "None", value: "none"}]>> <<set setup.buttplugs = [ - {name: "No default setting", value: "no default setting"}, {name: "None", value: "none"}, {name: "Standard plug", value: "plug"}, {name: "Long plug", value: "long plug", rs: "buyBigPlugs"}, @@ -2136,7 +2130,6 @@ Then pick _namePool.random(), or display those names as possible choices, or do ]>> <<set setup.buttplugAttachments = [ - {name: "No default setting", value: "no default setting"}, {name: "None", value: "none"}, {name: "Tail", value: "tail", rs: "buyTails"}, {name: "Fox tail", value: "fox tail", rs: "buyTails"}, diff --git a/src/js/DefaultRules.js b/src/js/DefaultRules.js index 70a74fe4081982148ac0f5e2c9467212ba3ab7cb..9d7b2379e89ad5db00f8c21b9d5bddec4d15ca50 100644 --- a/src/js/DefaultRules.js +++ b/src/js/DefaultRules.js @@ -86,6 +86,7 @@ window.DefaultRules = (function() { */ function MergeRules(slave) { // merge all rules applying on a slave into one big rule + /** @type {App.RA.Rule[]} */ const rules = V.defaultRules.filter((x) => ruleAppliesP(x.condition, slave)); slave.currentRules = rules.map((x) => x.ID); return mergeRules(rules.map((x) => ProcessAssignments(slave, Object.assign({}, x.set)))); @@ -93,14 +94,13 @@ window.DefaultRules = (function() { /** * @param {App.Entity.SlaveState} slave - * @param {object} rule // not sure about this - * @returns {object} // not sure about this - */ + * @param {App.RA.RuleSetters} rule + */ function ProcessAssignments(slave, rule) { // Before merging rules, we process assignments for each rule separately so we can remove slaves from facilities when they no longer qualify, even if the final "winning" rule assigns them elsewhere // We also ignore inapplicable assignments for the current slave, so we only merge assignments that are valid switch (rule.setAssignment) { - case "no default setting": + case null: delete rule.setAssignment; break; @@ -313,11 +313,11 @@ window.DefaultRules = (function() { /** * @param {App.Entity.SlaveState} slave - * @param {object} rule - */ + * @param {App.RA.RuleSetters} rule + */ function AssignJobToSlave(slave, rule) { // place slave on assignment defined by the rule - if ((rule.setAssignment !== undefined && rule.setAssignment !== "no default setting")) { + if ((rule.setAssignment !== undefined && rule.setAssignment !== null)) { if (((rule.setAssignment === "choose her own job" && !slave.choosesOwnAssignment) || rule.setAssignment !== slave.assignment)) { switch (rule.setAssignment) { case "live with your Head Girl": @@ -373,11 +373,11 @@ window.DefaultRules = (function() { /** * @param {App.Entity.SlaveState} slave - * @param {object} rule + * @param {App.RA.RuleSetters} rule */ function ProcessClothing(slave, rule) { // apply clothes to slave - if ((rule.clothes !== undefined) && (rule.clothes !== "no default setting")) { + if ((rule.clothes !== undefined) && (rule.clothes !== null)) { if ((rule.clothes === "choosing her own clothes")) { if ((slave.choosesOwnClothes === 0)) { slave.clothes = "choosing her own clothes"; @@ -394,11 +394,11 @@ window.DefaultRules = (function() { /** * @param {App.Entity.SlaveState} slave - * @param {object} rule + * @param {App.RA.RuleSetters} rule */ function ProcessCollar(slave, rule) { // apply collar to slave - if ((rule.collar !== undefined) && (rule.collar !== "no default setting")) { + if ((rule.collar !== undefined) && (rule.collar !== null)) { if ((slave.collar !== rule.collar)) { r += "<br>"; if (rule.collar === "preg biometrics" && slave.preg <= -1 && slave.ovaries === 0 && slave.mpreg === 0) { @@ -425,11 +425,11 @@ window.DefaultRules = (function() { /** * @param {App.Entity.SlaveState} slave - * @param {object} rule + * @param {App.RA.RuleSetters} rule */ function ProcessEyewear(slave, rule) { // apply glasses, contacts to slave - if ((rule.eyewear !== undefined) && (rule.eyewear !== "no default setting")) { + if ((rule.eyewear !== undefined) && (rule.eyewear !== null)) { switch (rule.eyewear) { case "correct with glasses": if (slave.eyes === -1) { @@ -519,11 +519,11 @@ window.DefaultRules = (function() { /** * @param {App.Entity.SlaveState} slave - * @param {object} rule + * @param {App.RA.RuleSetters} rule */ function ProcessEarwear(slave, rule) { // apply earplugs to slave - if ((rule.earwear !== undefined) && (rule.earwear !== "no default setting")) { + if ((rule.earwear !== undefined) && (rule.earwear !== null)) { switch (rule.earwear) { case "correct with hearing aids": if (slave.hears === -1) { @@ -582,7 +582,7 @@ window.DefaultRules = (function() { /** * @param {App.Entity.SlaveState} slave - * @param {object} rule + * @param {App.RA.RuleSetters} rule */ function ProcessDildos(slave, rule) { // apply vaginal dildos to slave @@ -598,11 +598,11 @@ window.DefaultRules = (function() { /** * @param {App.Entity.SlaveState} slave - * @param {object} rule + * @param {App.RA.RuleSetters} rule */ function ProcessVVirginDildos(slave, rule) { // apply vaginal dildos to vaginal virgins - if ((rule.virginAccessory !== undefined) && (rule.virginAccessory !== "no default setting")) { + if ((rule.virginAccessory !== undefined) && (rule.virginAccessory !== null)) { if (slave.vaginalAccessory !== rule.virginAccessory) { slave.vaginalAccessory = rule.virginAccessory; switch (slave.vaginalAccessory) { @@ -659,11 +659,11 @@ window.DefaultRules = (function() { /** * @param {App.Entity.SlaveState} slave - * @param {object} rule + * @param {App.RA.RuleSetters} rule */ function ProcessAVirginDildos(slave, rule) { // apply vaginal dildos to anal virgins - if ((rule.aVirginAccessory !== undefined) && (rule.aVirginAccessory !== "no default setting")) { + if ((rule.aVirginAccessory !== undefined) && (rule.aVirginAccessory !== null)) { if (slave.vaginalAccessory !== rule.aVirginAccessory) { slave.vaginalAccessory = rule.aVirginAccessory; switch (slave.vaginalAccessory) { @@ -724,7 +724,7 @@ window.DefaultRules = (function() { */ function ProcessNonVirginDildos(slave, rule) { // apply vaginal dildos to non-virgins - if ((rule.vaginalAccessory !== undefined) && (rule.vaginalAccessory !== "no default setting")) { + if ((rule.vaginalAccessory !== undefined) && (rule.vaginalAccessory !== null)) { if (slave.vaginalAccessory !== rule.vaginalAccessory) { slave.vaginalAccessory = rule.vaginalAccessory; switch (slave.vaginalAccessory) { @@ -786,7 +786,7 @@ window.DefaultRules = (function() { // apply vaginal accessories to slaves if (slave.vaginalAccessory === "none" && slave.vaginalAttachment === "vibrator") { slave.vaginalAttachment = "none"; // clears dildo attachment when dildos are removed above - } else if ((rule.vaginalAttachment !== undefined) && (rule.vaginalAttachment !== "no default setting")) { + } else if ((rule.vaginalAttachment !== undefined) && (rule.vaginalAttachment !== null)) { if ((slave.vaginalAttachment !== rule.vaginalAttachment)) { slave.vaginalAttachment = rule.vaginalAttachment; if (slave.vaginalAccessory !== "none") { @@ -826,7 +826,7 @@ window.DefaultRules = (function() { // apply dick accessories to slave if ((slave.dick > 0)) { if (slave.anus === 0) { - if ((rule.aVirginDickAccessory !== undefined) && (rule.aVirginDickAccessory !== "no default setting")) { + if ((rule.aVirginDickAccessory !== undefined) && (rule.aVirginDickAccessory !== null)) { if ((slave.dickAccessory !== rule.aVirginDickAccessory)) { slave.dickAccessory = rule.aVirginDickAccessory; if (slave.dickAccessory === "none") { @@ -837,7 +837,7 @@ window.DefaultRules = (function() { } } } else { - if ((rule.dickAccessory !== undefined) && (rule.dickAccessory !== "no default setting")) { + if ((rule.dickAccessory !== undefined) && (rule.dickAccessory !== null)) { if ((slave.dickAccessory !== rule.dickAccessory)) { slave.dickAccessory = rule.dickAccessory; if (slave.dickAccessory === "none") { @@ -857,7 +857,7 @@ window.DefaultRules = (function() { */ function ProcessChastity(slave, rule) { // apply chastity to slave - if ((rule.chastityVagina !== undefined) && (rule.chastityVagina !== "no default setting")) { + if ((rule.chastityVagina !== undefined) && (rule.chastityVagina !== null)) { if (slave.vagina > -1) { if ((slave.chastityVagina !== rule.chastityVagina)) { slave.chastityVagina = rule.chastityVagina; @@ -869,7 +869,7 @@ window.DefaultRules = (function() { } } } - if ((rule.chastityPenis !== undefined) && (rule.chastityPenis !== "no default setting")) { + if ((rule.chastityPenis !== undefined) && (rule.chastityPenis !== null)) { if (slave.dick > 0) { if ((slave.chastityPenis !== rule.chastityPenis)) { slave.chastityPenis = rule.chastityPenis; @@ -881,7 +881,7 @@ window.DefaultRules = (function() { } } } - if ((rule.chastityAnus !== undefined) && (rule.chastityAnus !== "no default setting")) { + if ((rule.chastityAnus !== undefined) && (rule.chastityAnus !== null)) { if ((slave.chastityAnus !== rule.chastityAnus)) { slave.chastityAnus = rule.chastityAnus; if (rule.chastityAnus === 1) { @@ -899,7 +899,7 @@ window.DefaultRules = (function() { */ function ProcessShoes(slave, rule) { // apply shoes to slave - if ((rule.shoes !== undefined) && (rule.shoes !== "no default setting")) { + if ((rule.shoes !== undefined) && (rule.shoes !== null)) { if ((slave.shoes !== rule.shoes)) { if ((slave.amp !== 1)) { slave.shoes = rule.shoes; @@ -915,7 +915,7 @@ window.DefaultRules = (function() { */ function ProcessBellyAccessories(slave, rule) { // apply belly accessories to slave - if ((rule.bellyAccessory !== undefined) && (rule.bellyAccessory !== "no default setting")) { + if ((rule.bellyAccessory !== undefined) && (rule.bellyAccessory !== null)) { if ((slave.bellyAccessory !== rule.bellyAccessory)) { if ((slave.belly >= 1500 || slave.weight >= 130) && setup.fakeBellies.includes(rule.bellyAccessory)) { r += `<br>${slave.slaveName}'s natural belly is too big to properly wear an empathy belly.`; @@ -937,7 +937,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessLegAccessory(slave, rule) { - if (rule.legAccessory !== undefined && rule.legAccessory !== "no default setting" && slave.amp !== 1 && slave.legAccessory !== rule.legAccessory) { + if (rule.legAccessory !== undefined && rule.legAccessory !== null && slave.amp !== 1 && slave.legAccessory !== rule.legAccessory) { slave.legAccessory = rule.legAccessory; r += `<br>${slave.slaveName}'s leg accessory was set to ${rule.legAccessory}.`; } @@ -965,7 +965,7 @@ window.DefaultRules = (function() { */ function ProcessAnalVirginButtplugs(slave, rule) { // apply buttplugs to virgins - if ((rule.aVirginButtplug !== undefined) && (rule.aVirginButtplug !== "no default setting")) { + if ((rule.aVirginButtplug !== undefined) && (rule.aVirginButtplug !== null)) { if ((slave.buttplug !== rule.aVirginButtplug)) { slave.buttplug = rule.aVirginButtplug; switch (slave.buttplug) { @@ -1026,7 +1026,7 @@ window.DefaultRules = (function() { */ function ProcessNonVirginButtplugs(slave, rule) { // apply buttplugs to non-virgins - if ((rule.buttplug !== undefined) && (rule.buttplug !== "no default setting")) { + if ((rule.buttplug !== undefined) && (rule.buttplug !== null)) { if ((slave.buttplug !== rule.buttplug)) { slave.buttplug = rule.buttplug; switch (slave.buttplug) { @@ -1089,7 +1089,7 @@ window.DefaultRules = (function() { // apply buttplug accessories to slaves if (slave.buttplug === "none" && slave.buttplugAttachment !== "none") { slave.buttplugAttachment = "none"; // clears buttplug attachments when buttplugs are removed above - } else if ((rule.buttplugAttachment !== undefined) && (rule.buttplugAttachment !== "no default setting")) { + } else if ((rule.buttplugAttachment !== undefined) && (rule.buttplugAttachment !== null)) { if ((slave.buttplugAttachment !== rule.buttplugAttachment)) { slave.buttplugAttachment = rule.buttplugAttachment; switch (slave.buttplugAttachment) { @@ -1192,7 +1192,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessContraceptives(slave, rule) { - if ((rule.preg !== undefined) && (rule.preg !== "no default setting")) { + if ((rule.preg !== undefined) && (rule.preg !== null)) { if (rule.preg === true && slave.preg === 0) { r += `<br>${slave.slaveName} is being given contraceptives.`; slave.preg = -1; @@ -1208,7 +1208,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessAbortions(slave, rule) { - if ((rule.abortion !== undefined) && (rule.abortion !== "no default setting")) { + if ((rule.abortion !== undefined) && (rule.abortion !== null)) { if (rule.abortion === "all") { if (slave.preg < 4 || (slave.fetish === "mindbroken" || slave.fuckdoll !== 0)) { r += `<br>${slave.slaveName}'s pregnancy has been terminated.`; @@ -1289,212 +1289,144 @@ window.DefaultRules = (function() { /** * @param {App.Entity.SlaveState} slave - * @param {object} rule + * @param {App.RA.RuleSetters} rule */ function ProcessAssetGrowthDrugs(slave, rule) { - // Asset Growth - const growthDrugs = new Set(["breast injections", "breast redistributors", "butt injections", "butt redistributors", "hyper breast injections", "hyper butt injections", "hyper penis enhancement", "hyper testicle enhancement", "intensive breast injections", "intensive butt injections", "intensive penis enhancement", "intensive testicle enhancement", "lip atrophiers", "lip injections", "penis atrophiers", "penis enhancement", "testicle atrophiers", "testicle enhancement"]); if ((slave.drugs === "super fertility drugs" || slave.drugs === "fertility drugs") && isFertile(slave)) { r += `<br>${slave.slaveName} is on ${slave.drugs} and will not be considered for drug enhancement until that regime is complete.`; return; - } else if ((rule.growth_boobs === "no default setting" && rule.growth_butt === "no default setting" && rule.growth_lips === "no default setting" && rule.growth_dick === "no default setting" && rule.growth_dick === "no default setting" && rule.growth_balls === "no default setting")) { + } else if ((rule.growth_boobs === null && rule.growth_butt === null && rule.growth_lips === null && rule.growth_dick === null && rule.growth_balls === null)) { return; } - if (rule.hyper_drugs !== 1) { // More resource intensive version with prioritizing. - let _priorities = []; - if (rule.growth_boobs !== "no default setting") { - let _priority; - if (slave.boobs < rule.growth_boobs) { - _priority = {drug: "breast injections", weight: (rule.growth_boobs - slave.boobs) / rule.growth_boobs}; - _priorities.push(_priority); - } else if ((slave.boobs > parseInt(rule.growth_boobs) + 200) && slave.weight < 100 && (V.arcologies[0].FSSlimnessEnthusiastResearch === 1)) { - _priority = {drug: "breast redistributors", weight: (1 + ((slave.boobs - slave.boobsImplant - slave.boobsMilk - rule.growth_boobs) / rule.growth_boobs))}; - _priorities.push(_priority); - } - } - if (rule.growth_butt !== "no default setting") { - let _priority; - if (slave.butt < rule.growth_butt) { - _priority = {drug: "butt injections", weight: (rule.growth_butt - slave.butt) / rule.growth_butt}; - _priorities.push(_priority); - } else if ((Math.trunc(slave.butt) > rule.growth_butt) && slave.weight < 100 && (V.arcologies[0].FSSlimnessEnthusiastResearch === 1)) { - _priority = {drug: "butt redistributors", weight: (1 + ((slave.butt - slave.buttImplant - rule.growth_butt) / rule.growth_butt))}; - _priorities.push(_priority); - } - } - if (rule.growth_lips !== "no default setting") { - let _priority; - if (slave.lips < rule.growth_lips) { - _priority = {drug: "lip injections", weight: (rule.growth_lips - slave.lips) / rule.growth_lips}; - _priorities.push(_priority); - } else if ((slave.lips > rule.growth_lips) && (V.arcologies[0].FSSlimnessEnthusiastResearch === 1)) { - _priority = {drug: "lip atrophiers", weight: (1 + ((slave.lips - slave.lipsImplant - rule.growth_lips) / rule.growth_lips))}; - _priorities.push(_priority); - } - } - if (rule.growth_dick !== "no default setting" && slave.dick) { - let _priority; - if (slave.dick < rule.growth_dick) { - _priority = {drug: "penis enhancement", weight: (rule.growth_dick - slave.dick) / rule.growth_dick}; - _priorities.push(_priority); - } else if ((slave.dick > rule.growth_dick) && (V.arcologies[0].FSSlimnessEnthusiastResearch === 1)) { - _priority = {drug: "penis atrophiers", weight: (1 + ((slave.dick - rule.growth_dick) / rule.growth_dick))}; - _priorities.push(_priority); - } - } - if (rule.growth_balls !== "no default setting" && slave.balls) { - let _priority; - if (slave.balls < rule.growth_balls) { - _priority = {drug: "testicle enhancement", weight: (rule.growth_balls - slave.balls) / rule.growth_balls}; - _priorities.push(_priority); - } else if ((slave.balls > rule.growth_balls) && (V.arcologies[0].FSSlimnessEnthusiastResearch === 1)) { - _priority = {drug: "testicle atrophiers", weight: (1 + ((slave.balls - rule.growth_balls) / rule.growth_balls))}; - _priorities.push(_priority); - } - } - if (_priorities.length > 1) { - _priorities = _priorities.sort(function(a, b) { - if (a.weight > b.weight) { - return -1; - } - if (a.weight < b.weight) { - return 1; - } - return 0; - }); - if (slave.drugs !== _priorities[0].drug) { - slave.drugs = _priorities[0].drug; - r += `<br>${slave.slaveName} has been put on `; - if (rule.growth_intensity && slave.drugs !== "lip injections" && slave.health > 0) { - slave.drugs = `intensive ${slave.drugs}`; - r += `${slave.drugs}, since ${he}'s healthy enough to take them, and `; - } else { - r += `${slave.drugs}, since `; - } - r += `that part of ${his} body is `; - if (!isNaN(_priorities[0].weight)) { - r += `${Math.trunc(_priorities[0].weight*100)}% `; - } - if (_priorities[0].weight < 1) { - r += "below "; - } else { - r += "above "; - } - r += "the targeted size."; - } - } else if (_priorities.length > 0) { - if (slave.drugs !== _priorities[0].drug) { - slave.drugs = _priorities[0].drug; - r += `<br>${slave.slaveName} has been put on `; - if (rule.growth_intensity && slave.drugs !== "lip injections" && slave.health > 0) { - slave.drugs = `intensive ${slave.drugs}`; - r += `${slave.drugs}, since ${he}'s healthy enough to take them, and `; - } else { - r += `${slave.drugs}, since `; - } - r += `that is the only part of ${his} body that does not meet the targeted size.`; - } - } else if (growthDrugs.has(slave.drugs)) { - slave.drugs = "no drugs"; - r += `<br>${slave.slaveName}'s body has met all relevant growth targets, so ${his} pharmaceutical regime has been ended.`; + + // Asset Growth + const growthDrugs = new Set(["breast injections", "breast redistributors", "butt injections", "butt redistributors", "hyper breast injections", "hyper butt injections", "hyper penis enhancement", "hyper testicle enhancement", "intensive breast injections", "intensive butt injections", "intensive penis enhancement", "intensive testicle enhancement", "lip atrophiers", "lip injections", "penis atrophiers", "penis enhancement", "testicle atrophiers", "testicle enhancement"]); + + // WARNING: property names in fleshFunc, growDrugs, and shrinkDrugs must be identical and this fact is used by the drugs() below + const fleshFunc = { + lips: s => s.lips - s.lipsImplant, + boobs: s => s.boobs - s.boobsImplant - s.boobsMilk, + butt: s => Math.trunc(s.butt - s.buttImplant), + dick: s => s.dick, + balls: s => s.balls, + }; + + const growDrugs = { + lips: "lip injections", + boobs: "breast injections", + butt: "butt injections", + dick: null, + balls: null + }; + + if (slave.dick > 0) { + growDrugs.dick = "penis enhancement"; + } + if (slave.balls > 0) { + growDrugs.balls = "testicle enhancement"; + } + + if (rule.hyper_drugs === 1 && V.arcologies[0].FSAssetExpansionistResearch == 1) { + growDrugs.boobs = "hyper breast injections"; + growDrugs.butt = "hyper butt injections"; + if (slave.dick > 0) { + growDrugs.dick = "hyper penis enhancement"; } - } else { - if (rule.growth_boobs !== "no default setting") { - if (slave.boobs < rule.growth_boobs) { - if (slave.drugs !== "hyper breast injections") { - slave.drugs = "hyper breast injections"; - r += `<br>${slave.slaveName} has been put on ${slave.drugs}.`; - } - return; - } + if (slave.balls > 0) { + growDrugs.balls = "hyper testicle enhancement"; } - if (rule.growth_butt !== "no default setting") { - if (slave.butt < rule.growth_butt) { - if (slave.drugs !== "hyper butt injections") { - slave.drugs = "hyper butt injections"; - r += `<br>${slave.slaveName} has been put on ${slave.drugs}.`; - } - return; - } + } else if (slave.indentureRestrictions < 2 && slave.health > 0) { + growDrugs.boobs = "intensive breast injections"; + growDrugs.butt = "intensive butt injections"; + if (slave.dick > 0) { + growDrugs.dick = "intensive penis enhancement"; } - if (rule.growth_lips !== "no default setting") { - if (slave.lips < rule.growth_lips) { - if (slave.drugs !== "lip injections") { - slave.drugs = "lip injections"; - r += `<br>${slave.slaveName} has been put on ${slave.drugs}.`; - } - return; - } + if (slave.balls > 0) { + growDrugs.balls = "intensive testicle enhancement"; } - if (rule.growth_dick !== "no default setting" && slave.dick) { - if (slave.dick < rule.growth_dick) { - if (slave.drugs !== "hyper penis enhancement") { - slave.drugs = "hyper penis enhancement"; - r += `<br>${slave.slaveName} has been put on ${slave.drugs}.`; - } - return; - } + } + + const shrinkDrugs = { + lips: null, + boobs: null, + butt: null, + dick: null, + balls: null + }; + + if (V.arcologies[0].FSSlimnessEnthusiastResearch === 1) { + shrinkDrugs.lip = "lip atrophiers"; + if (slave.dick > 0) { + shrinkDrugs.penis = "penis atrophiers"; } - if (rule.growth_balls !== "no default setting" && slave.balls) { - if (slave.balls < rule.growth_balls) { - if (slave.drugs !== "hyper testicle enhancement") { - slave.drugs = "hyper testicle enhancement"; - r += `<br>${slave.slaveName} has been put on ${slave.drugs}.`; - } - return; - } + if (slave.balls > 0) { + shrinkDrugs.testicle = "testicle atrophiers"; } - if (V.arcologies[0].FSSlimnessEnthusiastResearch === 1) { - if (rule.growth_boobs !== "no default setting") { - if (slave.boobs - slave.boobsImplant - slave.boobsMilk > parseInt(rule.growth_boobs) + 200 && slave.weight < 100) { - if (slave.drugs !== "breast redistributors") { - slave.drugs = "breast redistributors"; - r += `<br>${slave.slaveName} has been put on ${slave.drugs}.`; - } - return; - } - } - if (rule.growth_butt !== "no default setting") { - if (Math.trunc(slave.butt - slave.buttImplant) > rule.growth_butt && slave.weight < 100) { - if (slave.drugs !== "butt redistributors") { - slave.drugs = "butt redistributors"; - r += `<br>${slave.slaveName} has been put on ${slave.drugs}.`; - } - return; - } - } - if (rule.growth_lips !== "no default setting") { - if (slave.lips - slave.lipsImplant > rule.growth_lips) { - if (slave.drugs !== "lip atrophiers") { - slave.drugs = "lip atrophiers"; - r += `<br>${slave.slaveName} has been put on ${slave.drugs}.`; - } - return; - } + if (slave.weight < 100) { + shrinkDrugs.breast = "breast redistributors"; + shrinkDrugs.butt = "butt redistributors"; + } + } + + /** + * @param {App.Entity.SlaveState} slave + * @param {string} asset + * @param {App.RA.NumericTarget} target + * @param {Array} priorities + * @param {number} step + */ + function drugs(slave, asset, target, priorities, step) { + if (target === null || (growDrugs[asset] === null && shrinkDrugs[asset] === null)) { + return; + } + + const flesh = fleshFunc[asset](slave); + if (growDrugs[asset] !== null && App.RA.shallGrow(flesh, target, step)) { + priorities.push({ + drug: growDrugs[asset], + weight: 1.0 - (flesh / target.val) + }); + } else if (shrinkDrugs[asset] !== null && App.RA.shallShrink(flesh, target, step)) { + priorities.push({ + drug: shrinkDrugs[asset], + weight: flesh / target.val - 1.0 + }); + } + } + + let _priorities = []; + drugs(slave, "boobs", rule.growth_boobs, _priorities, 200); + drugs(slave, "butt", rule.growth_butt, _priorities, 1); + drugs(slave, "lips", rule.growth_lips, _priorities, 1); + drugs(slave, "dick", rule.growth_dick, _priorities, 1); + drugs(slave, "balls", rule.growth_balls, _priorities, 1); + + if (_priorities.length > 0) { + const action = _priorities.reduce((acc, cur) => (acc.weight > cur.weight) ? acc : cur); + if (slave.drugs !== action.drug) { + slave.drugs = action.drug; + r += `<br>${slave.slaveName} has been put on ${slave.drugs}, since `; + if (action.drug.startsWith("intensive")) { + r += `since ${he}'s healthy enough to take them, and `; } - if (rule.growth_dick !== "no default setting" && slave.dick) { - if (slave.dick > rule.growth_dick) { - if (slave.drugs !== "penis atrophiers") { - slave.drugs = "penis atrophiers"; - r += `<br>${slave.slaveName} has been put on ${slave.drugs}.`; - } - return; + if (_priorities.length > 1) { + r += `that part of ${his} body is `; + if (!isNaN(action.weight)) { + r += `${Math.trunc(action.weight * 100)}% `; } - } - if (rule.growth_balls !== "no default setting" && slave.balls) { - if (slave.balls > rule.growth_balls) { - if (slave.drugs !== "testicle atrophiers") { - slave.drugs = "testicle atrophiers"; - r += `<br>${slave.slaveName} has been put on ${slave.drugs}.`; - } - return; + if (action.weight < 1) { + r += "below "; + } else { + r += "above "; } + r += "the targeted size."; + } else { + r += `that is the only part of ${his} body that does not meet the targeted size.`; } } - if (growthDrugs.has(slave.drugs)) { - slave.drugs = "no drugs"; - r += `<br>${slave.slaveName} has met all relevant growth targets, so ${his} pharmaceutical regime has been ended.`; - } + } else if (growthDrugs.has(slave.drugs)) { + slave.drugs = "no drugs"; + r += `<br>${slave.slaveName}'s body has met all relevant growth targets, so ${his} pharmaceutical regime has been ended.`; } } @@ -1504,7 +1436,7 @@ window.DefaultRules = (function() { */ function ProcessOtherDrugs(slave, rule) { // Other Drugs - if (slave.indentureRestrictions < 2 && rule.drug !== "no default setting" && slave.drugs !== rule.drug) { + if (slave.indentureRestrictions < 2 && rule.drug !== null && slave.drugs !== rule.drug) { let flag = true; switch (rule.drug) { case "anti-aging cream": @@ -1678,7 +1610,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessEnema(slave, rule) { - if ((rule.inflationType !== undefined) && (rule.inflationType !== "no default setting")) { + if ((rule.inflationType !== undefined) && (rule.inflationType !== null)) { if (slave.inflationType !== rule.inflationType) { if ((slave.inflationType === "curative" && slave.health > 90) || (slave.inflationType === "tightener" && slave.anus <= 1 && slave.vagina <= 1)) { r += `<br>${slave.slaveName} cannot benefit from ${his} assigned enema and has been defaulted to none.`; @@ -1724,19 +1656,19 @@ window.DefaultRules = (function() { */ function ProcessDiet(slave, rule) { // Diet Setting - if (rule.diet !== undefined && rule.diet !== "no default setting") { + if (rule.diet !== undefined && rule.diet !== null) { /* - if ((slave.boobs >= 1600) && (slave.muscles <= 5) && (slave.amp !== 1) && ((rule.muscles == "no default setting") || (rule.muscles === 0))) { + if ((slave.boobs >= 1600) && (slave.muscles <= 5) && (slave.amp !== 1) && ((rule.muscles == null) || (rule.muscles === 0))) { if ((slave.diet !== "muscle building")) { slave.diet = "muscle building" r += `<br>${slave.slaveName} has big tits and no back muscles, so ${he}'s been assigned to gain some.` } - } else if ((slave.boobs >= 1600) && (slave.muscles > 5) && (slave.diet == "muscle building") && ((rule.muscles == "no default setting") || (rule.muscles === 0))) { + } else if ((slave.boobs >= 1600) && (slave.muscles > 5) && (slave.diet == "muscle building") && ((rule.muscles == null) || (rule.muscles === 0))) { */ if (rule.diet === "healthy" && slave.diet !== "healthy") { slave.diet = "healthy"; r += `<br>${slave.slaveName} has been assigned to a healthy diet.`; - } else if ((slave.boobs >= 1600) && (slave.muscles > 5) && (slave.diet === "muscle building") && ((rule.muscles === "no default setting") || (rule.muscles === 0))) { + } else if ((slave.boobs >= 1600) && (slave.muscles > 5) && (slave.diet === "muscle building") && ((rule.muscles === null) || (rule.muscles === 0))) { slave.diet = "healthy"; r += `<br>${slave.slaveName} has huge boobs, but ${he} already has the back muscles to bear them, so ${he}'s been assigned to stop working out so hard.`; } else if ((rule.dietGrowthSupport === 1) && ((slave.drugs === "breast injections") || (slave.drugs === "butt injections")) && (slave.weight <= 95)) { @@ -1756,13 +1688,13 @@ window.DefaultRules = (function() { slave.diet = "fattening"; r += `<br>${slave.slaveName} is too skinny so ${his} diet has been set to fattening.`; } - } else if ((rule.muscles !== undefined) && (rule.muscles !== "no default setting") && (slave.amp !== 1)) { - if ((slave.muscles >= rule.muscles + 8)) { + } else if ((rule.muscles !== undefined) && (rule.muscles !== null) && (slave.amp !== 1)) { + if (App.RA.shallShrink(slave.muscles, rule.muscles, 8)) { if ((slave.diet !== "slimming")) { slave.diet = "slimming"; r += `<br>${slave.slaveName} has been put on a slimming exercise regime.`; } - } else if ((slave.muscles <= rule.muscles - 2)) { + } else if (App.RA.shallGrow(slave.muscles, rule.muscles, 2)) { if ((slave.diet !== "muscle building")) { slave.diet = "muscle building"; r += `<br>${slave.slaveName} has been put on a muscle building exercise regime.`; @@ -1790,13 +1722,13 @@ window.DefaultRules = (function() { slave.diet = "fattening"; r += `<br>${slave.slaveName} is too skinny so ${his} diet has been set to fattening.`; } - } else if ((rule.muscles !== undefined) && (rule.muscles !== "no default setting") && (slave.amp !== 1)) { - if ((slave.muscles >= rule.muscles + 8)) { + } else if ((rule.muscles !== undefined) && (rule.muscles !== null) && (slave.amp !== 1)) { + if (App.RA.shallShrink(slave.muscles, rule.muscles, 8)) { if ((slave.diet !== "slimming")) { slave.diet = "slimming"; r += `<br>${slave.slaveName} has been put on a slimming exercise regime.`; } - } else if ((slave.muscles <= rule.muscles - 2)) { + } else if (App.RA.shallGrow(slave.muscles, rule.muscles, 2)) { if ((slave.diet !== "muscle building")) { slave.diet = "muscle building"; r += `<br>${slave.slaveName} has been put on a muscle building exercise regime.`; @@ -1871,13 +1803,13 @@ window.DefaultRules = (function() { } } } - } else if ((rule.muscles !== undefined) && (rule.muscles !== "no default setting") && (slave.amp !== 1)) { // no diet rule, muscles only - if ((slave.muscles >= rule.muscles + 8)) { + } else if ((rule.muscles !== undefined) && (rule.muscles !== null) && (slave.amp !== 1)) { // no diet rule, muscles only + if (App.RA.shallShrink(slave.muscles, rule.muscles, 8)) { if ((slave.diet !== "slimming")) { slave.diet = "slimming"; r += `<br>${slave.slaveName} has been put on a slimming exercise regime.`; } - } else if ((slave.muscles <= rule.muscles - 2)) { + } else if (App.RA.shallGrow(slave.muscles, rule.muscles, 2)) { if ((slave.diet !== "muscle building")) { slave.diet = "muscle building"; r += `<br>${slave.slaveName} has been put on a muscle building exercise regime.`; @@ -1904,7 +1836,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessCuratives(slave, rule) { - if ((rule.curatives !== undefined) && (rule.curatives !== "no default setting")) { + if ((rule.curatives !== undefined) && (rule.curatives !== null)) { if (slave.curatives !== rule.curatives) { if (rule.curatives === 2) { if (slave.health > 100) { @@ -1929,7 +1861,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessAphrodisiacs(slave, rule) { - if ((rule.aphrodisiacs !== undefined) && (rule.aphrodisiacs !== "no default setting")) { + if ((rule.aphrodisiacs !== undefined) && (rule.aphrodisiacs !== null)) { if (slave.aphrodisiacs !== rule.aphrodisiacs) { r += `<br>${slave.slaveName} has been ${rule.aphrodisiacs > 0 ? "put on the proper" : "taken off"} aphrodisiacs.`; slave.aphrodisiacs = rule.aphrodisiacs; @@ -1944,7 +1876,7 @@ window.DefaultRules = (function() { function ProcessPenisHormones(slave, rule) { if ((slave.dick > 0)) { if ((slave.balls === 0)) { - if ((rule.gelding !== undefined) && (rule.gelding !== "no default setting")) { + if ((rule.gelding !== undefined) && (rule.gelding !== null)) { if ((slave.hormones !== rule.gelding)) { const _oldHormones = slave.hormones; slave.hormones = rule.gelding; @@ -1957,7 +1889,7 @@ window.DefaultRules = (function() { } } } else if ((slave.balls > 0)) { - if ((rule.XY !== undefined) && (rule.XY !== "no default setting")) { + if ((rule.XY !== undefined) && (rule.XY !== null)) { if ((slave.hormones !== rule.XY)) { if ((slave.assignment !== "recruit girls")) { if ((slave.assignment !== "be the Wardeness")) { @@ -1984,7 +1916,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessFemaleHormones(slave, rule) { - if ((slave.vagina > -1) && (slave.dick === 0) && (rule.XX !== undefined) && (rule.XX !== "no default setting")) { + if ((slave.vagina > -1) && (slave.dick === 0) && (rule.XX !== undefined) && (rule.XX !== null)) { if ((slave.hormones !== rule.XX)) { const _oldHormones = slave.hormones; slave.hormones = rule.XX; @@ -2003,7 +1935,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessPregnancyDrugs(slave, rule) { - if (slave.pregKnown === 1 && rule.pregSpeed !== "no default setting" && (slave.breedingMark !== 1 || V.propOutcome === 0) && slave.indentureRestrictions < 1 && slave.broodmother === 0) { + if (slave.pregKnown === 1 && rule.pregSpeed !== null && (slave.breedingMark !== 1 || V.propOutcome === 0) && slave.indentureRestrictions < 1 && slave.broodmother === 0) { if (rule.pregSpeed === "slow" && slave.preg < slave.pregData.minLiveBirth) { slave.pregControl = "slow gestation"; r += `<br>${slave.slaveName} is pregnant, so ${he} has been put on the gestation slowing agents.`; @@ -2033,7 +1965,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessLivingStandard(slave, rule) { - if ((rule.livingRules !== undefined) && (rule.livingRules !== "no default setting")) { + if ((rule.livingRules !== undefined) && (rule.livingRules !== null)) { if (setup.facilityCareers.includes(slave.assignment)) { r += ""; // `<br>${slave.slaveName}'s living standards are controlled by ${his} assignment.`; } else if (((slave.assignment === "be your Head Girl") && (V.HGSuite === 1)) || ((slave.assignment === "guard you") && (V.dojo > 1))) { @@ -2070,7 +2002,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessSpeech(slave, rule) { - if ((rule.speechRules !== undefined) && (rule.speechRules !== "no default setting") && (slave.speechRules !== rule.speechRules)) { + if ((rule.speechRules !== undefined) && (rule.speechRules !== null) && (slave.speechRules !== rule.speechRules)) { if (slave.fetish === "mindbroken") { if ((slave.speechRules !== "restrictive")) { slave.speechRules = "restrictive"; @@ -2105,8 +2037,8 @@ window.DefaultRules = (function() { */ function ProcessRelationship(slave, rule) { if ((slave.fetish !== "mindbroken")) { - if ((rule.relationshipRules !== undefined) && (rule.relationshipRules !== "no default setting")) { - if ((slave.relationshipRules !== rule.relationshipRules)) { + if ((rule.relationshipRules !== undefined) && (rule.relationshipRules !== null)) { + if ((slave.relationshipRules !== rule.relationshipRules )) { slave.relationshipRules = rule.relationshipRules; r += `<br>${slave.slaveName}'s relationship rules have been set to ${rule.relationshipRules}.`; } @@ -2119,7 +2051,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessRelease(slave, rule) { - if ((rule.releaseRules !== undefined) && (rule.releaseRules !== "no default setting")) { + if ((rule.releaseRules !== undefined) && (rule.releaseRules !== null)) { let _release = 0; if (rule.releaseRules === "restrictive" && !(["be a subordinate slave", "be confined in the arcade", "be your Head Girl", "get milked", "please you", "serve in the club", "serve in the master suite", "serve the public", "whore", "work a glory hole", "work as a farmhand", "work in the brothel", "work in the dairy"].contains(slave.assignment))) { @@ -2145,7 +2077,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessPunishment(slave, rule) { - if ((rule.standardPunishment !== undefined) && (rule.standardPunishment !== "no default setting")) { + if ((rule.standardPunishment !== undefined) && (rule.standardPunishment !== null)) { if ((slave.standardPunishment !== rule.standardPunishment)) { slave.standardPunishment = rule.standardPunishment; r += `<br>${slave.slaveName}'s typical punishment has been updated to ${rule.standardPunishment}.`; @@ -2158,7 +2090,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessReward(slave, rule) { - if ((rule.standardReward !== undefined) && (rule.standardReward !== "no default setting")) { + if ((rule.standardReward !== undefined) && (rule.standardReward !== null)) { if ((slave.standardReward !== rule.standardReward)) { slave.standardReward = rule.standardReward; r += `<br>${slave.slaveName}'s typical reward has been updated to ${rule.standardReward}.`; @@ -2171,7 +2103,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessToyHole(slave, rule) { - if ((rule.toyHole !== undefined) && (rule.toyHole !== "no default setting")) { + if ((rule.toyHole !== undefined) && (rule.toyHole !== null)) { if (rule.toyHole === "pussy") { if (slave.vagina > 0 && canDoVaginal(slave)) { slave.toyHole = rule.toyHole; @@ -2208,7 +2140,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessDietCum(slave, rule) { - if ((rule.dietCum !== undefined) && (rule.dietCum !== "no default setting")) { + if ((rule.dietCum !== undefined) && (rule.dietCum !== null)) { if (slave.dietCum !== rule.dietCum) { slave.dietCum = rule.dietCum; if (slave.dietCum === 2) { @@ -2228,7 +2160,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessDietMilk(slave, rule) { - if ((rule.dietMilk !== undefined) && (rule.dietMilk !== "no default setting")) { + if ((rule.dietMilk !== undefined) && (rule.dietMilk !== null)) { if (slave.dietMilk !== rule.dietMilk) { slave.dietMilk = rule.dietMilk; if (slave.dietMilk === 2) { @@ -2248,7 +2180,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessSolidFood(slave, rule) { - if ((rule.onDiet !== undefined) && (rule.onDiet !== "no default setting")) { + if ((rule.onDiet !== undefined) && (rule.onDiet !== null)) { if ((slave.onDiet !== rule.onDiet)) { slave.onDiet = rule.onDiet; if (slave.onDiet === 1) { @@ -2265,7 +2197,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessTeeth(slave, rule) { - if ((rule.teeth !== undefined) && (rule.teeth !== "no default setting")) { + if ((rule.teeth !== undefined) && (rule.teeth !== null)) { if ((rule.teeth === "universal")) { if ((slave.teeth === "crooked")) { slave.teeth = "straightening braces"; @@ -2310,7 +2242,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessStyle(slave, rule) { - if (rule.eyeColor !== undefined && (rule.eyeColor !== "no default setting")) { + if (rule.eyeColor !== undefined && (rule.eyeColor !== null)) { if ((slave.eyeColor !== rule.eyeColor)) { slave.eyeColor = rule.eyeColor; cashX(forceNeg(V.modCost), "slaveMod", slave); @@ -2318,7 +2250,7 @@ window.DefaultRules = (function() { } } - if (rule.makeup !== undefined && (rule.makeup !== "no default setting")) { + if (rule.makeup !== undefined && (rule.makeup !== null)) { if ((slave.makeup !== rule.makeup)) { slave.makeup = rule.makeup; cashX(forceNeg(V.modCost), "slaveMod", slave); @@ -2327,7 +2259,7 @@ window.DefaultRules = (function() { } if ((slave.amp !== 1)) { - if (rule.nails !== undefined && (rule.nails !== "no default setting")) { + if (rule.nails !== undefined && (rule.nails !== null)) { if ((slave.nails !== rule.nails)) { slave.nails = rule.nails; cashX(forceNeg(V.modCost), "slaveMod", slave); @@ -2336,7 +2268,7 @@ window.DefaultRules = (function() { } } - if (rule.hColor !== undefined && (rule.hColor !== "no default setting")) { + if (rule.hColor !== undefined && (rule.hColor !== null)) { if (slave.bald !== 1) { if ((slave.hColor !== rule.hColor)) { slave.hColor = rule.hColor; @@ -2346,7 +2278,7 @@ window.DefaultRules = (function() { } } - if (rule.hStyle !== undefined && (rule.hStyle !== "no default setting")) { + if (rule.hStyle !== undefined && (rule.hStyle !== null)) { if (slave.bald !== 1) { if ((slave.hStyle !== rule.hStyle)) { slave.hStyle = rule.hStyle; @@ -2361,7 +2293,7 @@ window.DefaultRules = (function() { } } - if (rule.hLength !== undefined && (rule.hLength !== "no default setting")) { + if (rule.hLength !== undefined && (rule.hLength !== null)) { if (slave.bald !== 1) { if ((slave.hLength !== rule.hLength)) { if ((slave.hLength > rule.hLength)) { @@ -2377,7 +2309,7 @@ window.DefaultRules = (function() { } } - if (rule.haircuts !== undefined && (rule.haircuts !== "no default setting")) { + if (rule.haircuts !== undefined && (rule.haircuts !== null)) { if (slave.bald !== 1) { if (rule.haircuts === 1 && slave.haircuts !== 1) { r += `<br>${slave.slaveName}'s hair will now be maintained at ${lengthToEitherUnit(slave.hLength)} long.`; @@ -2389,7 +2321,7 @@ window.DefaultRules = (function() { } } - if (rule.eyebrowHColor !== undefined && (rule.eyebrowHColor !== "no default setting")) { + if (rule.eyebrowHColor !== undefined && (rule.eyebrowHColor !== null)) { if (slave.eyebrowHStyle !== "bald" && slave.eyebrowHStyle !== "hairless") { if ((slave.eyebrowHColor !== rule.eyebrowHColor)) { slave.eyebrowHColor = rule.eyebrowHColor; @@ -2399,7 +2331,7 @@ window.DefaultRules = (function() { } } - if (rule.eyebrowHStyle !== undefined && (rule.eyebrowHStyle !== "no default setting")) { + if (rule.eyebrowHStyle !== undefined && (rule.eyebrowHStyle !== null)) { if (slave.eyebrowHStyle !== "bald" && slave.eyebrowHStyle !== "hairless") { if ((slave.eyebrowHStyle !== rule.eyebrowHStyle)) { slave.eyebrowHStyle = rule.eyebrowHStyle; @@ -2409,7 +2341,7 @@ window.DefaultRules = (function() { } } - if (rule.eyebrowFullness !== undefined && (rule.eyebrowFullness !== "no default setting")) { + if (rule.eyebrowFullness !== undefined && (rule.eyebrowFullness !== null)) { if (slave.eyebrowHStyle !== "bald" && slave.eyebrowHStyle !== "hairless") { if ((slave.eyebrowFullness !== rule.eyebrowFullness)) { slave.eyebrowFullness = rule.eyebrowFullness; @@ -2419,7 +2351,7 @@ window.DefaultRules = (function() { } } - if (rule.pubicHColor !== undefined && (rule.pubicHColor !== "no default setting")) { + if (rule.pubicHColor !== undefined && (rule.pubicHColor !== null)) { if (slave.pubicHStyle !== "bald" && slave.pubicHStyle !== "hairless") { if ((slave.pubicHColor !== rule.pubicHColor)) { slave.pubicHColor = rule.pubicHColor; @@ -2429,7 +2361,7 @@ window.DefaultRules = (function() { } } - if (rule.pubicHStyle !== undefined && (rule.pubicHStyle !== "no default setting")) { + if (rule.pubicHStyle !== undefined && (rule.pubicHStyle !== null)) { if (slave.pubicHStyle !== "bald" && slave.pubicHStyle !== "hairless") { if ((slave.pubicHStyle !== rule.pubicHStyle)) { slave.pubicHStyle = rule.pubicHStyle; @@ -2439,7 +2371,7 @@ window.DefaultRules = (function() { } } - if (rule.underArmHColor !== undefined && (rule.underArmHColor !== "no default setting")) { + if (rule.underArmHColor !== undefined && (rule.underArmHColor !== null)) { if (slave.underArmHStyle !== "bald" && slave.underArmHStyle !== "hairless") { if ((slave.underArmHColor !== rule.underArmHColor)) { slave.underArmHColor = rule.underArmHColor; @@ -2449,7 +2381,7 @@ window.DefaultRules = (function() { } } - if (rule.underArmHStyle !== undefined && (rule.underArmHStyle !== "no default setting")) { + if (rule.underArmHStyle !== undefined && (rule.underArmHStyle !== null)) { if (slave.underArmHStyle !== "bald" && slave.underArmHStyle !== "hairless") { if ((slave.underArmHStyle !== rule.underArmHStyle)) { slave.underArmHStyle = rule.underArmHStyle; @@ -2459,7 +2391,7 @@ window.DefaultRules = (function() { } } - if (rule.eyebrowHColor !== undefined && (rule.eyebrowHColor !== "no default setting")) { + if (rule.eyebrowHColor !== undefined && (rule.eyebrowHColor !== null)) { if (slave.eyebrowHStyle !== "bald") { if ((slave.eyebrowHColor !== rule.eyebrowHColor)) { slave.eyebrowHColor = rule.eyebrowHColor; @@ -2469,7 +2401,7 @@ window.DefaultRules = (function() { } } - if (rule.eyebrowHStyle !== undefined && (rule.eyebrowHStyle !== "no default setting")) { + if (rule.eyebrowHStyle !== undefined && (rule.eyebrowHStyle !== null)) { if (slave.eyebrowHStyle !== "bald") { if ((slave.eyebrowHStyle !== rule.eyebrowHStyle)) { slave.eyebrowHStyle = rule.eyebrowHStyle; @@ -2479,7 +2411,7 @@ window.DefaultRules = (function() { } } - if (rule.eyebrowFullness !== undefined && (rule.eyebrowFullness !== "no default setting")) { + if (rule.eyebrowFullness !== undefined && (rule.eyebrowFullness !== null)) { if (slave.eyebrowHStyle !== "bald") { if ((slave.eyebrowFullness !== rule.eyebrowFullness)) { slave.eyebrowFullness = rule.eyebrowFullness; @@ -2489,7 +2421,7 @@ window.DefaultRules = (function() { } } - if (rule.markings !== undefined && (rule.markings !== "no default setting")) { + if (rule.markings !== undefined && (rule.markings !== null)) { if (slave.markings === "beauty mark" && (rule.markings === "remove beauty marks" || rule.markings === "remove both")) { r += `<br>${slave.slaveName}'s beauty mark has been removed.`; slave.markings = "none"; @@ -2502,7 +2434,7 @@ window.DefaultRules = (function() { } } - if (rule.skinColor !== undefined && rule.skinColor !== "no default setting" && rule.skinColor !== slave.skin) { + if (rule.skinColor !== undefined && rule.skinColor !== null && rule.skinColor !== slave.skin) { if (rule.skinColor === "natural") { slave.skin = slave.origSkin; r += `<br>${slave.slaveName}'s skin color has been returned to ${slave.origSkin}.`; @@ -2513,8 +2445,9 @@ window.DefaultRules = (function() { } } + /** @param {App.Entity.SlaveState} slave */ function ProcessPiercings(slave, rule) { - if (rule.nipplesPiercing !== undefined && (rule.nipplesPiercing !== "no default setting")) { + if (rule.nipplesPiercing !== undefined && (rule.nipplesPiercing !== null)) { if ((slave.nipplesPiercing !== rule.nipplesPiercing)) { if ((rule.nipplesPiercing === 0)) { slave.nipplesPiercing = 0; @@ -2529,7 +2462,7 @@ window.DefaultRules = (function() { } } - if (rule.areolaePiercing !== undefined && (rule.areolaePiercing !== "no default setting")) { + if (rule.areolaePiercing !== undefined && (rule.areolaePiercing !== null)) { if ((slave.areolaePiercing !== rule.areolaePiercing)) { if ((rule.areolaePiercing === 0)) { slave.areolaePiercing = 0; @@ -2542,7 +2475,7 @@ window.DefaultRules = (function() { } } - if (rule.clitPiercing !== undefined && (rule.clitPiercing !== "no default setting")) { + if (rule.clitPiercing !== undefined && (rule.clitPiercing !== null)) { if ((slave.clitPiercing !== rule.clitPiercing)) { if ((rule.clitPiercing === 0)) { slave.clitPiercing = 0; @@ -2569,7 +2502,7 @@ window.DefaultRules = (function() { } if ((slave.vagina !== -1)) { - if (rule.vaginaPiercing !== undefined && (rule.vaginaPiercing !== "no default setting")) { + if (rule.vaginaPiercing !== undefined && (rule.vaginaPiercing !== null)) { if ((slave.vaginaPiercing !== rule.vaginaPiercing)) { if ((rule.vaginaPiercing === 0)) { slave.vaginaPiercing = 0; @@ -2584,7 +2517,7 @@ window.DefaultRules = (function() { } if ((slave.dick > 0)) { - if (rule.dickPiercing !== undefined && (rule.dickPiercing !== "no default setting")) { + if (rule.dickPiercing !== undefined && (rule.dickPiercing !== null)) { if ((slave.dickPiercing !== rule.dickPiercing)) { if ((rule.dickPiercing === 0)) { slave.dickPiercing = 0; @@ -2598,7 +2531,7 @@ window.DefaultRules = (function() { } } - if (rule.anusPiercing !== undefined && (rule.anusPiercing !== "no default setting")) { + if (rule.anusPiercing !== undefined && (rule.anusPiercing !== null)) { if ((slave.anusPiercing !== rule.anusPiercing)) { if ((rule.anusPiercing === 0)) { slave.anusPiercing = 0; @@ -2611,7 +2544,7 @@ window.DefaultRules = (function() { } } - if (rule.lipsPiercing !== undefined && (rule.lipsPiercing !== "no default setting")) { + if (rule.lipsPiercing !== undefined && (rule.lipsPiercing !== null)) { if ((slave.lipsPiercing !== rule.lipsPiercing)) { if ((rule.lipsPiercing === 0)) { slave.lipsPiercing = 0; @@ -2624,7 +2557,7 @@ window.DefaultRules = (function() { } } - if (rule.tonguePiercing !== undefined && (rule.tonguePiercing !== "no default setting")) { + if (rule.tonguePiercing !== undefined && (rule.tonguePiercing !== null)) { if ((slave.tonguePiercing !== rule.tonguePiercing)) { if ((rule.tonguePiercing === 0)) { slave.tonguePiercing = 0; @@ -2637,7 +2570,7 @@ window.DefaultRules = (function() { } } - if (rule.earPiercing !== undefined && (rule.earPiercing !== "no default setting")) { + if (rule.earPiercing !== undefined && (rule.earPiercing !== null)) { if ((slave.earPiercing !== rule.earPiercing)) { if ((rule.earPiercing === 0)) { slave.earPiercing = 0; @@ -2650,7 +2583,7 @@ window.DefaultRules = (function() { } } - if (rule.nosePiercing !== undefined && (rule.nosePiercing !== "no default setting")) { + if (rule.nosePiercing !== undefined && (rule.nosePiercing !== null)) { if ((slave.nosePiercing !== rule.nosePiercing)) { if ((rule.nosePiercing === 0)) { slave.nosePiercing = 0; @@ -2663,7 +2596,7 @@ window.DefaultRules = (function() { } } - if (rule.eyebrowPiercing !== undefined && (rule.eyebrowPiercing !== "no default setting")) { + if (rule.eyebrowPiercing !== undefined && (rule.eyebrowPiercing !== null)) { if ((slave.eyebrowPiercing !== rule.eyebrowPiercing)) { if ((rule.eyebrowPiercing === 0)) { slave.eyebrowPiercing = 0; @@ -2676,7 +2609,7 @@ window.DefaultRules = (function() { } } - if (rule.navelPiercing !== undefined && (rule.navelPiercing !== "no default setting")) { + if (rule.navelPiercing !== undefined && (rule.navelPiercing !== null)) { if ((slave.navelPiercing !== rule.navelPiercing)) { if ((rule.navelPiercing === 0)) { slave.navelPiercing = 0; @@ -2689,7 +2622,7 @@ window.DefaultRules = (function() { } } - if (rule.corsetPiercing !== undefined && (rule.corsetPiercing !== "no default setting")) { + if (rule.corsetPiercing !== undefined && (rule.corsetPiercing !== null)) { if ((slave.corsetPiercing !== rule.corsetPiercing)) { if ((rule.corsetPiercing === 0)) { slave.corsetPiercing = 0; @@ -2710,7 +2643,7 @@ window.DefaultRules = (function() { function ProcessSmartPiercings(slave, rule) { if ((slave.clitPiercing === 3)) { let _used = 0; - if (rule.clitSetting !== undefined && (rule.clitSetting !== "no default setting")) { + if (rule.clitSetting !== undefined && (rule.clitSetting !== null)) { if (slave.clitSetting !== rule.clitSetting) { slave.clitSetting = rule.clitSetting; _used = 1; @@ -2720,7 +2653,7 @@ window.DefaultRules = (function() { } } if (_used === 0) { - if (rule.clitSettingEnergy !== undefined && (rule.clitSettingEnergy !== "no default setting")) { + if (rule.clitSettingEnergy !== undefined && (rule.clitSettingEnergy !== null)) { if (slave.energy < rule.clitSettingEnergy) { if (slave.clitSetting !== "all") { r += `<br>${slave.slaveName}'s smart piercing has been set to enhance libido.`; @@ -2737,7 +2670,7 @@ window.DefaultRules = (function() { } } if (_used === 0) { - if (rule.clitSettingXY !== undefined && (rule.clitSettingXY !== "no default setting")) { + if (rule.clitSettingXY !== undefined && (rule.clitSettingXY !== null)) { if (slave.attrXY < rule.clitSettingXY) { if (slave.clitSetting !== "men") { r += `<br>${slave.slaveName}'s smart piercing has been set to encourage attraction to men.`; @@ -2754,7 +2687,7 @@ window.DefaultRules = (function() { } } if (_used === 0) { - if (rule.clitSettingXX !== undefined && (rule.clitSettingXX !== "no default setting")) { + if (rule.clitSettingXX !== undefined && (rule.clitSettingXX !== null)) { if (slave.attrXX < rule.clitSettingXX) { if (slave.clitSetting !== "women") { r += `<br>${slave.slaveName}'s smart piercing has been set to encourage attraction to women.`; @@ -2778,7 +2711,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessTattoos(slave, rule) { - if (rule.boobsTat !== undefined && (rule.boobsTat !== "no default setting")) { + if (rule.boobsTat !== undefined && (rule.boobsTat !== null)) { if ((slave.boobsTat !== rule.boobsTat)) { slave.boobsTat = rule.boobsTat; cashX(forceNeg(V.modCost), "slaveMod", slave); @@ -2786,7 +2719,7 @@ window.DefaultRules = (function() { } } - if (rule.buttTat !== undefined && (rule.buttTat !== "no default setting")) { + if (rule.buttTat !== undefined && (rule.buttTat !== null)) { if ((slave.buttTat !== rule.buttTat)) { slave.buttTat = rule.buttTat; cashX(forceNeg(V.modCost), "slaveMod", slave); @@ -2794,7 +2727,7 @@ window.DefaultRules = (function() { } } - if (rule.vaginaTat !== undefined && (rule.vaginaTat !== "no default setting")) { + if (rule.vaginaTat !== undefined && (rule.vaginaTat !== null)) { if ((slave.vaginaTat !== rule.vaginaTat)) { slave.vaginaTat = rule.vaginaTat; cashX(forceNeg(V.modCost), "slaveMod", slave); @@ -2803,7 +2736,7 @@ window.DefaultRules = (function() { } if ((slave.dick > 0)) { - if (rule.dickTat !== undefined && (rule.dickTat !== "no default setting")) { + if (rule.dickTat !== undefined && (rule.dickTat !== null)) { if ((slave.dickTat !== rule.dickTat)) { slave.dickTat = rule.dickTat; cashX(forceNeg(V.modCost), "slaveMod", slave); @@ -2812,7 +2745,7 @@ window.DefaultRules = (function() { } } - if (rule.lipsTat !== undefined && (rule.lipsTat !== "no default setting")) { + if (rule.lipsTat !== undefined && (rule.lipsTat !== null)) { if ((slave.lipsTat !== rule.lipsTat)) { slave.lipsTat = rule.lipsTat; cashX(forceNeg(V.modCost), "slaveMod", slave); @@ -2820,7 +2753,7 @@ window.DefaultRules = (function() { } } - if (rule.anusTat !== undefined && (rule.anusTat !== "no default setting")) { + if (rule.anusTat !== undefined && (rule.anusTat !== null)) { if ((slave.anusTat !== rule.anusTat)) { slave.anusTat = rule.anusTat; cashX(forceNeg(V.modCost), "slaveMod", slave); @@ -2828,7 +2761,7 @@ window.DefaultRules = (function() { } } - if (rule.backTat !== undefined && (rule.backTat !== "no default setting")) { + if (rule.backTat !== undefined && (rule.backTat !== null)) { if ((slave.backTat !== rule.backTat)) { slave.backTat = rule.backTat; cashX(forceNeg(V.modCost), "slaveMod", slave); @@ -2836,7 +2769,7 @@ window.DefaultRules = (function() { } } - if (rule.shouldersTat !== undefined && (rule.shouldersTat !== "no default setting")) { + if (rule.shouldersTat !== undefined && (rule.shouldersTat !== null)) { if ((slave.shouldersTat !== rule.shouldersTat)) { slave.shouldersTat = rule.shouldersTat; cashX(forceNeg(V.modCost), "slaveMod", slave); @@ -2844,7 +2777,7 @@ window.DefaultRules = (function() { } } - if (rule.armsTat !== undefined && (rule.armsTat !== "no default setting")) { + if (rule.armsTat !== undefined && (rule.armsTat !== null)) { if ((slave.armsTat !== rule.armsTat)) { slave.armsTat = rule.armsTat; cashX(forceNeg(V.modCost), "slaveMod", slave); @@ -2852,7 +2785,7 @@ window.DefaultRules = (function() { } } - if (rule.legsTat !== undefined && (rule.legsTat !== "no default setting")) { + if (rule.legsTat !== undefined && (rule.legsTat !== null)) { if ((slave.legsTat !== rule.legsTat)) { slave.legsTat = rule.legsTat; cashX(forceNeg(V.modCost), "slaveMod", slave); @@ -2860,7 +2793,7 @@ window.DefaultRules = (function() { } } - if (rule.stampTat !== undefined && (rule.stampTat !== "no default setting")) { + if (rule.stampTat !== undefined && (rule.stampTat !== null)) { if ((slave.stampTat !== rule.stampTat)) { slave.stampTat = rule.stampTat; cashX(forceNeg(V.modCost), "slaveMod", slave); @@ -2888,7 +2821,7 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessPornFeedEnabled(slave, rule) { - if (rule.pornFeed === undefined || rule.pornFeed === "no default setting") { + if (rule.pornFeed === undefined || rule.pornFeed === null) { return; } if (rule.pornFeed === slave.pornFeed) { @@ -2902,8 +2835,9 @@ window.DefaultRules = (function() { r += `<br>Highlights of ${slave.slaveName}'s sex life ${yesno} being released.`; } + /** @param {App.Entity.SlaveState} slave */ function ProcessPorn(slave, rule) { - if ((rule.pornFameSpending !== undefined) && (rule.pornFameSpending !== "no default setting")) { + if ((rule.pornFameSpending !== undefined) && (rule.pornFameSpending !== null)) { if ((slave.pornPrestige < 3)) { if ((slave.pornFameSpending !== rule.pornFameSpending)) { slave.pornFameSpending = rule.pornFameSpending; @@ -2918,12 +2852,12 @@ window.DefaultRules = (function() { * @param {object} rule */ function ProcessLabel(slave, rule) { - if (rule.label !== "no default setting" && !slave.custom.label.includes(`[${rule.label}]`)) { - slave.custom.label = `${slave.custom.label}[${rule.label}]`; + if (rule.label !== null && !slave.custom.label.includes(`[${rule.label}]`)) { + slave.custom.label = `${slave.custom.label }[${ rule.label }]`; r += `<br>${slave.slaveName} has been tagged as ${rule.label}`; } - if (rule.removeLabel !== "no default setting" && slave.custom.label.includes(`[${rule.removeLabel}]`)) { + if (rule.removeLabel !== null && slave.custom.label.includes(`[${rule.removeLabel}]`)) { slave.custom.label = slave.custom.label.replace(`[${rule.removeLabel}]`, ""); r += `<br>${slave.slaveName}'s tag [${rule.removeLabel}] is removed.`; } diff --git a/src/js/SlaveState.js b/src/js/SlaveState.js index 7c39cffc61f0c58ab845ec512e624533fcc70df1..d14393995577e0cf1ac4c5be16456049321ab545 100644 --- a/src/js/SlaveState.js +++ b/src/js/SlaveState.js @@ -2009,7 +2009,7 @@ App.Entity.SlaveState = class SlaveState { * * 0: not being rude; 1: insists on calling you a rude title */ this.rudeTitle = 0; - /** @type {number[]} */ + /** @type {string[]} */ this.currentRules = []; /** * Slave has a tattoo that is only recognizable when she has a big belly. @@ -2388,3 +2388,9 @@ App.Entity.SlaveState = class SlaveState { }; } }; + +/** + * @callback slaveOperation + * @param {App.Entity.SlaveState} s + * @returns {void} +*/ diff --git a/src/js/datatypeCleanupJS.js b/src/js/datatypeCleanupJS.js index 3b8f31d33d173ae59e370733d65c650a494264e7..afc3a4c21df195683630bd105c183a4e52e4a92e 100644 --- a/src/js/datatypeCleanupJS.js +++ b/src/js/datatypeCleanupJS.js @@ -1950,3 +1950,71 @@ App.Entity.Utils.GenePoolRecordCleanup = (function() { ].forEach((s) => delete slave[s]); } })(); + +App.Entity.Utils.RARuleDatatypeCleanup = function() { + "use strict"; + + return ruleCleanup; + + /** @param {App.RA.Rule} rule */ + function ruleCleanup(rule) { + specialSlavesRule(rule); + cleanupDefaultValues(rule); + cleanupSetters(rule); + } + + /** @param {App.RA.Rule} rule */ + function specialSlavesRule(rule) { + if (rule.condition.excludeSpecialSlaves) { + rule.condition.specialSlaves = 0; + } else { + rule.condition.specialSlaves = -1; + } + delete rule.condition.excludeSpecialSlaves; + } + + /** @param {App.RA.Rule} rule */ + function cleanupDefaultValues(rule) { + for (const k in rule.set) { + const v = rule.set[k]; + if (v === "no default setting") { + rule.set[k] = null; + } + } + } + + /** @param {App.RA.Rule} rule */ + function cleanupSetters(rule) { + const set = rule.set; + if (!([true, false, null].includes(set.preg))) { + set.preg = (set.preg === -1); + } + [ + 'haircuts', 'label', 'removeLabel', 'skinColor', + 'earwear', "surgery_hears", 'surgery_tastes', + 'surgery_vasectomy', 'surgery_smells', + 'toyHole', 'pornFeed', 'legAccessory', 'hyper_drugs' + ].forEach(prop => { + if (set[prop] === undefined) { + set[prop] = null; + } + }); + + if (set.pornFameSpending === undefined || set.pornFameSpending === -1) { + set.pornFameSpending = null; + } + + [ + 'growth_boobs', 'growth_butt', 'growth_lips', 'growth_dick', 'growth_balls', + 'muscles', + 'surgery_butt', 'surgery_boobs', 'surgery_lips' + ].forEach(p => { + let v = set[p]; + if (v !== null) { + set[p] = App.RA.makeTarget('==', v); + } + }); + + rule.set.growth_intensity = Math.clamp(+rule.set.growth_intensity, 0, 1) || 0; + } +}(); diff --git a/src/js/rulesAssistant.js b/src/js/rulesAssistant.js index 22a80143d2974600d08dd0ad689b8c490ebd2e70..268e1f40925ab037ddee95d8a81cb205b8ea86a5 100644 --- a/src/js/rulesAssistant.js +++ b/src/js/rulesAssistant.js @@ -16,7 +16,7 @@ window.hasSurgeryRule = function(slave, rules) { */ window.hasRuleFor = function(slave, rules, what) { return rules.some( - rule => ruleApplied(slave, rule) && rule[what] !== "no default setting"); + rule => ruleApplied(slave, rule) && rule[what] !== null); }; /** @@ -30,7 +30,7 @@ window.hasHColorRule = function(slave, rules) { /** * @param {App.Entity.SlaveState} slave - * @param {Object[]} rules + * @param {App.RA.Rule[]} rules * @returns {boolean} * */ window.hasHStyleRule = function(slave, rules) { @@ -39,7 +39,7 @@ window.hasHStyleRule = function(slave, rules) { /** * @param {App.Entity.SlaveState} slave - * @param {Object[]} rules + * @param {App.RA.Rule[]} rules * @returns {boolean} * */ window.hasEyeColorRule = function(slave, rules) { @@ -49,7 +49,7 @@ window.hasEyeColorRule = function(slave, rules) { /** * return if a rule is applied on a slave * @param {App.Entity.SlaveState} slave - * @param {Object[]} rules + * @param {App.RA.Rule[]} rules * @returns {boolean} */ window.lastPregRule = function(slave, rules) { @@ -58,21 +58,21 @@ window.lastPregRule = function(slave, rules) { }; /** - * @param {Object[]} rules - * @returns {Object} + * @param {App.RA.Rule[]} rules + * @returns {App.RA.RuleSetters} */ -window.mergeRules = function mergeRules(rules) { +window.mergeRules = function (rules) { const combinedRule = {}; rules.forEach(rule => { // A rule overrides any preceding ones if, // * there are no preceding ones, // * or it sets autoBrand, - // * or it does not set autoBrand and is not "no default setting" + // * or it does not set autoBrand and is not null Object.keys(rule).forEach(key => { const applies = (combinedRule[key] === undefined || (key === "autoBrand" && rule[key]) || - (key !== "autoBrand" && rule[key] !== "no default setting")); - if (!applies) { return; } + (key !== "autoBrand" && rule[key] !== null)); + if (!applies) return; combinedRule[key] = rule[key]; }); }); @@ -82,7 +82,7 @@ window.mergeRules = function mergeRules(rules) { /** * return if a rule is applied on a slave * @param {App.Entity.SlaveState} slave - * @param {Object} rule + * @param {App.RA.Rule} rule * @returns {boolean} */ window.ruleApplied = function(slave, rule) { @@ -116,7 +116,7 @@ window.RAFacilityRemove = function RAFacilityRemove(slave, rule) { case "serve in the club": if (slave.assignment === rule.setAssignment) { - r += `<br>${slave.slaveName} has been removed from ${clubName} and has been assigned to ${rule.removalAssignment}.`; + r += `<br>${slave.slaveName} has been removed from ${V.clubName} and has been assigned to ${rule.removalAssignment}.`; assignJob(slave, rule.removalAssignment); } break; @@ -165,7 +165,7 @@ window.RAFacilityRemove = function RAFacilityRemove(slave, rule) { case "live with your Head Girl": if (slave.assignment === rule.setAssignment) { - r += `<br>${slave.slaveName} has been removed from ${HGSuiteName} and has been assigned to ${rule.removalAssignment}.`; + r += `<br>${slave.slaveName} has been removed from ${V.HGSuiteName} and has been assigned to ${rule.removalAssignment}.`; assignJob(slave, rule.removalAssignment); } break; @@ -238,7 +238,7 @@ window.ruleAppliesP = function ruleAppliesP(cond, slave) { }; /** - * @returns {Object} + * @returns {App.RA.Rule} */ window.emptyDefaultRule = function emptyDefaultRule() { const id = generateNewID(); @@ -256,132 +256,134 @@ window.emptyDefaultRule = function emptyDefaultRule() { /* eslint-disable */ // TODO: rename properties in snake_case to camelCase? set: { - releaseRules: "no default setting", - toyHole: "no default setting", - clitSetting: "no default setting", - clitSettingXY: "no default setting", - clitSettingXX: "no default setting", - clitSettingEnergy: "no default setting", - speechRules: "no default setting", - clothes: "no default setting", - collar: "no default setting", - shoes: "no default setting", - legAccessory: "no default setting", - chastityVagina: "no default setting", - chastityAnus: "no default setting", - chastityPenis: "no default setting", - virginAccessory: "no default setting", - aVirginAccessory: "no default setting", - vaginalAccessory: "no default setting", - aVirginDickAccessory: "no default setting", - dickAccessory: "no default setting", - bellyAccessory: "no default setting", - aVirginButtplug: "no default setting", - buttplug: "no default setting", - buttplugAttachment: "no default setting", - eyeColor: "no default setting", - makeup: "no default setting", - nails: "no default setting", - hColor: "no default setting", - hLength: "no default setting", - haircuts: "no default setting", - hStyle: "no default setting", - eyebrowHColor: "no default setting", - eyebrowHStyle: "no default setting", - eyebrowFullness: "no default setting", - markings: "no default setting", - pubicHColor: "no default setting", - pubicHStyle: "no default setting", - nipplesPiercing: "no default setting", - areolaePiercing: "no default setting", - clitPiercing: "no default setting", - vaginaLube: "no default setting", - vaginaPiercing: "no default setting", - dickPiercing: "no default setting", - anusPiercing: "no default setting", - lipsPiercing: "no default setting", - tonguePiercing: "no default setting", - earPiercing: "no default setting", - nosePiercing: "no default setting", - eyebrowPiercing: "no default setting", - navelPiercing: "no default setting", - corsetPiercing: "no default setting", - boobsTat: "no default setting", - buttTat: "no default setting", - vaginaTat: "no default setting", - dickTat: "no default setting", - lipsTat: "no default setting", - anusTat: "no default setting", - shouldersTat: "no default setting", - armsTat: "no default setting", - legsTat: "no default setting", - backTat: "no default setting", - stampTat: "no default setting", - curatives: "no default setting", - livingRules: "no default setting", - relationshipRules: "no default setting", - standardPunishment: "no default setting", - standardReward: "no default setting", - diet: "no default setting", - dietCum: "no default setting", - dietMilk: "no default setting", - onDiet: "no default setting", - muscles: "no default setting", - XY: "no default setting", - XX: "no default setting", - gelding: "no default setting", - preg: "no default setting", - abortion: "no default setting", - growth_boobs: "no default setting", - growth_butt: "no default setting", - growth_lips: "no default setting", - growth_dick: "no default setting", - growth_balls: "no default setting", + releaseRules: null, + toyHole: null, + clitSetting: null, + clitSettingXY: null, + clitSettingXX: null, + clitSettingEnergy: null, + speechRules: null, + clothes: null, + collar: null, + shoes: null, + legAccessory: null, + chastityVagina: null, + chastityAnus: null, + chastityPenis: null, + virginAccessory: null, + aVirginAccessory: null, + vaginalAccessory: null, + aVirginDickAccessory: null, + dickAccessory: null, + bellyAccessory: null, + aVirginButtplug: null, + buttplug: null, + buttplugAttachment: null, + vaginalAttachment: null, + eyeColor: null, + makeup: null, + nails: null, + hColor: null, + hLength: null, + haircuts: null, + hStyle: null, + eyebrowHColor: null, + eyebrowHStyle: null, + eyebrowFullness: null, + markings: null, + pubicHColor: null, + pubicHStyle: null, + nipplesPiercing: null, + areolaePiercing: null, + clitPiercing: null, + vaginaLube: null, + vaginaPiercing: null, + dickPiercing: null, + anusPiercing: null, + lipsPiercing: null, + tonguePiercing: null, + earPiercing: null, + nosePiercing: null, + eyebrowPiercing: null, + navelPiercing: null, + corsetPiercing: null, + boobsTat: null, + buttTat: null, + vaginaTat: null, + dickTat: null, + lipsTat: null, + anusTat: null, + shouldersTat: null, + armsTat: null, + legsTat: null, + backTat: null, + stampTat: null, + curatives: null, + livingRules: null, + relationshipRules: null, + standardPunishment: null, + standardReward: null, + diet: null, + dietCum: null, + dietMilk: null, + onDiet: null, + muscles: null, + XY: null, + XX: null, + gelding: null, + preg: null, + abortion: null, + growth_boobs: null, + growth_butt: null, + growth_lips: null, + growth_dick: null, + growth_balls: null, + growth_intensity: 0, hyper_drugs: 0, - aphrodisiacs: "no default setting", + aphrodisiacs: null, autoSurgery: 0, autoBrand: 0, - pornFeed: "no default setting", - pornFameSpending: "no default setting", + pornFeed: null, + pornFameSpending: null, dietGrowthSupport: 0, - eyewear: "no default setting", - earwear: "no default setting", - setAssignment: "no default setting", + eyewear: null, + earwear: null, + setAssignment: null, facilityRemove: false, removalAssignment: "rest", - surgery_eyes: "no default setting", - surgery_hears: "no default setting", - surgery_smells: "no default setting", - surgery_tastes: "no default setting", - surgery_lactation: "no default setting", - surgery_prostate: "no default setting", - surgery_cosmetic: "no default setting", - surgery_accent: "no default setting", - surgery_shoulders: "no default setting", - surgery_shouldersImplant: "no default setting", - surgery_boobs: "no default setting", - surgery_hips: "no default setting", - surgery_hipsImplant: "no default setting", - surgery_butt: "no default setting", - surgery_faceShape: "no default setting", - surgery_lips: "no default setting", - surgery_holes: "no default setting", - surgery_tummy: "no default setting", - surgery_hair: "no default setting", - surgery_bodyhair: "no default setting", - surgery_vasectomy: "no default setting", - surgery_bellyImplant: "no default setting", - underArmHColor: "no default setting", - underArmHStyle: "no default setting", - drug: "no default setting", - eyes: "no default setting", - pregSpeed: "no default setting", + surgery_eyes: null, + surgery_hears: null, + surgery_smells: null, + surgery_tastes: null, + surgery_lactation: null, + surgery_prostate: null, + surgery_cosmetic: null, + surgery_accent: null, + surgery_shoulders: null, + surgery_shouldersImplant: null, + surgery_boobs: null, + surgery_hips: null, + surgery_hipsImplant: null, + surgery_butt: null, + surgery_faceShape: null, + surgery_lips: null, + surgery_holes: null, + surgery_tummy: null, + surgery_hair: null, + surgery_bodyhair: null, + surgery_vasectomy: null, + surgery_bellyImplant: null, + underArmHColor: null, + underArmHStyle: null, + drug: null, + eyes: null, + pregSpeed: null, bellyImplantVol: -1, - teeth: "no default setting", - label: "no default setting", - removeLabel: "no default setting", - skinColor: "no default setting", - inflationType: "no default setting", + teeth: null, + label: null, + removeLabel: null, + skinColor: null, + inflationType: null, } /* eslint-enable */ }; @@ -454,3 +456,42 @@ window.RASummaryCell = function RASummaryCell() { } return r; }; + +/** + * Creates RA target object used in rules for body properties + * @param {string} condition comparison condition. One of '==', '>=', '<=', '>', '<' + * @param {number} val target value + * @returns {App.RA.NumericTarget} + */ +App.RA.makeTarget = function(condition, val) { + return { + cond: condition, + val: val + }; +}; + +/** + * Shall the current value be increased according to the target and condition + * @param {number} current + * @param {App.RA.NumericTarget} target + * @param {number} [step=1] change step + * @returns {boolean} + */ +App.RA.shallGrow = function(current, target, step = 1) { + return target && (((current < target.val - step) && (target.cond === '==')) || + ((current < target.val) && (target.cond === '>=' || target.cond === '>')) || + (current === target.val && target.cond === '>')); +}; + +/** + * Shall the current value be decreased according to the target and condition + * @param {number} current + * @param {App.RA.NumericTarget} target + * @param {number} [step=1] + * @returns {boolean} + */ +App.RA.shallShrink = function(current, target, step = 1) { + return target && (((current > target.val + step) && (target.cond === '==')) || + ((current > target.val) && (target.cond === '<=' || target.cond === '<')) || + (current === target.val && target.cond === '<')); +}; diff --git a/src/js/rulesAssistantOptions.js b/src/js/rulesAssistantOptions.js index a7adf9391d220732597455d3d49d6d6112fab90c..b67cf97c392f5fa54d84bb3f832b0a6830fc738b 100644 --- a/src/js/rulesAssistantOptions.js +++ b/src/js/rulesAssistantOptions.js @@ -7,7 +7,9 @@ window.rulesAssistantOptions = (function() { "use strict"; - let V, current_rule; + let V; + /** @type {App.RA.Rule} */ + let current_rule; function rulesAssistantOptions(element) { V = State.variables; @@ -115,7 +117,10 @@ window.rulesAssistantOptions = (function() { this.element.appendChild(child.element); } - // return the first argument to simplify creation of basic container items + /** + * returns the first argument to simplify creation of basic container items + * @returns {*} + */ render(...args) { return args[0]; } @@ -169,9 +174,22 @@ window.rulesAssistantOptions = (function() { // value display can optionally be an editable text input field // it can be "bound" to a variable by setting its "onchange" method class EditorWithShortcuts extends Element { - constructor(prefix, data = [], editor = false, ...args) { + /** + * + * @param {string} prefix + * @param {Array} [data] + * @param {boolean} [allowNullValue] + * @param {boolean} [editor] + * @param {...any} args + */ + constructor(prefix, data = [], allowNullValue = true, editor = false, ...args) { super(`${prefix}: `, editor, ...args); this.selectedItem = null; + /** @protected */ + this._allowNullValue = allowNullValue; + if (allowNullValue) { + this.appendChild(new ListItem("no default setting", null)); + } data.forEach(item => this.appendChild(new ListItem(...item))); } @@ -201,10 +219,11 @@ window.rulesAssistantOptions = (function() { } setValue(what) { + const str = what === null ? "no default setting" : `${what}`; if (this.value.tagName === "INPUT") { - this.value.value = `${what}`; + this.value.value = str; } else { - this.value.innerHTML = `${what}`; + this.value.innerHTML = str; } } @@ -253,8 +272,8 @@ window.rulesAssistantOptions = (function() { } class List extends EditorWithShortcuts { - constructor(prefix, data = [], textinput = false) { - super(prefix, data, textinput); + constructor(prefix, data = [], allowNullValue = true, textinput = false) { + super(prefix, data, allowNullValue, textinput); } createEditor() { @@ -273,28 +292,71 @@ window.rulesAssistantOptions = (function() { } class NumberRange extends EditorWithShortcuts { - constructor(prefix, data = [], min, max, spinbox = false) { - super(prefix, data, spinbox, min, max); - this.nullValue = data.length ? data[0][1] : null; + /** + * @param {string} prefix + * @param {Array} [data=[]] + * @param {boolean} [allowNullValue=true] + * @param {number} [min=0] + * @param {number} [max=100] + * @param {boolean} [spinBox=false] + */ + constructor(prefix, data = [], allowNullValue = true, min = 0, max = 100, spinBox = false) { + super(prefix, data, allowNullValue, spinBox, min, max); } createEditor(min, max) { - let res = document.createElement("input"); - res.setAttribute("type", "number"); - res.setAttribute("min", min); - res.setAttribute("max", max); - res.classList.add("rajs-value"); // - res.onblur = () => { + function makeOp(op, ui) { + return {op: op, ui: ui}; + } + this.opSelector = document.createElement("select"); + for (const o of [makeOp('==', '='), makeOp('>=', "⩾"), makeOp('<=', '⩽'), makeOp('>', '>'), makeOp('<', '<')]) { + let opt = document.createElement("option"); + opt.textContent = o.ui; + opt.value = o.op; + this.opSelector.appendChild(opt); + } + this.opSelector.classList.add("rajs-list"); + this.opSelector.onchange = () => { this.inputEdited(); }; - res.onkeypress = (e) => { - if (returnP(e)) { this.inputEdited(); } + + this.numEditor = document.createElement("input"); + this.numEditor.setAttribute("type", "number"); + this.numEditor.setAttribute("min", min); + this.numEditor.setAttribute("max", max); + this.numEditor.classList.add("rajs-value"); // + this.numEditor.onblur = () => { + this.inputEdited(); + }; + this.numEditor.onkeypress = (e) => { + if (returnP(e)) this.inputEdited(); }; + + const res = document.createElement("span"); + res.appendChild(this.opSelector); + res.appendChild(this.numEditor); return res; } parse(what) { - return what === "" ? this.nullValue : parseInt(what); + return what === "" ? null : parseInt(what); + } + + setValue(what) { + if (typeof what === 'number') { // comes from a pre-set + this.numEditor.value = what.toString(); + } else if (what === null) { + this.numEditor.value = null; + this.opSelector.value = '=='; + } else if (typeof what === 'object') { + this.numEditor.value = what.val; + this.opSelector.value = what.cond; + } + } + + getData(what) { + const v = this.parse(this.numEditor.value); + return v === null ? null : App.RA.makeTarget(this.opSelector.value, v); } } @@ -434,8 +496,12 @@ window.rulesAssistantOptions = (function() { try { const rule = JSON.parse(text); if (rule instanceof Array) { - rule.forEach(r => V.defaultRules.push(r)); + rule.forEach(r => { + App.Entity.Utils.RARuleDatatypeCleanup(r); + V.defaultRules.push(r); + }); } else { + App.Entity.Utils.RARuleDatatypeCleanup(rule); V.defaultRules.push(rule); } reload(this.root); @@ -485,7 +551,7 @@ window.rulesAssistantOptions = (function() { // buttons for selecting the current rule class RuleSelector extends List { constructor(root) { - super("Current rule", V.defaultRules.map(i => [i.name, i])); + super("Current rule", V.defaultRules.map(i => [i.name, i]), false); this.setValue(current_rule.name); this.onchange = function(rule) { V.currentRule = rule.ID; @@ -964,13 +1030,13 @@ window.rulesAssistantOptions = (function() { class EffectEditor extends Element { constructor() { super(); - this.appendChild(new AppearanceSection()); - this.appendChild(new CosmeticSection()); - this.appendChild(new BodyModSection()); - this.appendChild(new AutosurgerySection()); - this.appendChild(new RegimenSection()); - this.appendChild(new BehaviourSection()); - this.appendChild(new OtherSection()); + this.appendChild(new AppearanceSection(true)); + this.appendChild(new CosmeticSection(true)); + this.appendChild(new BodyModSection(true)); + this.appendChild(new AutosurgerySection(true)); + this.appendChild(new RegimenSection(true)); + this.appendChild(new BehaviourSection(true)); + this.appendChild(new OtherSection(true)); } render() { @@ -980,8 +1046,8 @@ window.rulesAssistantOptions = (function() { } class AppearanceSection extends Section { - constructor() { - super("Appearance Settings"); + constructor(isCollapsed) { + super("Appearance Settings", isCollapsed); this.appendChild(new ClothesList()); this.appendChild(new CollarList()); this.appendChild(new ShoeList()); @@ -1006,11 +1072,11 @@ window.rulesAssistantOptions = (function() { } class RegimenSection extends Section { - constructor() { - super("Physical Regimen Settings"); - if (V.arcologies[0].FSAssetExpansionistResearch === 1) { + constructor(isCollapsed) { + super("Physical Regimen Settings", isCollapsed); + if (V.arcologies[0].FSAssetExpansionistResearch === 1) this.appendChild(new HyperGrowthSwitch()); - } + this.appendChild(new IntensiveGrowthSwitch()); this.appendChild(new GrowthList()); this.appendChild(new CurrativesList()); this.appendChild(new AphrodisiacList()); @@ -1038,8 +1104,8 @@ window.rulesAssistantOptions = (function() { } class BehaviourSection extends Section { - constructor() { - super("Behavior Settings"); + constructor(isCollapsed) { + super("Behavior Settings", isCollapsed); this.appendChild(new AutomaticAssignmentList()); this.appendChild(new LivingStandardList()); this.appendChild(new PunishmentList()); @@ -1060,16 +1126,16 @@ window.rulesAssistantOptions = (function() { } class OtherSection extends Section { - constructor() { - super("Other Settings"); + constructor(isCollapsed) { + super("Other Settings", isCollapsed); this.appendChild(new LabelList()); this.appendChild(new LabelRemoveList()); } } class CosmeticSection extends Section { - constructor() { - super("Cosmetic Settings", true); + constructor(isCollapsed) { + super("Cosmetic Settings", isCollapsed); this.appendChild(new EyewearList()); this.appendChild(new LensesList()); this.appendChild(new EarwearList()); @@ -1092,8 +1158,8 @@ window.rulesAssistantOptions = (function() { } class BodyModSection extends Section { - constructor() { - super("Body Mod Settings", true); + constructor(isCollapsed) { + super("Body Mod Settings", isCollapsed); this.appendChild(new EarPiercingList()); this.appendChild(new NosePiercingList()); this.appendChild(new EyebrowPiercingList()); @@ -1163,7 +1229,6 @@ window.rulesAssistantOptions = (function() { super("Clothes", items); const nclothes = [ - ["No default clothes setting", "no default setting"], ["Apron", "an apron"], ["Ballgown", "a ball gown"], ["Bangles", "slutty jewelry"], @@ -1299,7 +1364,6 @@ window.rulesAssistantOptions = (function() { class CollarList extends List { constructor() { const items = [ - ["No default collar setting", "no default setting"], ["No collar", "none"], ]; super("Collar", items); @@ -1371,7 +1435,6 @@ window.rulesAssistantOptions = (function() { class LeggingsList extends List { constructor() { const items = [ - ["No default setting", "no default setting"], ["None", "none"], ["Short stockings", "short stockings"], ["Long stockings", "long stockings"], @@ -1385,7 +1448,6 @@ window.rulesAssistantOptions = (function() { class VagChastityList extends List { constructor() { const chaste = [ - ["No default setting", "no default setting"], ["None", 0], ["Chastity", 1], ]; @@ -1462,7 +1524,6 @@ window.rulesAssistantOptions = (function() { class DickChastityList extends List { constructor() { const items = [ - ["No default setting", "no default setting"], ["None", 0], ["Chastity cage", 1], ]; @@ -1491,7 +1552,6 @@ window.rulesAssistantOptions = (function() { class AnalChastityList extends List { constructor() { const items = [ - ["No default setting", "no default setting"], ["None", 0], ["Chastity", 1], ]; @@ -1565,7 +1625,7 @@ window.rulesAssistantOptions = (function() { ["Full-term with septuplets", 105000], ["Full-term with octuplets", 120000] ]; - super("Belly implant target volume (if present)", pairs); + super("Belly implant target volume (if present)", pairs, false); this.setValue(current_rule.set.bellyImplantVol); this.onchange = (value) => current_rule.set.bellyImplantVol = value; } @@ -1577,19 +1637,31 @@ window.rulesAssistantOptions = (function() { ["Activate", 1], ["Off", 0], ]; - super("Assistant-applied implants (Autosurgery global switch)", pairs); + super("Assistant-applied implants (Autosurgery global switch)", pairs, false); this.setValue(current_rule.set.autoSurgery); this.onchange = (value) => current_rule.set.autoSurgery = value; } } + class IntensiveGrowthSwitch extends List { + constructor() { + const pairs = [ + ["No", 0], + ["Yes", 1], + ]; + super("Use intensive growth drugs for healthy slaves", pairs, false); + this.setValue(current_rule.set.growth_intensity); + this.onchange = (value) => current_rule.set.growth_intensity = value; + } + } + class HyperGrowthSwitch extends List { constructor() { const pairs = [ ["No", 0], ["Yes", 1], ]; - super("Use hyper growth drugs", pairs); + super("Use hyper growth drugs", pairs, false); this.setValue(current_rule.set.hyper_drugs); this.onchange = (value) => current_rule.set.hyper_drugs = value; } @@ -1633,50 +1705,50 @@ window.rulesAssistantOptions = (function() { nds() { [this.breasts, this.butts, this.lips, this.dicks, this.balls].forEach(i => { - i.setValue("no default change"); + i.setValue(null); i.propagateChange(); }); } girlish() { - this.breasts.setValue(350); - this.butts.setValue(2); - this.lips.setValue(25); - if (this.dicks) { this.dicks.setValue(0); } - if (this.balls) { this.balls.setValue(0); } + this.breasts.setValue(App.RA.makeTarget('<=', 350)); + this.butts.setValue(App.RA.makeTarget('<=', 2)); + this.lips.setValue(App.RA.makeTarget('<=', 25)); + if (this.dicks) this.dicks.setValue(App.RA.makeTarget('==', 0)); + if (this.balls) this.balls.setValue(App.RA.makeTarget('==', 0)); this.sublists.forEach(i => i.propagateChange()); } stacked() { - this.breasts.setValue(1000); - this.butts.setValue(5); - this.lips.setValue(25); - if (this.dicks) { this.dicks.setValue(4); } - if (this.balls) { this.balls.setValue(4); } + this.breasts.setValue(App.RA.makeTarget('>=', 1000)); + this.butts.setValue(App.RA.makeTarget('>=', 5)); + this.lips.setValue(App.RA.makeTarget('>=', 25)); + if (this.dicks) this.dicks.setValue(App.RA.makeTarget('>=', 4)); + if (this.balls) this.balls.setValue(App.RA.makeTarget('>=', 4)); this.sublists.forEach(i => i.propagateChange()); } huge() { - this.breasts.setValue(9000); - this.butts.setValue(10); - this.lips.setValue(45); - if (this.dicks) { this.dicks.setValue(6); } - if (this.balls) { this.balls.setValue(6); } + this.breasts.setValue(App.RA.makeTarget('>=', 9000)); + this.butts.setValue(App.RA.makeTarget('>=', 10)); + this.lips.setValue(App.RA.makeTarget('>=', 45)); + if (this.dicks) this.dicks.setValue(App.RA.makeTarget('>=', 6)); + if (this.balls) this.balls.setValue(App.RA.makeTarget('>=', 6)); this.sublists.forEach(i => i.propagateChange()); } unlimited() { - this.breasts.setValue(48000); - this.butts.setValue(20); - this.lips.setValue(100); - if (this.dicks) { this.dicks.setValue(30); } - if (this.balls) { this.balls.setValue(125); } + this.breasts.setValue(App.RA.makeTarget('>=', 48000)); + this.butts.setValue(App.RA.makeTarget('>=', 20)); + this.lips.setValue(App.RA.makeTarget('>=', 100)); + if (this.dicks) this.dicks.setValue(App.RA.makeTarget('>=', 30)); + if (this.balls) this.balls.setValue(App.RA.makeTarget('>=', 125)); this.sublists.forEach(i => i.propagateChange()); } none() { this.sublists.forEach(i => { - i.setValue(0); + i.setValue(App.RA.makeTarget('==', 0)); i.propagateChange(); }); } @@ -1685,14 +1757,13 @@ window.rulesAssistantOptions = (function() { class BreastGrowthList extends NumberRange { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["B-Cup", 350], ["D-Cup", 1000], ["Monstrous", 9000], ["Unlimited", 48000], ["None", 0] ]; - super("Breasts", pairs, 0, 48000, true); + super("Breasts", pairs, true, 0, 48000, true); this.setValue(current_rule.set.growth_boobs); this.onchange = (value) => current_rule.set.growth_boobs = value; } @@ -1701,14 +1772,13 @@ window.rulesAssistantOptions = (function() { class ButtGrowthList extends NumberRange { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Cute", 2], ["Big", 4], ["Huge", 6], ["Unlimited", 20], ["None", 0] ]; - super("Butts", pairs, 0, 20, true); + super("Butts", pairs, true, 0, 20, true); this.setValue(current_rule.set.growth_butt); this.onchange = (value) => current_rule.set.growth_butt = value; } @@ -1717,13 +1787,12 @@ window.rulesAssistantOptions = (function() { class LipGrowthList extends NumberRange { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Plump", 25], ["Beestung", 45], ["Facepussy", 100], ["None", 0] ]; - super("Lips", pairs, 0, 100, true); + super("Lips", pairs, true, 0, 100, true); this.setValue(current_rule.set.growth_lips); this.onchange = (value) => current_rule.set.growth_lips = value; } @@ -1732,13 +1801,12 @@ window.rulesAssistantOptions = (function() { class DickGrowthList extends NumberRange { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Above average", 4], ["Pornstar", 6], ["Unlimited", 30], ["None", 0] ]; - super("Dicks, if present", pairs, 0, 30, true); + super("Dicks, if present", pairs, true, 0, 30, true); this.setValue(current_rule.set.growth_dick); this.onchange = (value) => current_rule.set.growth_dick = value; } @@ -1747,13 +1815,12 @@ window.rulesAssistantOptions = (function() { class BallGrowthList extends NumberRange { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Sizable", 4], ["Cumslave", 6], ["Unlimited", 125], ["None", 0] ]; - super("Balls, if present", pairs, 0, 125, true); + super("Balls, if present", pairs, true, 0, 125, true); this.setValue(current_rule.set.growth_balls); this.onchange = (value) => current_rule.set.growth_balls = value; } @@ -1762,7 +1829,6 @@ window.rulesAssistantOptions = (function() { class CurrativesList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Preventatives", 1], ["Curatives", 2], @@ -1776,7 +1842,6 @@ window.rulesAssistantOptions = (function() { class AphrodisiacList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Standard", 1], ["Extreme", 2], @@ -1791,7 +1856,6 @@ window.rulesAssistantOptions = (function() { class ContraceptiveList extends List { constructor() { const drugs = [ - ["No default setting", "no default setting"], ["Contraceptives", true], ["Fertile", false], ]; @@ -1804,7 +1868,6 @@ window.rulesAssistantOptions = (function() { class AbortionList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Abort all", "all"], ]; if (V.pregnancyMonitoringUpgrade === 1 && V.geneticMappingUpgrade === 1) { @@ -1820,7 +1883,6 @@ window.rulesAssistantOptions = (function() { class PregDrugsList extends List { constructor() { const pairs = [ - ["No changes", "no default setting"], ["None", "none"], ["Fast gestation", "fast"], ["Slow gestation", "slow"], @@ -1836,7 +1898,6 @@ window.rulesAssistantOptions = (function() { class FemaleHormonesList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Intensive Female", 2], ["Female", 1], ["None", 0], @@ -1852,7 +1913,6 @@ window.rulesAssistantOptions = (function() { class GeldingHormonesList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Intensive Female", 2], ["Female", 1], ["None", 0], @@ -1868,7 +1928,6 @@ window.rulesAssistantOptions = (function() { class ShemaleHormonesList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Intensive Female", 2], ["Female", 1], ["None", 0], @@ -1884,7 +1943,6 @@ window.rulesAssistantOptions = (function() { class OtherDrugsList extends List { constructor() { const drugs = [ - ["No default setting", "no default setting"], ["None", "none"], ["Fertility drugs", "fertility drugs"], ["Psychosuppressants", "psychosuppressants"], @@ -1945,7 +2003,6 @@ window.rulesAssistantOptions = (function() { class EnemaList extends List { constructor() { const enemas = [ - ["No default setting", "no default setting"], ["None", "none"], ["Water", "water"] ]; @@ -1965,7 +2022,6 @@ window.rulesAssistantOptions = (function() { class DietList extends List { constructor() { const diets = [ - ["no default setting", "no default setting"], ["Healthy diet", "healthy"], ["Fix fat and skinny slaves", "attractive"], ["Curvy", 30], @@ -1991,7 +2047,7 @@ window.rulesAssistantOptions = (function() { diets.push(["Cum production", "cum production"]); } - super("Slave diets", diets, true); + super("Slave diets", diets, true, true); this.setValue(current_rule.set.diet); this.onchange = (value) => current_rule.set.diet = value; } @@ -2003,7 +2059,7 @@ window.rulesAssistantOptions = (function() { ["On", 1], ["Off", 0] ]; - super("Diet support for growth drugs", pairs); + super("Diet support for growth drugs", pairs, false); this.setValue(current_rule.set.dietGrowthSupport); this.onchange = (value) => current_rule.set.dietGrowthSupport = value; } @@ -2013,7 +2069,7 @@ window.rulesAssistantOptions = (function() { constructor() { // TODO: better data structure? const pairs = [ - ["No default setting", {cum: "no default setting", milk: "no default setting"}], + ["No default setting", {cum: null, milk: null}], ["Normal Diet", {cum: 0, milk: 0}], ["Cum Added", {cum: 1, milk: 0}], ["Milk Added", {cum: 0, milk: 1}], @@ -2021,7 +2077,7 @@ window.rulesAssistantOptions = (function() { ["Cum-Based", {cum: 2, milk: 0}], ["Milk-Based", {cum: 0, milk: 2}], ]; - super("Diet base", pairs); + super("Diet base", pairs, false); this.setValue(this.value2string(current_rule.set.dietCum, current_rule.set.dietMilk)); this.onchange = (value) => { current_rule.set.dietCum = value.cum; @@ -2038,7 +2094,6 @@ window.rulesAssistantOptions = (function() { class DietSolidFoodList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Permitted", 0], ["Forbidden", 1], ]; @@ -2051,14 +2106,13 @@ window.rulesAssistantOptions = (function() { class MuscleList extends NumberRange { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Toned", 20], ["Ripped", 50], ["Massive", 100], ["Weak", -20] ]; - super("Muscles", pairs, -20, 100, true); + super("Muscles", pairs, true, -20, 100, true); this.setValue(current_rule.set.muscles); this.onchange = (value) => current_rule.set.muscles = value; } @@ -2067,7 +2121,6 @@ window.rulesAssistantOptions = (function() { class BraceList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", "none"], ["Straighten", "straighten"], ["Universal", "universal"] @@ -2081,7 +2134,6 @@ window.rulesAssistantOptions = (function() { class LivingStandardList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Luxurious", "luxurious"], ["Normal", "normal"], ["Spare", "spare"] @@ -2095,7 +2147,6 @@ window.rulesAssistantOptions = (function() { class PunishmentList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Confinement", "confinement"], ["Whipping", "whipping"], ["Chastity", "chastity"], @@ -2110,7 +2161,6 @@ window.rulesAssistantOptions = (function() { class RewardList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Relaxation", "relaxation"], ["Drugs", "drugs"], ["Orgasm", "orgasm"], @@ -2125,7 +2175,6 @@ window.rulesAssistantOptions = (function() { class ReleaseList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Permissive", "permissive"], ["Sapphic", "sapphic"], ["Masturbation", "masturbation"], @@ -2141,7 +2190,6 @@ window.rulesAssistantOptions = (function() { class ToyHoleList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["All her holes", "all her holes"], ["Mouth", "mouth"], ["Boobs", "boobs"], @@ -2158,7 +2206,6 @@ window.rulesAssistantOptions = (function() { class SmartFetishList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Vanilla", "vanilla"], ["Oral", "oral"], ["Anal", "anal"], @@ -2179,7 +2226,6 @@ window.rulesAssistantOptions = (function() { class SmartXYAttractionList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Passionate", 100], ["Attracted", 75], ["Indifferent", 45], @@ -2194,7 +2240,6 @@ window.rulesAssistantOptions = (function() { class SmartXXAttractionList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Passionate", 100], ["Attracted", 75], ["Indifferent", 45], @@ -2209,7 +2254,6 @@ window.rulesAssistantOptions = (function() { class SmartEnergyList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Nympho", 100], ["Sex Addict", 85], ["Powerful", 65], @@ -2226,7 +2270,6 @@ window.rulesAssistantOptions = (function() { class SpeechList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Permissive", "permissive"], ["Suppress accents", "accent elimination"], ["Restrictive", "restrictive"] @@ -2240,7 +2283,6 @@ window.rulesAssistantOptions = (function() { class RelationshipList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Permissive", "permissive"], ["Just friends", "just friends"], ["Restrictive", "restrictive"] @@ -2254,7 +2296,6 @@ window.rulesAssistantOptions = (function() { class PornBroadcastStatus extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["Disabled", 0], ["Enabled", 1] ]; @@ -2267,7 +2308,6 @@ window.rulesAssistantOptions = (function() { class PornList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], /* ["No broadcasting", -1], **This has changed, it would now use .pornFeed** */ ["No subsidy", 0], ["1000", 1000], @@ -2285,7 +2325,6 @@ window.rulesAssistantOptions = (function() { class EyewearList extends List { constructor() { const pairs = [ - ["no default setting"], ["none"], ["correct with glasses"], ["correct with contacts"], @@ -2302,7 +2341,7 @@ window.rulesAssistantOptions = (function() { class LensesList extends Element { constructor() { super(current_rule.set.eyeColor); - this.appendChild(new OptionsItem("No default setting", () => this.setValue("no default setting"))); + this.appendChild(new OptionsItem("No default setting", () => this.setValue(null))); this.colorlist = new LensesColorList(); this.shapelist = new LensesShapeList(); this.appendChild(this.colorlist); @@ -2320,17 +2359,12 @@ window.rulesAssistantOptions = (function() { combine() { const lst = []; - if (this.colorlist.value !== "no default setting") { + if (this.colorlist.value !== null) lst.push(this.colorlist.value); - } - if (this.shapelist.value !== "no default setting") { + if (this.shapelist.value !== null) lst.push(this.shapelist.value); - } - if (lst.length === 0) { - return "no default setting"; - } else { - return lst.join(" "); - } + if (lst.length === 0) return null; + else return lst.join(" "); } setValue(val) { @@ -2344,7 +2378,7 @@ window.rulesAssistantOptions = (function() { constructor() { const items = []; [ - "no default setting", + null, "blue", "black", "brown", @@ -2371,7 +2405,7 @@ window.rulesAssistantOptions = (function() { constructor() { const items = []; [ - "no default setting", + null, "catlike", "serpent-like", "goat-like", @@ -2396,7 +2430,6 @@ window.rulesAssistantOptions = (function() { class EarwearList extends List { constructor() { const pairs = [ - ["no default setting"], ["none"], ["correct with hearing aids"], ["muffle with ear plugs"], @@ -2410,15 +2443,14 @@ window.rulesAssistantOptions = (function() { class MakeupList extends List { constructor() { - super("Makeup"); - [ - ["no default setting"], + const pairs = [ ["makeup-free", 0], ["nice", 1], ["gorgeous", 2], ["color-coordinate with hair", 3], ["slutty", 4] - ].forEach(pair => this.appendChild(new ListItem(...pair))); + ]; + super("Makeup", pairs); this.setValue(current_rule.set.makeup); this.onchange = (value) => current_rule.set.makeup = value; } @@ -2426,9 +2458,7 @@ window.rulesAssistantOptions = (function() { class NailsList extends List { constructor() { - super("Nails"); - [ - ["no default setting"], + const pairs = [ ["clipped", 0], ["extended", 1], ["color-coordinate with hair", 2], @@ -2439,7 +2469,8 @@ window.rulesAssistantOptions = (function() { ["neon color-coordinate with hair", 7], ["metallic painted", 8], ["metallic color-coordinate with hair", 9] - ].forEach(pair => this.appendChild(new ListItem(...pair))); + ]; + super("Nails", pairs); this.setValue(current_rule.set.nails); this.onchange = (value) => current_rule.set.nails = value; } @@ -2448,7 +2479,6 @@ window.rulesAssistantOptions = (function() { class HairLengthList extends List { constructor() { const pairs = [ - ["no default setting"], ["very short", 5], ["short", 10], ["shoulder length", 30], @@ -2465,7 +2495,6 @@ window.rulesAssistantOptions = (function() { class HaircutsList extends List { constructor() { const pairs = [ - ["no default setting"], ["maintain hair length", 1], ["do not maintain hair length", 0] ]; @@ -2478,7 +2507,6 @@ window.rulesAssistantOptions = (function() { class HairColorList extends List { constructor() { const pairs = [ - ["no default setting"], ["blonde"], ["golden"], ["platinum blonde"], @@ -2522,7 +2550,6 @@ window.rulesAssistantOptions = (function() { class HairStyleList extends List { constructor() { const pairs = [ - ["no default setting"], ["neat"], ["shaved"], ["trimmed"], @@ -2552,7 +2579,6 @@ window.rulesAssistantOptions = (function() { class EyebrowColorList extends List { constructor() { const pairs = [ - ["no default setting"], ["blonde"], ["golden"], ["platinum blonde"], @@ -2596,7 +2622,6 @@ window.rulesAssistantOptions = (function() { class EyebrowStyleList extends List { constructor() { const pairs = [ - ["no default setting"], ["shaved"], ["straight"], ["rounded"], @@ -2617,7 +2642,6 @@ window.rulesAssistantOptions = (function() { class EyebrowFullnessList extends List { constructor() { const pairs = [ - ["no default setting"], ["pencil-thin"], ["thin"], ["threaded"], @@ -2635,7 +2659,6 @@ window.rulesAssistantOptions = (function() { class MarkingsList extends List { constructor() { const pairs = [ - ["no default setting"], ["remove beauty marks"], ["remove birthmarks"], ["remove both"] @@ -2649,7 +2672,6 @@ window.rulesAssistantOptions = (function() { class PubicHairColorList extends List { constructor() { const pairs = [ - ["no default setting"], ["blonde"], ["golden"], ["platinum blonde"], @@ -2693,7 +2715,6 @@ window.rulesAssistantOptions = (function() { class PubicHairStyleList extends List { constructor() { const pairs = [ - ["no default setting"], ["waxed"], ["in a strip"], ["neat"], @@ -2710,7 +2731,6 @@ window.rulesAssistantOptions = (function() { class ArmpitHairColorList extends List { constructor() { const pairs = [ - ["no default setting"], ["blonde"], ["golden"], ["platinum blonde"], @@ -2754,7 +2774,6 @@ window.rulesAssistantOptions = (function() { class ArmpitHairStyleList extends List { constructor() { const pairs = [ - ["no default setting"], ["waxed"], ["shaved"], ["neat"], @@ -2769,7 +2788,6 @@ window.rulesAssistantOptions = (function() { class EarPiercingList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Light", 1], ["Heavy", 2] @@ -2783,7 +2801,6 @@ window.rulesAssistantOptions = (function() { class NosePiercingList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Light", 1], ["Heavy", 2] @@ -2797,7 +2814,6 @@ window.rulesAssistantOptions = (function() { class EyebrowPiercingList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Light", 1], ["Heavy", 2] @@ -2811,7 +2827,6 @@ window.rulesAssistantOptions = (function() { class NavelPiercingList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Light", 1], ["Heavy", 2] @@ -2825,7 +2840,6 @@ window.rulesAssistantOptions = (function() { class NipplePiercingList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Light", 1], ["Heavy", 2] @@ -2839,7 +2853,6 @@ window.rulesAssistantOptions = (function() { class AreolaPiercingList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Studded", 1] ]; @@ -2852,7 +2865,6 @@ window.rulesAssistantOptions = (function() { class LipPiercingList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Light", 1], ["Heavy", 2] @@ -2866,7 +2878,6 @@ window.rulesAssistantOptions = (function() { class TonguePiercingList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Light", 1], ["Heavy", 2] @@ -2880,7 +2891,6 @@ window.rulesAssistantOptions = (function() { class ClitPiercingList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Light", 1], ["Heavy", 2], @@ -2895,7 +2905,6 @@ window.rulesAssistantOptions = (function() { class LabiaPiercingList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Light", 1], ["Heavy", 2] @@ -2909,7 +2918,6 @@ window.rulesAssistantOptions = (function() { class ShaftPiercingList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Light", 1], ["Heavy", 2] @@ -2923,7 +2931,6 @@ window.rulesAssistantOptions = (function() { class PerineumPiercingList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Light", 1], ["Heavy", 2] @@ -2937,7 +2944,6 @@ window.rulesAssistantOptions = (function() { class CorsetPiercingList extends List { constructor() { const pairs = [ - ["No default setting", "no default setting"], ["None", 0], ["Apply", 1] ]; @@ -2953,7 +2959,7 @@ window.rulesAssistantOptions = (function() { ["Activate", 1], ["Off", 0], ]; - super("Automatic branding", pairs); + super("Automatic branding", pairs, false); this.setValue(current_rule.set.autoBrand); this.onchange = (value) => current_rule.set.autoBrand = value; } @@ -3194,7 +3200,6 @@ window.rulesAssistantOptions = (function() { class FaceTattooList extends List { constructor() { const items = [ - ["no default setting"], ["none", 0], ["tribal patterns"], ["flowers"], @@ -3219,7 +3224,6 @@ window.rulesAssistantOptions = (function() { class ShoulderTattooList extends List { constructor() { const items = [ - ["no default setting"], ["none", 0], ["tribal patterns"], ["flowers"], @@ -3244,7 +3248,6 @@ window.rulesAssistantOptions = (function() { class ChestTattooList extends List { constructor() { const items = [ - ["no default setting"], ["none", 0], ["tribal patterns"], ["flowers"], @@ -3269,7 +3272,6 @@ window.rulesAssistantOptions = (function() { class ArmTattooList extends List { constructor() { const items = [ - ["no default setting"], ["none", 0], ["tribal patterns"], ["flowers"], @@ -3294,7 +3296,6 @@ window.rulesAssistantOptions = (function() { class UpperBackTattooList extends List { constructor() { const items = [ - ["no default setting"], ["none", 0], ["tribal patterns"], ["flowers"], @@ -3319,7 +3320,6 @@ window.rulesAssistantOptions = (function() { class LowerBackTattooList extends List { constructor() { const items = [ - ["no default setting"], ["none", 0], ["tribal patterns"], ["flowers"], @@ -3344,7 +3344,6 @@ window.rulesAssistantOptions = (function() { class AbdomenTattooList extends List { constructor() { const items = [ - ["no default setting"], ["none", 0], ["tribal patterns"], ["flowers"], @@ -3369,7 +3368,6 @@ window.rulesAssistantOptions = (function() { class DickTattooList extends List { constructor() { const items = [ - ["no default setting"], ["none", 0], ["tribal patterns"], ["flowers"], @@ -3393,7 +3391,6 @@ window.rulesAssistantOptions = (function() { class ButtockTattooList extends List { constructor() { const items = [ - ["no default setting"], ["none", 0], ["tribal patterns"], ["flowers"], @@ -3418,7 +3415,6 @@ window.rulesAssistantOptions = (function() { class AnalTattooList extends List { constructor() { const items = [ - ["no default setting"], ["none", 0], ["tribal patterns"], ["flowers"], @@ -3442,7 +3438,6 @@ window.rulesAssistantOptions = (function() { class LegTattooList extends List { constructor() { const items = [ - ["no default setting"], ["none", 0], ["tribal patterns"], ["flowers"], @@ -3467,7 +3462,6 @@ window.rulesAssistantOptions = (function() { class VisionSurgeryList extends List { constructor() { const items = [ - ["no default setting"], ["fixed", 1], ["blurred", -1], ]; @@ -3480,7 +3474,6 @@ window.rulesAssistantOptions = (function() { class HearingSurgeryList extends List { constructor() { const items = [ - ["no default setting"], ["fixed", 0], ["muffled", -1], ]; @@ -3493,7 +3486,6 @@ window.rulesAssistantOptions = (function() { class SmellSurgeryList extends List { constructor() { const items = [ - ["no default setting"], ["fixed", 0], ["disabled", -1], ]; @@ -3506,7 +3498,6 @@ window.rulesAssistantOptions = (function() { class TasteSurgeryList extends List { constructor() { const items = [ - ["no default setting"], ["fixed", 0], ["disabled", -1], ]; @@ -3519,7 +3510,6 @@ window.rulesAssistantOptions = (function() { class LactationSurgeryList extends List { constructor() { const items = [ - ["no default setting"], ["implanted", 1], ["removed", 0], ]; @@ -3532,7 +3522,6 @@ window.rulesAssistantOptions = (function() { class SemenSurgeryList extends List { constructor() { const items = [ - ["no default setting"], ["implanted", 1], ["removed", 0], ]; @@ -3545,7 +3534,6 @@ window.rulesAssistantOptions = (function() { class VasectomyList extends List { constructor() { const items = [ - ["no default setting"], ["apply vasectomy", true], ["undo vasectomy", false], ]; @@ -3558,7 +3546,6 @@ window.rulesAssistantOptions = (function() { class CosmeticSurgeryList extends List { constructor() { const items = [ - ["no default setting"], ["none", 0], ["subtle", 1], ["invasive", 2], @@ -3572,14 +3559,13 @@ window.rulesAssistantOptions = (function() { class LipSurgeryList extends NumberRange { constructor() { const items = [ - ["no default setting"], ["removed", 0], ["plush", 20], ["big", 40], ["huge", 70], ["facepussy", 95], ]; - super("Lip implants", items, 0, 95, true); + super("Lip implants", items, true, 0, 95, true); this.setValue(current_rule.set.surgery_lips); this.onchange = (value) => current_rule.set.surgery_lips = value; } @@ -3588,14 +3574,13 @@ window.rulesAssistantOptions = (function() { class ButtSurgeryList extends NumberRange { constructor() { const items = [ - ["no default setting"], ["removed", 0], ["slim", 2], ["stacked", 4], ["huge", 6], ["maximized", 9], ]; - super("Buttock implants", items, 0, 9, true); + super("Buttock implants", items, true, 0, 9, true); this.setValue(current_rule.set.surgery_butt); this.onchange = (value) => current_rule.set.surgery_butt = value; } @@ -3604,7 +3589,6 @@ window.rulesAssistantOptions = (function() { class BreastSurgeryList extends NumberRange { constructor() { const items = [ - ["no default setting"], ["removed", 0], ["slim", 400], ["stacked", 1000], @@ -3612,7 +3596,7 @@ window.rulesAssistantOptions = (function() { ["barely functional", 9000], ["maximized", 48000] ]; - super("Breast implants", items, 0, 48000, true); + super("Breast implants", items, true, 0, 48000, true); this.setValue(current_rule.set.surgery_boobs); this.onchange = (value) => current_rule.set.surgery_boobs = value; } @@ -3621,7 +3605,6 @@ window.rulesAssistantOptions = (function() { class TighteningSurgeryList extends List { constructor() { const items = [ - ["no default setting"], ["tightening", 1], ["virginity restoration", 2], ]; @@ -3634,7 +3617,6 @@ window.rulesAssistantOptions = (function() { class TummyTuckSurgeryList extends List { constructor() { const items = [ - ["no default setting"], ["tuck", 1], ]; super("Tummy Tuck", items); @@ -3647,7 +3629,6 @@ window.rulesAssistantOptions = (function() { class BodyHairSurgeryList extends List { constructor() { const items = [ - ["no default setting"], ["keep", 1], ["removal", 2], ]; @@ -3660,7 +3641,6 @@ window.rulesAssistantOptions = (function() { class HairSurgeryList extends List { constructor() { const items = [ - ["no default setting"], ["keep", 1], ["removal", 2], ]; @@ -3673,7 +3653,6 @@ window.rulesAssistantOptions = (function() { class AutomaticAssignmentList extends List { constructor() { const items = [ - ["No default setting", "no default setting"], ["Rest", "rest"], ["Fucktoy", "please you"], ["Subordinate Slave", "be a subordinate slave"], @@ -3733,7 +3712,6 @@ window.rulesAssistantOptions = (function() { class BellyImplantList extends List { constructor() { const items = [ - ["no default setting"], ["install", "install"], ["remove", "remove"], ]; @@ -3745,10 +3723,7 @@ window.rulesAssistantOptions = (function() { class LabelList extends List { constructor() { - const items = [ - ["no default setting"], - ]; - super("Custom label", items, true); + super("Custom label", [], true, true); this.setValue(current_rule.set.label); this.onchange = (value) => current_rule.set.label = value; } @@ -3756,10 +3731,7 @@ window.rulesAssistantOptions = (function() { class LabelRemoveList extends List { constructor() { - const items = [ - ["no default setting"], - ]; - super("Remove custom label", items, true); + super("Remove custom label", [], true, true); this.setValue(current_rule.set.removeLabel); this.onchange = (value) => current_rule.set.removeLabel = value; } @@ -3768,7 +3740,6 @@ window.rulesAssistantOptions = (function() { class SkinColorList extends List { constructor() { const items = [ - ["no default setting"], ["natural"], ["pure white"], ["ivory"], diff --git a/src/js/rulesAutosurgery.js b/src/js/rulesAutosurgery.js index 3fd11675c89df24510535f98dba834878d4a3e0c..8f0b8c4093bf8515a5a7d6107996779ee2da6a8a 100644 --- a/src/js/rulesAutosurgery.js +++ b/src/js/rulesAutosurgery.js @@ -1,5 +1,5 @@ /* eslint-disable camelcase */ -window.rulesAutosurgery = (function() { +window.rulesAutosurgery = (function () { "use strict"; let V; let r; @@ -25,14 +25,14 @@ window.rulesAutosurgery = (function() { /** * @param {App.Entity.SlaveState} slave - * @param {Object[]} ruleset + * @param {App.RA.RuleSetters[]} ruleset * @returns {Object} */ function autoSurgerySelector(slave, ruleset) { const surgery = {}; ruleset.forEach(rule => { Object.keys(rule) - .filter(key => key.startsWith("surgery_") && rule[key] !== "no default setting") + .filter(key => key.startsWith("surgery_") && rule[key] !== null) .forEach(key => { surgery[key] = rule[key]; }); @@ -52,14 +52,14 @@ window.rulesAutosurgery = (function() { surgery_lactation: 0, surgery_cosmetic: 1, surgery_faceShape: "cute", - surgery_lips: 10, + surgery_lips: App.RA.makeTarget('==', 10), surgery_hips: 0, surgery_hipsImplant: 0, - surgery_butt: 0, + surgery_butt: App.RA.makeTarget('==', 0), surgery_accent: 0, surgery_shoulders: 0, surgery_shouldersImplant: 0, - surgery_boobs: 0, + surgery_boobs: App.RA.makeTarget('==', 0), surgery_holes: 0 }; break; @@ -68,14 +68,14 @@ window.rulesAutosurgery = (function() { surgery_lactation: 0, surgery_cosmetic: 1, surgery_faceShape: "cute", - surgery_lips: 60, + surgery_lips: App.RA.makeTarget('==', 60), surgery_hips: 0, surgery_hipsImplant: 0, - surgery_butt: 4, + surgery_butt: App.RA.makeTarget('==', 4), surgery_accent: 0, surgery_shoulders: 0, surgery_shouldersImplant: 0, - surgery_boobs: 1200, + surgery_boobs: App.RA.makeTarget('==', 1200), surgery_holes: 0 }; break; @@ -84,14 +84,14 @@ window.rulesAutosurgery = (function() { surgery_lactation: 0, surgery_cosmetic: 1, surgery_faceShape: "cute", - surgery_lips: 95, + surgery_lips: App.RA.makeTarget('==', 95), surgery_hips: 0, surgery_hipsImplant: 0, - surgery_butt: 8, + surgery_butt: App.RA.makeTarget('==', 8), surgery_accent: 0, surgery_shoulders: 0, surgery_shouldersImplant: 0, - surgery_boobs: 10000, + surgery_boobs: App.RA.makeTarget('==', 10000), surgery_holes: 2 }; break; @@ -100,14 +100,14 @@ window.rulesAutosurgery = (function() { surgery_lactation: 1, surgery_cosmetic: 1, surgery_faceShape: "cute", - surgery_lips: 10, + surgery_lips: App.RA.makeTarget('==', 10), surgery_hips: 3, surgery_hipsImplant: 0, - surgery_butt: 0, + surgery_butt: App.RA.makeTarget('==', 0), surgery_accent: 0, surgery_shoulders: 0, surgery_shouldersImplant: 0, - surgery_boobs: 0, + surgery_boobs: App.RA.makeTarget('==', 0), surgery_holes: 0 }; break; @@ -117,24 +117,24 @@ window.rulesAutosurgery = (function() { V.defaultRules .filter(x => ruleApplied(slave, x) && x.set.autoSurgery === 1) .map(x => x.set)); - if ((thisSurgery.surgery_hips !== "no default setting") && (thisSurgery.surgery_butt !== "no default setting")) { + if ((thisSurgery.surgery_hips !== null) && (thisSurgery.surgery_butt !== null)) { if (slave.hips < -1) { - if (thisSurgery.surgery_butt > 2) { - thisSurgery.surgery_butt = 2; + if (App.RA.shallGrow(2, thisSurgery.surgery_butt)) { + thisSurgery.surgery_butt = App.RA.makeTarget('==', 2); } } else if (slave.hips < 0) { - if (thisSurgery.surgery_butt > 4) { - thisSurgery.surgery_butt = 4; + if (App.RA.shallGrow(4, thisSurgery.surgery_butt)) { + thisSurgery.surgery_butt = App.RA.makeTarget('==', 4); } } else if (slave.hips > 0) { - if (thisSurgery.surgery_butt > 8) { - thisSurgery.surgery_butt = 8; + if (App.RA.shallGrow(8, thisSurgery.surgery_butt)) { + thisSurgery.surgery_butt = App.RA.makeTarget('==', 8); } } else if (slave.hips > 1) { // true } else { - if (thisSurgery.surgery_butt > 6) { - thisSurgery.surgery_butt = 6; + if (App.RA.shallGrow(6, thisSurgery.surgery_butt)) { + thisSurgery.surgery_butt = App.RA.makeTarget('==', 6); } } } @@ -149,573 +149,296 @@ window.rulesAutosurgery = (function() { * @param {string[]} surgeries */ function CommitSurgery(slave, thisSurgery, surgeries) { + /** + * Performs an individual surgery procedure + * @param {string} desc + * @param {slaveOperation} proc + * @param {number} [healthCost=10] normal health cost + */ + function commitProcedure(desc, proc, healthCost = 10) { + surgeries.push(desc); + proc(slave); + cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); + slave.health -= (V.PC.medicine >= 100) ? Math.round(healthCost / 2) : healthCost; + } + + // NOTE: App.RA.shallShrink() and App.RA.shallGrow() return 'false' when target is 'null' + // Hence they have to be first conditions in the '&&' chains to avoid type errors + // (reading properties of the 'null' object) if (slave.health > 20 && surgeries.length < 3) { if (slave.eyes === -1 && thisSurgery.surgery_eyes === 1) { - surgeries.push("surgery to correct her vision"); - slave.eyes = 1; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure(`surgery to correct ${slave.possessive} vision`, s => { s.eyes = 1 }); } else if (slave.eyes === 1 && thisSurgery.surgery_eyes === -1) { - surgeries.push("surgery to blur her vision"); - slave.eyes = -1; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure(`surgery to blur ${slave.possessive} vision`, s => { s.eyes = -1 }); } else if (slave.hears === -1 && thisSurgery.surgery_hears === 0) { - surgeries.push("surgery to correct her hearing"); - slave.hears = 0; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure(`surgery to correct ${slave.possessive} hearing`, s => { s.hears = 0 }); } else if (slave.hears === 0 && thisSurgery.surgery_hears === -1) { - surgeries.push("surgery to muffle her hearing"); - slave.hears = -1; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure(`surgery to muffle ${slave.possessive} hearing`, s => { s.hears = -1 }); } else if (slave.smells === -1 && thisSurgery.surgery_smells === 0) { - surgeries.push("surgery to correct her sense of smell"); - slave.smells = 0; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure(`surgery to correct ${slave.possessive} sense of smell`, s => { s.smells = 0 }); } else if (slave.smells === 0 && thisSurgery.surgery_smells === -1) { - surgeries.push("surgery to muffle her sense of smell"); - slave.smells = -1; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure(`surgery to muffle ${slave.possessive} sense of smell`, s => { s.smells = -1 }); } else if (slave.tastes === -1 && thisSurgery.surgery_tastes === 0) { - surgeries.push("surgery to correct her sense of taste"); - slave.tastes = 0; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure(`surgery to correct ${slave.possessive} sense of taste`, s => { s.tastes = 0; }); } else if (slave.tastes === 0 && thisSurgery.surgery_tastes === -1) { - surgeries.push("surgery to muffle her sense of taste"); - slave.tastes = -1; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure(`surgery to muffle ${slave.possessive} sense of taste`, s => { s.tastes = -1; }); } } if (slave.health > 20 && surgeries.length < 3) { if (slave.lactation === 2 && thisSurgery.surgery_lactation === 0) { - surgeries.push("surgery to remove her lactation implants"); - slave.lactation = 0; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure(`surgery to remove ${slave.possessive} lactation implants`, s => { s.lactation = 0; }); } else if (slave.lactation !== 2 && (thisSurgery.surgery_lactation === 1)) { - surgeries.push("lactation inducing implanted drugs"); - slave.lactation = 2; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("lactation inducing implanted drugs", s => { s.lactation = 2; }); } else if ((slave.boobShape === "saggy" || slave.boobShape === "downward-facing") && thisSurgery.surgery_cosmetic > 0 && slave.breastMesh !== 1) { - surgeries.push("a breast lift"); - slave.boobShape = "normal"; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("a breast lift", s => { s.boobShape = "normal"; }); } else if ((slave.boobShape === "normal" || slave.boobShape === "wide-set") && thisSurgery.surgery_cosmetic > 0 && slave.breastMesh !== 1) { - if (slave.boobs > 800) { - slave.boobShape = "torpedo-shaped"; - } else { - slave.boobShape = "perky"; - } - surgeries.push("more interestingly shaped breasts"); - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } - } else if (thisSurgery.surgery_boobs === 0 && slave.boobsImplant > 0) { - surgeries.push("surgery to remove her boob implants"); - slave.boobs -= slave.boobsImplant; - slave.boobsImplant = 0; - slave.boobsImplantType = 0; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } - } else if (slave.boobs <= 600 && slave.lactation < 2 && (slave.boobs + 400 <= thisSurgery.surgery_boobs)) { - surgeries.push("bigger boobs"); - slave.boobsImplant += 400; - slave.boobs += 400; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } - } else if (slave.boobs <= 600 && slave.lactation < 2 && (slave.boobs + 200 <= thisSurgery.surgery_boobs)) { - surgeries.push("modestly bigger boobs"); - slave.boobsImplant += 200; - slave.boobs += 200; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } - } else if (slave.boobs <= 2000 && slave.lactation < 2 && (slave.boobs + 400 < thisSurgery.surgery_boobs)) { - surgeries.push("bigger boobs"); - slave.boobsImplant += 400; - slave.boobs += 400; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } - } else if (slave.boobs <= 9000 && slave.lactation < 2 && (slave.boobs < thisSurgery.surgery_boobs)) { - surgeries.push("bigger boobs"); - slave.boobsImplant += 200; - slave.boobs += 200; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("more interestingly shaped breasts", slave => { + if (slave.boobs > 800) { + slave.boobShape = "torpedo-shaped"; + } else { + slave.boobShape = "perky"; + } + }); + } else if (App.RA.shallShrink(slave.boobsImplant, thisSurgery.surgery_boobs) && thisSurgery.surgery_boobs.val === 0) { + commitProcedure(`surgery to remove ${slave.possessive} boob implants`, slave => { + slave.boobs -= slave.boobsImplant; + slave.boobsImplant = 0; + slave.boobsImplantType = 0; + }); + } else if (App.RA.shallGrow(slave.boobs, thisSurgery.surgery_boobs, 400) && slave.boobs <= 600 && slave.lactation < 2) { + commitProcedure("bigger boobs", slave => { + slave.boobsImplant += 400; + slave.boobs += 400; + }); + } else if (App.RA.shallGrow(slave.boobs, thisSurgery.surgery_boobs, 200) && slave.boobs <= 600 && slave.lactation < 2) { + commitProcedure("modestly bigger boobs", slave => { + slave.boobsImplant += 200; + slave.boobs += 200; + }); + } else if (App.RA.shallGrow(slave.boobs, thisSurgery.surgery_boobs, 400) && slave.boobs <= 2000 && slave.lactation < 2) { + commitProcedure("bigger boobs", slave => { + slave.boobsImplant += 400; + slave.boobs += 400; + }); + } else if (App.RA.shallGrow(slave.boobs, thisSurgery.surgery_boobs) && slave.boobs <= 9000 && slave.lactation < 2) { + commitProcedure("bigger boobs", slave => { + slave.boobsImplant += 200; + slave.boobs += 200; + }); } } - if (slave.health > 20 && surgeries.length < 3) { - if (thisSurgery.surgery_butt === 0 && slave.buttImplant > 0) { - surgeries.push("surgery to remove her butt implants"); - slave.butt -= slave.buttImplant; - slave.buttImplant = 0; - slave.buttImplantType = 0; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } - } else if (slave.butt <= 3 && (slave.butt < thisSurgery.surgery_butt)) { - surgeries.push("a bigger butt"); - slave.buttImplant = 1; - slave.butt += 1; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } - } else if (slave.butt <= 5 && (slave.butt < thisSurgery.surgery_butt)) { - surgeries.push("a bigger butt"); - slave.buttImplant = 1; - slave.butt += 1; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } - } else if (slave.butt <= 8 && (slave.butt < thisSurgery.surgery_butt)) { - surgeries.push("a bigger butt"); - slave.buttImplant = 1; - slave.butt += 1; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + if (thisSurgery.surgery_butt !== null && slave.health > 20 && surgeries.length < 3) { + if (App.RA.shallShrink(slave.buttImplant, thisSurgery.surgery_butt) && thisSurgery.surgery_butt.val === 0) { + commitProcedure(`surgery to remove ${slave.possessive} butt implants`, slave => { + slave.butt -= slave.buttImplant; + slave.buttImplant = 0; + slave.buttImplantType = 0; + }); + } else if (App.RA.shallGrow(slave.butt, thisSurgery.surgery_butt) && slave.butt <= 3) { + commitProcedure("a bigger butt", slave => { + slave.buttImplant = 1; // FIXME: +=1? + slave.butt += 1; + }); + } else if (App.RA.shallGrow(slave.butt, thisSurgery.surgery_butt) && slave.butt <= 5) { + commitProcedure("a bigger butt", slave => { + slave.buttImplant = 1; // FIXME: +=1? + slave.butt += 1; + }); + } else if (App.RA.shallGrow(slave.butt, thisSurgery.surgery_butt) && slave.butt <= 8) { + commitProcedure("a bigger butt", slave => { + slave.buttImplant = 1; // FIXME: +=1? + slave.butt += 1; + }); } } if (slave.health > 20 && surgeries.length < 3) { if (slave.anus > 3 && thisSurgery.surgery_cosmetic > 0) { - surgeries.push("a restored anus"); - slave.anus = 3; - if (slave.skill.anal > 10) { - slave.skill.anal -= 10; - } - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("a restored anus", slave => { + slave.anus = 3; + if (slave.skill.anal > 10) { + slave.skill.anal -= 10; + } + }); } else if (slave.vagina > 3 && thisSurgery.surgery_cosmetic > 0) { - surgeries.push("a restored pussy"); - slave.vagina = 3; - if (slave.skill.vaginal > 10) { - slave.skill.vaginal -= 10; - } - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("a restored pussy", slave => { + slave.vagina = 3; + if (slave.skill.vaginal > 10) { + slave.skill.vaginal -= 10; + } + }); } else if (slave.anus > 0 && V.surgeryUpgrade === 1 && thisSurgery.surgery_holes === 2) { - surgeries.push("a virgin anus"); - slave.anus = 0; - if (slave.skill.anal > 10) { - slave.skill.anal -= 10; - } - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("a virgin anus", slave => { + slave.anus = 0; + if (slave.skill.anal > 10) { + slave.skill.anal -= 10; + } + }); } else if (slave.vagina > 0 && V.surgeryUpgrade === 1 && thisSurgery.surgery_holes === 2) { - surgeries.push("a virgin pussy"); - slave.vagina = 0; - if (slave.skill.vaginal > 10) { - slave.skill.vaginal -= 10; - } - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("a virgin pussy", slave => { + slave.vagina = 0; + if (slave.skill.vaginal > 10) { + slave.skill.vaginal -= 10; + } + }); } else if (slave.anus > 1 && thisSurgery.surgery_holes === 1) { - surgeries.push("a tighter anus"); - slave.anus = 1; - if (slave.skill.anal > 10) { - slave.skill.anal -= 10; - } - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("a tighter anus", slave => { + slave.anus = 1; + if (slave.skill.anal > 10) { + slave.skill.anal -= 10; + } + }); } else if (slave.vagina > 1 && thisSurgery.surgery_holes === 1) { - surgeries.push("a tighter pussy"); - slave.vagina = 1; - if (slave.skill.vaginal > 10) { - slave.skill.vaginal -= 10; - } - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("a tighter pussy", slave => { + slave.vagina = 1; + if (slave.skill.vaginal > 10) { + slave.skill.vaginal -= 10; + } + }); } } if (slave.health > 20 && surgeries.length < 3) { if (slave.prostate === 2 && thisSurgery.surgery_prostate === 0) { - surgeries.push("surgery to remove her prostate implant"); - slave.prostate = 0; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure(`surgery to remove ${slave.possessive} prostate implant`, s => { s.prostate = 0; }); } else if (slave.prostate === 1 && thisSurgery.surgery_prostate === 1) { - surgeries.push("a precum production enhancing drug implant"); - slave.prostate = 2; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("a precum production enhancing drug implant", s => { s.prostate = 2; }); } else if (slave.balls > 0 && slave.vasectomy === 0 && thisSurgery.surgery_vasectomy === true) { - surgeries.push("vasectomy"); + commitProcedure("vasectomy", s => { s.vasectomy = 1; }); V.surgeryType = "vasectomy"; - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } - slave.vasectomy = 1; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); } else if (slave.balls > 0 && slave.vasectomy === 1 && thisSurgery.surgery_vasectomy === false) { - surgeries.push("undo vasectomy"); + commitProcedure("undo vasectomy", s => { s.vasectomy = 0; }); V.surgeryType = "vasectomy undo"; - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } - slave.vasectomy = 0; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); } } if (slave.health > 20 && surgeries.length < 3) { if (slave.faceImplant <= 15 && slave.face <= 95 && thisSurgery.surgery_cosmetic > 0) { - surgeries.push("a nicer face"); - if (slave.faceShape === "masculine") { slave.faceShape = "androgynous"; } - slave.faceImplant += 25 - 5 * Math.trunc(V.PC.medicine / 50) - 5 * V.surgeryUpgrade; - slave.face = Math.clamp(slave.face + 20, -100, 100); - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("a nicer face", slave => { + if (slave.faceShape === "masculine") slave.faceShape = "androgynous"; + slave.faceImplant += 25 - 5 * Math.trunc(V.PC.medicine / 50) - 5 * V.surgeryUpgrade; + slave.face = Math.clamp(slave.face + 20, -100, 100); + }); } else if (slave.faceImplant <= 15 && slave.ageImplant !== 1 && slave.visualAge >= 25 && thisSurgery.surgery_cosmetic > 0) { - surgeries.push("an age lift"); - slave.ageImplant = 1; - slave.faceImplant += 25 - 5 * Math.trunc(V.PC.medicine / 50) - 5 * V.surgeryUpgrade; - if (slave.visualAge > 80) { - slave.visualAge -= 40; - } else if (slave.visualAge >= 70) { - slave.visualAge -= 30; - } else if (slave.visualAge > 50) { - slave.visualAge -= 20; - } else if (slave.visualAge > 36) { - slave.visualAge -= 10; - } else { - slave.visualAge -= 5; - } - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("an age lift", slave => { + slave.ageImplant = 1; + slave.faceImplant += 25 - 5 * Math.trunc(V.PC.medicine / 50) - 5 * V.surgeryUpgrade; + if (slave.visualAge > 80) slave.visualAge -= 40; + else if (slave.visualAge >= 70) slave.visualAge -= 30; + else if (slave.visualAge > 50) slave.visualAge -= 20; + else if (slave.visualAge > 36) slave.visualAge -= 10; + else slave.visualAge -= 5; + }); } else if (((slave.underArmHStyle !== "bald" && slave.underArmHStyle !== "hairless") || (slave.pubicHStyle !== "bald" && slave.pubicHStyle !== "hairless")) && thisSurgery.surgery_bodyhair === 2) { - surgeries.push("body hair removal"); - if (slave.underArmHStyle !== "hairless") { slave.underArmHStyle = "bald"; } - if (slave.pubicHStyle !== "hairless") { slave.pubicHStyle = "bald"; } - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); + commitProcedure("body hair removal", slave => { + if (slave.underArmHStyle !== "hairless") slave.underArmHStyle = "bald"; + if (slave.pubicHStyle !== "hairless") slave.pubicHStyle = "bald"; + }, 0); } else if ((slave.bald === 0 || slave.hStyle !== "bald" || slave.eyebrowHStyle !== "bald") && thisSurgery.surgery_hair === 2) { - surgeries.push("hair removal"); - slave.eyebrowHStyle = "bald"; - slave.hStyle = "bald"; - slave.bald = 1; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); + commitProcedure("hair removal", slave => { + slave.eyebrowHStyle = "bald"; + slave.hStyle = "bald"; + slave.bald = 1; + }, 0); } else if (slave.weight >= 10 && thisSurgery.surgery_cosmetic > 0) { - surgeries.push("liposuction"); - slave.weight -= 50; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } - } else if ((slave.bellySagPreg > 0 || slave.bellySag > 0) && (thisSurgery.surgery_cosmetic > 0 || thisSurgery.surgery_tummy > 0)) { - surgeries.push("a tummy tuck"); - slave.bellySag = 0; - slave.bellySagPreg = 0; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 10; - } else { - slave.health -= 20; - } + commitProcedure("liposuction", s => { s.weight -= 50; }); + } else if ((slave.bellySagPreg > 0 || slave.bellySag > 0) && (thisSurgery.surgery_cosmetic > 0 || thisSurgery.surgery_tummy > 0 )) { + commitProcedure("a tummy tuck", slave => { + slave.bellySag = 0; + slave.bellySagPreg = 0; + }, 20); } else if (slave.voice === 1 && slave.voiceImplant === 0 && thisSurgery.surgery_cosmetic > 0) { - surgeries.push("a feminine voice"); - slave.voice += 1; - slave.voiceImplant += 1; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } - } else if (thisSurgery.surgery_lips === 0 && slave.lipsImplant > 0) { - surgeries.push("surgery to remove her lip implants"); - slave.lips -= slave.lipsImplant; - slave.lipsImplant = 0; - if (slave.skill.oral > 10) { - slave.skill.oral -= 10; - } - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } - } else if (slave.lips <= 95 && (slave.lips < thisSurgery.surgery_lips)) { - surgeries.push("bigger lips"); - slave.lipsImplant += 10; - slave.lips += 10; - if (slave.skill.oral > 10) { - slave.skill.oral -= 10; - } - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("a feminine voice", slave => { + slave.voice += 1; + slave.voiceImplant += 1; + }); + } else if (App.RA.shallShrink(slave.lipsImplant, thisSurgery.surgery_lips) && thisSurgery.surgery_lips.val === 0) { + commitProcedure(`surgery to remove ${slave.possessive} lip implants`, slave => { + slave.lips -= slave.lipsImplant; + slave.lipsImplant = 0; + if (slave.skill.oral > 10) { + slave.skill.oral -= 10; + } + }); + } else if (App.RA.shallGrow(slave.lipsImplant, thisSurgery.surgery_lips, 10) && slave.lips <= 95) { + commitProcedure("bigger lips", slave => { + slave.lipsImplant += 10; + slave.lips += 10; + if (slave.skill.oral > 10) { + slave.skill.oral -= 10; + } + }); } else if (slave.cSec === 1 && thisSurgery.surgery_cosmetic > 0) { - surgeries.push("surgery to remove a c-section scar"); - slave.cSec = 0; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("surgery to remove a c-section scar", s => { s.cSec = 0; }); } else if (slave.faceImplant <= 45 && slave.face <= 95 && thisSurgery.surgery_cosmetic === 2) { - surgeries.push("a nicer face"); - if (slave.faceShape === "masculine") { slave.faceShape = "androgynous"; } - slave.faceImplant += 25 - 5 * Math.trunc(V.PC.medicine / 50) - 5 * V.surgeryUpgrade; - slave.face = Math.clamp(slave.face + 20, -100, 100); - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("a nicer face", slave => { + if (slave.faceShape === "masculine") slave.faceShape = "androgynous"; + slave.faceImplant += 25 - 5 * Math.trunc(V.PC.medicine / 50) - 5 * V.surgeryUpgrade; + slave.face = Math.clamp(slave.face + 20, -100, 100); + }); } else if (slave.faceImplant <= 45 && slave.ageImplant !== 1 && slave.visualAge >= 25 && thisSurgery.surgery_cosmetic === 2) { - surgeries.push("an age lift"); - slave.ageImplant = 1; - if (slave.visualAge > 80) { - slave.visualAge -= 40; - } else if (slave.visualAge >= 70) { - slave.visualAge -= 30; - } else if (slave.visualAge > 50) { - slave.visualAge -= 20; - } else if (slave.visualAge > 36) { - slave.visualAge -= 10; - } else { - slave.visualAge -= 5; - } - slave.faceImplant += 25 - 5 * Math.trunc(V.PC.medicine / 50) - 5 * V.surgeryUpgrade; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("an age lift", slave => { + slave.ageImplant = 1; + if (slave.visualAge > 80) { + slave.visualAge -= 40; + } else if (slave.visualAge >= 70) { + slave.visualAge -= 30; + } else if (slave.visualAge > 50) { + slave.visualAge -= 20; + } else if (slave.visualAge > 36) { + slave.visualAge -= 10; + } else { + slave.visualAge -= 5; + } + slave.faceImplant += 25 - 5 * Math.trunc(V.PC.medicine / 50) - 5 * V.surgeryUpgrade; + }); } else if (slave.voice < 3 && slave.voiceImplant === 0 && thisSurgery.surgery_cosmetic === 2) { - surgeries.push("a bimbo's voice"); - slave.voice += 1; - slave.voiceImplant += 1; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("a bimbo's voice", slave => { + slave.voice += 1; + slave.voiceImplant += 1; + }); } } if (slave.health > 20 && surgeries.length < 3) { if (slave.waist >= -10 && thisSurgery.surgery_cosmetic > 0) { - surgeries.push("a narrower waist"); - slave.waist -= 20; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("a narrower waist", s => { s.waist -= 20; }); } else if (slave.hips < 1 && V.surgeryUpgrade === 1 && (slave.hips < thisSurgery.surgery_hips)) { - surgeries.push("wider hips"); - slave.hips++; - slave.hipsImplant++; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("wider hips", slave => { + slave.hips++; + slave.hipsImplant++; + }); } else if (slave.waist >= -95 && V.seeExtreme === 1 && thisSurgery.surgery_cosmetic === 2) { - surgeries.push("a narrower waist"); - slave.waist = Math.clamp(slave.waist - 20, -100, 100); - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("a narrower waist", s => { s.waist = Math.clamp(s.waist - 20, -100, 100); }); } else if (slave.hips < 2 && V.surgeryUpgrade === 1 && (slave.hips < thisSurgery.surgery_hips)) { - surgeries.push("wider hips"); - slave.hips++; - slave.hipsImplant++; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("wider hips", slave => { + slave.hips++; // FIXME: repeats branch above + slave.hipsImplant++; + }); } else if (slave.hips < 3 && V.surgeryUpgrade === 1 && (slave.hips < thisSurgery.surgery_hips)) { - surgeries.push("wider hips"); - slave.hips++; - slave.hipsImplant++; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("wider hips", slave => { + slave.hips++; // FIXME: repeats branch above + slave.hipsImplant++; + }); } } if (slave.health > 20 && surgeries.length < 3) { if (slave.bellyImplant < 0 && V.bellyImplants > 0 && thisSurgery.surgery_bellyImplant === "install" && slave.womb.length === 0 && slave.broodmother === 0) { - slave.bellyImplant = 100; - slave.preg = -2; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); + const proc = slave => { + slave.bellyImplant = 100; + slave.preg = -2; + }; if (slave.ovaries === 1 || slave.mpreg === 1) { - surgeries.push("belly implant"); V.surgeryType = "bellyIn"; - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } + commitProcedure("belly implant", proc, 10); } else { - surgeries.push("male belly implant"); V.surgeryType = "bellyInMale"; - if (V.PC.medicine >= 100) { - slave.health -= 25; - } else { - slave.health -= 50; - } + commitProcedure("male belly implant", proc, 50); } bellyIn(slave); } else if (slave.bellyImplant >= 0 && thisSurgery.surgery_bellyImplant === "remove") { - surgeries.push("belly implant removal"); + commitProcedure("belly implant removal", slave => { + slave.preg = 0; + slave.bellyImplant = -1; + slave.cervixImplant = 0; + }); V.surgeryType = "bellyOut"; - if (V.PC.medicine >= 100) { - slave.health -= 5; - } else { - slave.health -= 10; - } - slave.preg = 0; - slave.bellyImplant = -1; - slave.cervixImplant = 0; - cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); } } } diff --git a/src/uncategorized/BackwardsCompatibility.tw b/src/uncategorized/BackwardsCompatibility.tw index 5ce39ffbf6a1b800f6a22e12ccadea76f2e57d89..93430a9f3812c25275f4a859dfe6db6d6c04836b 100644 --- a/src/uncategorized/BackwardsCompatibility.tw +++ b/src/uncategorized/BackwardsCompatibility.tw @@ -3593,7 +3593,13 @@ Updating gene pool records: <<run $heroSlaves.forEach(function(s) {if (s.pregType > 0 && Array.isArray(s.womb)) delete s.womb;})>> <<set $activeSlave = BaseSlave()>> <<set $baseHeroSlave = clone($activeSlave)>> -Done! +Done<br> + +Updating Rules Assistant data... +<<for _rule range $defaultRules>> + <<run App.Entity.Utils.RARuleDatatypeCleanup(_rule)>> +<</for>> +Done<br> /* Sec Exp */ <<if $secExp == 1>> @@ -3624,55 +3630,6 @@ Done! <<set $showMissingSlavesSD = false>> <</if>> -<<for _bci = 0; _bci < $defaultRules.length; _bci++>> - <<set _rule = $defaultRules[_bci].set>> - <<if !([true, false, "no default setting"].includes(_rule.preg))>> - <<set _rule.preg = (_rule.preg === -1 ? true : false)>> - <</if>> - <<if ndef _rule.haircuts>> - <<set _rule.haircuts = "no default setting">> - <</if>> - <<if ndef _rule.label>> - <<set _rule.label = "no default setting">> - <</if>> - <<if ndef _rule.removeLabel>> - <<set _rule.removeLabel = "no default setting">> - <</if>> - <<if ndef _rule.skinColor>> - <<set _rule.skinColor = "no default setting">> - <</if>> - <<if ndef _rule.earwear>> - <<set _rule.earwear = "no default setting">> - <</if>> - <<if ndef _rule.surgery_hears>> - <<set _rule.surgery_hears = "no default setting">> - <</if>> - <<if ndef _rule.surgery_smells>> - <<set _rule.surgery_smells = "no default setting">> - <</if>> - <<if ndef _rule.surgery_tastes>> - <<set _rule.surgery_tastes = "no default setting">> - <</if>> - <<if ndef _rule.surgery_vasectomy>> - <<set _rule.surgery_vasectomy = "no default setting">> - <</if>> - <<if ndef _rule.toyHole>> - <<set _rule.toyHole = "no default setting">> - <</if>> - <<if ndef _rule.pornFeed>> - <<set _rule.pornFeed = "no default setting">> - <</if>> - <<if ndef _rule.pornFameSpending || _rule.pornFameSpending === -1>> - <<set _rule.pornFameSpending = "no default setting">> - <</if>> - <<if ndef _rule.legAccessory>> - <<set _rule.legAccessory = "no default setting">> - <</if>> - <<if ndef _rule.hyper_drugs>> - <<set _rule.hyper_drugs = 0>> - <</if>> -<</for>> - <<if ndef $postSexCleanUp>> <<set $postSexCleanUp = 1>> <</if>>