From f2599a5959e38a3c8e35865c6f55775c8f43f3d6 Mon Sep 17 00:00:00 2001 From: kopareigns <kopareigns@gmail.com> Date: Wed, 18 Jul 2018 12:31:30 -0400 Subject: [PATCH] Hope this works --- devNotes/twine JS.txt | 20689 ++++++++++++++++++++-------------------- 1 file changed, 10408 insertions(+), 10281 deletions(-) diff --git a/devNotes/twine JS.txt b/devNotes/twine JS.txt index 79d93f7c99e..c7f8bd1a097 100644 --- a/devNotes/twine JS.txt +++ b/devNotes/twine JS.txt @@ -36,9 +36,7 @@ if (typeof interpolate == "undefined") { }; window.interpolate = interpolate; } -config.history.maxStates = 1; -config.saves.autosave = "autosave"; window.isFullyPotent = function(slave) { if (!slave) { return null; @@ -514,9 +512,9 @@ window.tooBigBalls = function(slave){ window.tooBigDick = function(slave){ if (!slave) { return null; - } else if (slave.dick >= 15+(slave.muscles*.1) && slave.physicalAge <= 3 && slave.dick !== 0) { + } else if (slave.dick >= 20+(slave.muscles*.1) && slave.physicalAge <= 3 && slave.dick !== 0) { return true; - } else if (slave.dick >= 30+(slave.muscles*.3) && slave.physicalAge <= 12) { + } else if (slave.dick >= 45+(slave.muscles*.3) && slave.physicalAge <= 12) { return true; } else if (slave.dick >= 68+(slave.muscles*.4)) { return true; @@ -2553,6 +2551,7 @@ window.emptyDefaultRule = function emptyDefaultRule() { nails: "no default setting", hColor: "no default setting", hLength: "no default setting", + haircuts: "no default setting", hStyle: "no default setting", pubicHColor: "no default setting", pubicHStyle: "no default setting", @@ -2633,6 +2632,7 @@ window.emptyDefaultRule = function emptyDefaultRule() { pregSpeed: "no default setting", bellyImplantVol: -1, teeth: "no default setting", + label: "no default setting", } }; return rule; @@ -2644,7 +2644,7 @@ window.emptyDefaultRule = function emptyDefaultRule() { window.RulesDeconfliction = function RulesDeconfliction(slave) { const before = clone(slave); DefaultRules(slave); - V.slaveAfterRA = clone(slave); + State.variables.slaveAfterRA = clone(slave); slave = before; } @@ -2871,7 +2871,7 @@ window.Height = (function(){ "Finnish": 165.3, "French Guianan": 157, "French Polynesian": undefined, "French": 162.5, "Gabonese": 158.4, "Gambian": 157.8, "Georgian": 160.5, "German": 162.8, "Ghanan": 158.5, "Greek": 165, "Greenlandic": undefined, "Grenadian": undefined, "Guamanian": undefined, "Guatemalan": 147.3, "Guinean": 158.8, "Guyanese": 157.9, "Haitian": 158.6, "Honduran": 152.0, "Hungarian": 164, "I-Kiribati": undefined, "Icelandic": 168, "Indian": 151.9, "Indonesian": 147, "Iranian": 157.2, "Iraqi": 155.8, "Irish": 163, "Israeli": 166, "Italian": 162.5, "Ivorian": 158.9, - "Jamaican": 160.8, "Japanese": 158, "Jordanian": 158.2, "Kazakh": 159.8, "Kenyan": 159.4, "Kittitian": 156.9, "Korean": 156.15, "Kosovan": undefined, "Kurdish": undefined, "Kuwaiti": 156.1, + "Jamaican": 160.8, "Japanese": 158, "Jordanian": 158.2, "Kazakh": 159.8, "Kenyan": 159.4, "Kittitian": 156.9, "Korean": 156.15, "Kosovan": 165.7, "Kurdish": undefined, "Kuwaiti": 156.1, "Kyrgyz": 158.6, "Laotian": undefined, "Latvian": 165.7, "Lebanese": 165, "Liberian": 157.3, "Libyan": 160.5, "a Liechtensteiner": 164.3, "Lithuanian": 167.5, "Luxembourgian": 164.8, "Macedonian": undefined, "Malagasy": 154.3, "Malawian": 155, "Malaysian": 154.7, "Maldivian": undefined, "Malian": 160.4, "Maltese": 159.9, "Marshallese": undefined, "Mauritanian": undefined, "Mauritian": undefined, "Mexican": 154, "Micronesian": undefined, "Moldovan": 161.2, "Monégasque": undefined, "Mongolian": 157.7, "Montenegrin": 168.4, "Moroccan": 158.5, "Mosotho": 157.6, @@ -2897,8 +2897,8 @@ window.Height = (function(){ "Egyptian": 170.3, "Emirati": 170.3, "Equatoguinean": undefined, "Eritrean": undefined, "Estonian": 179.1, "Ethiopian": undefined, "Fijian": 170.4, "Filipina": 163.5, "Finnish": 178.9, "French Guianan": 168, "French Polynesian": undefined, "French": 175.6, "Gabonese": undefined, "Gambian": 168, "Georgian": 172.7, "German": 175.4, "Ghanan": 169.5, "Greek": 177, "Greenlandic": undefined, "Grenadian": undefined, "Guamanian": undefined, "Guatemalan": 157.5, "Guinean": undefined, "Guyanese": 168.6, "Haitian": undefined, "Honduran": undefined, "Hungarian": 176, "I-Kiribati": undefined, "Icelandic": 181, - "Indian": 164.7, "Indonesian": 158, "Iranian": 170.3, "Iraqi": 165.4, "Irish": 177, "Israeli": 177, "Italian": 176.5, "Ivorian": undefined, "Jamaican": 171.8, "Japanese": 172, "Jordanian": undefined, - "Kazakh": 169, "Kenyan": 170.0, "Kittitian": 164.4, "Korean": 168.15, "Kosovan": undefined, "Kurdish": undefined, "Kuwaiti": 169.2, "Kyrgyz": 170.4, "Laotian": 160.5, "Latvian": 174.2, "Lebanese": 176, + "Indian": 164.7, "Indonesian": 158, "Iranian": 170.3, "Iraqi": 165.4, "Irish": 177, "Israeli": 177, "Italian": 176.5, "Ivorian": 170.1, "Jamaican": 171.8, "Japanese": 172, "Jordanian": undefined, + "Kazakh": 169, "Kenyan": 170.0, "Kittitian": 164.4, "Korean": 168.15, "Kosovan": 179.5, "Kurdish": undefined, "Kuwaiti": 169.2, "Kyrgyz": 170.4, "Laotian": 160.5, "Latvian": 174.2, "Lebanese": 176, "Liberian": undefined, "Libyan": 171.3, "a Liechtensteiner": 175.4, "Lithuanian": 177.2, "Luxembourgian": 179.9, "Macedonian": undefined, "Malagasy": 161.5, "Malawian": 166, "Malaysian": 166.3, "Maldivian": undefined, "Malian": 171.3, "Maltese": 169.9, "Marshallese": undefined, "Mauritanian": undefined, "Mauritian": undefined, "Mexican": 167, "Micronesian": undefined, "Moldovan": undefined, "Monégasque": undefined, "Mongolian": 168.4, "Montenegrin": 183.2, "Moroccan": 172.7, "Mosotho": undefined, "Motswana": undefined, "Mozambican": undefined, "Namibian": undefined, "Nauruan": undefined, @@ -3359,6 +3359,76 @@ window.getSlaveTrustClass = function (slave) { } }; +//takes an integer e.g. $activeSlave.hLength, returns a string in the format 10 inches +window.cmToInchString = function(s) { + return Math.round(s/2.54) + (Math.round(s/2.54) === 1?" inch":" inches"); +}; + +//takes an integer e.g. $activeSlave.height, returns a string in the format 6'5" +window.cmToFootInchString = function(s) { + if (Math.round(s/2.54) < 12) + return cmToInchString(s); + return Math.trunc(Math.round(s/2.54)/12) + `'` + Math.round(s/2.54)%12 + `"`; +}; + +//takes a dick value e.g. $activeSlave.dick, returns a string in the format 6 inches +window.dickToInchString = function(s) { + return cmToInchString(dickToCM(s)); +}; + +//takes a dick value e.g. $activeSlave.dick, returns an int of the dick length in cm +window.dickToCM = function(s) { + return (s<9?s*5:(s===9?50:s*6)); +}; + +//takes a ball value e.g. $activeSlave.balls, returns a string in the format 3 inches +window.ballsToInchString = function(s) { + return cmToInchString(ballsToCM(s)); +}; + +//takes a ball value e.g. $activeSlave.balls, returns an int of the ball size in cm +window.ballsToCM = function(s) { + if (s < 2) + return 0; + return (s<10?(s-1)*2:s*2); +}; + +//takes a dick value e.g. $activeSlave.dick, returns a string in the format of either `20cm (8 inches)`, `8 inches`, or `20cm` +window.dickToEitherUnit = function(s) { + if (State.variables.showInches === 1) + return dickToCM(s) + "cm (" + dickToInchString(s) + ")"; + if (State.variables.showInches === 2) + return dickToInchString(s); + return dickToCM(s) + "cm"; +}; + +//takes a ball value e.g. $activeSlave.balls, returns a string in the format of either `20cm (8 inches)`, `8 inches`, or `20cm` +window.ballsToEitherUnit = function(s) { + if (State.variables.showInches === 1) + return ballsToCM(s) + "cm (" + ballsToInchString(s) + ")"; + if (State.variables.showInches === 2) + return ballsToInchString(s); + return ballsToCM(s) + "cm"; +}; + +//takes an int in centimetres e.g. $activeSlave.height, returns a string in the format of either `200cm (6'7")`, `6'7"`, or `200cm` +window.heightToEitherUnit = function(s) { + if (State.variables.showInches === 1) + return s + "cm (" + cmToFootInchString(s) + ")"; + if (State.variables.showInches === 2) + return cmToFootInchString(s); + return s + "cm"; +}; + +//takes an int in centimetres e.g. $activeSlave.hLength, returns a string in the format of either `30cm (12 inches)`, `12 inches`, or `30cm` +window.lengthToEitherUnit = function(s) { + if (State.variables.showInches === 1) + return s + "cm (" + cmToInchString(s) + ")"; + if (State.variables.showInches === 2) + return cmToInchString(s); + return s + "cm"; +}; + /*:: Span Macro JS [script]*/ /* @@ -10770,11120 +10840,11177 @@ window.HSM = function() { else if (State.variables.PC.hacking >= 100) return .75; } + +/*:: colorModeJS [script]*/ -/*:: Slave Summary Widgets JS [script]*/ +window.setColors = function(colorMap){ + let styleSheetArray = Array.from(document.styleSheets); + styleSheetArray.forEach( styleSheet => { + let cssRules = Array.from(styleSheet.cssRules); + cssRules.forEach( cssRule => { + if ( cssRule.type === 1 ){ + let color = cssRule.style.color; + let bgcolor = cssRule.style.backgroundColor; + if ( + color != "" && + color != "inherit" ){ + cssRule.style.color = colorMap[color] || color; + console.log('color: ',color); + } + if ( + bgcolor != "" && + bgcolor != "inherit" && + bgcolor != "transparent" ){ + cssRule.style.backgroundColor = colorMap[bgcolor] || bgcolor; + console.log('color: ',color); + } + } + }); + }); +} -window.clearSummaryCache = function clearSummaryCache(slave) { - if (!slave) - setup.summaryCache = {}; - else if (slave instanceof Object && slave.ID !== Infinity && slave.ID !== -Infinity) - setup.summaryCache[slave.ID] = undefined; - else - setup.summaryCache[slave] = undefined; +/*:: HTAG Macro JS [script]*/ + +/* + * <<htag>> macro + * A simple macro which allows to create wrapping html elements with dynamic IDs. + * idea blatantly robbed from the spanMacroJS.tw but expanded to a more generic + * case, allowing <div>, <button> or whatever you want. elements, default is for + * the div though. In addition, you can pass an object in as the first argument + * instead of an id, and each of the object's attributes will become attributes + * of the generate tag. + * + * Usage: <<htag id>>...<</htag>> + * Usage: <<htag id tag>>...<</htag>> + * Usage: <<htag atributes>>...<</htag>> + * Usage: <<htag atributes tag>>...<</htag>> + */ +Macro.add('htag', { + tags: null, + handler() { + const payload = this.payload[0].contents.replace(/(^\n+|\n+$)/, ''); + let htag = 'div'; + let attributes; + function munge (val, key) { + return key + '="' + val + '"'; + } + + if (1 > this.args.length) + return this.error('invalid syntax, format: <<htag [id [ tag ] | attributes [ tag ] >>'); + if (1 < this.args.length) + htag = String(this.args[1]).trim(); + if ("object" === typeof this.args[0]) + attributes = $.map(this.args[0], munge).join(" "); + else + attributes = 'id="' + String(this.args[0]).trim() + '"'; + if (Config.debug) + this.debugView.modes({block: true}); + + jQuery('<' + htag + ' ' + attributes + ' />') + .wiki(payload) + .appendTo(this.output); + } +}); + +/*:: Quick List [script]*/ + +window.sortDomObjects = function (objects, attrName, reverse = 0) { + reverse = (reverse) ? -1 : 1; + function sortingByAttr (a, b) { + var aVal = a.getAttribute(attrName); + var bVal = b.getAttribute(attrName); + var aInt = parseInt(aVal); + if (!isNaN(aInt)) + return ((parseInt(bVal) - aInt) * reverse); + else if (bVal > aVal) + return -1 * reverse; + return ((aVal == bVal) ? 0 : 1) * reverse; + } + return objects.toArray().sort(sortingByAttr); }; -window.SlaveSummary = function SlaveSummary(slave) { - const V = State.variables; - if(V.useSummaryCache) { - if (setup.summaryCache[slave.ID] === undefined) - setup.summaryCache[slave.ID] = SlaveSummaryUncached(slave); - //this.output.appendChild(setup.summaryCache[State.temporary.Slave.ID].cloneNode(true)) - return setup.summaryCache[slave.ID]; - } else return SlaveSummaryUncached(slave); +window.sortButtonsByDevotion = function () { + var $sortedButtons = $('#qlWrapper button').remove(); + $sortedButtons = sortDomObjects($sortedButtons, 'data-devotion'); + $($sortedButtons).appendTo($('#qlWrapper')); + quickListBuildLinks(); }; -window.SlaveSummaryUncached = (function(){ +window.sortButtonsByTrust = function () { + var $sortedButtons = $('#qlWrapper button').remove(); + $sortedButtons = sortDomObjects($sortedButtons, 'data-trust'); + $($sortedButtons).appendTo($('#qlWrapper')); + quickListBuildLinks(); +}; + +window.quickListBuildLinks = function () { + $("[data-scroll-to]").click(function() { + var $this = $(this), $toElement = $this.attr('data-scroll-to'); + // note the * 1 enforces $offset to be an integer, without + // it we scroll to True, which goes nowhere fast. + var $offset = $this.attr('data-scroll-offset') * 1 || 0; + var $speed = $this.attr('data-scroll-speed') * 1 || 500; + // Use javascript scrollTop animation for in page navigation. + $('html, body').animate({ + scrollTop: $($toElement).offset().top + $offset + }, $speed); + }); +}; + +window.sortIncubatorPossiblesByName = function () { + var $sortedIncubatorPossibles = $('#qlIncubator div.possible').detach(); + $sortedIncubatorPossibles = sortDomObjects($sortedIncubatorPossibles, 'data-name'); + $($sortedIncubatorPossibles).appendTo($('#qlIncubator')); +}; + +window.sortIncubatorPossiblesByPregnancyWeek = function () { + var $sortedIncubatorPossibles = $('#qlIncubator div.possible').detach(); + $sortedIncubatorPossibles = sortDomObjects($sortedIncubatorPossibles, 'data-preg-week'); + $($sortedIncubatorPossibles).appendTo($('#qlIncubator')); +}; + +window.sortIncubatorPossiblesByPregnancyCount = function () { + var $sortedIncubatorPossibles = $('#qlIncubator div.possible').detach(); + $sortedIncubatorPossibles = sortDomObjects($sortedIncubatorPossibles, 'data-preg-count'); + $($sortedIncubatorPossibles).appendTo($('#qlIncubator')); +}; + +window.sortIncubatorPossiblesByReservedSpots = function () { + var $sortedIncubatorPossibles = $('#qlIncubator div.possible').detach(); + $sortedIncubatorPossibles = sortDomObjects($sortedIncubatorPossibles, 'data-reserved-spots'); + $($sortedIncubatorPossibles).appendTo($('#qlIncubator')); +}; + +window.sortIncubatorPossiblesByPreviousSort = function () { + var sort = State.variables.sortIncubatorList; + console.log(State.variables); + console.log('sort', sort); + if ('unsorted' !== sort) { + console.log("sort isn't unsorted", sort); + if ('Name' === sort) { + console.log("sort is name", sort); + sortIncubatorPossiblesByName(); + } else if ('Reserved Incubator Spots' === sort) { + console.log("sort is spots", sort); + sortIncubatorPossiblesByReservedSpots(); + } else if ('Pregnancy Week' === sort) { + console.log("sort is week", sort); + sortIncubatorPossiblesByPregnancyWeek(); + } else if ('Number of Children' === sort) { + console.log("sort is count", sort); + sortIncubatorPossiblesByPregnancyCount(); + } + } +}; + +/*:: DefaultRules [script]*/ +// this code applies RA rules onto slaves + +window.DefaultRules = (function() { "use strict"; - let V, r; - - function SlaveSummaryUncached(slave) { + let V; + let r; + + function DefaultRules(slave) { + if (slave.useRulesAssistant === 0) return r; //exempted + V = State.variables; r = ""; - if (V.abbreviateDevotion === 1) - short_devotion(slave); - else if (V.abbreviateDevotion === 2) - long_devotion(slave); - if (slave.fuckdoll === 0) { - if (V.abbreviateRules === 1) - short_rules(slave); - else if (V.abbreviateRules === 2) - long_rules(slave); - } - if (slave.tired !== 0) - r += `Tired.`; - if (V.abbreviateDiet === 1) - short_weight(slave); - else if (V.abbreviateDiet === 2) - long_weight(slave); - if (V.abbreviateDiet === 1) - short_diet(slave); - else if (V.abbreviateDiet === 2) - long_diet(slave); - if (V.abbreviateHealth === 1) - short_health(slave); - else if (V.abbreviateHealth === 2) - long_health(slave); - if (V.abbreviateDrugs === 1) - short_drugs(slave); - else if (V.abbreviateDrugs === 2) - long_drugs(slave); - if (V.abbreviateNationality + V.abbreviateGenitalia + V.abbreviatePhysicals + V.abbreviateSkills + V.abbreviateMental !== 0) { - r += `<br>`; - if (V.seeImages !== 1 || V.seeSummaryImages !== 1 || V.imageChoice === 1) - r += ` `; + let rule = MergeRules(slave); + if (Object.keys(rule).length === 0) return r; // no rules apply + + AssignJobToSlave(slave, rule); + if(slave.fuckdoll === 0) { + ProcessClothing(slave, rule); + ProcessCollar(slave, rule); + ProcessEyewear(slave, rule); + ProcessDildos(slave, rule); + ProcessDickAccessories(slave, rule); + ProcessAnalAccessories(slave, rule); + ProcessShoes(slave, rule); + ProcessBellyAccessories(slave, rule); + ProcessLegAccessory(slave, rule); } - V.desc = SlaveTitle(slave); - V.seed = V.desc.substring(0, 1); - V.seed = V.seed.toUpperCase(); - V.desc = V.seed + V.desc.substring(1); - r += `<strong><span class="coral">${V.desc}${V.abbreviatePhysicals === 2? '.' : ''}</span></strong> `; - if (V.seeRace === 1) { - r += `<span class="tan">`; - if (V.abbreviateRace === 1) - short_race(slave); - else if (V.abbreviateRace === 2) - long_race(slave); - r += `</span> `; - } - if (V.abbreviateNationality === 1) - short_nationality(slave); - else if (V.abbreviateNationality === 2) - long_nationality(slave); - if (V.abbreviatePhysicals === 1) - short_skin(slave); - else - r += `<span class="pink">${slave.skin.charAt(0).toUpperCase() + slave.skin.slice(1)} skin.</span> `; - if (V.abbreviateGenitalia === 1) - short_genitals(slave); - else if (V.abbreviateGenitalia === 2) - long_genitals(slave); - if (V.abbreviatePhysicals === 1) { - short_age(slave); - short_face(slave); - short_eyes(slave); - if (slave.markings !== "none") - r += `Markings`; - short_lips(slave); - short_teeth(slave); - short_muscles(slave); - short_limbs(slave); - short_voice(slave); - short_tits_ass(slave); - short_hips(slave); - short_waist(slave); - short_implants(slave); - short_lactation(slave); - short_mods(slave); - r += `</span>`; - } else if (V.abbreviatePhysicals === 2) { - long_age(slave); - long_face(slave); - long_eyes(slave); - long_lips(slave); - long_teeth(slave); - long_muscles(slave); - long_limbs(slave); - long_voice(slave); - long_tits_ass(slave); - long_hips(slave); - long_waist(slave); - long_implants(slave); - long_lactation(slave); - long_mods(slave); - if (slave.brand !== 0) - r += `Branded.`; - r += `</span>`; - } - r += `<br>`; - if (V.seeImages !== 1 || V.seeSummaryImages !== 1 || V.imageChoice === 1) - r += ` `; - if (V.abbreviateSkills === 1) { - short_intelligence(slave); - short_sex_skills(slave); - if (slave.combatSkill > 0) - r += `C`; - r += `</span> `; - short_prestige(slave); - } else if (V.abbreviateSkills === 2) { - long_intelligence(slave); - long_sex_skills(slave); - if (slave.combatSkill > 0) - r += `Trained fighter.`; - r += `</span> `; - long_prestige(slave); - } - if (V.abbreviateMental === 1) { - if (slave.fetish !== "mindbroken") { - if (slave.fetishKnown === 1) - short_fetish(slave); - if (slave.attrKnown === 1) - short_attraction(slave); - } - if (slave.clitPiercing === 3) { - short_smart_fetish(slave); - short_smart_attraction(slave); - } - short_behavior_flaw(slave); - short_sex_flaw(slave); - short_behavior_quirk(slave); - short_sex_quirk(slave); - } else if (V.abbreviateMental === 2) { - if (slave.fetish !== "mindbroken") { - if (slave.fetishKnown === 1) - long_fetish(slave); - if (slave.attrKnown === 1) - long_attraction(slave); - } - if (slave.clitPiercing === 3) { - long_smart_fetish(slave); - long_smart_attraction(slave); - } - long_behavior_flaw(slave); - long_sex_flaw(slave); - long_behavior_quirk(slave); - long_sex_quirk(slave); - } - if (slave.customLabel != "") - r += `<strong><span class="yellow">${slave.customLabel}</span></strong>`; - if ((slave.relationship !== 0) || (slave.relation !== 0) || (V.abbreviateClothes === 2) || (V.abbreviateRulesets === 2)) { - r += `<br>`; - if (V.seeImages !== 1 || V.seeSummaryImages !== 1 || V.imageChoice === 1) - r += ` `; - } - if (V.abbreviateMental === 1) { - r += `<span class="lightgreen">`; - if (V.familyTesting === 1) - short_extended_family(slave); - else - short_legacy_family(slave); - r += `</span>`; - short_rival(slave); - } else if (V.abbreviateMental === 2) { - if (V.familyTesting === 1) - long_extended_family(slave); - else - long_legacy_family(slave); - long_rival(slave); - } - if (slave.fuckdoll === 0) { - if (V.abbreviateClothes === 2) { - r += ` `; - if (slave.choosesOwnClothes === 1) - r += `Dressing herself. `; - long_clothes(slave); - long_collar(slave); - long_belly(slave); - if (slave.amp !== 1) - long_legs(slave); - if (canWalk(slave)) - long_shoes(slave); - long_vaginal_acc(slave); - long_dick_acc(slave); - long_buttplug(slave); - } + ProcessBellyImplant(slave, rule); + if (isFertile(slave)) + ProcessContraceptives(slave, rule); + ProcessOtherDrugs(slave, rule); + ProcessAssetGrowthDrugs(slave, rule); + ProcessDiet(slave, rule); + ProcessCuratives(slave, rule); + ProcessAphrodisiacs(slave, rule); + ProcessPenisHormones(slave, rule); + ProcessFemaleHormones(slave, rule); + ProcessPregnancyDrugs(slave, rule); + if(slave.fuckdoll === 0) { + ProcessLivingStandard(slave, rule); + ProcessSpeech(slave, rule); + ProcessRelationship(slave, rule); + ProcessRelease(slave, rule); + ProcessPunishment(slave, rule); + ProcessReward(slave, rule); } - r += ` `; - rules_assistant(slave); - if (V.abbreviateOrigins === 2 && slave.origin !== 0) - origins(slave); + ProcessDietCum(slave, rule); + ProcessDietMilk(slave, rule); + ProcessTeeth(slave, rule); + ProcessStyle(slave, rule); + ProcessPiercings(slave, rule); + ProcessSmartPiercings(slave, rule); + ProcessTattoos(slave, rule); + ProcessPorn(slave, rule); + ProcessLabel(slave, rule); return r; } - - function short_devotion(slave) { - if (slave.fetish === "mindbroken") { - r += `<span class="red">MB</span>`; - } else if (slave.devotion < -95) { - r += `<span class="darkviolet">Hate${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; - } else if (slave.devotion < -50) { - r += `<span class="darkviolet">Hate${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; - } else if (slave.devotion < -20) { - r += `<span class="mediumorchid">Res${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; - } else if (slave.devotion <= 20) { - r += `<span class="yellow">Ambiv${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; - } else if (slave.devotion <= 50) { - r += `<span class="hotpink">Accept${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; - } else if (slave.devotion <= 95) { - r += `<span class="deeppink">Devo${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; - } else { - r += `<span class="magenta">Wor${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; - } - r += " "; - if (slave.fetish === "mindbroken") { - return; - } else if (slave.trust < -95) { - r += `<span class="darkgoldenrod">ETerr${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; - } else if (slave.trust < -50) { - r += `<span class="goldenrod">Terr${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; - } else if (slave.trust < -20) { - r += `<span class="gold">Fright${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; - } else if (slave.trust <= 20) { - r += `<span class="yellow">Fear${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; - } else if (slave.trust <= 50) { - if (slave.devotion < -20) { - r += `<span class="orange">Caref${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; - } else { - r += `<span class="mediumaquamarine">Caref${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; - } - } else if (slave.trust < 95) { - if (slave.devotion < -20) { - r += `<span class="orangered">Bold${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; - } else { - r += `<span class="mediumseagreen">Trust${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; - } - } else { - if (slave.devotion < -20) { - r += `<span class="darkred">Defiant${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; - } else { - r += `<span class="seagreen">VTrust ${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; - } - } - r += " "; + + function MergeRules(slave) { + // merge all rules applying on a slave into one big 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)))); } - - function long_devotion(slave) { - if (slave.fetish === "mindbroken") { - r += `<span class="red">Mindbroken.</span>`; - } else if (slave.devotion < -95) { - r += `<span class="darkviolet">Very hateful${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; - } else if (slave.devotion < -50) { - r += `<span class="darkviolet">Hateful${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; - } else if (slave.devotion < -20) { - r += `<span class="mediumorchid">Resistant${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; - } else if (slave.devotion <= 20) { - r += `<span class="yellow">Ambivalent${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; - } else if (slave.devotion <= 50) { - r += `<span class="hotpink">Accepting${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; - } else if (slave.devotion <= 95) { - r += `<span class="deeppink">Devoted${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; - } else { - r += `<span class="magenta">Worshipful${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; - } - r += " "; - if (slave.fetish === "mindbroken") { - return; - } else if (slave.trust < -95) { - r += `<span class="darkgoldenrod">Extremely terrified${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; - } else if (slave.trust < -50) { - r += `<span class="goldenrod">Terrified${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; - } else if (slave.trust < -20) { - r += `<span class="gold">Frightened${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; - } else if (slave.trust <= 20) { - r += `<span class="yellow">Fearful${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; - } else if (slave.trust <= 50) { - if (slave.devotion < -20) { - r += `<span class="orange">Careful${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; - } else { - r += `<span class="mediumaquamarine">Careful${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; - } - } else if (slave.trust < 95) { - if (slave.devotion < -20) { - r += `<span class="orangered">Bold${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; - } else { - r += `<span class="mediumseagreen">Trusting${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; - } - } else { - if (slave.devotion < -20) { - r += `<span class="darkred">Defiant${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; - } else { - r += `<span class="seagreen">Profoundly trusting${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; - } - } - r += " "; - } - - function short_rules(slave) { - switch (slave.livingRules) { - case "luxurious": - r += `<strong>LS:Lux</strong>`; - break; - case "normal": - r += `<strong>LS:Nor</strong>`; + + 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": + delete rule.setAssignment; break; - default: - r += `<strong>LS:Spa</strong>`; + + case "rest": + case "please you": + // slaves always qualify for this assignment break; - } - r += " "; - if (canTalk(slave)) { - switch (slave.speechRules) { - case "permissive": - r += `<strong>SpR:P</strong>`; + + case "live with your Head Girl": + if ((V.HGSuiteSlaves < 1 && slave.indentureRestrictions <= 0)) break; - case "accent elimination": - r += `<strong>SpR:NoAcc</strong>`; + else { + RAFacilityRemove(slave, rule); // before deleting rule.setAssignment + delete rule.setAssignment; + } + break; + + case "be confined in the arcade": + if ((V.arcadeSlaves < V.arcade && slave.indentureRestrictions <= 0 && slave.breedingMark != 1)) break; - case "language lessons": - r += `<strong>SpR:LL</strong>`; + else { + RAFacilityRemove(slave, rule); // before deleting rule.setAssignment + delete rule.setAssignment; + } + break; + + case "serve in the master suite": + if ((V.masterSuiteSlaves < V.masterSuite && (slave.devotion > 20 || slave.trust < -50 || (slave.devotion >= -50 && slave.trust < -20)))) break; - default: - r += `<strong>SpR:R</strong>`; + else { + RAFacilityRemove(slave, rule); // before deleting rule.setAssignment + delete rule.setAssignment; + } + break; + + case "get treatment in the clinic": + if ((V.clinicSlaves < V.clinic && (slave.health < 20 || (slave.chem > 15 && V.Nurse !== 0 && V.clinicUpgradeFilters == 1)) || ((slave.bellyImplant > -1) && (V.bellyImplants == 1)) || slave.preg > 1)) break; - } - r += " "; - } - switch (slave.relationshipRules) { - case "permissive": - r += `<strong>ReR:P</strong>`; + else { + RAFacilityRemove(slave, rule); // before deleting rule.setAssignment + delete rule.setAssignment; + } break; - case "just friends": - r += `<strong>ReR:Fr</strong>`; + + case "rest in the spa": + if ((V.spaSlaves < V.spa) && (slave.health < 20) || (slave.trust < 60) || (slave.devotion <= 60) || (slave.fetish == "mindbroken") && (slave.devotion >= -20)) + break; + else { + RAFacilityRemove(slave,rule); // before deleting rule.setAssignment + delete rule.setAssignment; + } break; - default: - r += `<strong>ReR:R</strong>`; + + case "work in the brothel": + if ((V.brothelSlaves < V.brothel && (slave.devotion > 50 || slave.trust > 50 || slave.trust < -50 || (slave.devotion >= -50 && slave.trust < -20)) && slave.breedingMark != 1)) + break; + else { + RAFacilityRemove(slave, rule); // before deleting rule.setAssignment + delete rule.setAssignment; + } break; - } - r += " "; - switch (slave.standardPunishment) { - case "confinement": - r += `<strong>Pun:Conf</strong>`; + + case "serve in the club": + if ((V.clubSlaves < V.club && (slave.devotion > 50 || slave.trust > 50 || slave.trust < -50 || (slave.devotion >= -50 && slave.trust < -20)) && slave.breedingMark != 1)) + break; + else { + RAFacilityRemove(slave, rule); // before deleting rule.setAssignment + delete rule.setAssignment; + } break; - case "whipping": - r += `<strong>Pun:Whip</strong>`; + + case "work in the dairy": + if ((V.dairy > V.dairySlaves+V.bioreactorsXY+V.bioreactorsXX+V.bioreactorsHerm+V.bioreactorsBarren)) { + if ((slave.indentureRestrictions > 0) && (V.dairyRestraintsSetting > 1)) + break; + else if (((slave.indentureRestrictions > 1) && (V.dairyRestraintsSetting > 0)) || (slave.breedingMark == 1 && V.dairyRestriantsSettings > 0) || ((V.dairyPregSetting > 0) && ((slave.bellyImplant != -1) || (slave.broodmother !== 0)))) + break; + else { + if ((slave.lactation > 0 || ((V.dairySlimMaintainUpgrade === 0 || V.dairySlimMaintain === 0) && (slave.boobs > 300 || slave.dick === 0 || V.dairyImplantsSetting == 1) && V.dairyImplantsSetting != 2)) || (slave.balls > 0)) { + if ((slave.devotion > 20) || ((slave.devotion >= -50) && (slave.trust < -20)) || (slave.trust < -50) || (slave.amp == 1) || (V.dairyRestraintsUpgrade == 1)) { + if ((V.dairyStimulatorsSetting < 2) || (slave.anus > 2) || (V.dairyPrepUpgrade == 1)) { + if ((V.dairyPregSetting < 2) || (slave.vagina > 2) || (slave.ovaries === 0) || (V.dairyPrepUpgrade == 1)) + break; + else { + RAFacilityRemove(slave,rule); // before deleting rule.setAssignment + delete rule.setAssignment; + } + } else { + RAFacilityRemove(slave,rule); // before deleting rule.setAssignment + delete rule.setAssignment; + } + } else { + RAFacilityRemove(slave,rule); // before deleting rule.setAssignment + delete rule.setAssignment; + } + } else { + RAFacilityRemove(slave,rule); // before deleting rule.setAssignment + delete rule.setAssignment; + } + } + } break; - case "chastity": - r += `<strong>Pun:Chas</strong>`; + + case "work as a servant": + if ((V.servantsQuartersSlaves < V.servantsQuarters && canSee(slave) && canWalk(slave) && (slave.devotion >= -20 || slave.trust < -20 || (slave.devotion >= -50 && slave.trust <= 20)))) + break; + else { + RAFacilityRemove(slave,rule); // before deleting rule.setAssignment + delete rule.setAssignment; + } break; - default: - r += `<strong>Pun:Situ</strong>`; + + case "learn in the schoolroom": + if ((V.schoolroomSlaves < V.schoolroom && slave.fetish != "mindbroken" && (slave.devotion >= -20 || slave.trust < -50 || (slave.devotion >= -50 && slave.trust < -20)))) + if ((slave.intelligenceImplant < 1) || (slave.voice !== 0 && slave.accent+V.schoolroomUpgradeLanguage > 2) || (slave.oralSkill <= 10+V.schoolroomUpgradeSkills*20) || (slave.whoreSkill <= 10+V.schoolroomUpgradeSkills*20) || (slave.entertainSkill <= 10+V.schoolroomUpgradeSkills*20) || (slave.analSkill < 10+V.schoolroomUpgradeSkills*20) || ((slave.vagina >= 0) && (slave.vaginalSkill < 10+V.schoolroomUpgradeSkills*20))) + break; + else { + RAFacilityRemove(slave,rule); // before deleting rule.setAssignment + delete rule.setAssignment; + } + else { + RAFacilityRemove(slave,rule); // before deleting rule.setAssignment + delete rule.setAssignment; + } break; - } - r += " "; - switch (slave.standardReward) { - case "relaxation": - r += `<strong>Rew:Relx</strong>`; + + case "be confined in the cellblock": + if ((V.cellblockSlaves < V.cellblock && ((slave.devotion < -20 && slave.trust >= -20) || (slave.devotion < -50 && slave.trust >= -50)))) + break; + else { + RAFacilityRemove(slave,rule); // before deleting rule.setAssignment + delete rule.setAssignment; + } break; - case "drugs": - r += `<strong>Rew:Drug</strong>`; + + case "take classes": + if (slave.intelligenceImplant !== 1 && slave.fetish != "mindbroken" && (slave.devotion >= -20 || slave.trust < -50 || (slave.trust < -20 && slave.devotion >= -50))) + break; + else + delete rule.setAssignment; break; - case "orgasm": - r += `<strong>Rew:Orga</strong>`; + + case "choose her own job": + if ((slave.fetish != "mindbroken")) + break; + else + delete rule.setAssignment; break; - default: - r += `<strong>Rew:Situ</strong>`; + + case "get milked": + if ((slave.lactation > 0 || slave.balls > 0)) + break; + else + delete rule.setAssignment; break; - } - r += " "; - switch (slave.releaseRules) { - case "permissive": - r += `<strong>MaR:P</strong>`; + + case "be a servant": + if ((canWalk(slave) && canSee(slave) && (slave.devotion >= -20 || slave.trust < -50 || (slave.trust < -20 && slave.devotion >= -50)))) + break; + else + delete rule.setAssignment; break; - case "sapphic": - r += `<strong>MaR:S</strong>`; + + case "work a glory hole": + if (slave.indentureRestrictions <= 0 && slave.breedingMark != 1) + break; + else + delete rule.setAssignment; break; - case "masturbation": - r += `<strong>MaR:M</strong>`; + + case "whore": + case "serve the public": + case "stay confined": + if ((slave.fuckdoll === 0) && slave.breedingMark != 1) + break; + else + delete rule.setAssignment; break; + default: - r += `<strong>MaR:R</strong>`; + r += `<span class="red">raWidgets missing case for assignment 'V.{rule.setAssignment}'</span>.`; break; } - r += " "; - } - - function long_rules(slave) { - r += `Living standard: ${slave.livingRules}. `; - if (canTalk(slave)) { - r += `Speech rules: ${slave.speechRules}. `; - } - r += `Relationship rules: ${slave.relationshipRules}. `; - r += `Typical punishment: ${slave.standardPunishment}. `; - r += `Typical reward: ${slave.standardReward}. `; - r += `Release rules: ${slave.releaseRules}. `; + return rule; } - - function short_weight(slave) { - if (slave.weight < -95) { - r += `<strong><span class="red">W---${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; - } else if (slave.weight < -30) { - if (slave.hips < -1) { - r += `<strong>W--${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; - } else { - r += `<strong><span class="red">W--${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; - } - } else if (slave.weight < -10) { - r += `<strong>W-${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; - } else if (slave.weight <= 10) { - r += `<strong>W${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; - } else if (slave.weight <= 30) { - r += `<strong>W+${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; - } else if (slave.weight <= 95) { - if (slave.hips > 1 || V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `<strong>W++${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; - } else { - r += `<strong><span class="red">W++${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; - } - } else if (slave.weight <= 130) { - if (slave.hips >= 2 || V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `<strong>W+++${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; - } else { - r += `<strong><span class="red">W+++${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; - } - } else if (slave.weight <= 160) { - if (V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `<strong>W++++${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; - } else { - r += `<strong><span class="red">W++++${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; - } - } else if (slave.weight <= 190) { - if (V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `<strong>W+++++${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; - } else { - r += `<strong><span class="red">W+++++${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; - } - } else { - if (V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `<strong>W++++++${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; - } else { - r += `<strong><span class="red">W++++++${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; + + function AssignJobToSlave(slave, rule) { + // place slave on assignment defined by the rule + if ((rule.setAssignment !== undefined && rule.setAssignment != "no default setting")) { + if (((rule.setAssignment == "choose her own job" && !slave.choosesOwnAssignment) || rule.setAssignment != slave.assignment)) { + switch (rule.setAssignment) { + case "live with your Head Girl": + r += `<br>${slave.slaveName} has been automatically assigned to live in your Head Girl's private suite.`; + break; + case "be confined in the arcade": + r += `<br>${slave.slaveName} has been automatically assigned to be confined in ${V.arcadeName}.`; + break; + case "serve in the master suite": + r += `<br>${slave.slaveName} has been automatically assigned to ${V.masterSuiteName}.`; + break; + case "get treatment in the clinic": + r += `<br>${slave.slaveName} has been automatically assigned to get treatment in ${V.clinicName}.`; + break; + case "rest in the spa": + r += `<br>${slave.slaveName} has been automatically assigned to rest in ${V.spaName}.`; + break; + case "work in the brothel": + r += `<br>${slave.slaveName} has been automatically assigned to work in ${V.brothelName}.`; + break; + case "serve in the club": + r += `<br>${slave.slaveName} has been automatically assigned to serve in ${V.clubName}.`; + break; + case "work in the dairy": + r += `<br>${slave.slaveName} has been automatically assigned to be milked in ${V.dairyName}.`; + break; + case "work as a servant": + r += `<br>${slave.slaveName} has been automatically assigned to work in ${V.servantsQuartersName}.`; + break; + case "learn in the schoolroom": + r += `<br>${slave.slaveName} has been automatically assigned to study in ${V.schoolroomName}.`; + break; + case "be confined in the cellblock": + r += `<br>${slave.slaveName} has been automatically assigned to be confined in ${V.cellblockName}.`; + break; + case "choose her own job": + r += `<br>${slave.slaveName} is now allowed to select her own assignments.`; + break; + default: + r += `<br>${slave.slaveName} has been automatically assigned to ${rule.setAssignment}.`; + break; + } + assignJob(slave, rule.setAssignment); } } - r += " "; } - - function long_weight(slave) { - if (slave.weight < -95) { - r += `<span class="red">Emaciated${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; - } else if (slave.weight < -30) { - if (slave.hips < -1) { - r += `Model-thin${V.summaryStats? `[${slave.weight}]`: ''}.`; - } else { - r += `<span class="red">Very thin${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; - } - } else if (slave.weight < -10) { - r += `Thin${V.summaryStats? `[${slave.weight}]`: ''}.`; - } else if (slave.weight <= 10) { - r += `Trim${V.summaryStats? `[${slave.weight}]`: ''}.`; - } else if (slave.weight <= 30) { - r += `Plush${V.summaryStats? `[${slave.weight}]`: ''}.`; - } else if (slave.weight <= 95) { - if (slave.hips > 1 || V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `Nicely chubby${V.summaryStats? `[${slave.weight}]`: ''}.`; - } else { - r += `<span class="red">Overweight${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; - } - } else if (slave.weight <= 130) { - if (slave.hips >= 2 || V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `Pleasantly soft and shapely${V.summaryStats? `[${slave.weight}]`: ''}.`; - } else { - r += `<span class="red">Fat${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; - } - } else if (slave.weight <= 160) { - if (V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `Amazingly voluptuous${V.summaryStats? `[${slave.weight}]`: ''}.`; - } else { - r += `<span class="red">Obese${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; - } - } else if (slave.weight <= 190) { - if (V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `SSBBW${V.summaryStats? `[${slave.weight}]`: ''}.`; - } else { - r += `<span class="red">Super Obese${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; - } - } else { - if (V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `Perfectly massive${V.summaryStats? `[${slave.weight}]`: ''}.`; - } else { - r += `<span class="red">Dangerously Obese${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; + + function ProcessClothing(slave, rule) { + // apply clothes to slave + if ((rule.clothes !== undefined) && (rule.clothes !== "no default setting")) { + if ((rule.clothes == "choosing her own clothes")) { + if ((slave.choosesOwnClothes === 0)) { + slave.clothes = "choosing her own clothes"; + slave.choosesOwnClothes = 1; + r += `<br>${slave.slaveName} is now allowed to choose her own clothes.`; + } + } else if ((slave.clothes !== rule.clothes)) { + slave.clothes = rule.clothes; + slave.choosesOwnClothes = 0; + r += `<br>${slave.slaveName} is now wearing ${slave.clothes}.`; } } - r += " "; - } - - function short_diet(slave) { - r += `<span class="teal">`; - switch (slave.diet) { - case "restricted": - r += `<strong>Di:W-</strong>`; - break; - case "fattening": - r += `<strong>Di:W+</strong>`; - break; - case "XX": - r += `<strong>Di:XX+</strong>`; - break; - case "XY": - r += `<strong>Di:XY+</strong>`; - break; - case "XXY": - r += `<strong>Di:XXY+</strong>`; - break; - case "muscle building": - r += `<strong>Di:M+</strong>`; - break; - case "slimming": - r += `<strong>Di:M-</strong>`; - break; - case "cum production": - r += `<strong>Di:C+</strong>`; - break; - case "cleansing": - r += `<strong>Di:H+</strong>`; - break; - case "fertility": - r += `<strong>Di:F+</strong>`; - break; - } - r += `</span> `; - r += `<span class="cyan">`; - if (slave.dietCum === 2) { - r += `<strong>Cum++</strong>`; - } else if (((slave.dietCum === 1) && (slave.dietMilk === 0))) { - r += `<strong>Cum+</strong>`; - } else if (((slave.dietCum === 1) && (slave.dietMilk === 1))) { - r += `<strong>Cum+ Milk+</strong>`; - } else if (((slave.dietCum === 0) && (slave.dietMilk === 1))) { - r += `<strong>Milk+</strong>`; - } else if ((slave.dietMilk === 2)) { - r += `<strong>Milk++</strong>`; + + function ProcessCollar(slave, rule) { + // apply collar to slave + if ((rule.collar !== undefined) && (rule.collar != "no default setting")) { + if ((slave.collar !== rule.collar)) { + r += '<br>'; + if ((rule.collar == "preg biometrics" && slave.preg <= -1)) { + slave.collar = "none"; + r += `${slave.slaveName} cannot utilize preg biometrics.`; + } else if ((rule.collar == "massive dildo gag" && slave.oralSkill <= 50)) { + slave.collar = "none"; + r += `${slave.slaveName} lacks the oral skill to successfully keep the massive dildo gag in her throat.`; + } else + slave.collar = rule.collar; + if ((slave.collar == "none")) + r += `${slave.slaveName} has been given no collar.`; + else + r += `${slave.slaveName} has been given a ${slave.collar} collar.`; + } } - r += `</span> `; } - - function long_diet(slave) { - r += `<span class="teal">`; - switch (slave.diet) { - case "restricted": - r += `Dieting.`; - break; - case "fattening": - r += `Gaining weight.`; - break; - case "XX": - r += `Estrogen rich.`; - break; - case "XY": - r += `Testosterone rich.`; - break; - case "XXY": - r += `Futanari mix.`; - break; - case "muscle building": - r += `Pumping iron.`; - break; - case "slimming": - r += `Slimming down.`; - break; - case "cum production": - r += `Cum production.`; - break; - case "cleansing": - r += `Cleansing.`; - break; - case "fertility": - r += `Fertility.`; - break; - } - r += `</span> `; - if (slave.dietCum === 2) { - r += `Diet Base: <span class="cyan">Cum Based.</span>`; - } else if (((slave.dietCum === 1) && (slave.dietMilk === 0))) { - r += `Diet Base: <span class="cyan">Cum Added.</span>`; - } else if (((slave.dietCum === 1) && (slave.dietMilk === 1))) { - r += `Diet Base: <span class="cyan">Milk & Cum Added.</span>`; - } else if (((slave.dietCum === 0) && (slave.dietMilk === 1))) { - r += `Diet Base: <span class="cyan">Milk Added.</span>`; - } else if ((slave.dietMilk === 2)) { - r += `Diet Base: <span class="cyan">Milk Based.</span>`; + + function ProcessEyewear(slave, rule) { + // apply glasses, contacts to slave + if ((rule.eyewear !== undefined) && (rule.eyewear !== "no default setting")) { + switch (rule.eyewear) { + case "correct with glasses": + if (slave.eyes == -1) { + if (slave.eyewear != "corrective glasses") { + slave.eyewear = "corrective glasses"; + V.cash -= V.modCost; + r += `<br>${slave.slaveName} has been given corrective glasses.`; + } + } else { + if (slave.eyewear != "none") { + slave.eyewear = "none"; + r += `<br>${slave.slaveName}'s eyewear has been removed.`; + } + } + break; + + case "correct with contacts": + if (slave.eyes == -1) { + if (slave.eyewear != "corrective contacts") { + slave.eyewear = "corrective contacts"; + V.cash -= V.modCost; + r += `<br>${slave.slaveName} has been given corrective contacts.`; + } + } else { + if (slave.eyewear != "none") { + slave.eyewear = "none"; + r += `<br>${slave.slaveName}'s eyewear has been removed.`; + } + } + break; + + case "blur with glasses": + if (slave.eyes > -1) { + if (slave.eyewear != "blurring glasses") { + slave.eyewear = "blurring glasses"; + V.cash -= V.modCost; + r += `<br>${slave.slaveName} has been given blurring glasses.`; + } + } else { + if (slave.eyewear != "none") { + slave.eyewear = "none"; + r += `<br>${slave.slaveName}'s eyewear has been removed.`; + } + } + break; + + case "blur with contacts": + if (slave.eyes > -1) { + if (slave.eyewear != "blurring contacts") { + slave.eyewear = "blurring contacts"; + V.cash -= V.modCost; + r += `<br>${slave.slaveName} has been given blurring contacts.`; + } + } else { + if (slave.eyewear != "none") { + slave.eyewear = "none"; + r += `<br>${slave.slaveName}'s eyewear has been removed.`; + } + } + break; + + case "universal glasses": + if (slave.eyes == -1) { + if (slave.eyewear != "corrective glasses") { + slave.eyewear = "corrective glasses"; + V.cash -= V.modCost; + r += `<br>${slave.slaveName} has been given corrective glasses.`; + } + } else { + if (slave.eyewear != "glasses") { + slave.eyewear = "glasses"; + V.cash -= V.modCost; + r += `<br>${slave.slaveName} has been given decorative glasses.`; + } + } + break; + + default: + if (slave.eyewear != "none") { + slave.eyewear = "none"; + r += `<br>${slave.slaveName}'s eyewear has been removed.`; + } + break; + } } - r += " "; } - - function short_health(slave) { - if (slave.health < -20) { - r += `<strong><span class="red">H${V.summaryStats? `[${slave.health}]` : ''}</span></strong>`; - } else if (slave.health <= 20) { - r += `<strong><span class="yellow">H${V.summaryStats? `[${slave.health}]` : ''}</span></strong>`; - } else if (slave.health > 20) { - r += `<strong><span class="green">H${V.summaryStats? `[${slave.health}]` : ''}</span></strong>`; - } - r += " "; + + function ProcessDildos(slave, rule) { + // apply vaginal dildos to slave + if (slave.vagina === 0) + ProcessVVirginDildos(slave, rule); + else if ((slave.vagina > 0) && (slave.anus === 0)) + ProcessAVirginDildos(slave, rule); + else if (slave.vagina > 0) + ProcessNonVirginDildos(slave, rule); } - - function long_health(slave) { - if (slave.health < -90) { - r += `<span class="red">On the edge of death${V.summaryStats? `[${slave.health}]` : ''}.</span>`; - } else if (slave.health < -50) { - r += `<span class="red">Extremely unhealthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; - } else if (slave.health < -20) { - r += `<span class="red">Unhealthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; - } else if (slave.health <= 20) { - r += `<span class="yellow">Healthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; - } else if (slave.health <= 50) { - r += `<span class="green">Very healthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; - } else if (slave.health <= 90) { - r += `<span class="green">Extremely healthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; - } else { - r += `<span class="green">Unnaturally healthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; + + function ProcessVVirginDildos(slave, rule) { + // apply vaginal dildos to varginal virgins + if ((rule.virginAccessory !== undefined) && (rule.virginAccessory !== "no default setting")) { + if (slave.vaginalAccessory !== rule.virginAccessory) { + slave.vaginalAccessory = rule.virginAccessory; + switch (slave.vaginalAccessory) { + case "huge dildo": + r += `<br>${slave.slaveName} is a virgin and has been given a`; + if (slave.vagina >= 2) + r += `massive dildo to permanently gape her cunt.`; + else { + r += `large dildo for her pussy, since it must be stretched before it can accommodate a huge one.`; + slave.vaginalAccessory = "large dildo"; + } + break; + + case "long dildo": + if (slave.breedingMark == 1) { + r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length dildo for her pussy.`; + slave.vaginalAccessory = "dildo"; + } + break; + + case "long, large dildo": + if (slave.breedingMark == 1) { + r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length large dildo for her pussy.`; + slave.vaginalAccessory = "large dildo"; + } + break; + + case "long, huge dildo": + if (slave.breedingMark == 1) { + r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length huge dildo for her pussy.`; + slave.vaginalAccessory = "huge dildo"; + } else { + r += `<br>slave.slaveName is a virgin and has been given a`; + if (slave.vagina >= 2) + r += `massive and oversized dildo to permanently gape her cunt.`; + else { + r += `long, large dildo for her pussy, since it must be stretched before it can accommodate a huge one.`; + slave.vaginalAccessory = "long, large dildo"; + } + } + break; + + case "none": + r += `<br>${slave.slaveName} is a virgin and has been instructed not to use a vaginal accessory.`; + break; + + default: + r += `<br>${slave.slaveName} is a virgin and has been given a ${slave.vaginalAccessory} for her pussy.`; + break; + } + } } - r += " "; } - - function short_drugs(slave) { - r += `<span class="tan">`; - switch (slave.drugs) { - case "breast injections": - r += `<strong>Dr:Boobs+</strong>`; - break; - case "intensive breast injections": - r += `<strong>Dr:Boobs++</strong>`; - break; - case "hyper breast injections": - r += `<strong>Dr:Boobs+++</strong>`; - break; - case "butt injections": - r += `<strong>Dr:Butt+</strong>`; - break; - case "intensive butt injections": - r += `<strong>Dr:Butt++</strong>`; - break; - case "hyper butt injections": - r += `<strong>Dr:Butt+++</strong>`; - break; - case "lip injections": - r += `<strong>Dr:Lip+</strong>`; - break; - case "fertility drugs": - r += `<strong>Dr:Fert+</strong>`; - break; - case "super fertility drugs": - r += `<strong>Dr:Fert++</strong>`; - break; - case "penis enhancement": - r += `<strong>Dr:Dick+</strong>`; - break; - case "intensive penis enhancement": - r += `<strong>Dr:Dick++</strong>`; - break; - case "hyper penis enhancement": - r += `<strong>Dr:Dick+++</strong>`; - break; - case "testicle enhancement": - r += `<strong>Dr:Balls+</strong>`; - break; - case "intensive testicle enhancement": - r += `<strong>Dr:Balls++</strong>`; - break; - case "hyper testicle enhancement": - r += `<strong>Dr:Balls+++</strong>`; - break; - case "psychosuppressants": - r += `<strong>Dr:Psych</strong>`; - break; - case "steroids": - r += `<strong>Dr:Ster</strong>`; - break; - case "female hormone injections": - r += `<strong>Dr:HormXX++</strong>`; - break; - case "male hormone injections": - r += `<strong>Dr:HormXY++</strong>`; - break; - case "hormone enhancers": - r += `<strong>Dr:Horm+</strong>`; - break; - case "hormone blockers": - r += `<strong>Dr:Horm-</strong>`; - break; - case "anti-aging cream": - r += `<strong>Dr:Age-</strong>`; - break; - case "appetite suppressors": - r += `<strong>Dr:ApSup</strong>`; - break; - case "penis atrophiers": - r += `<strong>Dr:Dick-</strong>`; - break; - case "testicle atrophiers": - r += `<strong>Dr:Balls-</strong>`; - break; - case "clitoris atrophiers": - r += `<strong>Dr:Clit-</strong>`; - break; - case "labia atrophiers": - r += `<strong>Dr:Labia-</strong>`; - break; - case "nipple atrophiers": - r += `<strong>Dr:Nipple-</strong>`; - break; - case "lip atrophiers": - r += `<strong>Dr:Lip-</strong>`; - break; - case "breast redistributors": - r += `<strong>Dr:Breast-</strong>`; - break; - case "butt redistributors": - r += `<strong>Dr:Butt-</strong>`; - break; - case "sag-B-gone": - r += `<strong>Dr:AntiSag</strong>`; - break; - case "growth stimulants": - r += `<strong>Dr:groStim</strong>`; - break; + + function ProcessAVirginDildos(slave, rule) { + // apply vaginal dildos to anal virgins + if ((rule.aVirginAccessory !== undefined) && (rule.aVirginAccessory !== "no default setting")) { + if (slave.vaginalAccessory !== rule.aVirginAccessory) { + slave.vaginalAccessory = rule.aVirginAccessory; + switch (slave.vaginalAccessory) { + case "huge dildo": + r += `<br>${slave.slaveName} is a virgin and has been given a`; + if (slave.vagina >= 2) + r += `massive dildo to permanently gape her cunt.`; + else { + r += `large dildo for her pussy, since it must be stretched before it can accommodate a huge one.`; + slave.vaginalAccessory = "large dildo"; + } + break; + + case "long dildo": + if (slave.breedingMark == 1) { + r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length dildo for her pussy.`; + slave.vaginalAccessory = "dildo"; + } + break; + + case "long, large dildo": + if (slave.breedingMark == 1) { + r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length large dildo for her pussy.`; + slave.vaginalAccessory = "large dildo"; + } + break; + + case "long, huge dildo": + if (slave.breedingMark == 1) { + r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length huge dildo for her pussy.`; + slave.vaginalAccessory = "huge dildo"; + } else { + r += `<br>${slave.slaveName} is a virgin and has been given a`; + if (slave.vagina >= 2) + r += `massive and oversized dildo to permanently gape her cunt.`; + else { + r += `long, large dildo for her pussy, since it must be stretched before it can accommodate a huge one.`; + slave.vaginalAccessory = "long, large dildo"; + } + } + break; + + case "none": + r += `<br>slave.slaveName is a virgin and has been instructed not to use a vaginal accessory.`; + break; + + default: + r += `<br>slave.slaveName is a virgin and has been given a slave.vaginalAccessory for her pussy.`; + break; + } + } } - r += `</span> `; - r += `<span class="lightgreen">`; - if (slave.curatives === 2) { - r += `<strong>Cura</strong>`; - } else if (slave.curatives === 1) { - r += `<strong>Prev</strong>`; + } + + function ProcessNonVirginDildos(slave, rule) { + // apply vaginal dildos to non-virgins + if ((rule.vaginalAccessory !== undefined) && (rule.vaginalAccessory !== "no default setting")) { + if (slave.vaginalAccessory !== rule.vaginalAccessory) { + slave.vaginalAccessory = rule.vaginalAccessory; + switch (slave.vaginalAccessory) { + case "huge dildo": + r += `<br>${slave.slaveName} has been given a`; + if (slave.vagina >= 2) + r += `massive dildo to permanently gape her cunt.`; + else { + r += `large dildo for her pussy, since it must be stretched before it can accommodate a huge one.`; + slave.vaginalAccessory = "large dildo"; + } + break; + + case "long dildo": + if (slave.breedingMark == 1) { + r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so ${slave.slaveName} has been given a standard length dildo for her pussy.`; + slave.vaginalAccessory = "dildo"; + } + break; + + case "long, large dildo": + if (slave.breedingMark == 1) { + r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so ${slave.slaveName} has been given a standard length large dildo for her pussy.`; + slave.vaginalAccessory = "large dildo"; + } + break; + + case "long, huge dildo": + if (slave.breedingMark == 1) { + r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so ${slave.slaveName} has been given a standard length huge dildo for her pussy.`; + slave.vaginalAccessory = "huge dildo"; + } else { + r += `<br>${slave.slaveName} has been given a`; + if (slave.vagina >= 2) + r += `massive and oversized dildo to permanently gape her cunt.`; + else { + r += `long, large dildo for her pussy, since it must be stretched before it can accommodate a huge one.`; + slave.vaginalAccessory = "long, large dildo"; + } + } + break; + case "none": + r += `<br>${slave.slaveName} has been instructed not to use a vaginal accessory.`; + break; + + default: + r += `<br>${slave.slaveName} has been given a slave.vaginalAccessory for her pussy.`; + break; + } + } } - r += `</span> `; - if (slave.aphrodisiacs !== 0) { - r += `<span class="lightblue">`; - if (slave.aphrodisiacs === 1) { - r += `<strong>Aph</strong>`; - } else if (slave.aphrodisiacs === 2) { - r += `<strong>Aph++</strong>`; + } + + function ProcessDickAccessories(slave, rule) { + // apply dick accessories to slave + if ((slave.dick > 0)) { + if (slave.anus === 0) { + if ((rule.aVirginDickAccessory !== undefined) && (rule.aVirginDickAccessory !== "no default setting")) { + if ((slave.dickAccessory !== rule.aVirginDickAccessory)) { + slave.dickAccessory = rule.aVirginDickAccessory; + if (slave.dickAccessory == "none") + r += `<br>${slave.slaveName} is a virgin and has been instructed not to wear a dick accessory.`; + else + r += `<br>${slave.slaveName} is a virgin and has been given a ${slave.dickAccessory} accessory for her cock.`; + } + } } else { - r += `<strong>Anaph</strong>`; + if ((rule.dickAccessory !== undefined) && (rule.dickAccessory !== "no default setting")) { + if ((slave.dickAccessory !== rule.dickAccessory)) { + slave.dickAccessory = rule.dickAccessory; + if (slave.dickAccessory == "none") + r += `<br>${slave.slaveName} has been instructed not to wear a dick accessory.`; + else + r += `<br>${slave.slaveName} has been given a ${slave.dickAccessory} accessory for her cock.`; + } + } } - r += `</span> `; } - if (slave.addict !== 0) { - r += `<span class="cyan">Add</span>`; + } + + function ProcessShoes(slave, rule) { + // apply shoes to slave + if ((rule.shoes !== undefined) && (rule.shoes !== "no default setting")) { + if ((slave.shoes !== rule.shoes)) { + if ((slave.amp != 1)) { + slave.shoes = rule.shoes; + r += `<br>${slave.slaveName}'s shoes have been set to ${slave.shoes}.`; + } + } } - r += `<span class="lightsalmon">`; - if (slave.hormones > 1) { - r += `<strong>Ho:F+</strong>`; - } else if (slave.hormones > 0) { - r += `<strong>Ho:F</strong>`; - } else if (slave.hormones < -1) { - r += `<strong>Ho:M+</strong>`; - } else if (slave.hormones < 0) { - r += `<strong>Ho:M</strong>`; + } + + function ProcessBellyAccessories(slave, rule) { + // apply belly accessories to slave + if ((rule.bellyAccessory !== undefined) && (rule.bellyAccessory !== "no default setting")) { + 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.`; + slave.bellyAccessory = "none"; + } else { + slave.bellyAccessory = rule.bellyAccessory; + if (slave.bellyAccessory == "none") + r += `<br>${slave.slaveName} has been instructed not to wear a torso accessory.`; + else + r += `<br>${slave.slaveName} has been given ${slave.bellyAccessory} to wear.`; + } + } } - r += `</span> `; - r += `<span class="mediumseagreen">`; - if ((slave.bellyImplant > -1)) { - r += `<strong>Belly Imp</strong>`; - } else if (((slave.preg <= -2) || (slave.ovaries === 0)) && (slave.vagina !== -1)) { - r += `<strong>Barr</strong>`; - } else if (slave.pubertyXX === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) { - r += `<strong>Prepub</strong>`; - } else if (slave.ovaryAge >= 47 && (slave.ovaries === 1 || slave.mpreg === 1)) { - r += `<strong>Meno</strong>`; - } else if (slave.pregWeek < 0) { - r += `<strong>Postpartum</strong>`; - } else if (slave.preg === -1) { - r += `<strong>CC</strong>`; - } else if (slave.preg === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) { - r += `<strong>Fert+</strong>`; - } else if (((slave.preg < 4) && (slave.preg > 0) && slave.pregKnown === 0) || slave.pregWeek === 1) { - r += `<strong>Preg?</strong>`; - } else if ((slave.preg >= 36) && (slave.broodmother > 0)) { - r += `<strong>Perm preg</strong>`; - } else if (slave.pregKnown === 1) { - r += `<strong>${slave.pregWeek} wks preg</strong>`; + } + + function ProcessLegAccessory(slave, rule) { + if (rule.legAccessory !== undefined && rule.legAccessory !== "no default setting" && slave.amp !== 1 && slave.legAccessory !== rule.legAccessory) { + slave.legAccessory = rule.legAccessory; + r += `<br>${slave.slaveName}'s leg accessory was set to ${rule.legAccessory}.`; } - r += `</span> `; - if (slave.induce === 1) { - r += `<span class="orange"><strong>Early Labor</strong></span>`; + } + + function ProcessAnalAccessories(slave, rule) { + // apply buttplugs to slave + if ((slave.vaginalAccessory !== "anal chastity") && (slave.vaginalAccessory !== "combined chastity") && (slave.dickAccessory !== "anal chastity") && (slave.dickAccessory !== "combined chastity")) { + if (slave.anus === 0) + ProcessAnalVirginButtplugs(slave, rule); + else + ProcessNonVirginButtplugs(slave, rule); } - if (slave.pubertyXY === 0 && slave.balls > 0) { - r += `<strong>Prepub balls</strong>`; + } + + function ProcessAnalVirginButtplugs(slave, rule) { + // apply buttplugs to virgins + if ((rule.aVirginButtplug !== undefined) && (rule.aVirginButtplug !== "no default setting")) { + if ((slave.buttplug !== rule.aVirginButtplug)) { + slave.buttplug = rule.aVirginButtplug; + switch (slave.buttplug) { + case "huge plug": + r += `<br>${slave.slaveName} is an anal virgin and has been given a`; + if ((slave.anus >= 2)) + r += `massive plug to permanently gape her asshole.`; + else { + slave.buttplug = "large plug"; + r += `large buttplug for her asshole, since it must be stretched before it can accommodate a huge one.`; + } + break; + + case "long plug": + if (slave.breedingMark == 1) { + r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so the anal virgin ${slave.slaveName} has been given a standard length plug for her anus.`; + slave.buttplug = "plug"; + } + break; + + case "long, large plug": + if (slave.breedingMark == 1) { + r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so the anal virgin ${slave.slaveName} has been given a standard length large plug for her anus.`; + slave.buttplug = "large plug"; + } + break; + + case "long, huge plug": + if (slave.breedingMark == 1) { + r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so the anal virgin ${slave.slaveName} has been given a standard length huge plug for her anus.`; + slave.buttplug = "huge plug"; + } else { + r += `<br>slave.slaveName is an anal virgin and has been given a`; + if (slave.anus >= 2) + r += `massive and oversized plug to permanently gape her asshole.`; + else { + r += `long, large buttplug for her asshole, since it must be stretched before it can accommodate a huge one.`; + slave.buttplug = "long, large plug"; + } + } + break; + + case "none": + r += `<br>${slave.slaveName} is an anal virgin and has been instructed not to use an anal accessory.`; + break; + + default: + r += `<br>${slave.slaveName} is an anal virgin and has been given a slave.buttplug for her asshole.`; + break; + } + } } - if (slave.balls > 0 && slave.vasectomy === 1) { - r += `<strong>Vasect</strong>`; + } + + function ProcessNonVirginButtplugs(slave, rule) { + // apply buttplugs to non-virgins + if ((rule.buttplug !== undefined) && (rule.buttplug !== "no default setting")) { + if ((slave.buttplug !== rule.buttplug)) { + slave.buttplug = rule.buttplug; + switch (slave.buttplug) { + case "huge plug": + r += `<br>${slave.slaveName} has been given a`; + if ((slave.anus >= 2)) + r += `massive plug to permanently gape her asshole.`; + else { + slave.buttplug = "large plug"; + r += `large buttplug for her asshole, since it must be stretched before it can accommodate a huge one.`; + } + break; + + case "long plug": + if (slave.breedingMark == 1) { + r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so ${slave.slaveName} has been given a standard length plug for her anus.`; + slave.buttplug = "plug"; + } + break; + + case "long, large plug": + if (slave.breedingMark == 1) { + r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so ${slave.slaveName} has been given a standard length large plug for her anus.`; + slave.buttplug = "large plug"; + } + break; + + case "long, huge plug": + if (slave.breedingMark == 1) { + r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so ${slave.slaveName} has been given a standard length huge plug for her anus.`; + slave.buttplug = "huge plug"; + } else { + r += `<br>${slave.slaveName} has been given a`; + if (slave.anus >= 2) + r += `massive and oversized plug to permanently gape her asshole.`; + else { + r += `long, large buttplug for her asshole, since it must be stretched before it can accommodate a huge one.`; + slave.buttplug = "long, large plug"; + } + } + break; + + case "none": + r += `<br>${slave.slaveName} has been instructed not to use an anal accessory.`; + break; + + default: + r += `<br>${slave.slaveName} has been given a slave.buttplug for her asshole.`; + break; + } + } } - r += `<span class="springgreen">`; - if (slave.inflation === 3) { - r += `<strong>8 ltr ${slave.inflationType}</strong>`; - } else if (slave.inflation === 2) { - r += `<strong>4 ltr ${slave.inflationType}</strong>`; - } else if (slave.inflation === 1) { - r += `<strong>2 ltr ${slave.inflationType}</strong>`; - } else if (slave.bellyFluid > 0) { - r += `<strong>${slave.bellyFluid}ccs ${slave.inflationType}</strong>`; + } + + function ProcessBellyImplant(slave, rule) { + // Here is belly implant size control, it's used in Surgery Degradation passage to setup devotion and trust changes. + // silent calls to surgery degradation have been replaced with a js function, which is less hacky + if ((rule.bellyImplantVol !== undefined) && slave.bellyImplant >= 0 && rule.bellyImplantVol >= 0) { + r += "<br>"; + if (slave.health > -10 ) { + let diff = rule.bellyImplantVol - slave.bellyImplant; + if (diff >= 5000 && slave.bellyPain === 0 && slave.health > 50) { + r += `${slave.slaveName}'s belly is way too small, so she has been directed to have intensive belly implant filling procedures throughout this week.`; + slave.bellyImplant += 1000; + slave.bellyPain += 2; + BellySurgery(slave, diff); + } else if (diff >= 500 && slave.bellyPain < 2 ) { + r += `${slave.slaveName}'s belly has not reached the desired size, so she has been directed to have belly implant filling procedures throughout this week.`; + slave.bellyImplant += 500; + slave.bellyPain += 1; + BellySurgery(slave, diff); + } else if (diff <= -5000 ) { + r += `${slave.slaveName}'s belly is way too big, so she has been directed to have intensive belly implant draining procedures throughout this week.`; + slave.bellyImplant -= 1000; + BellySurgery(slave, diff); + } else if (diff <= -500 ) { + r += `${slave.slaveName}'s belly is too big, so she has been directed to have belly implant draining procedures throughout this week.`; + slave.bellyImplant -= 500; + BellySurgery(slave, diff); + } + } else { + r += `${slave.slaveName} is not healthy enough to safely adjust her belly implant.`; + } } - r += `</span> `; } - - function long_drugs(slave) { - if ((slave.drugs !== "no drugs") && (slave.drugs !== "none")) { - r += `<span class="tan">On ${slave.drugs}.</span> `; + + function BellySurgery(slave, volume) { + // this is a port of the belly implant portion of surgeryDegradation.tw + // that way, we don't have to use ugly hacks + // the original still exists, and may be worth replacing + if (volume > 0) { // bellyUp + SetBellySize(slave); + if (slave.bellyPain === 1) { + if (slave.devotion > 50) { + slave.devotion += 4; + } else if (slave.devotion >= -20) { + slave.trust -= 5; + } else { + slave.trust -= 10; + slave.devotion -= 5; + } + } else if (slave.bellyPain === 2) { + if (slave.devotion > 50) { + slave.devotion += 2; + } else if (slave.devotion >= -20) { + slave.trust -= 7; + } else { + slave.trust -= 12; + slave.devotion -= 7; + } + } + } else { // bellyDown + if (slave.bellyImplant < 0) + slave.bellyImplant = 0; + SetBellySize(slave); + if (slave.devotion > 50) { + slave.devotion += 3; + slave.trust += 3; + } else if (slave.devotion >= -20) { + slave.trust += 2; + } else { + slave.devotion += 1; + slave.trust -= 10; + } } - r += `<span class="lightgreen">`; - if (slave.curatives === 2) { - r += `On curatives.`; - } else if (slave.curatives === 1) { - r += `On preventatives.`; + } + + function ProcessContraceptives(slave, rule) { + if ((rule.preg !== undefined) && (rule.preg !== "no default setting")) { + if (rule.preg === true && slave.preg === 0) { + r += `<br>${slave.slaveName} is being given contraceptives.`; + slave.preg = -1; + } else if (slave.preg === -1 && rule.preg === false) { + r += `<br>${slave.slaveName} is no longer being put on contraceptives.`; + slave.preg = 0; + } } - r += `</span> `; - r += `<span class="lightblue">`; - if (slave.aphrodisiacs > 0) { - r += `On ${slave.aphrodisiacs > 1 ? 'extreme': ''} aphrodisiacs.`; - } else if (slave.aphrodisiacs === -1) { - r += `On anaphrodisiacs.`; + } + + function ProcessAssetGrowthDrugs(slave, rule) { + // Asset Growth + const growth_drugs = new Set(["breast injections", "intensive breast injections", "breast redistributors", "butt injections", "intensive butt injections", "butt redistributors", "lip injections", "lip atrophiers", "penis enhancement", "intensive penis enhancement", "penis atrophiers", "testicle enhancement", "intensive testicle enhancement", "testicle atrophiers", "hyper breast injections", "hyper butt injections", "hyper penis enhancement", "hyper 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")) { + return; } - r += `</span> `; - if (slave.addict !== 0) { - r += `<span class="cyan">Addict.</span>`; - } - r += `<span class="lightsalmon">`; - if (slave.hormones > 1) { - r += `Heavy female hormones.`; - } else if (slave.hormones > 0) { - r += `Female hormones.`; - } else if (slave.hormones < -1) { - r += `Heavy male hormones.`; - } else if (slave.hormones < 0) { - r += `Male hormones.`; - } - r += `</span> `; - r += `<span class="mediumseagreen">`; - if ((slave.bellyImplant > -1)) { - r += `Belly Implant.`; - } else if (((slave.preg <= -2) || (slave.ovaries === 0)) && (slave.vagina !== -1)) { - r += `Barren.`; - } else if (slave.pubertyXX === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) { - r += `Not ovulating yet.`; - } else if (slave.ovaryAge >= 47 && (slave.ovaries === 1 || slave.mpreg === 1)) { - r += `Menopausal.`; - } else if (slave.pregWeek < 0) { - r += `Postpartum.`; - } else if (slave.preg === -1) { - r += `On contraceptives.`; - } else if (slave.preg === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) { - r += `Fertile.`; - } else if (((slave.preg < 4) && (slave.preg > 0) && slave.pregKnown === 0) || slave.pregWeek === 1) { - r += `May be pregnant.`; - } else if ((slave.preg >= 36) && (slave.broodmother > 0)) { - r += `Permanently pregnant.`; - } else if (slave.pregKnown === 1) { - if (slave.pregType < 2 || slave.broodmother > 0) { - r += `${slave.pregWeek} weeks pregnant.`; - } else { - r += `${slave.pregWeek} weeks pregnant with `; - if (slave.pregType >= 40) { - r += `a tremendous brood of offspring.`; - } else if (slave.pregType >= 20) { - r += `a brood of offspring.`; - } else if (slave.pregType >= 10) { - r += `${slave.pregType} babies.`; - } else if (slave.pregType === 9) { - r += `nonuplets.`; - } else if (slave.pregType === 8) { - r += `octuplets.`; - } else if (slave.pregType === 7) { - r += `septuplets.`; - } else if (slave.pregType === 6) { - r += `sextuplets.`; - } else if (slave.pregType === 5) { - r += `quintuplets.`; - } else if (slave.pregType === 4) { - r += `quadruplets.`; - } else if (slave.pregType === 3) { - r += `triplets.`; - } else { - r += `twins.`; + if (slave.assignmentVisible) { // More resource intensive version with prioritizing. Possible to give this a toggle rather than basing it on visibility. + 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 > rule.growth_boobs+200) && slave.weight < 100 && (V.arcologies[0].FSSlimnessEnthusiastResearch == 1)) { + _priority = { + drug: "breast redistributors", + weight: (1+((slave.boobs-slave.boobsImplant-rule.growth_boobs)/rule.growth_boobs)) }; + _priorities.push(_priority); } } - } - r += `</span> `; - if (slave.induce === 1) { - r += `<span class="orange">Showing signs of early labor.</span>`; - } - if (slave.pubertyXY === 0 && slave.balls > 0) { - r += `Has not had first ejaculation.`; - } - if (slave.balls > 0 && slave.vasectomy === 1) { - r += `Vasectomy.`; - } - r += `<span class="springgreen">`; - if (slave.inflation === 3) { - r += `Filled with 8 liters of ${slave.inflationType}.`; - } else if (slave.inflation === 2) { - r += `Filled with 4 liters of ${slave.inflationType}.`; - } else if (slave.inflation === 1) { - r += `Filled with 2 liters of ${slave.inflationType}.`; - } else if (slave.bellyFluid > 0) { - r += `Stuffed with ${slave.bellyFluid}ccs of ${slave.inflationType}.`; - } - r += `</span> `; - } - - function long_race(slave) { - switch (slave.race) { - case "white": - r += `Caucasian.`; - break; - case "asian": - r += `Asian.`; - break; - case "indo-aryan": - r += `Indo-aryan.`; - break; - case "latina": - r += `Latina.`; - break; - case "middle eastern": - r += `Middle Eastern.`; - break; - case "black": - r += `Black.`; - break; - case "pacific islander": - r += `Pacific Islander.`; - break; - case "malay": - r += `Malay.`; - break; - case "amerindian": - r += `Amerindian.`; - break; - case "semitic": - r += `Semitic.`; - break; - case "southern european": - r += `Southern European.`; - break; - case "mixed race": - r += `Mixed race.`; - break; - default: - r += `${slave.race.charAt(0).toUpperCase() + slave.race.slice(1)}.`; - break; - } - r += " "; - } - - function short_race(slave) { - switch (slave.race) { - case "white": - r += `C`; - break; - case "asian": - r += `A`; - break; - case "indo-aryan": - r += `I`; - break; - case "latina": - r += `L`; - break; - case "middle eastern": - r += `ME`; - break; - case "black": - r += `B`; - break; - case "pacific islander": - r += `PI`; - break; - case "malay": - r += `M`; - break; - case "amerindian": - r += `AI`; - break; - case "semitic": - r += `S`; - break; - case "southern european": - r += `SE`; - break; - case "mixed race": - r += `MR`; - break; - default: - r += `${slave.race.charAt(0).toUpperCase() + slave.race.charAt(1) + slave.race.charAt(2)}`; - break; - } - r += " "; - } - - function short_nationality(slave) { - r += `<span class="tan">`; - switch (slave.nationality) { - case "Afghan": - r += `Afg`; - break; - case "Albanian": - r += `Alb`; - break; - case "Algerian": - r += `Alg`; - break; - case "American": - r += `USA`; - break; - case "Andorran": - r += `And`; - break; - case "Angolan": - r += `Ang`; - break; - case "Antiguan": - r += `AB`; - break; - case "Argentinian": - r += `Arg`; - break; - case "Armenian": - r += `Arm`; - break; - case "Aruban": - r += `Aru`; - break; - case "Australian": - r += `Aus`; - break; - case "Austrian": - r += `Aut`; - break; - case "Azerbaijani": - r += `Aze`; - break; - case "Bahamian": - r += `Bah`; - break; - case "Bahraini": - r += `Bah`; - break; - case "Bangladeshi": - r += `Bgd`; - break; - case "Barbadian": - r += `Bar`; - break; - case "Belarusian": - r += `Ber`; - break; - case "Belgian": - r += `Bel`; - break; - case "Belizean": - r += `Blz`; - break; - case "Beninese": - r += `Ben`; - break; - case "Bermudian": - r += `Bmd`; - break; - case "Bhutanese": - r += `Bhu`; - break; - case "Bissau-Guinean": - r += `GB`; + 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 she's healthy enough to take them, and `; + } else { + r += `${slave.drugs}, since `; + } + r += `that part of her body is ${Math.trunc(_priorities[0].weight*100)}% `; + if (_priorities[0].weight < 1) r+= "below "; + else r+= "above "; + r += "the targeted size."; + } + return; + } 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 she's healthy enough to take them, and `; + } else + r += `${slave.drugs}, since `; + r += `that is the only part of her body that does not meet the targeted size.`; + } + return; + } else if (growth_drugs.has(slave.drugs)) { + slave.drugs = "no drugs"; + r += `<br>${slave.slaveName}'s body has met all relevant growth targets, so her pharmaceutical regime has been ended.`; + return; + } + } else { + let _hyper; + if (V.arcologies[0].FSAssetExpansionistResearch == 1) + _hyper = "hyper "; + else + _hyper = ""; + 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 (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; + } + } + 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 (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; + } + } + 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 (V.arcologies[0].FSSlimnessEnthusiastResearch == 1) { + if (rule.growth_boobs != "no default setting") { + if (slave.boobs-slave.boobsImplant > 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 (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 (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 (growth_drugs.has(slave.drugs)) { + slave.drugs = "no drugs"; + r += `<br>${slave.slaveName} has met all relevant growth targets, so her pharmaceutical regime has been ended.`; + return; + } + } + } + + function ProcessOtherDrugs(slave, rule) { + // Other Drugs + if (slave.indentureRestrictions < 2 && rule.drug !== "no default setting" && slave.drugs !== rule.drug) { + let flag = true; + switch (rule.drug) { + case "anti-aging cream": + if (slave.visualAge < 18) + flag = false; break; - case "Bolivian": - r += `Bol`; + + case "growth stimulants": + if (!(slave.height < 274 && slave.height < Math.clamp((Height.mean(slave) * 1.25),0,274))) + flag = false; break; - case "Bosnian": - r += `Bos`; + + case "sag-B-gone": + if (!(slave.boobs > 250 && slave.boobShape != "saggy")) + flag = false; break; - case "Brazilian": - r += `Bra`; + + case "female hormone injections": + if (!(slave.breedingMark != 1 && (slave.ovaries == 1 || slave.mpreg == 1) && slave.pubertyXX === 0)) + flag = false; break; - case "British": - r += `UK`; + + case "male hormone injections": + if (!(slave.breedingMark != 1 && slave.balls > 0 && slave.pubertyXY === 0)) + flag = false; break; - case "Bruneian": - r += `Bru`; + + case "psychosuppressants": + if (!(slave.intelligence > -2 && slave.indentureRestrictions < 1)) + flag = false; break; - case "Bulgarian": - r += `Bul`; + + case "breast injections": + if (!(slave.boobs < 48000)) + flag = false; break; - case "Burkinabé": - r += `BF`; + + case "hyper breast injections": + if (!(slave.boobs < 25000)) + flag = false; break; - case "Burmese": - r += `Bur`; + + case "breast redistributors": + if (!(slave.boobs - slave.boobsImplant > 100)) + flag = false; break; - case "Burundian": - r += `Bnd`; + + case "butt injections": + if (!(slave.butt < 9)) + flag = false; break; - case "Cambodian": - r += `Kam`; - break; - case "Cameroonian": - r += `Cam`; - break; - case "Canadian": - r += `Can`; - break; - case "Cape Verdean": - r += `CV`; - break; - case "Catalan": - r += `Cat`; - break; - case "Central African": - r += `CAR`; - break; - case "Chadian": - r += `Cha`; - break; - case "Chilean": - r += `Chl`; - break; - case "Chinese": - r += `Chi`; - break; - case "Colombian": - r += `Col`; - break; - case "Comorian": - r += `Com`; - break; - case "Congolese": - r += `RC`; - break; - case "a Cook Islander": - r += `CI`; - break; - case "Costa Rican": - r += `CR`; - break; - case "Croatian": - r += `Cro`; - break; - case "Cuban": - r += `Cub`; - break; - case "Cypriot": - r += `Cyp`; - break; - case "Czech": - r += `Cze`; - break; - case "Danish": - r += `Den`; - break; - case "Djiboutian": - r += `Dji`; - break; - case "Dominican": - r += `DR`; - break; - case "Dominiquais": - r += `Dom`; - break; - case "Dutch": - r += `Nld`; - break; - case "East Timorese": - r += `ET`; - break; - case "Ecuadorian": - r += `Ecu`; - break; - case "Egyptian": - r += `Egy`; - break; - case "Emirati": - r += `UAE`; - break; - case "Equatoguinean": - r += `EG`; - break; - case "Eritrean": - r += `Eri`; - break; - case "Estonian": - r += `Est`; - break; - case "Ethiopian": - r += `Eth`; - break; - case "Fijian": - r += `Fij`; - break; - case "Filipina": - r += `Phl`; - break; - case "Finnish": - r += `Fin`; - break; - case "French": - r += `Fra`; - break; - case "French Guianan": - r += `FG`; - break; - case "French Polynesian": - r += `FP`; - break; - case "Gabonese": - r += `Gab`; - break; - case "Gambian": - r += `Gam`; - break; - case "Georgian": - r += `Geo`; - break; - case "German": - r += `Ger`; - break; - case "Ghanan": - r += `Gha`; - break; - case "Greek": - r += `Gre`; - break; - case "Greenlandic": - r += `Grn`; - break; - case "Grenadian": - r += `Gda`; - break; - case "Guamanian": - r += `Gua`; - break; - case "Guatemalan": - r += `Gtm`; - break; - case "Guinean": - r += `Gui`; - break; - case "Guyanese": - r += `Guy`; + + case "hyper butt injections": + if (!(slave.butt < 20)) + flag = false; break; - case "Haitian": - r += `Hai`; + + case "hyper butt injections": + if (!(slave.butt < 20)) + flag = false; break; - case "Honduran": - r += `Hon`; + + case "nipple atrophiers": + if (!(["huge", "puffy", "cute"].includes(slave.nipples))) + flag = false; break; - case "Hungarian": - r += `Hun`; + + case "butt redistributors": + if (!(slave.buttImplant > 0)) + flag = false; break; - case "I-Kiribati": - r += `Kir`; + + case "lip injections": + if (!(slave.lips <= 95 || (slave.lips <= 85 && V.seeExtreme !== 1))) + flag = false; break; - case "Icelandic": - r += `Ice`; + + case "lip atrophiers": + if (!(slave.lips - slave.lipsImplant > 0)) + flag = false; break; - case "Indian": - r += `Ind`; + + case "super fertility drugs": + if (!(slave.indentureRestrictions < 1 && slave.breedingMark !== 1)) + flag = false; break; - case "Indonesian": - r += `Idn`; + + case "penis enhancement": + if (!((slave.dick > 0 && slave.dick < 10) || slave.clit < 5)) + flag = false; break; - case "Iranian": - r += `Irn`; + + case "hyper penis enhancement": + if (!((slave.dick > 0 && slave.dick < 31) || slave.clit < 5)) + flag = false; break; - case "Iraqi": - r += `Irq`; + + case "penis atrophiers": + if (!(slave.dick > 1)) + flag = false; break; - case "Irish": - r += `Irl`; + + case "testicle enhancement": + if (!(slave.balls > 0)) + flag = false; break; - case "Israeli": - r += `Isr`; + + case "hyper testicle enhancement": + if (!(slave.balls > 0)) + flag = false; break; - case "Italian": - r += `Ita`; + + case "testicle atrophiers": + if (!(slave.balls > 1)) + flag = false; break; - case "Ivorian": - r += `IC`; + + case "clitoris atrophiers": + if (!(slave.clit > 0)) + flag = false; break; - case "Jamaican": - r += `Jam`; + + case "labia atrophiers": + if (!(slave.labia > 0)) + flag = false; break; - case "Japanese": - r += `Jpn`; + + case "appetite suppressors": + if (!(slave.weight > -95)) + flag = false; break; - case "Jordanian": - r += `Jor`; + + case "female hormone injections": + if (!(slave.breedingMark !== 1 && (slave.ovaries === 1 || slave.mpreg === 1) && slave.pubertyXX === 0)) + flag = false; break; - case "Kazakh": - r += `Kaz`; + + case "male hormone injections": + if (!(slave.balls > 0 && slave.pubertyXY === 0)) + flag = false; break; - case "Kenyan": - r += `Ken`; - break; - case "Kittitian": - r += `SKN`; - break; - case "Korean": - r += `Kor`; - break; - case "Kosovan": - r += `Kos`; - break; - case "Kurdish": - r += `Kur`; - break; - case "Kuwaiti": - r += `Kuw`; - break; - case "Kyrgyz": - r += `Kyr`; - break; - case "Laotian": - r += `Lao`; - break; - case "Latvian": - r += `Lat`; - break; - case "Lebanese": - r += `Lbn`; - break; - case "Liberian": - r += `Lib`; - break; - case "Libyan": - r += `Lby`; - break; - case "a Liechtensteiner": - r += `Lie`; - break; - case "Lithuanian": - r += `Lit`; - break; - case "Luxembourgian": - r += `Lux`; - break; - case "Macedonian": - r += `Mac`; - break; - case "Malagasy": - r += `Mad`; - break; - case "Malawian": - r += `Mwi`; - break; - case "Malaysian": - r += `Mys`; - break; - case "Maldivian": - r += `Mdv`; - break; - case "Malian": - r += `Mal`; - break; - case "Maltese": - r += `Mlt`; - break; - case "Marshallese": - r += `MI`; - break; - case "Mauritanian": - r += `Mta`; - break; - case "Mauritian": - r += `Mts`; - break; - case "Mexican": - r += `Mex`; - break; - case "Micronesian": - r += `FSM`; - break; - case "Moldovan": - r += `Mol`; - break; - case "Monégasque": - r += `Mnc`; - break; - case "Mongolian": - r += `Mon`; - break; - case "Montenegrin": - r += `Mng`; - break; - case "Moroccan": - r += `Mor`; - break; - case "Mosotho": - r += `Les`; - break; - case "Motswana": - r += `Bot`; - break; - case "Mozambican": - r += `Moz`; - break; - case "Namibian": - r += `Nam`; - break; - case "Nauruan": - r += `Nau`; - break; - case "Nepalese": - r += `Npl`; - break; - case "New Caledonian": - r += `NC`; - break; - case "a New Zealander": - r += `NZ`; - break; - case "Ni-Vanuatu": - r += `Van`; - break; - case "Nicaraguan": - r += `Nic`; - break; - case "Nigerian": - r += `Nga`; - break; - case "Nigerien": - r += `Ngr`; - break; - case "Niuean": - r += `Niu`; - break; - case "Norwegian": - r += `Nor`; - break; - case "Omani": - r += `Omn`; - break; - case "Pakistani": - r += `Pak`; - break; - case "Palauan": - r += `Plu`; - break; - case "Palestinian": - r += `Pal`; - break; - case "Panamanian": - r += `Pan`; - break; - case "Papua New Guinean": - r += `PNG`; - break; - case "Paraguayan": - r += `Par`; - break; - case "Peruvian": - r += `Per`; - break; - case "Polish": - r += `Pol`; - break; - case "Portuguese": - r += `Por`; - break; - case "Puerto Rican": - r += `PR`; - break; - case "Qatari": - r += `Qat`; - break; - case "Romanian": - r += `Rom`; - break; - case "Russian": - r += `Rus`; - break; - case "Rwandan": - r += `Rwa`; - break; - case "Sahrawi": - r += `Sah`; - break; - case "Saint Lucian": - r += `SL`; - break; - case "Salvadoran": - r += `ES`; - break; - case "Sammarinese": - r += `SM`; - break; - case "Samoan": - r += `Sam`; - break; - case "São Toméan": - r += `STP`; - break; - case "Saudi": - r += `Sau`; - break; - case "Scottish": - r += `Sco`; - break; - case "Senegalese": - r += `Sen`; - break; - case "Serbian": - r += `Srb`; - break; - case "Seychellois": - r += `Sey`; - break; - case "Sierra Leonean": - r += `Sie`; - break; - case "Singaporean": - r += `Sng`; - break; - case "Slovak": - r += `Svk`; - break; - case "Slovene": - r += `Svn`; - break; - case "a Solomon Islander": - r += `SI`; - break; - case "Somali": - r += `Som`; - break; - case "South African": - r += `RSA`; - break; - case "South Sudanese": - r += `SS`; - break; - case "Spanish": - r += `Spa`; - break; - case "Sri Lankan": - r += `Sri`; - break; - case "Sudanese": - r += `Sud`; - break; - case "Surinamese": - r += `Sur`; - break; - case "Swazi": - r += `Swa`; - break; - case "Swedish": - r += `Swe`; - break; - case "Swiss": - r += `Swi`; - break; - case "Syrian": - r += `Syr`; - break; - case "Taiwanese": - r += `Tai`; - break; - case "Tajik": - r += `Taj`; - break; - case "Tanzanian": - r += `Tza`; - break; - case "Thai": - r += `Tha`; - break; - case "Tibetan": - r += `Tib`; - break; - case "Togolese": - r += `Tog`; - break; - case "Tongan": - r += `Ton`; - break; - case "Trinidadian": - r += `TT`; - break; - case "Tunisian": - r += `Tun`; - break; - case "Turkish": - r += `Tur`; - break; - case "Turkmen": - r += `Tkm`; - break; - case "Tuvaluan": - r += `Tuv`; - break; - case "Ugandan": - r += `Uga`; - break; - case "Ukrainian": - r += `Ukr`; - break; - case "Uruguayan": - r += `Uru`; - break; - case "Uzbek": - r += `Uzb`; - break; - case "Vatican": - r += `VC`; - break; - case "Venezuelan": - r += `Ven`; - break; - case "Vietnamese": - r += `Vnm`; - break; - case "Vincentian": - r += `SVG`; - break; - case "Yemeni": - r += `Yem`; - break; - case "Zairian": - r += `DRC`; - break; - case "Zambian": - r += `Zam`; - break; - case "Zimbabwean": - if (slave.race === "white") { - r += `Rho`; - } else { - r += `Zwe`; - } - break; - case "Ancient Chinese Revivalist": - r += `Chi Rev`; - break; - case "Ancient Egyptian Revivalist": - r += `Egy Rev`; - break; - case "Arabian Revivalist": - r += `Ara Rev`; - break; - case "Aztec Revivalist": - r += `Azt Rev`; - break; - case "Edo Revivalist": - r += `Edo Rev`; - break; - case "Roman Revivalist": - r += `Rom Rev`; - break; - case "": - case "none": - case "slave": - case "Stateless": - r += `None`; - break; - default: - r += `${slave.nationality.charAt(0) + slave.nationality.charAt(1) + slave.nationality.charAt(2)}`; - break; - } - r += `</span> `; - } - - function long_nationality(slave) { - r += `<span class="tan">`; - switch (slave.nationality) { - case "Zimbabwean": - if (slave.race === "white") { - r += `Rhodesian.`; - } else { - r += `${slave.nationality}.`; - } - break; - case "slave": - case "none": - case "": - case "Stateless": - r += `Stateless.`; - break; - default: - r += `${slave.nationality}.`; - break; - } - r += `</span> `; - } - - function short_skin(slave) { - r += `<span class="pink">`; - switch (slave.skin) { - case "light brown": - r += `L. Br`; - break; - case "dark brown": - r += `D. Br`; - break; - case "light olive": - r += `L. Oli`; - break; - case "dark olive": - r += `D. Oli`; - break; - case "extremely pale": - r += `Ex. Pa`; - break; - case "pure white": - r += `P. Whi`; - break; - case "tanned": - r += `Tan`; - break; - case "dark": - case "fair": - case "pale": - r += `${slave.skin.charAt(0).toUpperCase() + slave.skin.slice(1)}`; - break; - default: - r += `${slave.skin.charAt(0).toUpperCase() + slave.skin.charAt(1) + slave.skin.charAt(2)}`; - break; - } - r += `</span> `; - } - - function short_genitals(slave) { - if (slave.dick > 0) { - r += `<span class="pink">`; - if (slave.balls === 0) { - r += `Geld`; - } - if ((slave.dick > 8) && (slave.balls > 8)) { - r += `Junk+++`; - } else if ((slave.dick > 5) && (slave.balls > 5)) { - r += `Junk++`; - } else if ((slave.dick > 4) && (slave.balls > 4)) { - r += `Junk+`; - } else if ((slave.dick > 3) && (slave.balls > 3)) { - r += `Junk`; - } else if (slave.dick > 8) { - r += `Dick+++`; - } else if (slave.dick > 5) { - r += `Dick++`; - } else if (slave.dick > 4) { - r += `Dick+`; - } else if (slave.dick > 3) { - r += `Dick`; - } else if (slave.balls > 10) { - r += `Balls+++`; - } else if (slave.balls > 5) { - r += `Balls++`; - } else if (slave.balls > 4) { - r += `Balls+`; - } else if (slave.balls > 3) { - r += `Balls`; - } - r += `</span> `; - } - if (slave.vagina === 0) { - r += `<span class="lime">VV</span>`; - } else if ((slave.pregKnown === 1) && canWalk(slave) && (slave.clothes === "no clothing" || slave.clothes === "body oil") && (slave.shoes === "none")) { - r += `<span class="pink">NBP</span>`; - } - if (slave.anus === 0) { - r += ` <span class="lime">AV</span>`; - } - r += `<span class="pink">`; - if ((slave.vagina > 3) && (slave.anus > 3)) { - r += ` V++A++`; - } else if ((slave.vagina > 2) && (slave.anus > 2)) { - r += ` V+A+`; - } else if (slave.vagina > 3) { - r += ` V++`; - } else if (slave.vagina > 2) { - r += ` V+`; - } else if (slave.anus > 3) { - r += ` A++`; - } else if (slave.anus > 2) { - r += ` A+`; - } - r += `</span> `; - } - - function long_genitals(slave) { - if (slave.dick > 0) { - r += `<span class="pink">`; - if (slave.balls === 0) { - r += `Gelded.`; - } - if ((slave.dick > 8) && (slave.balls > 8)) { - r += `Hyper dick & balls.`; - } else if ((slave.dick > 5) && (slave.balls > 5)) { - r += `Monster dick & balls.`; - } else if ((slave.dick > 4) && (slave.balls > 4)) { - r += `Huge dick & balls.`; - } else if ((slave.dick > 3) && (slave.balls > 3)) { - r += `Big dick & balls.`; - } else if (slave.dick > 8) { - r += `Hyper dong.`; - } else if (slave.dick > 5) { - r += `Monster dong.`; - } else if (slave.dick > 4) { - r += `Huge dick.`; - } else if (slave.dick > 3) { - r += `Big dick.`; - } else if (slave.balls > 8) { - r += `Hyper balls.`; - } else if (slave.balls > 5) { - r += `Monstrous balls.`; - } else if (slave.balls > 4) { - r += `Huge balls.`; - } else if (slave.balls > 3) { - r += `Big balls.`; - } - r += `</span> `; - } - if (slave.vagina === 0) { - r += `<span class="lime">Virgin.</span> `; - } else if ((slave.pregKnown === 1) && canWalk(slave) && (slave.clothes === "no clothing" || slave.clothes === "body oil") && (slave.shoes === "none")) { - r += `<span class="pink">Naked, barefoot, and pregnant.</span> `; - } - if (slave.anus === 0) { - r += `<span class="lime">Anal virgin.</span> `; - } - r += `<span class="pink">`; - if ((slave.vagina > 3) && (slave.anus > 3)) { - r += `Blown out holes.`; - } else if ((slave.vagina > 2) && (slave.anus > 2)) { - r += `High mileage.`; - } else if (slave.vagina > 3) { - r += `Cavernous pussy.`; - } else if (slave.vagina > 2) { - r += `Loose pussy.`; - } else if (slave.anus > 3) { - r += `Permagaped anus.`; - } else if (slave.anus > 2) { - r += `Gaping anus.`; - } - r += `</span> `; - } - - function short_age(slave) { - r += `<span class="pink">`; - if (V.showAgeDetail === 1) { - r += slave.actualAge; - } else if (slave.actualAge >= 40) { - r += `40s`; - } else if (slave.actualAge >= 35) { - r += `Lt30s`; - } else if (slave.actualAge >= 30) { - r += `Ea30s`; - } else if (slave.actualAge >= 25) { - r += `Lt20s`; - } else if (slave.actualAge >= 20) { - r += `Ea20s`; - } else if (slave.actualAge >= 18) { - r += slave.actualAge; - } - if (slave.actualAge !== slave.physicalAge) { - r += `${slave.physicalAge}y-bdy`; - } - if (slave.visualAge !== slave.physicalAge) { - r += `Lks${slave.visualAge}`; - } - r += " "; - } - - function short_face(slave) { - if (slave.face < -95) { - r += `<span class="red">Face---${V.summaryStats? `[${slave.face}]` : ''}</span>`; - } else if (slave.face < -40) { - r += `<span class="red">Face--${V.summaryStats? `[${slave.face}]` : ''}</span>`; - } else if (slave.face < -10) { - r += `<span class="red">Face-${V.summaryStats? `[${slave.face}]` : ''}</span>`; - } else if (slave.face <= 10) { - r += `Face${V.summaryStats? `[${slave.face}]` : ''}`; - } else if (slave.face <= 40) { - r += `<span class="pink">Face+${V.summaryStats? `[${slave.face}]` : ''}</span>`; - } else if (slave.face <= 95) { - r += `<span class="pink">Face++${V.summaryStats? `[${slave.face}]` : ''}</span>`; - } else { - r += `<span class="pink">Face+++${V.summaryStats? `[${slave.face}]` : ''}</span>`; - } - r += " "; - } - - function short_eyes(slave) { - if (slave.eyes === -2) { - r += `<span class="red">Blind</span>`; - } else if (((slave.eyes === -1) && (slave.eyewear !== "corrective glasses") && (slave.eyewear !== "corrective contacts"))) { - r += `<span class="yellow">Sight-</span>`; - } - r += " "; - } - - function short_lips(slave) { - if (slave.lips > 95) { - r += `Facepussy`; - } else if (slave.lips > 70) { - r += `Lips+++${V.summaryStats? `[${slave.lips}]` : ''}`; - } else if (slave.lips > 40) { - r += `Lips++${V.summaryStats? `[${slave.lips}]` : ''}`; - } else if (slave.lips > 20) { - r += `Lips+${V.summaryStats? `[${slave.lips}]` : ''}`; - } else if (slave.lips > 10) { - r += `Lips${V.summaryStats? `[${slave.lips}]` : ''}`; - } else { - r += `<span class="red">Lips-</span>${V.summaryStats? `[${slave.lips}]` : ''}`; - } - r += " "; - } - - function short_teeth(slave) { - if (slave.teeth === "crooked") { - r += `<span class="yellow">Cr Teeth</span>`; - } else if (slave.teeth === "cosmetic braces") { - r += `Cos Braces`; - } else if (slave.teeth === "straightening braces") { - r += `Braces`; - } else if (slave.teeth === "removable") { - r += `Rem Teeth`; - } else if (slave.teeth === "pointy") { - r += `Fangs`; - } - r += " "; - } - - function short_muscles(slave) { - if (slave.muscles > 95) { - r += `Musc++${V.summaryStats? `[${slave.muscles}]`: ''}`; - } else if (slave.muscles > 50) { - r += `Musc+${V.summaryStats? `[${slave.muscles}]`: ''}`; - } else if (slave.muscles > 5) { - r += `Fit${V.summaryStats? `[${slave.muscles}]`: ''}`; - } else if (slave.muscles > -6) { - r += `Soft${V.summaryStats? `[${slave.muscles}]`: ''}`; - } else if (slave.muscles > -31) { - if (V.arcologies[0].FSPhysicalIdealist === "unset") { - r += `<span class="red">Weak</span>${V.summaryStats? `[${slave.muscles}]`: ''}`; - } else { - r += `Soft${V.summaryStats? `[${slave.muscles}]`: ''}`; - } - } else if (slave.muscles > -96) { - if (V.arcologies[0].FSPhysicalIdealist === "unset") { - r += `<span class="red">Weak+</span>${V.summaryStats? `[${slave.muscles}]`: ''}`; - } else { - r += `Soft+${V.summaryStats? `[${slave.muscles}]`: ''}`; - } - } else { - r += `<span class="red">Weak++</span>${V.summaryStats? `[${slave.muscles}]`: ''}`; - } - r += " "; - } - - function short_limbs(slave) { - if (slave.amp !== 0) { - if (slave.amp === -1) { - r += `P-Limbs`; - } else if (slave.amp === -2) { - r += `Sex P-Limbs`; - } else if (slave.amp === -3) { - r += `Beauty P-Limbs`; - } else if (slave.amp === -4) { - r += `Combat P-Limbs`; - } else if (slave.amp === -5) { - r += `Cyber P-Limbs`; - } else { - r += `Amp`; - } - r += " "; - } - if (!canWalk(slave)) { - r += `Immob`; - } - if (slave.heels === 1) { - r += `Heel`; - } - r += `</span> `; - } - - function short_voice(slave) { - if (slave.voice === 0) { - r += `<span class="pink">Mute</span>`; - } else { - if (slave.accent === 3) { - r += `<span class="red">Acc--</span>`; - } else if (slave.accent === 2) { - r += `Acc-`; - } else if (slave.accent === 4) { - r += `Acc--`; - } else if (slave.accent === 1) { - r += `<span class="pink">Acc</span>`; - } - } - r += " "; - } - - function short_tits_ass(slave) { - r += `<span class="pink">`; - if ((slave.boobs >= 12000) && (slave.butt > 9)) { - r += `T&A+++`; - } else if ((slave.boobs > 4000) && (slave.butt > 8)) { - r += `T&A++`; - } else if ((slave.boobs > 2000) && (slave.butt > 6)) { - r += `T&A+`; - } else if ((slave.boobs > 800) && (slave.butt > 4)) { - r += `T&A`; - } else if ((slave.boobs < 500) && (slave.butt < 3) && (slave.weight <= 10) && (slave.muscles <= 30)) { - r += `Girlish`; - } else if (slave.boobs >= 12000) { - r += `Boobs+++`; - } else if (slave.boobs > 4000) { - r += `Boobs++`; - } else if (slave.boobs > 2000) { - r += `Boobs+`; - } else if (slave.boobs > 800) { - r += `Boobs`; - } else if (slave.butt > 9) { - r += `Ass+++`; - } else if (slave.butt > 8) { - r += `Ass++`; - } else if (slave.butt > 6) { - r += `Ass+`; - } else if (slave.butt > 4) { - r += `Ass`; - } - r += `</span> `; - } - - function short_hips(slave) { - r += `<span class="red">`; - if (slave.hips < -1) { - if (slave.butt > 2 && (V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { - r += `Disp+`; - } - } else if (slave.hips < 0) { - if (slave.butt > 4 && (V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { - r += `Disp+`; - } - } else if (slave.hips > 2) { - if (slave.butt <= 8) { - r += `Disp-`; - } - } else if (slave.hips > 1) { - if (slave.butt <= 3 && (V.arcologies[0].FSSlimnessEnthusiast === "unset" || (slave.boobs >= 500))) { - r += `Disp-`; - } - } else if (slave.hips > 0) { - if (slave.butt > 8) { - if ((V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { - r += `Disp+`; - } - } else if (slave.butt <= 2 && (V.arcologies[0].FSSlimnessEnthusiast === "unset" || (slave.boobs >= 500))) { - r += `Disp-`; - } - } else { - if (slave.butt > 6) { - if ((V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { - r += `Disp+`; - } - } else if (slave.butt <= 1 && (V.arcologies[0].FSSlimnessEnthusiast === "unset" || (slave.boobs >= 500))) { - r += `Disp-`; - } - } - r += `</span> `; - } - - function short_waist(slave) { - if (slave.waist > 95) { - r += `<span class="red">Wst---${V.summaryStats? `[${slave.waist}]` : ''}</span>`; - } else if (slave.waist > 40) { - r += `<span class="red">Wst--${V.summaryStats? `[${slave.waist}]`: ''}</span>`; - } else if (slave.waist > 10) { - r += `<span class="red">Wst-${V.summaryStats? `[${slave.waist}]` : ''}</span>`; - } else if (slave.waist >= -10) { - r += `Wst${V.summaryStats? `[${slave.waist}]`: ''}`; - } else if (slave.waist >= -40) { - r += `<span class="pink">Wst+${V.summaryStats? `[${slave.waist}]` : ''}</span>`; - } else if (slave.waist >= -95) { - r += `<span class="pink">Wst++${V.summaryStats? `[${slave.waist}]` : ''}</span>`; - } else { - r += `<span class="pink">Wst+++${V.summaryStats? `[${slave.waist}]`: ''}</span>`; - } - r += " "; - } - - function short_implants(slave) { - r += `<span class="pink">`; - if ((slave.boobsImplant === 0) && (slave.buttImplant === 0) && (slave.waist >= -95) && (slave.lipsImplant === 0) && (slave.faceImplant <= 5) && (slave.bellyImplant === -1)) { - r += `Natr`; - } else { - r += `Impl`; - } - r += " "; - } - - function short_lactation(slave) { - if (slave.lactation === 1) { - r += `Lact`; - } else if (slave.lactation === 2) { - r += `Lact++`; - } - r += " "; - } - - function short_mods(slave) { - modScore(slave); - if (slave.corsetPiercing === 0 && V.piercingScore < 3 && V.tatScore < 2) { - return; - } else if (V.modScore > 15 || (V.piercingScore > 8 && V.tatScore > 5)) { - r += `Mods++`; - } else if (V.modScore > 7) { - r += `Mods+`; - } else { - r += `Mods`; - } - if (slave.brand !== 0) { - r += `Br`; - } - r += " "; - } - - function long_age(slave) { - r += `<span class="pink">`; - if (V.showAgeDetail === 1) { - r += `Age ${slave.actualAge}.`; - } else if (slave.actualAge >= 40) { - r += `Forties.`; - } else if (slave.actualAge >= 35) { - r += `Late thirties.`; - } else if (slave.actualAge >= 30) { - r += `Early thirties.`; - } else if (slave.actualAge >= 25) { - r += `Late twenties.`; - } else if (slave.actualAge >= 20) { - r += `Early twenties.`; - } else if (slave.actualAge >= 19) { - r += `Nineteen.`; - } else if (slave.actualAge >= 18) { - r += `Eighteen.`; - } else { - r += `Underage.`; - } - r += " "; - /* - ** No NCS, then do the standard, However because of the wrinkes of Incubators, as long as visual age is greater - ** than or equal to physical age, we do the old physical body/Looks for fresh out of the can NCS slaves. - */ - if (((slave.inducedNCS === 0) || (slave.visualAge >= slave.physicalAge))) { - if (slave.actualAge !== slave.physicalAge) { - r += `${slave.physicalAge} year old body. `; - } - if (slave.visualAge !== slave.physicalAge) { - r += `Looks ${slave.visualAge}. `; - } - } else { - /* - ** Now the rub. The use of physical Age for the year old body above, basically conflicts with the changes - ** that NCS introduces, so here to *distinguish* the changes, we use visual age with the 'year old body' - ** and appears, for example: Slave release from incubator at age 10, Her summary would show, 'Age 0. 10 - ** year old body.' But if she's given NCS a few weeks after release, while she's still before her first - ** birthday, it'll appear the same. But once her birthday fires, if we ran with the above code it would - ** say: 'Age 1. 11 year old body.' -- this conflicts with the way NCS works though, because she hasn't - ** visually aged, so our change here makes it say 'Age 1. Appears to have a 10 year old body.' - */ - r += `Appears to have a ${slave.visualAge} year old body. `; - } - if (slave.inducedNCS === 1) { - r += `(<span class="orange">NCS</span>) `; - } - } - - function long_face(slave) { - if (slave.face < -95) { - r += `<span class="red">Very ugly${V.summaryStats? `[${slave.face}]`: ''}</span>`; - } else if (slave.face < -40) { - r += `<span class="red">Ugly${V.summaryStats? `[${slave.face}]`: ''}</span>`; - } else if (slave.face < -10) { - r += `<span class="red">Unattractive${V.summaryStats? `[${slave.face}]`: ''}</span>`; - } else if (slave.face <= 10) { - r += `Average${V.summaryStats? `[${slave.face}]`: ''}`; - } else if (slave.face <= 40) { - r += `<span class="pink">Attractive${V.summaryStats? `[${slave.face}]`: ''}</span>`; - } else if (slave.face <= 95) { - r += `<span class="pink">Beautiful${V.summaryStats? `[${slave.face}]`: ''}</span>`; - } else { - r += `<span class="pink">Very beautiful${V.summaryStats? `[${slave.face}]`: ''}</span>`; - } - r += ` ${slave.faceShape} face.`; - } - - function long_eyes(slave) { - if (slave.eyes <= -2) { - r += `<span class="red">Blind.</span>`; - } else if (((slave.eyes <= -1) && (slave.eyewear !== "corrective glasses") && (slave.eyewear !== "corrective contacts"))) { - r += `<span class="yellow">Nearsighted.</span>`; - } - r += " "; - } - - function long_lips(slave) { - if (slave.lips > 95) { - r += `Facepussy${V.summaryStats? `[${slave.lips}]`: ''}.`; - } else if (slave.lips > 70) { - r += `Huge lips${V.summaryStats? `[${slave.lips}]`: ''}.`; - } else if (slave.lips > 40) { - r += `Big lips${V.summaryStats? `[${slave.lips}]`: ''}.`; - } else if (slave.lips > 20) { - r += `Pretty lips${V.summaryStats? `[${slave.lips}]`: ''}.`; - } else if (slave.lips > 10) { - r += `Normal lips${V.summaryStats? `[${slave.lips}]`: ''}.`; - } else { - r += `<span class="red">Thin lips${V.summaryStats? `[${slave.lips}]`: ''}.</span>`; - } - r += " "; - } - - function long_teeth(slave) { - if (slave.teeth === "crooked") { - r += `<span class="yellow">Crooked teeth.</span>`; - } else if (slave.teeth === "cosmetic braces") { - r += `Cosmetic braces.`; - } else if (slave.teeth === "straightening braces") { - r += `Braces.`; - } else if (slave.teeth === "removable") { - r += `Removable teeth.`; - } else if (slave.teeth === "pointy") { - r += `Sharp fangs.`; - } - r += " "; - } - - function long_muscles(slave) { - if (slave.muscles > 95) { - r += `Hugely muscular${V.summaryStats? `[${slave.muscles}]` : ''}.`; - } else if (slave.muscles > 50) { - r += `Muscular${V.summaryStats? `[${slave.muscles}]`: ''}.`; - } else if (slave.muscles > 5) { - r += `Fit${V.summaryStats? `[${slave.muscles}]`: ''}.`; - } else if (slave.muscles > -6) { - r += `Soft${V.summaryStats? `[${slave.muscles}]`: ''}.`; - } else if (slave.muscles > -31) { - if (V.arcologies[0].FSPhysicalIdealist === "unset") { - r += `<span class="red">Weak${V.summaryStats? `[${slave.muscles}]`: ''}.</span>`; - } else { - r += `Weak${V.summaryStats? `[${slave.muscles}]`: ''}.`; - } - } else if (slave.muscles > -96) { - if (V.arcologies[0].FSPhysicalIdealist === "unset") { - r += `<span class="red">Very weak${V.summaryStats? `[${slave.muscles}]`: ''}.</span>`; - } else { - r += `Very weak${V.summaryStats? `[${slave.muscles}]`: ''}.`; - } - } else { - r += `<span class="red">Frail${V.summaryStats? `[${slave.muscles}]`: ''}.</span>`; - } - r += " "; - } - - function long_limbs(slave) { - if (slave.amp !== 0) { - if (slave.amp === -1) { - r += `Prosthetic limbs.`; - } else if (slave.amp === -2) { - r += `Sexy prosthetic limbs.`; - } else if (slave.amp === -3) { - r += `Beautiful prosthetic limbs.`; - } else if (slave.amp === -4) { - r += `Deadly prosthetic limbs.`; - } else if (slave.amp === -5) { - r += `Cyber prosthetic limbs.`; - } else { - r += `Amputee.`; - } - } - r += " "; - if (!canWalk(slave)) { - r += `Immobile. `; - } - if (slave.heels === 1) { - r += `Heeled. `; - } - r += `</span> `; - } - - function long_voice(slave) { - if (slave.voice === 0) { - r += `<span class="pink">Mute.</span>`; - } else { - if (slave.accent === 3) { - r += `<span class="red">Bad accent.</span>`; - } else if (slave.accent === 4) { - r += `<span class="red">No language skills.</span>`; - } else if (slave.accent === 2) { - r += `Accent.`; - } else if (slave.accent === 1) { - r += `<span class="pink">Cute accent.</span>`; - } - } - r += " "; - } - - function long_tits_ass(slave) { - r += `<span class="pink">`; - if ((slave.boobs >= 12000) && (slave.butt > 9)) { - r += `Hyper T&A.`; - } else if ((slave.boobs > 4000) && (slave.butt > 8)) { - r += `Enormous T&A.`; - } else if ((slave.boobs > 2000) && (slave.butt > 6)) { - r += `Huge T&A.`; - } else if ((slave.boobs > 800) && (slave.butt > 4)) { - r += `Big T&A.`; - } else if ((slave.boobs < 500) && (slave.butt < 3) && (slave.weight <= 10) && (slave.muscles <= 30)) { - r += `Girlish figure.`; - } else if (slave.boobs >= 12000) { - r += `Immobilizing tits.`; - } else if (slave.boobs > 4000) { - r += `Monstrous tits.`; - } else if (slave.boobs > 2000) { - r += `Huge tits.`; - } else if (slave.boobs > 800) { - r += `Big tits.`; - } else if (slave.butt > 9) { - r += `Hyper ass.`; - } else if (slave.butt > 8) { - r += `Titanic ass.`; - } else if (slave.butt > 6) { - r += `Huge ass.`; - } else if (slave.butt > 4) { - r += `Big ass.`; - } - r += `</span> `; - } - - function long_hips(slave) { - r += `<span class="red">`; - if (slave.hips < -1) { - if (slave.butt > 2 && (V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { - r += `Disproportionately big butt.`; - } - } else if (slave.hips < 0) { - if (slave.butt > 4 && (V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { - r += `Disproportionately big butt.`; - } - } else if (slave.hips > 2) { - if (slave.butt <= 8) { - r += `Disproportionately small butt.`; - } - } else if (slave.hips > 1) { - if (slave.butt <= 3 && ((V.arcologies[0].FSSlimnessEnthusiast === "unset") || (slave.boobs >= 500))) { - r += `Disproportionately small butt.`; - } - } else if (slave.hips > 0) { - if (slave.butt > 8) { - if ((V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { - r += `Disproportionately big butt.`; - } - } else if (slave.butt <= 2 && ((V.arcologies[0].FSSlimnessEnthusiast === "unset") || (slave.boobs >= 500))) { - r += `Disproportionately small butt.`; - } - } else { - if (slave.butt > 6) { - if ((V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { - r += `Disproportionately big butt.`; - } - } else if (slave.butt <= 1 && ((V.arcologies[0].FSSlimnessEnthusiast === "unset") || (slave.boobs >= 500))) { - r += `Disproportionately small butt.`; - } - } - r += `</span> `; - } - - function long_waist(slave) { - if (slave.waist > 95) { - r += `<span class="red">Masculine waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; - } else if (slave.waist > 40) { - r += `<span class="red">Ugly waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; - } else if (slave.waist > 10) { - r += `<span class="red">Unattractive waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; - } else if (slave.waist >= -10) { - r += `Average waist${V.summaryStats? `[${slave.waist}]`: ''}.`; - } else if (slave.waist >= -40) { - r += `<span class="pink">Feminine waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; - } else if (slave.waist >= -95) { - r += `<span class="pink">Hourglass waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; - } else { - r += `<span class="pink">Absurdly narrow waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; - } - r += " "; - } - - function long_implants(slave) { - r += `<span class="pink">`; - if ((slave.boobsImplant !== 0) || (slave.buttImplant !== 0) || (slave.lipsImplant !== 0) || (slave.bellyImplant !== -1)) { - r += `Implants.`; - } else if ((slave.faceImplant >= 30) || (slave.waist < -95)) { - r += `Surgery enhanced.`; - } else { - r += `All natural.`; - } - r += " "; - } - - function long_lactation(slave) { - if (slave.lactation === 1) { - r += `Lactating naturally.`; - } else if (slave.lactation === 2) { - r += `Heavy lactation.`; - } - r += " "; - } - - function long_mods(slave) { - modScore(slave); - if (slave.corsetPiercing === 0 && V.piercingScore < 3 && V.tatScore < 2) { - return; - } else if (V.modScore > 15 || (V.piercingScore > 8 && V.tatScore > 5)) { - r += `Extensive body mods.`; - } else if (V.modScore > 7) { - r += `Noticeable body mods.`; - } else { - r += `Light body mods.`; - } - r += " "; - } - - function short_intelligence(slave) { - if (slave.fetish === "mindbroken") { - return; - } else if (slave.intelligenceImplant === 1) { - switch (slave.intelligence) { - case 3: - r += `<span class="deepskyblue">I+++(e)</span>`; - break; - case 2: - r += `<span class="deepskyblue">I++(e)</span>`; - break; - case 1: - r += `<span class="deepskyblue">I+(e)</span>`; - break; - case -1: - r += `<span class="orangered">I-(e)</span>`; - break; - case -2: - r += `<span class="orangered">I--(e)</span>`; - break; - case -3: - r += `<span class="orangered">I---(e)</span>`; - break; - default: - r += `I(e)`; - break; - } - } else { - switch (slave.intelligence) { - case 3: - r += `<span class="deepskyblue">I+++</span>`; - break; - case 2: - r += `<span class="deepskyblue">I++</span>`; - break; - case 1: - r += `<span class="deepskyblue">I+</span>`; - break; - case -1: - r += `<span class="orangered">I-</span>`; - break; - case -2: - r += `<span class="orangered">I--</span>`; - break; - case -3: - r += `<span class="orangered">I---</span>`; - break; - default: - r += `I`; - break; - } - } - r += " "; - } - - function short_sex_skills(slave) { - let _SSkills = slave.analSkill + slave.oralSkill; - r += `<span class="aquamarine">`; - if (((_SSkills + slave.whoreSkill + slave.entertainSkill) >= 400) && ((slave.vagina < 0) || (slave.vaginalSkill >= 100))) { - r += `MSS`; - } else { - _SSkills += slave.vaginalSkill; - _SSkills = Math.trunc(_SSkills); - if (_SSkills > 180) { - r += `S++`; - } else if ((_SSkills > 120) && (slave.vagina < 0)) { - r += `Sh++`; - } else if (_SSkills > 90) { - r += `S+`; - } else if (_SSkills > 30) { - r += `S`; - } else { - r += `S-`; - } - if (V.summaryStats) { - r += `[${_SSkills}] `; - } - r += " "; - if (slave.whoreSkill >= 100) { - r += `W+++`; - } else if (slave.whoreSkill > 60) { - r += `W++`; - } else if (slave.whoreSkill > 30) { - r += `W+`; - } else if (slave.whoreSkill > 10) { - r += `W`; - } - if (slave.whoreSkill > 10) { - if (V.summaryStats) { - r += `[${slave.whoreSkill}] `; - } - } - r += " "; - if (slave.entertainSkill >= 100) { - r += `E+++`; - } else if (slave.entertainSkill > 60) { - r += `E++`; - } else if (slave.entertainSkill > 30) { - r += `E+`; - } else if (slave.entertainSkill > 10) { - r += `E`; - } - if (slave.entertainSkill > 10) { - if (V.summaryStats) { - r += `[${slave.entertainSkill}] `; - } - } - } - r += " "; - } - - function short_prestige(slave) { - if (slave.prestige > 0) { - r += `<span class="green">`; - if (slave.prestige > 2) { - r += `Prest++`; - } else if (slave.prestige === 2) { - r += `Prest+`; - } else if (slave.prestige === 1) { - r += `Prest`; - } - r += `</span> `; - } - } - - function long_intelligence(slave) { - if (slave.fetish === "mindbroken") { - return; - } else if (slave.intelligenceImplant === 1) { - switch (slave.intelligence) { - case 3: - r += `<span class="deepskyblue">Brilliant, educated.</span>`; - break; - case 2: - r += `<span class="deepskyblue">Very smart, educated.</span>`; - break; - case 1: - r += `<span class="deepskyblue">Smart, educated.</span>`; - break; - case -1: - r += `<span class="orangered">Slow, educated.</span>`; - break; - case -2: - r += `<span class="orangered">Very slow, educated.</span>`; - break; - case -3: - r += `<span class="orangered">Moronic, educated.</span>`; - break; - default: - r += `Average intelligence, educated.`; - break; - } - } else { - switch (slave.intelligence) { - case 3: - r += `<span class="deepskyblue">Brilliant.</span>`; - break; - case 2: - r += `<span class="deepskyblue">Very smart.</span>`; - break; - case 1: - r += `<span class="deepskyblue">Smart.</span>`; - break; - case -1: - r += `<span class="orangered">Slow.</span>`; - break; - case -2: - r += `<span class="orangered">Very slow.</span>`; - break; - case -3: - r += `<span class="orangered">Moronic.</span>`; - break; - default: - r += `Average intelligence.`; - break; - } - } - r += " "; - } - - function long_sex_skills(slave) { - let _SSkills = (slave.analSkill + slave.oralSkill); - r += `<span class="aquamarine">`; - if (((_SSkills + slave.whoreSkill + slave.entertainSkill) >= 400) && ((slave.vagina < 0) || (slave.vaginalSkill >= 100))) { - r += `Masterful Sex Slave. `; - } else { - _SSkills += slave.vaginalSkill; - if (_SSkills > 180) { - r += `Sex master${V.summaryStats? `[${Math.trunc(_SSkills)}]`: ''}.`; - } else if ((_SSkills > 120) && (slave.vagina < 0)) { - r += `Masterful shemale${V.summaryStats? `[${Math.trunc(_SSkills)}]`: ''}.`; - } else if (_SSkills > 90) { - r += `Sexual expert${V.summaryStats? `[${Math.trunc(_SSkills)}]`: ''}.`; - } else if (_SSkills > 30) { - r += `Sexually skilled${V.summaryStats? `[${Math.trunc(_SSkills)}]` : ''}.`; - } else { - r += `Sexually unskilled${V.summaryStats? `[${Math.trunc(_SSkills)}]` : ''}.`; - } - r += " "; - if (slave.whoreSkill >= 100) { - r += `Masterful whore${V.summaryStats? `[${slave.whoreSkill}]`: ''}.`; - } else if (slave.whoreSkill >= 60) { - r += `Expert whore${V.summaryStats? `[${slave.whoreSkill}]`: ''}.`; - } else if (slave.whoreSkill >= 30) { - r += `Skilled whore${V.summaryStats? `[${slave.whoreSkill}]`: ''}.`; - } else if (slave.whoreSkill >= 10) { - r += `Basic whore${V.summaryStats? `[${slave.whoreSkill}]`: ''}.`; - } - r += " "; - if (slave.entertainSkill >= 100) { - r += `Masterful entertainer${V.summaryStats? `[${slave.entertainSkill}]`: ''}.`; - } else if (slave.entertainSkill >= 60) { - r += `Expert entertainer${V.summaryStats? `[${slave.entertainSkill}]`: ''}.`; - } else if (slave.entertainSkill >= 30) { - r += `Skilled entertainer${V.summaryStats? `[${slave.entertainSkill}]`: ''}.`; - } else if (slave.entertainSkill >= 10) { - r += `Basic entertainer${V.summaryStats? `[${slave.entertainSkill}]`: ''}.`; - } - r += " "; - } - } - - function long_prestige(slave) { - if (slave.prestige > 0) { - r += `<span class="green">`; - if (slave.prestige > 2) { - r += `Extremely prestigious.`; - } else if (slave.prestige === 2) { - r += `Very prestigious.`; - } else if (slave.prestige === 1) { - r += `Prestigious.`; - } - r += `</span> `; - } - } - - function short_fetish(slave) { - r += `<span class="lightcoral">`; - switch (slave.fetish) { - case "submissive": - if (slave.fetishStrength > 95) { - r += `Sub++`; - } else if (slave.fetishStrength > 60) { - r += `Sub+`; - } else { - r += `Sub`; - } - break; - case "cumslut": - if (slave.fetishStrength > 95) { - r += `Oral++`; - } else if (slave.fetishStrength > 60) { - r += `Oral+`; - } else { - r += `Oral`; - } - break; - case "humiliation": - if (slave.fetishStrength > 95) { - r += `Humil++`; - } else if (slave.fetishStrength > 60) { - r += `Humil+`; - } else { - r += `Humil`; - } - break; - case "buttslut": - if (slave.fetishStrength > 95) { - r += `Anal++`; - } else if (slave.fetishStrength > 60) { - r += `Anal+`; - } else { - r += `Anal`; - } - break; - case "boobs": - if (slave.fetishStrength > 95) { - r += `Boobs++`; - } else if (slave.fetishStrength > 60) { - r += `Boobs+`; - } else { - r += `Boobs`; - } - break; - case "sadist": - if (slave.fetishStrength > 95) { - r += `Sadist++`; - } else if (slave.fetishStrength > 60) { - r += `Sadist+`; - } else { - r += `Sadist`; - } - break; - case "masochist": - if (slave.fetishStrength > 95) { - r += `Pain++`; - } else if (slave.fetishStrength > 60) { - r += `Pain+`; - } else { - r += `Pain`; - } - break; - case "dom": - if (slave.fetishStrength > 95) { - r += `Dom++`; - } else if (slave.fetishStrength > 60) { - r += `Dom+`; - } else { - r += `Dom`; - } - break; - case "pregnancy": - if (slave.fetishStrength > 95) { - r += `Preg++`; - } else if (slave.fetishStrength > 60) { - r += `Preg+`; - } else { - r += `Preg`; - } - break; - default: - r += `Vanilla`; - break; - } - if (V.summaryStats) { - r += `[${slave.fetishStrength}]`; - } - r += `</span> `; - } - - function short_attraction(slave) { - if (slave.attrXY <= 5) { - r += `<span class="red">XY---${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; - } else if (slave.attrXY <= 15) { - r += `<span class="red">XY--${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; - } else if (slave.attrXY <= 35) { - r += `<span class="red">XY-${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; - } else if (slave.attrXY <= 65) { - r += `XY${V.summaryStats? `[${slave.attrXY}]`: ''}`; - } else if (slave.attrXY <= 85) { - r += `<span class="green">XY+${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; - } else if (slave.attrXY <= 95) { - r += `<span class="green">XY++${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; - } else if (slave.attrXX > 95) { - if (slave.energy <= 95) { - r += `<span class="green">Omni!</span>`; - } else { - r += `<span class="green">Omni+Nympho!!</span>`; - } - } else { - r += `<span class="green">XY+++${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; - } - r += " "; - if (slave.attrXX <= 5) { - r += `<span class="red">XX---${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; - } else if (slave.attrXX <= 15) { - r += `<span class="red">XX--${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; - } else if (slave.attrXX <= 35) { - r += `<span class="red">XX-${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; - } else if (slave.attrXX <= 65) { - r += `XX${V.summaryStats? `[${slave.attrXX}]`: ''}`; - } else if (slave.attrXX <= 85) { - r += `<span class="green">XX+${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; - } else if (slave.attrXX <= 95) { - r += `<span class="green">XX++${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; - } else if (slave.attrXY <= 95) { - r += `<span class="green">XX+++${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; - } - r += " "; - if (slave.energy > 95) { - if ((slave.attrXY <= 95) || (slave.attrXX <= 95)) { - r += `<span class="green">Nympho!</span>`; - } - } else if (slave.energy > 80) { - r += `<span class="green">SD++${V.summaryStats? `[${slave.energy}]`: ''}</span>`; - } else if (slave.energy > 60) { - r += `<span class="green">SD+${V.summaryStats? `[${slave.energy}]`: ''}</span>`; - } else if (slave.energy > 40) { - r += `<span class="yellow">SD${V.summaryStats? `[${slave.energy}]`: ''}</span>`; - } else if (slave.energy > 20) { - r += `<span class="red">SD-${V.summaryStats? `[${slave.energy}]`: ''}</span>`; - } else { - r += `<span class="red">SD--${V.summaryStats? `[${slave.energy}]`: ''}</span>`; - } - r += " "; - } - - function short_smart_fetish(slave) { - if (slave.fetishKnown === 1) { - if (slave.clitSetting === "off") { - r += `SP-`; - } else if (((slave.fetish !== "submissive") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "submissive")) { - r += `SP:sub`; - } else if (((slave.fetish !== "cumslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "oral")) { - r += `SP:oral`; - } else if (((slave.fetish !== "humiliation") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "humiliation")) { - r += `SP:humil`; - } else if (((slave.fetish !== "buttslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "anal")) { - r += `SP:anal`; - } else if (((slave.fetish !== "boobs") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "boobs")) { - r += `SP:boobs`; - } else if (((slave.fetish !== "sadist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "sadist")) { - r += `SP:sade`; - } else if (((slave.fetish !== "masochist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "masochist")) { - r += `SP:pain`; - } else if (((slave.fetish !== "dom") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "dom")) { - r += `SP:dom`; - } else if (((slave.fetish !== "pregnancy") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "pregnancy")) { - r += `SP:preg`; - } else if (((slave.fetish !== "none") && (slave.clitSetting === "vanilla"))) { - r += `SP:vanilla`; - } else if ((slave.energy <= 95) && (slave.clitSetting === "all")) { - r += `SP:all`; - } else if ((slave.energy > 5) && (slave.clitSetting === "none")) { - r += `SP:none`; - } else if (!["women", "men", "anti-women", "anti-men"].includes(slave.clitSetting)) { - r += `SP:monitoring`; - } - } else { - switch (slave.clitSetting) { - case "off": - r += `SP-`; - break; - case "submissive": - r += `SP:sub`; - break; - case "lesbian": - r += `SP:les`; - break; - case "oral": - r += `SP:oral`; - break; - case "humiliation": - r += `SP:humil`; - break; - case "anal": - r += `SP:anal`; - break; - case "boobs": - r += `SP:boobs`; - break; - case "sadist": - r += `SP:sade`; - break; - case "masochist": - r += `SP:pain`; - break; - case "dom": - r += `SP:dom`; - break; - case "pregnancy": - r += `SP:pregnancy`; - break; - case "vanilla": - r += `SP:vanilla`; - break; - case "all": - r += `SP:all`; - break; - case "none": - r += `SP:none`; - break; - } - } - r += " "; - } - - function short_smart_attraction(slave) { - if (slave.attrKnown === 1) { - if (slave.clitSetting === "women") { - if (slave.attrXX < 95) { - r += `SP:women`; - } else { - r += `SP:monitoring`; - } - } else if (slave.clitSetting === "men") { - if (slave.attrXY < 95) { - r += `SP:men`; - } else { - r += `SP:monitoring`; - } - } else if (slave.clitSetting === "anti-women") { - if (slave.attrXX > 0) { - r += `SP:anti-women`; - } else { - r += `SP:monitoring`; - } - } else if (slave.clitSetting === "anti-men") { - if (slave.attrXY > 0) { - r += `SP:anti-men`; - } else { - r += `SP:monitoring`; - } - } - } else { - if (slave.clitSetting === "women") { - r += `SP:women`; - } else if (slave.clitSetting === "men") { - r += `SP:men`; - } else if (slave.clitSetting === "anti-women") { - r += `SP:anti-women`; - } else if (slave.clitSetting === "anti-men") { - r += `SP:anti-men`; - } - } - r += " "; - } - - function short_behavior_flaw(slave) { - r += `<span class="red">`; - switch (slave.behavioralFlaw) { - case "arrogant": - r += `Arrog`; - break; - case "bitchy": - r += `Bitchy`; - break; - case "odd": - r += `Odd`; - break; - case "hates men": - r += `Men-`; - break; - case "hates women": - r += `Women-`; - break; - case "gluttonous": - r += `Glut`; - break; - case "anorexic": - r += `Ano`; - break; - case "devout": - r += `Dev`; - break; - case "liberated": - r += `Lib`; - break; - default: - slave.behavioralFlaw = "none"; + + default: break; + } + if (flag) { + slave.drugs = rule.drug; + r += `<br>${slave.slaveName} has been put on ${slave.drugs}.`; + } else { + slave.drugs = "no drugs"; + r += `<br>${slave.slaveName} cannot benefit from her assigned drug and has been defaulted to ${slave.drugs}`; + } } - r += `</span> `; } - - function short_sex_flaw(slave) { - switch (slave.sexualFlaw) { - case "hates oral": - r += `<span class="red">Oral-</span>`; - break; - case "hates anal": - r += `<span class="red">Anal-</span>`; - break; - case "hates penetration": - r += `<span class="red">Fuck-</span>`; - break; - case "shamefast": - r += `<span class="red">Shame</span>`; - break; - case "idealistic": - r += `<span class="red">Ideal</span>`; - break; - case "repressed": - r += `<span class="red">Repre</span>`; - break; - case "apathetic": - r += `<span class="red">Apath</span>`; - break; - case "crude": - r += `<span class="red">Crude</span>`; - break; - case "judgemental": - r += `<span class="red">Judge</span>`; - break; - case "cum addict": - r += `<span class="yellow">CumAdd</span>`; - break; - case "anal addict": - r += `<span class="yellow">AnalAdd</span>`; - break; - case "attention whore": - r += `<span class="yellow">Attention</span>`; - break; - case "breast growth": - r += `<span class="yellow">BoobObsess</span>`; - break; - case "abusive": - r += `<span class="yellow">Abusive</span>`; - break; - case "malicious": - r += `<span class="yellow">Malice</span>`; - break; - case "self hating": - r += `<span class="yellow">SelfHatr</span>`; - break; - case "neglectful": - r += `<span class="yellow">SelfNeglect</span>`; - break; - case "breeder": - r += `<span class="yellow">BreedObsess</span>`; - break; - default: - slave.sexualFlaw = "none"; - break; - } - r += " "; - } - - function short_behavior_quirk(slave) { - r += `<span class="green">`; - switch (slave.behavioralQuirk) { - case "confident": - r += `Confid`; - break; - case "cutting": - r += `Cutting`; - break; - case "funny": - r += `Funny`; - break; - case "fitness": - r += `Fit`; - break; - case "adores women": - r += `Women+`; - break; - case "adores men": - r += `Men+`; - break; - case "insecure": - r += `Insec`; - break; - case "sinful": - r += `Sinf`; - break; - case "advocate": - r += `Advoc`; - break; - default: - slave.behavioralQuirk = "none"; - break; + + function ProcessDiet(slave, rule) { + // Diet Setting + if (rule.diet !== undefined && rule.diet !== "no default setting") { + /* + if ((slave.boobs >= 1600) && (slave.muscles <= 5) && (slave.amp != 1) && ((rule.muscles == "no default setting") || (rule.muscles === 0))) { + if ((slave.diet !== "muscle building")) { + slave.diet = "muscle building" + r += `<br>${slave.slaveName} has big tits and no back muscles, so she'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))) { + */ + 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))) { + slave.diet = "healthy"; + r += `<br>${slave.slaveName} has huge boobs, but she already has the back muscles to bear them, so she'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)) { + if (slave.diet !== "fattening") { + slave.diet = "fattening"; + r += `<br>${slave.slaveName} is on drugs designed to expand major body parts, so she's been put on a fattening diet to provide her body as much fuel for growth as possible.`; + } + } else { + if (!(isNaN(rule.diet))) { + if ((slave.weight - rule.diet) > 5) { + if ((slave.diet !== "restricted")) { + slave.diet = "restricted"; + r += `<br>${slave.slaveName} is too fat so her diet has been set to restricted.`; + } + + } else if ((slave.weight - rule.diet) < -5) { + if ((slave.diet !== "fattening")) { + slave.diet = "fattening"; + r += `<br>${slave.slaveName} is too skinny so her 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)) { + 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)) { + if ((slave.diet !== "muscle building")) { + slave.diet = "muscle building"; + r += `<br>${slave.slaveName} has been put on a muscle building exercise regime.`; + } + } else { + if ((slave.diet !== "healthy")) { + slave.diet = "healthy"; + r += `<br>${slave.slaveName} is at the target weight, so her diet has been normalized.`; + } + } + } else { + if ((slave.diet !== "healthy")) { + slave.diet = "healthy"; + r += `<br>${slave.slaveName} is at the target weight, so her diet has been normalized.`; + } + } + } else if ((rule.diet == "attractive")) { + if (((slave.weight > 95) || ((slave.weight > 30) && (slave.hips < 2)))) { + if ((slave.diet !== "restricted")) { + slave.diet = "restricted"; + r += `<br>${slave.slaveName} is too fat so her diet has been set to restricted.`; + } + } else if (((slave.weight < -95) || ((slave.weight < -30) && (slave.hips > -2)))) { + if ((slave.diet !== "fattening")) { + slave.diet = "fattening"; + r += `<br>${slave.slaveName} is too skinny so her 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)) { + 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)) { + if ((slave.diet !== "muscle building")) { + slave.diet = "muscle building"; + r += `<br>${slave.slaveName} has been put on a muscle building exercise regime.`; + } + } else { + if ((slave.diet !== "healthy")) { + slave.diet = "healthy"; + r += `<br>${slave.slaveName} is at the target weight, so her diet has been normalized.`; + } + } + } else { + if ((slave.diet !== "healthy")) { + slave.diet = "healthy"; + r += `<br>${slave.slaveName} is at the target weight, so her diet has been normalized.`; + } + } + } else if ((rule.diet == "XX")) { + if ((slave.diet !== "XX")) { + slave.diet = "XX"; + r += `<br>${slave.slaveName} has been put on a diet that favors feminine development.`; + } + } else if ((rule.diet == "XY")) { + if ((slave.diet !== "XY")) { + slave.diet = "XY"; + r += `<br>${slave.slaveName} has been put on a diet that favors masculine development.`; + } + } else if ((rule.diet == "XXY")) { + if (slave.balls > 0 && (slave.ovaries == 1 || slave.mpreg == 1)) { + if ((slave.diet !== "XXY")) { + slave.diet = "XXY"; + r += `<br>${slave.slaveName} has been put on a diet that enhances a herm's unique sexuality.`; + } + } else { + if ((slave.diet !== "healthy")) { + slave.diet = "healthy"; + r += `<br>${slave.slaveName} has been put on a standard diet since she is not a hermaphrodite.`; + } + } + } else if ((rule.diet == "cleansing")) { + if (((slave.diet !== "cleansing") && (slave.health < 100))) { + slave.diet = "cleansing"; + r += `<br>${slave.slaveName} has been put on a diet of cleansers.`; + } + } else if ((rule.diet == "fertility")) { + if (canGetPregnant(slave)) { + if ((slave.diet !== "fertility")) { + slave.diet = "fertility"; + r += `<br>${slave.slaveName} has been put on a diet to enhance fertility.`; + } + } else { + if ((slave.diet !== "healthy")) { + slave.diet = "healthy"; + if (slave.pregKnown === 0 && slave.preg > 0) { + r += `<br>${slave.slaveName} has been put on a standard diet since tests reveal she has become pregnant.`; + slave.pregKnown = 1; + } else { + r += `<br>${slave.slaveName} has been put on a standard diet since she is currently unable to become pregnant.`; + } + } + } + } else if ((rule.diet == "cum production")) { + if ((slave.balls > 0)) { + if ((slave.diet !== "cum production")) { + slave.diet = "cum production"; + r += `<br>${slave.slaveName} has been put on a diet to promote cum production.`; + } + } else { + if ((slave.diet !== "healthy")) { + slave.diet = "healthy"; + r += `<br>${slave.slaveName} has been put on a standard diet since she is no longer able to produce cum.`; + } + } + } + } + } else if ((rule.muscles !== undefined) && (rule.muscles !== "no default setting") && (slave.amp != 1)) { // no diet rule, muscles only + if ((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)) { + if ((slave.diet !== "muscle building")) { + slave.diet = "muscle building"; + r += `<br>${slave.slaveName} has been put on a muscle building exercise regime.`; + } + } else { + if ((slave.diet !== "healthy")) { + slave.diet = "healthy"; + r += `<br>${slave.slaveName} has achieved the target musculature, so her exercise regime has been normalized.`; + } + } } - r += " "; - } - - function short_sex_quirk(slave) { - switch (slave.sexualQuirk) { - case "gagfuck queen": - r += `Gagfuck`; - break; - case "painal queen": - r += `Painal`; - break; - case "strugglefuck queen": - r += `Struggle`; - break; - case "tease": - r += `Tease`; - break; - case "romantic": - r += `Romantic`; - break; - case "perverted": - r += `Perverted`; - break; - case "caring": - r += `Caring`; - break; - case "unflinching": - r += `Unflinch`; - break; - case "size queen": - r += `SizeQ`; - break; - default: - slave.sexualQuirk = "none"; - break; + + if (slave.drugs === "appetite suppressors" && slave.diet !== "restricted") { + slave.drugs = "no drugs"; + r += `<br>${slave.slaveName} is no longer losing weight, so she's no longer being given appetite suppressors.`; + } else if (slave.diet === "restricted" && V.arcologies[0].FSSlimnessEnthusiastResearch == 1 && (slave.drugs == "no drugs" || slave.drugs == "none")) { + slave.drugs = "appetite suppressors"; + r += `<br>${slave.slaveName} is losing weight so she will be given weight loss pills.`; } - r += `</span> `; } - - function long_fetish(slave) { - r += `<span class="lightcoral">`; - switch (slave.fetish) { - case "submissive": - if (slave.fetishStrength > 95) { - r += `Complete submissive${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Submissive${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Submissive tendencies${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } - break; - case "cumslut": - if (slave.fetishStrength > 95) { - r += `Cumslut${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Oral fixation${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Prefers oral${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } - break; - case "humiliation": - if (slave.fetishStrength > 95) { - r += `Humiliation slut${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Exhibitionist${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + + function ProcessCuratives(slave, rule) { + if ((rule.curatives !== undefined) && (rule.curatives !== "no default setting")) { + if (slave.curatives !== rule.curatives) { + if (rule.curatives === 2) { + if (slave.health > 100) { + if ((slave.curatives != 1)) { + r += `<br>${slave.slaveName} has been put on preventatives, since curatives cannot improve her health further.`; + slave.curatives = 1; + } + } else { + r += `<br>${slave.slaveName} has been put on curatives.`; + slave.curatives = rule.curatives; + } } else { - r += `Interest in humiliation${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + r += `<br>${slave.slaveName} has been ${rule.curatives > 0 ? `put on preventatives` : `taken off health drugs`}`; + slave.curatives = rule.curatives; } - break; - case "buttslut": - if (slave.fetishStrength > 95) { - r += `Buttslut${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Anal fixation${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Prefers anal${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } + } + } + + function ProcessAphrodisiacs(slave, rule) { + if ((rule.aphrodisiacs !== undefined) && (rule.aphrodisiacs != "no default setting")) { + 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; + } + } + } + + function ProcessPenisHormones(slave, rule) { + if ((slave.dick > 0)) { + if ((slave.balls === 0)) { + if ((rule.gelding !== undefined) && (rule.gelding !== "no default setting")) { + if ((slave.hormones !== rule.gelding)) { + const _oldHormones = slave.hormones; + slave.hormones = rule.gelding; + if (slave.indentureRestrictions >= 2) { + slave.hormones = Math.clamp(slave.hormones, -1, 1); + } + if (slave.hormones != _oldHormones) { + r += `<br>${slave.slaveName} is a gelding, so she has been put on the appropriate hormonal regime.`; + } + } } - break; - case "boobs": - if (slave.fetishStrength > 95) { - r += `Boobslut${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Breast fixation${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Loves boobs${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else if ((slave.balls > 0)) { + if ((rule.XY !== undefined) && (rule.XY !== "no default setting")) { + if ((slave.hormones !== rule.XY)) { + if ((slave.assignment != "recruit girls")) { + if ((slave.assignment != "be the Wardeness")) { + if ((slave.assignment != "be the Madam")) { + const _oldHormones = slave.hormones; + slave.hormones = rule.XY; + if (slave.indentureRestrictions >= 2) { + slave.hormones = Math.clamp(slave.hormones, -1, 1); + } + if (slave.hormones != _oldHormones) { + r += `<br>${slave.slaveName} is a shemale, so she has been put on the appropriate hormonal regime.`; + } + } + } + } + } } - break; - case "sadist": - if (slave.fetishStrength > 95) { - r += `Complete sadist${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Sadist${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Sadistic tendencies${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } + } + } + + function ProcessFemaleHormones(slave, rule) { + if ((slave.vagina > -1) && (slave.dick === 0) && (rule.XX !== undefined) && (rule.XX !== "no default setting")) { + if ((slave.hormones !== rule.XX)) { + const _oldHormones = slave.hormones; + slave.hormones = rule.XX; + if (slave.indentureRestrictions >= 2) { + slave.hormones = Math.clamp(slave.hormones, -1, 1); } - break; - case "masochist": - if (slave.fetishStrength > 95) { - r += `Complete masochist${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Masochist${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Masochistic tendencies${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + if (slave.hormones != _oldHormones) { + r += `<br>${slave.slaveName} is a female, so she has been put on the appropriate hormonal regime.`; } - break; - case "dom": - if (slave.fetishStrength > 95) { - r += `Complete dom${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Dominant${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Dominant tendencies${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } + } + } + + function ProcessPregnancyDrugs(slave, rule) { + if (slave.pregKnown == 1 && rule.pregSpeed != "no default setting" && slave.breedingMark != 1 && slave.indentureRestrictions < 1 && slave.broodmother === 0) { + if (rule.pregSpeed == "slow" && slave.preg < 35) { + slave.pregControl = "slow gestation"; + r += `<br>${slave.slaveName} is pregnant, so she has been put on the gestation slowing agents.`; + } else if (rule.pregSpeed == "fast" && slave.preg < 35 && slave.health > -50) { + slave.pregControl = "speed up"; + r += `<br>${slave.slaveName} is pregnant, so she has been put on rapid gestation agents. CAUTION! Can be dangerous. Clinic supervision is recommended.`; + } else if (rule.pregSpeed == "suppress" && slave.preg > 34 && slave.health > -50) { + slave.pregControl = "labor supressors"; + r += `<br>${slave.slaveName} is ready to birth, so she has been put on labor suppressing agents.`; + } else if (rule.pregSpeed == "stimulate" && slave.preg >= 37 && slave.health > -50) { + slave.labor = 1; + slave.induce = 1; + V.birthee = 1; + r += `<br>slave.slaveName is ready to birth, so her labor has been stimulated.`; + } else if (rule.pregSpeed == "fast" && slave.pregControl == "speed up" && slave.health <= -50) { + slave.pregControl = "none"; + r += `<br>${slave.slaveName} is on rapid gestation agents and dangerously unhealthy, so her agent regimen has been stopped.`; + } else if (rule.pregSpeed == "suppress" && slave.pregControl == "labor supressors" && slave.health <= -50) { + slave.pregControl = "none"; + r += `<br>${slave.slaveName} is on labor suppression agents and unhealthy, so her agent regimen has been stopped.`; + } + } + } + + function ProcessLivingStandard(slave, rule) { + if ((rule.livingRules !== undefined) && (rule.livingRules !== "no default setting")) { + if (setup.facilityCareers.includes(slave.assignment)) { + r += ``; // `<br>${slave.slaveName}'s living standards are controlled by her assignment.`; + } else if (((slave.assignment == "be your Head Girl") && (V.HGSuite == 1)) || ((slave.assignment == "guard you") && (V.dojo > 1))) { + r += `<br>${slave.slaveName} has a private room.`; + } else if ((slave.fetish == "mindbroken")) { + if ((slave.livingRules !== "spare")) { + slave.livingRules = "spare"; + r += `<br>Since ${slave.slaveName} is mindbroken her living standard has been set to spare.`; } - break; - case "pregnancy": - if (slave.fetishStrength > 95) { - r += `Pregnancy fetish${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Pregnancy kink${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else if (slave.livingRules !== rule.livingRules) { + if (rule.livingRules !== "luxurious") { + if (V.roomsPopulation <= V.rooms-0.5) { + slave.livingRules = rule.livingRules; + r += `<br>${slave.slaveName}'s living standard has been set to ${rule.livingRules}.`; + if (slave.relationship >= 4) + V.roomsPopulation += 0.5; + else + V.roomsPopulation += 1; + } else { + slave.livingRules = "normal"; + r += `<br>${slave.slaveName}'s living standard has been set to normal, since there is no room for her to occupy.`; + } } else { - r += `Interest in impregnation${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + slave.livingRules = rule.livingRules; + r += `<br>${slave.slaveName}'s living standard has been set to ${rule.livingRules}.`; } - break; - default: - r += `Sexually vanilla${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - break; + } } - r += `</span> `; } - - function long_attraction(slave) { - if (slave.attrXY <= 5) { - r += `<span class="red">Disgusted by men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; - } else if (slave.attrXY <= 15) { - r += `<span class="red">Turned off by men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; - } else if (slave.attrXY <= 35) { - r += `<span class="red">Not attracted to men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; - } else if (slave.attrXY <= 65) { - r += `Indifferent to men${V.summaryStats? `[${slave.attrXY}]` : ''}, `; - } else if (slave.attrXY <= 85) { - r += `<span class="green">Attracted to men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; - } else if (slave.attrXY <= 95) { - r += `<span class="green">Aroused by men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; - } else if (slave.attrXX > 95) { - if (slave.energy <= 95) { - r += `<span class="green">Omnisexual!</span> `; - } else { - r += `<span class="green">Omnisexual nymphomaniac!</span> `; + + function ProcessSpeech(slave, rule) { + if ((rule.speechRules !== undefined) && (rule.speechRules !== "no default setting")) { + if ((slave.fetish == "mindbroken")) { + if ((slave.speechRules !== "restrictive")) { + slave.speechRules = "restrictive"; + r += `<br>Since ${slave.slaveName} is mindbroken her speech rules have been set to restrictive.`; + } + } else if ((slave.speechRules !== rule.speechRules)) { + slave.speechRules = rule.speechRules; + r += `<br>${slave.slaveName}'s speech rules have been set to ${rule.speechRules}.`; } - } else { - r += `<span class="green">Passionate about men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; - } - if (slave.attrXX <= 5) { - r += `<span class="red">disgusted by women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; - } else if (slave.attrXX <= 15) { - r += `<span class="red">turned off by women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; - } else if (slave.attrXX <= 35) { - r += `<span class="red">not attracted to women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; - } else if (slave.attrXX <= 65) { - r += `indifferent to women${V.summaryStats? `[${slave.attrXX}]` : ''}. `; - } else if (slave.attrXX <= 85) { - r += `<span class="green">attracted to women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; - } else if (slave.attrXX <= 95) { - r += `<span class="green">aroused by women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; - } else if (slave.attrXY <= 95) { - r += `<span class="green">passionate about women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; } - if (slave.energy > 95) { - if ((slave.attrXY <= 95) || (slave.attrXX <= 95)) { - r += `<span class="green">Nymphomaniac!</span>`; + } + + function ProcessRelationship(slave, rule) { + if ((slave.fetish !== "mindbroken")) { + if ((rule.relationshipRules !== undefined) && (rule.relationshipRules !== "no default setting")) { + if ((slave.relationshipRules !== rule.relationshipRules )) { + slave.relationshipRules = rule.relationshipRules ; + r += `<br>${slave.slaveName}'s relationship rules have been set to ${rule.relationshipRules}.`; + } } - } else if (slave.energy > 80) { - r += `<span class="green">Powerful sex drive${V.summaryStats? `[${slave.energy}]` : ''}.</span>`; - } else if (slave.energy > 60) { - r += `<span class="green">Good sex drive${V.summaryStats? `[${slave.energy}]` : ''}.</span>`; - } else if (slave.energy > 40) { - r += `<span class="yellow">Average sex drive${V.summaryStats? `[${slave.energy}]` : ''}.</span>`; - } else if (slave.energy > 20) { - r += `<span class="red">Poor sex drive${V.summaryStats? `[${slave.energy}]` : ''}.</span>`; - } else { - r += `<span class="red">No sex drive${V.summaryStats? `[${slave.energy}]` : ''}.</span>`; } - r += " "; } - - function long_smart_fetish(slave) { - if (slave.fetishKnown === 1) { - if (slave.clitSetting === "off") { - r += `SP off.`; - } else if (((slave.fetish !== "submissive") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "submissive")) { - r += `SP: submissive.`; - } else if (((slave.fetish !== "cumslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "oral")) { - r += `SP: oral.`; - } else if (((slave.fetish !== "humiliation") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "humiliation")) { - r += `SP: humiliation.`; - } else if (((slave.fetish !== "buttslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "anal")) { - r += `SP: anal.`; - } else if (((slave.fetish !== "boobs") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "boobs")) { - r += `SP: breasts.`; - } else if (((slave.fetish !== "sadist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "sadist")) { - r += `SP: sadism.`; - } else if (((slave.fetish !== "masochist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "masochist")) { - r += `SP: masochism.`; - } else if (((slave.fetish !== "dom") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "dom")) { - r += `SP: dominance.`; - } else if (((slave.fetish !== "pregnancy") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "pregnancy")) { - r += `SP: pregnancy.`; - } else if ((slave.fetish !== "none") && (slave.clitSetting === "vanilla")) { - r += `SP: vanilla.`; - } else if ((slave.energy <= 95) && (slave.clitSetting === "all")) { - r += `SP: all.`; - } else if ((slave.energy > 5) && (slave.clitSetting === "none")) { - r += `SP: none.`; - } else if (!["women", "men", "anti-women", "anti-men"].includes(slave.clitSetting)) { - r += `SP: monitoring.`; - } - } else { - switch (slave.clitSetting) { - case "off": - r += `SP off.`; - break; - case "submissive": - r += `SP: submissive.`; - break; - case "oral": - r += `SP: oral.`; - break; - case "humiliation": - r += `SP: humiliation.`; - break; - case "anal": - r += `SP: anal.`; - break; - case "boobs": - r += `SP: breasts.`; - break; - case "sadist": - r += `SP: sadism.`; - break; - case "masochist": - r += `SP: masochism.`; - break; - case "dom": - r += `SP: dominance.`; - break; - case "pregnancy": - r += `SP: pregnancy.`; - break; - case "vanilla": - r += `SP: vanilla.`; - break; - case "all": - r += `SP: all.`; - break; - case "none": - r += `SP: none.`; - break; + + function ProcessRelease(slave, rule) { + if ((rule.releaseRules !== undefined) && (rule.releaseRules !== "no default setting")) { + let _release = 0; + if (rule.releaseRules === "restrictive" && + !(["serve the public", "serve in the club", "whore", "work in the brothel", "please you", "serve in the master suite", "be a subordinate slave", "work a glory hole", "be confined in the arcade", "get milked", "work in the dairy", "be your Head Girl"].contains(slave.assignment))) + _release = 1; + else + _release = 1; + if ((slave.fetish == "mindbroken") && (slave.releaseRules !== "permissive")) { + slave.releaseRules = "permissive"; + r += `<br>Since ${slave.slaveName} is mindbroken her masturbation rules have been set to permissive.`; + } else if ((slave.amp === 1 || slave.fuckdoll > 0) && (slave.releaseRules === "masturbation")) { + slave.releaseRules = "restrictive"; + r += `<br>Since ${slave.slaveName} is unable to masturbate, her masturbation rules have been set to restrictive.`; + } else if ((_release !== 0) && (slave.releaseRules !== rule.releaseRules)) { + slave.releaseRules = rule.releaseRules; + r += `<br>${slave.slaveName}'s masturbation rules have been set to ${rule.releaseRules}.`; } } - r += " "; } - - function long_smart_attraction(slave) { - if (slave.attrKnown === 1) { - if ((slave.attrXX < 100) && (slave.clitSetting === "women")) { - r += `SP: women.`; - } else if ((slave.attrXY < 100) && (slave.clitSetting === "men")) { - r += `SP: men.`; - } - } else { - if (slave.clitSetting === "women") { - r += `SP: women.`; - } else if (slave.clitSetting === "men") { - r += `SP: men.`; + + function ProcessPunishment(slave, rule) { + if ((rule.standardPunishment !== undefined) && (rule.standardPunishment !== "no default setting")) { + if ((slave.standardPunishment !== rule.standardPunishment)) { + slave.standardPunishment = rule.standardPunishment ; + r += `<br>${slave.slaveName}'s typical punishment has been updated to ${rule.standardPunishment}.`; } } - r += " "; } - - function long_behavior_flaw(slave) { - r += `<span class="red">`; - switch (slave.behavioralFlaw) { - case "arrogant": - r += `Arrogant.`; - break; - case "bitchy": - r += `Bitchy.`; - break; - case "odd": - r += `Odd.`; - break; - case "hates men": - r += `Hates men.`; - break; - case "hates women": - r += `Hates women.`; - break; - case "gluttonous": - r += `Stress eater.`; - break; - case "anorexic": - r += `Anorexic.`; - break; - case "devout": - r += `Devoutly religious.`; - break; - case "liberated": - r += `Mentally liberated.`; - break; - default: - slave.behavioralFlaw = "none"; - break; + + function ProcessReward(slave, rule) { + if ((rule.standardReward !== undefined) && (rule.standardReward !== "no default setting")) { + if ((slave.standardReward !== rule.standardReward)) { + slave.standardReward = rule.standardReward ; + r += `<br>${slave.slaveName}'s typical reward has been updated to ${rule.standardReward}.`; + } } - r += `</span> `; } - - function long_sex_flaw(slave) { - switch (slave.sexualFlaw) { - case "hates oral": - r += `<span class="red">Hates oral.</span>`; - break; - case "hates anal": - r += `<span class="red">Hates anal.</span>`; - break; - case "hates penetration": - r += `<span class="red">Hates penetration.</span>`; - break; - case "shamefast": - r += `<span class="red">Shamefast.</span>`; - break; - case "idealistic": - r += `<span class="red">Sexually idealistic.</span>`; - break; - case "repressed": - r += `<span class="red">Sexually repressed.</span>`; - break; - case "apathetic": - r += `<span class="red">Sexually apathetic.</span>`; - break; - case "crude": - r += `<span class="red">Sexually crude.</span>`; - break; - case "judgemental": - r += `<span class="red">Sexually judgemental.</span>`; - break; - case "cum addict": - r += `<span class="yellow">Cum addict.</span>`; - break; - case "anal addict": - r += `<span class="yellow">Anal addict.</span>`; - break; - case "attention whore": - r += `<span class="yellow">Attention whore.</span>`; - break; - case "breast growth": - r += `<span class="yellow">Breast obsession.</span>`; - break; - case "abusive": - r += `<span class="yellow">Sexually abusive.</span>`; - break; - case "malicious": - r += `<span class="yellow">Sexually malicious.</span>`; - break; - case "self hating": - r += `<span class="yellow">Self hatred.</span>`; - break; - case "neglectful": - r += `<span class="yellow">Self neglectful.</span>`; - break; - case "breeder": - r += `<span class="yellow">Breeding obsession.</span>`; - break; - default: - slave.sexualFlaw = "none"; - break; + + function ProcessDietCum(slave, rule) { + if ((rule.dietCum !== undefined) && (rule.dietCum !== "no default setting")) { + if (slave.dietCum != rule.dietCum) { + slave.dietCum = rule.dietCum; + if (slave.dietCum == 2) { + r += `<br>${slave.slaveName} has been put on a diet based on cum.`; + slave.dietMilk = 0; + } + if (slave.dietCum == 1) + r += `<br>${slave.slaveName} has had cum added to her diet.`; + else + r += `<br>${slave.slaveName} has had cum removed from her diet.`; + } } - r += " "; } - - function long_behavior_quirk(slave) { - r += `<span class="green">`; - switch (slave.behavioralQuirk) { - case "confident": - r += `Confident.`; - break; - case "cutting": - r += `Cutting.`; - break; - case "funny": - r += `Funny.`; - break; - case "fitness": - r += `Fitness.`; - break; - case "adores women": - r += `Adores women.`; - break; - case "adores men": - r += `Adores men.`; - break; - case "insecure": - r += `Insecure.`; - break; - case "sinful": - r += `Sinful.`; - break; - case "advocate": - r += `Advocate.`; - break; - default: - slave.behavioralQuirk = "none"; - break; + + function ProcessDietMilk(slave, rule) { + if ((rule.dietMilk !== undefined) && (rule.dietMilk !== "no default setting")) { + if (slave.dietMilk != rule.dietMilk) { + slave.dietMilk = rule.dietMilk; + if (slave.dietMilk == 2) { + r += `<br>${slave.slaveName} has been put on a diet based on human milk.`; + slave.dietCum = 0; + } + if (slave.dietMilk == 1) + r += `<br>${slave.slaveName} has had human milk added to her diet.`; + else + r += `<br>${slave.slaveName} has had human milk removed from her diet.`; + } } - r += " "; } - - function long_sex_quirk(slave) { - switch (slave.sexualQuirk) { - case "gagfuck queen": - r += `Gagfuck queen.`; - break; - case "painal queen": - r += `Painal queen.`; - break; - case "strugglefuck queen": - r += `Strugglefuck queen.`; - break; - case "tease": - r += `Tease.`; - break; - case "romantic": - r += `Romantic.`; - break; - case "perverted": - r += `Perverted.`; - break; - case "caring": - r += `Caring.`; - break; - case "unflinching": - r += `Unflinching.`; - break; - case "size queen": - r += `Size queen.`; - break; - default: - slave.sexualQuirk = "none"; - break; + + function ProcessTeeth(slave, rule) { + if ((rule.teeth !== undefined) && (rule.teeth !== "no default setting")) { + if ((rule.teeth == "universal")) { + if ((slave.teeth == "crooked")) { + slave.teeth = "straightening braces"; + V.cash -= V.surgeryCost; + r += `<br>${slave.slaveName} has been given braces for her crooked teeth.`; + } else if ((slave.teeth == "normal")) { + slave.teeth = "cosmetic braces"; + V.cash -= V.surgeryCost; + r += `<br>${slave.slaveName} has been given cosmetic braces.`; + } + } else if ((rule.teeth == "straighten")) { + if ((slave.teeth == "crooked")) { + slave.teeth = "straightening braces"; + V.cash -= V.surgeryCost; + r += `<br>${slave.slaveName} has been given braces for her crooked teeth.`; + } else if ((slave.teeth == "cosmetic braces")) { + slave.teeth = "normal"; + r += `<br>${slave.slaveName} has gotten her braces off, since her teeth are straight.`; + } + } else if ((rule.teeth == "none")) { + if ((slave.teeth == "straightening braces")) { + slave.teeth = "crooked"; + r += `<br>${slave.slaveName} has gotten her braces off.`; + } else if ((slave.teeth == "cosmetic braces")) { + slave.teeth = "normal"; + r += `<br>${slave.slaveName} has gotten her braces off.`; + } + } } - r += `</span> `; } - - function short_extended_family(slave) { - let handled = 0; - if (slave.mother > 0) { - let _ssj = V.slaves.findIndex(function(s) { - return s.ID === slave.mother; - }); - if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s daughter`; - if (slave.relationshipTarget === V.slaves[_ssj].ID) { - if (slave.relationship === 1) { - r += ` & friend`; - } else if (slave.relationship === 2) { - r += ` & BFF`; - } else if (slave.relationship === 3) { - r += ` & FWB`; - } else if (slave.relationship === 4) { - r += ` & lover`; + + function ProcessStyle(slave, rule) { + if (rule.eyeColor !== undefined && (rule.eyeColor !== "no default setting")) { + if ((slave.eyeColor !== rule.eyeColor)) { + slave.eyeColor = rule.eyeColor; + V.cash -= V.modCost; + r += `<br>${slave.slaveName} has been given ${slave.eyeColor} contact lenses.`; + } + } + + if (rule.makeup !== undefined && (rule.makeup !== "no default setting")) { + if ((slave.makeup !== rule.makeup)) { + slave.makeup = rule.makeup; + V.cash -= V.modCost; + r += `<br>${slave.slaveName} has been assigned the standard makeup.`; + } + } + + if ((slave.amp != 1)) { + if (rule.nails !== undefined && (rule.nails !== "no default setting")) { + if ((slave.nails !== rule.nails)) { + slave.nails = rule.nails; + V.cash -= V.modCost; + r += `<br>${slave.slaveName} has been assigned the standard nails.`; + } + } + } + + if (rule.hColor !== undefined && (rule.hColor !== "no default setting")) { + if (slave.bald != 1) { + if ((slave.hColor !== rule.hColor)) { + slave.hColor = rule.hColor; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s hair has been dyed ${rule.hColor}.`; + } + } + } + + if (rule.hStyle !== undefined && (rule.hStyle !== "no default setting")) { + if (slave.bald != 1) { + if ((slave.hStyle !== rule.hStyle)) { + slave.hStyle = rule.hStyle; + V.cash -= V.modCost; + if ((rule.hStyle == "shaved")) { + slave.hLength = 0; + r += `<br>${slave.slaveName}'s hair has been shaved.`; + } else + r += `<br>${slave.slaveName}'s hair has been restyled.`; + } + } + } + + if (rule.hLength !== undefined && (rule.hLength !== "no default setting")) { + if (slave.bald != 1) { + if ((slave.hLength !== rule.hLength)) { + if ((slave.hLength > rule.hLength)) { + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s hair has been cut; it `; } else { - r += ` & wife`; + V.cash -= V.modCost*Math.trunc((rule.hLength-slave.hLength)/10); + r += `<br>${slave.slaveName} has been given extensions; her hair `; } - handled = 1; + r += `is now ${lengthToEitherUnit(rule.hLength)} long.`; + slave.hLength = rule.hLength; } } - r += " "; - } else if (slave.mother === -1) { - r += `Your daughter`; - if (slave.relationship === -3) { - r += ` & wife`; - handled = 1; - } else if (slave.relationship === -2) { - r += ` & lover`; - handled = 1; + } + + if (rule.haircuts !== undefined && (rule.haircuts !== "no default setting")) { + 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.`; + slave.haircuts = 1; + } else if (rule.haircuts === 0 && slave.haircuts !== 0) { + r += `<br>${slave.slaveName}'s hair length will no longer be maintained.`; + slave.haircuts = 0; + } } - r += " "; } - if (slave.father > 0 && slave.father !== slave.mother) { - let _ssj = V.slaves.findIndex(function(s) { - return s.ID === slave.father; - }); - if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s daughter`; - if (slave.relationshipTarget === V.slaves[_ssj].ID && handled !== 1) { - if (slave.relationship === 1) { - r += ` & friend`; - } else if (slave.relationship === 2) { - r += ` & BFF`; - } else if (slave.relationship === 3) { - r += ` & FWB`; - } else if (slave.relationship === 4) { - r += ` & lover`; - } else { - r += ` & wife`; - } - handled = 1; + + if (rule.pubicHColor !== undefined && (rule.pubicHColor !== "no default setting")) { + if (slave.pubicHStyle != "bald" && slave.pubicHStyle != "hairless") { + if ((slave.pubicHColor !== rule.pubicHColor)) { + slave.pubicHColor = rule.pubicHColor; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s pubic hair, if present, has been dyed ${rule.pubicHColor}.`; } } - r += " "; - } else if (slave.father === -1 && slave.mother !== -1) { - r += `Your daughter`; - if (slave.relationship === -3) { - r += ` & wife`; - handled = 1; - } else if (slave.relationship === -2) { - r += ` & lover`; - handled = 1; + } + + if (rule.pubicHStyle !== undefined && (rule.pubicHStyle !== "no default setting")) { + if (slave.pubicHStyle != "bald" && slave.pubicHStyle != "hairless") { + if ((slave.pubicHStyle !== rule.pubicHStyle)) { + slave.pubicHStyle = rule.pubicHStyle; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s pubic hair has been restyled; it is now ${rule.pubicHStyle}.`; + } } } - if (slave.daughters === 1) { - let _ssj = V.slaves.findIndex(function(s) { - return s.mother === slave.ID; - }); - if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s mother`; - if (slave.relationshipTarget === V.slaves[_ssj].ID) { - if (slave.relationship === 1) { - r += ` & friend`; - } else if (slave.relationship === 2) { - r += ` & BFF`; - } else if (slave.relationship === 3) { - r += ` & FWB`; - } else if (slave.relationship === 4) { - r += ` & lover`; + + if (rule.underArmHColor !== undefined && (rule.underArmHColor !== "no default setting")) { + if (slave.underArmHStyle != "bald" && slave.underArmHStyle != "hairless") { + if ((slave.underArmHColor !== rule.underArmHColor)) { + slave.underArmHColor = rule.underArmHColor; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s underarm hair, if present, has been dyed ${rule.underArmHColor}.`; + } + } + } + + if (rule.underArmHStyle !== undefined && (rule.underArmHStyle !== "no default setting")) { + if (slave.underArmHStyle != "bald" && slave.underArmHStyle != "hairless") { + if ((slave.underArmHStyle !== rule.underArmHStyle)) { + slave.underArmHStyle = rule.underArmHStyle; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s underarm hair has been restyled; it is now ${rule.underArmHStyle}.`; + } + } + } + } + + function ProcessPiercings(slave, rule) { + if (rule.nipplesPiercing !== undefined && (rule.nipplesPiercing !== "no default setting")) { + if ((slave.nipplesPiercing !== rule.nipplesPiercing)) { + if ((rule.nipplesPiercing === 0)) { + slave.nipplesPiercing = 0; + r += `<br>${slave.slaveName}'s nipple piercings have been removed.`; + } else if (slave.nipples !== "fuckable") { + slave.nipplesPiercing = rule.nipplesPiercing; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s nipples have been pierced.`; + } else { + r += `<br>${slave.slaveName}'s nipples are inverted and cannot be pierced.`; + } + } + } + + if (rule.areolaePiercing !== undefined && (rule.areolaePiercing !== "no default setting")) { + if ((slave.areolaePiercing !== rule.areolaePiercing)) { + if ((rule.areolaePiercing === 0)) { + slave.areolaePiercing = 0; + r += `<br>${slave.slaveName}'s areolae piercings have been removed.`; + } else { + slave.areolaePiercing = rule.areolaePiercing; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s areolae have been given stud piercings.`; + } + } + } + + if (rule.clitPiercing !== undefined && (rule.clitPiercing !== "no default setting")) { + if ((slave.clitPiercing !== rule.clitPiercing)) { + if ((rule.clitPiercing === 0)) { + slave.clitPiercing = 0; + if (slave.dick > 0) + r += `<br>${slave.slaveName}'s frenulum piercing has been removed.`; + else + r += `<br>${slave.slaveName}'s clit piercing has been removed.`; + + } else if ((slave.vagina != -1) || (slave.dick !== 0)) { + slave.clitPiercing = rule.clitPiercing; + if (slave.dick > 0) + r += `<br>${slave.slaveName}'s frenulum has been pierced.`; + else + r += `<br>${slave.slaveName}'s clit has been pierced.`; + + if (rule.clitPiercing == 3) + V.cash -= 1000; + else + V.cash -= V.modCost; + } + } + } + + if ((slave.vagina != -1)) { + if (rule.vaginaPiercing !== undefined && (rule.vaginaPiercing !== "no default setting")) { + if ((slave.vaginaPiercing !== rule.vaginaPiercing)) { + if ((rule.vaginaPiercing === 0)) { + slave.vaginaPiercing = 0; + r += `<br>${slave.slaveName}'s labia piercings have been removed.`; } else { - r += ` & wife`; + slave.vaginaPiercing = rule.vaginaPiercing; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s pussylips have been pierced.`; } - handled = 1; } } - r += " "; - _ssj = V.slaves.findIndex(function(s) { - return s.father === slave.ID; - }); - if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s father`; - if (slave.relationshipTarget === V.slaves[_ssj].ID && handled !== 1) { - if (slave.relationship === 1) { - r += ` & friend`; - } else if (slave.relationship === 2) { - r += ` & BFF`; - } else if (slave.relationship === 3) { - r += ` & FWB`; - } else if (slave.relationship === 4) { - r += ` & lover`; + } + + if ((slave.dick > 0)) { + if (rule.dickPiercing !== undefined && (rule.dickPiercing !== "no default setting")) { + if ((slave.dickPiercing !== rule.dickPiercing)) { + if ((rule.dickPiercing === 0)) { + slave.dickPiercing = 0; + r += `<br>${slave.slaveName}'s shaft piercings have been removed.`; } else { - r += ` & wife`; + slave.dickPiercing = rule.dickPiercing; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s shaft has been pierced.`; } - handled = 1; } } - r += " "; - } else if (slave.daughters > 1) { - r += `multiple daughters `; } - if (slave.sisters === 1) { - let _ssj = V.slaves.findIndex(function(s) { - return areSisters(s, slave) > 0; - }); - if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s sister`; - if (slave.relationshipTarget === V.slaves[_ssj].ID) { - if (slave.relationship === 1) { - r += ` & friend`; - } else if (slave.relationship === 2) { - r += ` & BFF`; - } else if (slave.relationship === 3) { - r += ` & FWB`; - } else if (slave.relationship === 4) { - r += ` & lover`; - } else { - r += ` & wife`; - } - handled = 1; + + if (rule.anusPiercing !== undefined && (rule.anusPiercing !== "no default setting")) { + if ((slave.anusPiercing !== rule.anusPiercing)) { + if ((rule.anusPiercing === 0)) { + slave.anusPiercing = 0; + r += `<br>${slave.slaveName}'s asshole piercings have been removed.`; + } else { + slave.anusPiercing = rule.anusPiercing; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s asshole has been pierced.`; + } + } + } + + if (rule.lipsPiercing !== undefined && (rule.lipsPiercing !== "no default setting")) { + if ((slave.lipsPiercing !== rule.lipsPiercing)) { + if ((rule.lipsPiercing === 0)) { + slave.lipsPiercing = 0; + r += `<br>${slave.slaveName}'s lip piercings have been removed.`; + } else { + slave.lipsPiercing = rule.lipsPiercing; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s lips have been pierced.`; + } + } + } + + if (rule.tonguePiercing !== undefined && (rule.tonguePiercing !== "no default setting")) { + if ((slave.tonguePiercing !== rule.tonguePiercing)) { + if ((rule.tonguePiercing === 0)) { + slave.tonguePiercing = 0; + r += `<br>${slave.slaveName}'s tongue piercings have been removed.`; + } else { + slave.tonguePiercing = rule.tonguePiercing; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s tongue has been pierced.`; + } + } + } + + if (rule.earPiercing !== undefined && (rule.earPiercing !== "no default setting")) { + if ((slave.earPiercing !== rule.earPiercing)) { + if ((rule.earPiercing === 0)) { + slave.earPiercing = 0; + r += `<br>${slave.slaveName}'s ear piercings have been removed.`; + } else { + slave.earPiercing = rule.earPiercing; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s ears have been pierced.`; + } + } + } + + if (rule.nosePiercing !== undefined && (rule.nosePiercing !== "no default setting")) { + if ((slave.nosePiercing !== rule.nosePiercing)) { + if ((rule.nosePiercing === 0)) { + slave.nosePiercing = 0; + r += `<br>${slave.slaveName}'s nose piercing has been removed.`; + } else { + slave.nosePiercing = rule.nosePiercing; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s nose has been pierced.`; } } - r += " "; - } else if (slave.sisters > 1) { - r += `multiple sisters `; } - if (slave.relationship > 0 && handled !== 1) { - let _ssj = V.slaves.findIndex(function(s) { - return s.ID === slave.relationshipTarget; - }); - if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s`; - switch (slave.relationship) { - case 1: - r += ` friend`; - break; - case 2: - r += ` BFF`; - break; - case 3: - r += ` FWB`; - break; - case 4: - r += ` lover`; - break; - case 5: - r += ` wife`; - break; + + if (rule.eyebrowPiercing !== undefined && (rule.eyebrowPiercing !== "no default setting")) { + if ((slave.eyebrowPiercing !== rule.eyebrowPiercing)) { + if ((rule.eyebrowPiercing === 0)) { + slave.eyebrowPiercing = 0; + r += `<br>${slave.slaveName}'s eyebrow piercings have been removed.`; + } else { + slave.eyebrowPiercing = rule.eyebrowPiercing; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s eyebrows have been pierced.`; } } - } else if (slave.relationship === -3) { - r += `Your wife`; - } else if (slave.relationship === -2) { - r += `E Bonded`; - } else if (slave.relationship === -1) { - r += `E Slut`; } - r += " "; - } - - function short_legacy_family(slave) { - if (slave.relation !== 0) { - let _ssj = V.slaves.findIndex(function(s) { - return s.ID === slave.relationTarget; - }); - if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s ${slave.relation}`; + + if (rule.navelPiercing !== undefined && (rule.navelPiercing !== "no default setting")) { + if ((slave.navelPiercing !== rule.navelPiercing)) { + if ((rule.navelPiercing === 0)) { + slave.navelPiercing = 0; + r += `<br>${slave.slaveName}'s navel piercing have been removed.`; + } else { + slave.navelPiercing = rule.navelPiercing; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s navel has been pierced.`; + } } } - if (slave.relationship > 0) { - let _ssj = V.slaves.findIndex(function(s) { - return s.ID === slave.relationshipTarget; - }); - if (_ssj !== -1) { - switch (slave.relationship) { - case 1: - if (slave.relationshipTarget !== slave.relationTarget) { - r += `${SlaveFullName(V.slaves[_ssj])}'s`; - } else { - r += ` &`; + + if (rule.corsetPiercing !== undefined && (rule.corsetPiercing !== "no default setting")) { + if ((slave.corsetPiercing !== rule.corsetPiercing)) { + if ((rule.corsetPiercing === 0)) { + slave.corsetPiercing = 0; + r += `<br>${slave.slaveName}'s corset piercings have been removed.`; + } else { + slave.corsetPiercing = rule.corsetPiercing; + V.cash -= V.modCost; + r += `<br>${slave.slaveName} has been given a set of corset piercings.`; + } + } + } + } + + function ProcessSmartPiercings(slave, rule) { + if ((slave.clitPiercing == 3)) { + let _used = 0; + if (rule.clitSetting !== undefined && (rule.clitSetting !== "no default setting")) { + if (slave.clitSetting !== rule.clitSetting) { + slave.clitSetting = rule.clitSetting; + _used = 1; + r += `<br>${slave.slaveName}'s smart piercing has been set to ${slave.clitSetting}.`; + } else if (slave.fetishStrength < 100) { + _used = 1; + } + } + if (_used === 0) { + if (rule.clitSettingEnergy !== undefined && (rule.clitSettingEnergy !== "no default setting")) { + if (slave.energy < rule.clitSettingEnergy) { + if (slave.clitSetting !== "all") { + r += `<br>${slave.slaveName}'s smart piercing has been set to enhance libido.`; } - r += ` friend`; - break; - case 2: - if (slave.relationshipTarget !== slave.relationTarget) { - r += `${SlaveFullName(V.slaves[_ssj])}'s`; - } else { - r += ` &`; + slave.clitSetting = "all"; + _used = 1; + } else if (slave.energy >= rule.clitSettingEnergy + 10) { + if (slave.clitSetting !== "none") { + r += `<br>${slave.slaveName}'s smart piercing has been set to suppress libido.`; } - r += ` BFF`; - break; - case 3: - if (slave.relationshipTarget !== slave.relationTarget) { - r += `${SlaveFullName(V.slaves[_ssj])}'s`; - } else { - r += ` &`; + slave.clitSetting = "none"; + _used = 1; + } + } + } + if (_used === 0) { + if (rule.clitSettingXY !== undefined && (rule.clitSettingXY !== "no default setting")) { + if (slave.attrXY < rule.clitSettingXY) { + if (slave.clitSetting !== "men") { + r += `<br>${slave.slaveName}'s smart piercing has been set to encourage attraction to men.`; } - r += ` FWB`; - break; - case 4: - if (slave.relationshipTarget !== slave.relationTarget) { - r += `${SlaveFullName(V.slaves[_ssj])}'s`; - } else { - r += ` &`; + slave.clitSetting = "men"; + _used = 1; + } else if (slave.attrXY >= rule.clitSettingXY + 10) { + if (slave.clitSetting !== "anti-men") { + r += `<br>${slave.slaveName}'s smart piercing has been set to discourage attraction to men.`; } - r += ` lover`; - break; - case 5: - if (slave.relationshipTarget !== slave.relationTarget) { - r += `${SlaveFullName(V.slaves[_ssj])}'s`; - } else { - r += ` &`; + slave.clitSetting = "anti-men"; + _used = 1; + } + } + } + if (_used === 0) { + if (rule.clitSettingXX !== undefined && (rule.clitSettingXX !== "no default setting")) { + if (slave.attrXX < rule.clitSettingXX) { + if (slave.clitSetting !== "women") { + r += `<br>${slave.slaveName}'s smart piercing has been set to encourage attraction to women.`; } - r += ` wife`; - break; + slave.clitSetting = "women"; + _used = 1; + } else if (slave.attrXX >= rule.clitSettingXX + 10) { + if (slave.clitSetting !== "anti-women") { + r += `<br>${slave.slaveName}'s smart piercing has been set to discourage attraction to women.`; + } + slave.clitSetting = "anti-women"; + _used = 1; + } } } - } else if (slave.relationship === -3) { - r += `Your wife`; - } else if (slave.relationship === -2) { - r += `E Bonded`; - } else if (slave.relationship === -1) { - r += `E Slut`; } } - - function short_rival(slave) { - if (slave.rivalry !== 0) { - r += ` `; - let _ssj = V.slaves.findIndex(function(s) { - return s.ID === slave.rivalryTarget; - }); - if (_ssj !== -1) { - r += `<span class="lightsalmon">`; - if (slave.rivalry <= 1) { - r += `Disl ${SlaveFullName(V.slaves[_ssj])}`; - } else if (slave.rivalry <= 2) { - r += `${SlaveFullName(V.slaves[_ssj])}'s rival`; - } else { - r += `Hates ${SlaveFullName(V.slaves[_ssj])}`; + + function ProcessTattoos(slave, rule) { + if (rule.boobsTat !== undefined && (rule.boobsTat !== "no default setting")) { + if ((slave.boobsTat !== rule.boobsTat)) { + slave.boobsTat = rule.boobsTat; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s chest has been tattooed.`; + } + } + + if (rule.buttTat !== undefined && (rule.buttTat !== "no default setting")) { + if ((slave.buttTat !== rule.buttTat)) { + slave.buttTat = rule.buttTat; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s butt has been tattooed.`; + } + } + + if (rule.vaginaTat !== undefined && (rule.vaginaTat !== "no default setting")) { + if ((slave.vaginaTat !== rule.vaginaTat)) { + slave.vaginaTat = rule.vaginaTat; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s abdomen has been tattooed.`; + } + } + + if ((slave.dick > 0)) { + if (rule.dickTat !== undefined && (rule.dickTat !== "no default setting")) { + if ((slave.dickTat !== rule.dickTat)) { + slave.dickTat = rule.dickTat; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s dick has been tattooed.`; } - r += `</span> `; } } - } - - function long_extended_family(slave) { - let handled = 0; - if (slave.mother > 0) { - let _ssj = V.slaves.findIndex(function(s) { - return s.ID === slave.mother; - }); - if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">daughter`; - if (slave.relationshipTarget === V.slaves[_ssj].ID) { - if (slave.relationship === 1) { - r += ` and friend`; - } else if (slave.relationship === 2) { - r += ` and best friend`; - } else if (slave.relationship === 3) { - r += ` and FWB`; - } else if (slave.relationship === 4) { - r += ` and lover`; - } else { - r += ` and wife`; - } - handled = 1; - } - r += `.</span> `; + + if (rule.lipsTat !== undefined && (rule.lipsTat !== "no default setting")) { + if ((slave.lipsTat !== rule.lipsTat)) { + slave.lipsTat = rule.lipsTat; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s face has been tattooed.`; } - } else if (slave.mother === -1) { - r += `Your `; - if (slave.relationship === -3) { - r += `<span class="lightgreen">daughter and wife.</span> `; - handled = 1; - } else if (slave.relationship === -2) { - r += `<span class="lightgreen">daughter and lover.</span> `; - handled = 1; - } else { - r += `<span class="lightgreen">daughter.</span> `; + } + + if (rule.anusTat !== undefined && (rule.anusTat !== "no default setting")) { + if ((slave.anusTat !== rule.anusTat)) { + slave.anusTat = rule.anusTat; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s asshole has been modded.`; } } - if (slave.father > 0 && slave.father !== slave.mother) { - let _ssj = V.slaves.findIndex(function(s) { - return s.ID === slave.father; - }); - if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">daughter`; - if (slave.relationshipTarget === V.slaves[_ssj].ID) { - if (slave.relationship === 1) { - r += ` and friend`; - } else if (slave.relationship === 2) { - r += ` and best friend`; - } else if (slave.relationship === 3) { - r += ` and FWB`; - } else if (slave.relationship === 4) { - r += ` and lover`; - } else { - r += ` and wife`; - } - handled = 1; - } - r += `.</span> `; + + if (rule.shouldersTat !== undefined && (rule.shouldersTat !== "no default setting")) { + if ((slave.shouldersTat !== rule.shouldersTat)) { + slave.shouldersTat = rule.shouldersTat; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s shoulders have been tattooed.`; } - } else if (slave.father === -1 && slave.father !== slave.mother) { - r += `Your `; - if (slave.relationship === -3) { - r += `<span class="lightgreen">daughter and wife.</span> `; - handled = 1; - } else if (slave.relationship === -2) { - r += `<span class="lightgreen">daughter and lover.</span> `; - handled = 1; - } else { - r += `<span class="lightgreen">daughter.</span> `; + } + + if (rule.armsTat !== undefined && (rule.armsTat !== "no default setting")) { + if ((slave.armsTat !== rule.armsTat)) { + slave.armsTat = rule.armsTat; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s arms have been tattooed.`; } } - if (slave.daughters === 1) { - let _ssj = V.slaves.findIndex(function(s) { - return s.mother === slave.ID; - }); - if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">mother`; - if (slave.relationshipTarget === V.slaves[_ssj].ID) { - if (slave.relationship === 1) { - r += ` and friend`; - } else if (slave.relationship === 2) { - r += ` and best friend`; - } else if (slave.relationship === 3) { - r += ` and FWB`; - } else if (slave.relationship === 4) { - r += ` and lover`; - } else { - r += ` and wife`; - } - handled = 1; - } - r += `.</span> `; + + if (rule.legsTat !== undefined && (rule.legsTat !== "no default setting")) { + if ((slave.legsTat !== rule.legsTat)) { + slave.legsTat = rule.legsTat; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s legs have been tattooed.`; } - _ssj = V.slaves.findIndex(function(s) { - return s.father === slave.ID; - }); - if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">father`; - if (slave.relationshipTarget === V.slaves[_ssj].ID) { - if (slave.relationship === 1) { - r += ` and friend`; - } else if (slave.relationship === 2) { - r += ` and best friend`; - } else if (slave.relationship === 3) { - r += ` and FWB`; - } else if (slave.relationship === 4) { - r += ` and lover`; - } else { - r += ` and wife`; - } - handled = 1; + } + + if (rule.stampTat !== undefined && (rule.stampTat !== "no default setting")) { + if ((slave.stampTat !== rule.stampTat)) { + slave.stampTat = rule.stampTat; + V.cash -= V.modCost; + r += `<br>${slave.slaveName}'s lower back has been tattooed.`; + } + } + if ((rule.autoBrand == 1)) { + if ((slave.brand === 0)) { + if ((slave.health > -20)) { + slave.brand = V.brandDesign; + slave.brandLocation = V.brandTarget; + if ((slave.devotion < 18)) + slave.devotion -= 5; + slave.trust -= 5; + slave.health -= 10; + r += `<br>${slave.slaveName} has been branded, with <span class="gold">fear</span>${slave.devotion < 18? `, <span class="mediumorchid">regard,</span>`:``} and <span class="red">health</span> consequences.`; } - r += `.</span> `; } - } else if (slave.daughters > 1) { - if (slave.daughters > 10) { - r += `<span class="lightgreen">Has tons of daughters.</span> `; - } else if (slave.daughters > 5) { - r += `<span class="lightgreen">Has many daughters.</span> `; - } else { - r += `<span class="lightgreen">Has several daughters.</span> `; + } + } + + function ProcessPorn(slave, rule) { + if ((rule.pornFameSpending !== undefined) && (rule.pornFameSpending !== "no default setting")) { + if ((slave.prestige < 3)) { + if ((slave.pornFameSpending !== rule.pornFameSpending)) { + slave.pornFameSpending = rule.pornFameSpending; + r += `<br>${slave.slaveName}'s porn publicity has been corrected.`; + } } } - if (slave.sisters === 1) { - let _ssj = V.slaves.findIndex(function(s) { - return areSisters(s, slave) > 0; - }); - if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">sister`; - if (slave.relationshipTarget === V.slaves[_ssj].ID) { - if (slave.relationship === 1) { - r += ` and friend`; - } else if (slave.relationship === 2) { - r += ` and best friend`; - } else if (slave.relationship === 3) { - r += ` and FWB`; - } else if (slave.relationship === 4) { - r += ` and lover`; - } else { - r += ` and wife`; - } - handled = 1; - } - r += `.</span> `; - } - } else if (slave.sisters > 1) { - if (slave.sisters > 10) { - r += `<span class="lightgreen">One of many sisters.</span> `; - } else if (slave.sisters > 5) { - r += `<span class="lightgreen">Has many sisters.</span> `; - } else { - r += `<span class="lightgreen">Has several sisters.</span> `; - } + } + + function ProcessLabel(slave, rule) { + if (rule.label !== "no default setting" && slave.customLabel !== rule.label) { + slave.customLabel = rule.label; + r += `<br>${slave.slaveName}'s label has been set to ${rule.label}`; + } + } + + return DefaultRules; +})(); + +/*:: Rules Assistant Options [script]*/ +// rewrite of the rules assistant options page in javascript +// uses an object-oriented widget pattern +// wrapped in a closure so as not to polute the global namespace +// the widgets are generic enough to be reusable; if similar user interfaces are ported to JS, we could move the classes to the global scope + +window.rulesAssistantOptions = (function() { + "use strict"; + let V, current_rule; + + function rulesAssistantOptions(element) { + V = State.variables; + V.nextButton = "Back to Main"; + V.nextLink = "Main"; + V.returnTo = "Main"; + V.showEncyclopedia = 1; + V.encyclopedia = "Personal Assistant"; + if (V.currentRule !== null) { + const idx = V.defaultRules.findIndex(rule => rule.ID === V.currentRule); + if (idx === -1) + current_rule = V.defaultRules[0]; + else + current_rule = V.defaultRules[idx]; + } + const root = new Root(element); + } + + function returnP(e) { return e.keyCode === 13; } + + function newRule(root) { + const rule = emptyDefaultRule(); + V.defaultRules.push(rule); + V.currentRule = rule.ID; + reload(root); + } + + function removeRule(root) { + const idx = V.defaultRules.findIndex(rule => rule.ID === current_rule.ID); + V.defaultRules.splice(idx, 1); + if (V.defaultRules.length > 0) { + const new_idx = idx < V.defaultRules.length ? idx : V.defaultRules.length - 1; + V.currentRule = V.defaultRules[new_idx].ID; + } else V.currentRule = null; + reload(root); + } + + function lowerPriority(root) { + if (V.defaultRules.length === 1) return; // nothing to swap with + const idx = V.defaultRules.findIndex(rule => rule.ID === current_rule.ID); + if (idx === 0) return; // no lower rule + arraySwap(V.defaultRules, idx, idx-1); + reload(root); + } + + function higherPriority(root) { + if (V.defaultRules.length === 1) return; // nothing to swap with + const idx = V.defaultRules.findIndex(rule => rule.ID === current_rule.ID); + if (idx === V.defaultRules.length - 1) return; // no higher rule + arraySwap(V.defaultRules, idx, idx+1); + reload(root); + } + + function changeName(name, root) { + if (name === current_rule.name) return; + current_rule.name = name; + reload(root); + } + + // reload the passage + function reload(root) { + const elem = root.element; + elem.innerHTML = ""; + rulesAssistantOptions(elem); + } + + const parse = { + integer(string) { + let n = parseInt(string, 10); + return isNaN(n)? 0: n; + }, + boobs(string) { + return Math.clamp(parse.integer(string), 0, 48000); + }, + butt(string) { + return Math.clamp(parse.integer(string), 0, 20); + }, + lips(string) { + return Math.clamp(parse.integer(string), 0, 100); + }, + dick(string) { + return Math.clamp(parse.integer(string), 0, 30); + }, + balls(string) { + return Math.clamp(parse.integer(string), 0, 125); + }, + }; + + // the Element class wraps around a DOM element and adds extra functionality + // this is safer than extending DOM objects directly + // it also turns DOM manipulation into an implementation detail + class Element { + constructor(...args) { + this.parent = null; + this.element = this.render(...args); + this.children = []; + } + + appendChild(child) { + child.parent = this; + this.children.push(child); + this.element.appendChild(child.element); } - if (slave.relationship > 0 && handled !== 1) { - let _ssj = V.slaves.findIndex(function(s) { - return s.ID === slave.relationshipTarget; - }); - if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s `; - switch (slave.relationship) { - case 1: - r += `<span class="lightgreen">friend.</span> `; - break; - case 2: - r += `<span class="lightgreen">best friend.</span> `; - break; - case 3: - r += `<span class="lightgreen">FWB.</span> `; - break; - case 4: - r += `<span class="lightgreen">lover.</span> `; - break; - case 5: - r += `<span class="lightgreen">slave wife.</span> `; - break; - } - } - } else if (slave.relationship === -3) { - r += `<span class="lightgreen">Your wife.</span> `; - } else if (slave.relationship === -2) { - r += `<span class="lightgreen">Emotionally bonded to you.</span> `; - } else if (slave.relationship === -1) { - r += `<span class="lightgreen">Emotional slut.</span> `; + + // return the first argument to simplify creation of basic container items + render(...args) { + return args[0]; + } + + remove() { + const idx = this.parent.children.findIndex(child => child === this); + this.parent.children.slice(idx, 1); + this.element.remove(); } } - function long_legacy_family(slave) { - if (slave.relation !== 0) { - let _ssj = V.slaves.findIndex(function(s) { - return s.ID === slave.relationTarget; - }); - if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s `; - if (slave.relationshipTarget !== slave.relationTarget) { - r += `<span class="lightgreen">${slave.relation}</span>. `; - } else { - r += `<span class="lightgreen">${slave.relation}</span> `; - } - if (slave.relationship <= 0) { - r += ` `; - } + class Section extends Element { + constructor(header, hidden=false) { + super(header); + this.hidey = this.element.querySelector("div"); + if (hidden) this.toggle_hidey(); + } + + render(header) { + const section = document.createElement("section"); + section.classList.add("rajs-section"); + const h1 = document.createElement("h1"); + h1.onclick = () => { this.toggle_hidey(); }; + h1.innerHTML = header; + const hidey = document.createElement("div"); + section.appendChild(h1); + section.appendChild(hidey); + return section; + } + + appendChild(child) { + child.parent = this; + this.children.push(child); + this.hidey.appendChild(child.element); + } + + toggle_hidey() { + switch(this.hidey.style.display) { + case "none": + this.hidey.style.display = "initial"; + break; + default: + this.hidey.style.display = "none"; + break; } } - if (slave.relationship > 0) { - let _ssj = V.slaves.findIndex(function(s) { - return s.ID === slave.relationshipTarget; - }); - if (_ssj !== -1) { - switch (slave.relationship) { - case 1: - if (slave.relationshipTarget !== slave.relationTarget) { - r += `${SlaveFullName(V.slaves[_ssj])}'s `; - } else { - r += ` and `; - } - r += `<span class="lightgreen">friend.</span> `; - break; - case 2: - if (slave.relationshipTarget !== slave.relationTarget) { - r += `${SlaveFullName(V.slaves[_ssj])}'s `; - } else { - r += ` and `; - } - r += `<span class="lightgreen">best friend.</span> `; - break; - case 3: - if (slave.relationshipTarget !== slave.relationTarget) { - r += `${SlaveFullName(V.slaves[_ssj])}'s `; - } else { - r += ` and `; - } - r += `<span class="lightgreen">FWB.</span> `; - break; - case 4: - if (slave.relationshipTarget !== slave.relationTarget) { - r += `${SlaveFullName(V.slaves[_ssj])}'s `; - } else { - r += ` and `; - } - r += `<span class="lightgreen">lover.</span> `; - break; - case 5: - if (slave.relationshipTarget !== slave.relationTarget) { - r += `${SlaveFullName(V.slaves[_ssj])}'s`; - } else { - r += ` and `; - } - r += `<span class="lightgreen">slave wife.</span> `; - break; - } + } + + // list of clickable elements + // has a short explanation (the prefix) and a value display + // value display can optionally be an editable text input field + // it can be "bound" to a variable by setting its "onchange" method + class List extends Element { + constructor(prefix, data=[], textinput=false) { + super(prefix + ": ", textinput); + this.selectedItem = null; + data.forEach(item => this.appendChild(new ListItem(...item))); + } + + render(prefix, textinput) { + const elem = document.createElement("div"); + const label = document.createElement("span"); + label.innerHTML = prefix; + let value; + if (textinput) { + value = document.createElement("input"); + value.setAttribute("type", "text"); + value.classList.add("rajs-value"); // + // call the variable binding when the input field is no longer being edited, and when the enter key is pressed + value.onblur = () => {this.inputEdited(); }; + value.onkeypress = (e) => { if (returnP(e)) this.inputEdited(); }; + } else { + value = document.createElement("strong"); } - } else if (slave.relationship === -3) { - r += `<span class="lightgreen">Your wife.</span> `; - } else if (slave.relationship === -2) { - r += `<span class="lightgreen">Emotionally bonded to you.</span> `; - } else if (slave.relationship === -1) { - r += `<span class="lightgreen">Emotional slut.</span> `; + this.value = value; + elem.appendChild(label); + elem.appendChild(value); + elem.classList.add("rajs-list"); + return elem; + } + + inputEdited() { + if (this.selectedItem) this.selectedItem.deselect(); + this.propagateChange(); + } + + selectItem(item) { + if (this.selectedItem) this.selectedItem.deselect(); + this.selectedItem = item; + this.setValue(item.data); + this.propagateChange(); + } + + setValue(what) { + if (this.value.tagName === "INPUT") + this.value.value = ""+what; + else + this.value.innerHTML = ""+what; + } + + getData(what) { + return (this.value.tagName === "INPUT" ? this.parse(this.value.value): this.selectedItem.data); + } + + // customisable input field parser / sanity checker + parse(what) { return what; } + + propagateChange() { + if (this.onchange instanceof Function) + this.onchange(this.getData()); } } - - function long_rival(slave) { - if (slave.rivalry !== 0) { - r += ` `; - let _ssj = V.slaves.findIndex(function(s) { - return s.ID === slave.rivalryTarget; - }); - if (_ssj !== -1) { - if (slave.rivalry <= 1) { - r += `<span class="lightsalmon">Dislikes</span> ${SlaveFullName(V.slaves[_ssj])}.`; - } else if (slave.rivalry <= 2) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightsalmon">rival.</span>`; - } else { - r += `<span class="lightsalmon">Hates</span> ${SlaveFullName(V.slaves[_ssj])}.`; - } - } - r += " "; + + // a clickable item of a list + class ListItem extends Element { + constructor(displayvalue, data) { + super(displayvalue); + this.data = data !== undefined ? data: displayvalue; + this.selected = false; + } + + render(displayvalue) { + const elem = document.createElement("span"); + elem.classList.add("rajs-listitem"); + elem.innerHTML = displayvalue; + elem.onclick = () => { return this.select(); }; + return elem; + } + + select() { + if (this.selected) return false; + this.parent.selectItem(this); + this.element.classList.add("selected"); + this.selected = true; + return true; + } + + deselect() { + this.element.classList.remove("selected"); + this.selected = false; } } - - function long_clothes(slave) { - switch (slave.clothes) { - case "attractive lingerie": - r += `Lingerie.`; - break; - case "a succubus outfit": - r += `Succubus outfit.`; - break; - case "a string bikini": - r += `String bikini.`; - break; - case "a scalemail bikini": - r += `Scalemail bikini.`; - break; - case "a monokini": - r += `Monokini.`; - break; - case "an apron": - r += `Apron.`; - break; - case "a cybersuit": - r += `Cybersuit.`; - break; - case "cutoffs and a t-shirt": - r += `Cutoffs, t-shirt.`; - break; - case "a slutty outfit": - r += `Slutty outfit.`; - break; - case "uncomfortable straps": - r += `Leather straps.`; - break; - case "a fallen nuns habit": - r += `Slutty habit.`; - break; - case "a chattel habit": - r += `Chattel habit.`; - break; - case "a penitent nuns habit": - r += `Cilice.`; - break; - case "slutty jewelry": - r += `Bangles.`; - break; - case "attractive lingerie for a pregnant woman": - r += `Preggo lingerie.`; - break; - case "a maternity dress": - r += `Maternity dress.`; - break; - case "stretch pants and a crop-top": - r += `Stretch pants, crop-top.`; - break; - case "harem gauze": - r += `Harem outfit.`; - break; - case "a slave gown": - r += `Slave gown.`; - break; - case "a halter top dress": - r += `Halter top dress.`; - break; - case "a mini dress": - r += `Mini dress.`; - break; - case "a ball gown": - r += `Ball gown.`; - break; - case "slutty business attire": - r += `Slutty suit.`; - break; - case "nice business attire": - r += `Nice suit.`; - break; - case "a comfortable bodysuit": - r += `Bodysuit.`; - break; - case "a military uniform": - r += `Military uniform.`; - break; - case "a schutzstaffel uniform": - r += `Schutzstaffel uniform.`; - break; - case "a slutty schutzstaffel uniform": - r += `Slutty Schutzstaffel uniform.`; - break; - case "a red army uniform": - r += `Red Army uniform.`; - break; - case "a long qipao": - r += `Long Qipao.`; - break; - case "battlearmor": - r += `Battlearmor.`; - break; - case "a mounty outfit": - r += `Mounty outfit.`; - break; - case "a dirndl": - r += `Dirndl.`; - break; - case "lederhosen": - r += `Lederhosen.`; - break; - case "a biyelgee costume": - r += `Biyelgee costume.`; - break; - case "a leotard": - r += `Leotard.`; - break; - case "a bunny outfit": - r += `Bunny outfit.`; - break; - case "a slutty maid outfit": - r += `Slutty maid.`; - break; - case "a nice maid outfit": - r += `Nice maid.`; - break; - case "a slutty nurse outfit": - r += `Slutty nurse.`; - break; - case "a nice nurse outfit": - r += `Nice nurse.`; - break; - case "a schoolgirl outfit": - r += `Schoolgirl outfit.`; - break; - case "a kimono": - r += `Kimono.`; - break; - case "a hijab and abaya": - r += `Hijab and abaya.`; - break; - case "battledress": - r += `Battledress.`; - break; - case "a latex catsuit": - r += `Nice latex.`; - break; - case "restrictive latex": - r += `Bondage latex.`; - break; - case "conservative clothing": - r += `Conservative clothing.`; - break; - case "chains": - r += `Chains.`; - break; - case "a cheerleader outfit": - r += `Cheerleader.`; - break; - case "clubslut netting": - r += `Netting.`; - break; - case "shibari ropes": - r += `Shibari.`; - break; - case "Western clothing": - r += `Chaps.`; - break; - case "body oil": - r += `Body oil.`; - break; - case "a toga": - r += `Toga.`; - break; - case "a huipil": - r += `Huipil.`; - break; - case "a slutty qipao": - r += `Qipao.`; - break; - case "spats and a tank top": - r += `Spats, tank top.`; - break; - default: - r += `Naked.`; - break; + + // a way to organise lists with too many elements in subsections + // children are bound to the master list + class ListSubSection extends Element { + constructor(parent, label, pairs) { + super(label); + this.parent = parent; + pairs.forEach(item => this.appendChild(new ListItem(...item))); + } + + render(label) { + const elem = document.createElement("div"); + const lelem = document.createElement("em"); + lelem.innerText = label + ": "; + elem.appendChild(lelem); + return elem; + } + + appendChild(child) { + super.appendChild(child); + child.parent = this.parent; + this.parent.children.push(child); } - r += " "; } - function long_collar(slave) { - switch (slave.collar) { - case "uncomfortable leather": - r += `Leather collar.`; - break; - case "tight steel": - r += `Steel collar.`; - break; - case "preg biometrics": - r += `Pregnancy biometrics collar.`; - break; - case "cruel retirement counter": - r += `Cruel counter collar.`; - break; - case "shock punishment": - r += `Shock collar.`; - break; - case "dildo gag": - r += `Dildo gag.`; - break; - case "massive dildo gag": - r += `Throat-bulging dildo gag.`; - break; - case "neck corset": - r += `Neck corset.`; - break; - case "stylish leather": - r += `Stylish leather collar.`; - break; - case "satin choker": - r += `Satin choker.`; - break; - case "silk ribbon": - r += `Silken ribbon.`; - break; - case "heavy gold": - r += `Gold collar.`; - break; - case "bowtie": - r += `Bowtie collar.`; - break; - case "pretty jewelry": - r += `Pretty collar.`; - break; - case "nice retirement counter": - r += `Nice counter collar.`; - break; - case "leather with cowbell": - r += `Cowbell collar.`; - break; - case "ancient Egyptian": - r += `Wesekh.`; - break; - case "ball gag": - r += `Ball gag.`; - break; - case "bit gag": - r += `Bit gag.`; - break; - case "porcelain mask": - r += `Porcelain mask.`; - break; + // similar to list, but is just a collection of buttons + class Options extends Element { + constructor(elements=[]) { + super(); + elements.forEach(element => { this.appendChild(element); }); + } + + render() { + const elem = document.createElement("div"); + elem.classList.add("rajs-list"); + return elem; } - r += " "; } - - function long_belly(slave) { - switch (slave.bellyAccessory) { - case "shapewear": - r += `Shapewear.`; - break; - case "a small empathy belly": - r += `Small fake belly.`; - break; - case "a medium empathy belly": - r += `Medium fake belly.`; - break; - case "a large empathy belly": - r += `Large fake belly.`; - break; - case "a huge empathy belly": - r += `Huge fake belly.`; - break; - case "a corset": - r += `Corset.`; - break; - case "an extreme corset": - r += `Extreme corsetage.`; - break; + + // options equivalent of ListItem + class OptionsItem extends Element { + constructor(label, onclick) { + super(label); + this.label = label; + this.onclick = onclick; + } + render(label, onclick) { + const elem = document.createElement("span"); + elem.classList.add("rajs-listitem"); + elem.innerHTML = label; + elem.onclick = () => { return this.onclick(this); }; + return elem; } - r += " "; } - - function long_legs(slave) { - if (slave.legAccessory === "short stockings") { - r += `Short stockings.`; - } else if (slave.legAccessory === "long stockings") { - r += `Long stockings.`; + + class ButtonList extends Element { + render(label) { + const elem = document.createElement("div"); + const labelel = document.createElement("span"); + labelel.innerHTML = label += ": "; + elem.appendChild(labelel); + return elem; + } + + getSelection() { + return (this.children + .filter(child => child.selected) + .map(child => child.setvalue) + ); + } + + onchange() { return; } + } + + class ButtonItem extends Element { + constructor(label, setvalue, selected=false) { + super(label, selected); + this.selected = selected; + this.setvalue = setvalue ? setvalue : label; + } + + render(label, selected) { + const container = document.createElement("div"); + container.classList.add("rajs-listitem"); + + const labelel = document.createElement("span"); + labelel.innerHTML = label; + + const button = document.createElement("input"); + button.setAttribute("type", "checkbox"); + button.checked = selected; + button.onchange = () => this.onchange(button.checked); + labelel.onclick = () => button.click(); + + container.appendChild(labelel); + container.appendChild(button); + + return container; + } + + onchange(value) { + this.selected = value; + this.parent.onchange(this); + } + } + + // rule import field + class NewRuleField extends Element { + constructor(root) { + super(); + this.root = root; + } + + render() { + let element = document.getElementById("importfield"); + if (element !== null) { return element; } + const container = document.createElement("div"); + container.id = "importfield"; + const textarea = document.createElement("textarea"); + textarea.placeholder = "Paste your rule here"; + container.appendChild(textarea); + this.textarea = textarea; + const button = document.createElement("button"); + button.name = "Load"; + button.innerHTML = "Load"; + button.onclick = () => { this.loadNewRule(); }; + container.appendChild(button); + return container; + } + + loadNewRule() { + const text = this.textarea.value; + try { + const rule = JSON.parse(text); + if (rule instanceof Array) + rule.forEach(r => V.defaultRules.push(r)); + else + V.defaultRules.push(rule); + reload(this.root); + } catch (e) { + alert("Couldn't import that rule:\n" + e.message); + } + } + } + + // the base element, parent of all elements + class Root extends Element { + constructor(element) { + super(element); + if(V.defaultRules.length === 0) { + const paragraph = document.createElement("p"); + paragraph.innerHTML = "<strong>No rules</strong>"; + this.appendChild(new Element(paragraph)); + this.appendChild(new NoRules(this)); + return; + } + this.appendChild(new RuleSelector(this)); + this.appendChild(new RuleOptions(this)); + this.appendChild(new ConditionEditor(this)); + this.appendChild(new EffectEditor(this)); + } + + render(element) { + const greeting = document.createElement("p"); + greeting.innerHTML = `<em>${properTitle()}, I will review your slaves and make changes that will have a beneficial effect. Apologies, ${properTitle()}, but this function is... not fully complete. It may have some serious limitations. Please use the 'no default setting' option to identify areas I should not address.</em>`; + element.appendChild(greeting); + return element; + } + } + + // optoins displayed when there are no rules + class NoRules extends Options { + constructor(root) { + super(); + this.root = root; + const newrule = new OptionsItem("Add a new rule", () => { newRule(this.root); }); + this.appendChild(newrule); + const importrule = new OptionsItem("Import a rule", () => { this.root.appendChild(new NewRuleField(this.root)); }); + this.appendChild(importrule); } - r += " "; } - - function long_shoes(slave) { - if (slave.shoes === "heels") { - r += `Heels.`; - } else if (slave.shoes === "pumps") { - r += `Pumps.`; - } else if (slave.shoes === "extreme heels") { - r += `Extreme heels.`; - } else if (slave.shoes === "boots") { - r += `Boots.`; - } else if (slave.heels === 1) { - r += `<span class="yellow">Crawling.</span>`; - } else if (slave.shoes === "flats") { - r += `Flats.`; + + // buttons for selecting the current rule + class RuleSelector extends List { + constructor(root) { + super("Current rule", V.defaultRules.map(i => [i.name, i])); + this.setValue(current_rule.name); + this.onchange = function (rule) { + V.currentRule = rule.ID; + reload(root); + }; } - r += " "; } - - function long_vaginal_acc(slave) { - switch (slave.vaginalAccessory) { - case "chastity belt": - r += `Vaginal chastity.`; - break; - case "combined chastity": - r += `Combined chastity.`; - break; - case "anal chastity": - r += `Anal chastity.`; - break; - case "dildo": - r += `Vaginal dildo.`; - break; - case "large dildo": - r += `Large vaginal dildo.`; - break; - case "huge dildo": - r += `Huge vaginal dildo.`; - break; - case "long dildo": - r += `Long vaginal dildo.`; - break; - case "long, large dildo": - r += `Long and large vaginal dildo.`; - break; - case "long, huge dildo": - r += `Long and wide vaginal dildo.`; - break; + + // buttons for doing transformations on rules + class RuleOptions extends Options { + constructor(root) { + super(); + this.appendChild(new OptionsItem("New Rule", () => newRule(root))); + this.appendChild(new OptionsItem("Remove Rule", () => removeRule(root))); + this.appendChild(new OptionsItem("Apply rules", () => this.appendChild(new ApplicationLog()))); + this.appendChild(new OptionsItem("Lower Priority", () => lowerPriority(root))); + this.appendChild(new OptionsItem("Higher Priority", () => higherPriority(root))); + this.appendChild(new OptionsItem("Rename", () => this.appendChild(new RenameField(root)))); + this.appendChild(new OptionsItem("Export this rule", () => this.appendChild(new ExportField(current_rule)))); + this.appendChild(new OptionsItem("Export all rules", () => this.appendChild(new ExportField(...V.defaultRules)))); + this.appendChild(new OptionsItem("Import rule(s)", () => this.appendChild(new NewRuleField(root)))); } - r += " "; } - - function long_dick_acc(slave) { - if (slave.dickAccessory === "chastity") { - r += `Chastity cage.`; - } else if (slave.dickAccessory === "combined chastity") { - r += `Combined chastity.`; - } else if (slave.dickAccessory === "anal chastity") { - r += `Anal chastity.`; + + class ApplicationLog extends Element { + render() { + const elem = document.querySelector("#application-log") || document.createElement("div"); + elem.id = "application-log"; + clearSummaryCache(); + elem.innerHTML = V.slaves.map(slave => DefaultRules(slave)).join(""); + return elem; } - r += " "; } - - function long_buttplug(slave) { - switch (slave.buttplug) { - case "plug": - r += `Buttplug.`; - break; - case "large plug": - r += `Large buttplug.`; - break; - case "huge plug": - r += `Huge buttplug.`; - break; - case "long plug": - r += `Long buttplug.`; - break; - case "long, large plug": - r += `Large, long buttplug.`; - break; - case "long, huge plug": - r += `Enormous buttplug.`; - break; + + class RenameField extends Element { + constructor(root) { + super(); + this.element.onblur = () => changeName(this.element.value, root); + this.element.onkeypress = (e) => { if (returnP(e)) changeName(this.element.value, root); }; } - r += " "; - switch (slave.buttplugAttachment) { - case "tail": - r += `Attached tail. `; - break; + + render() { + const elem = document.createElement("input"); + elem.setAttribute("type", "text"); + elem.setAttribute("value", current_rule.name); + return elem; } } - - function rules_assistant(slave) { - if (slave.useRulesAssistant === 0) { - r += `<span class="lightgreen">RA-Exempt</span> `; - } else if (V.abbreviateRulesets === 2 && (slave.currentRules !== undefined) && (slave.currentRules.length > 0)) { - r += `Rules: ${V.defaultRules.filter(x => ruleApplied(slave, x)).map(x => x.name).join(", ") }`; + + class ExportField extends Element { + render(...args) { + let element = document.getElementById("exportfield"); + if (element === null) { + element = document.createElement("textarea"); + element.id = "exportfield"; + } + element.value = JSON.stringify(args, null, 2); + return element; } } - - function origins(slave) { - r += `<br>`; - if (V.seeImages !== 1 || V.seeSummaryImages !== 1 || V.imageChoice === 1) { - r += ` `; + + // parent section for condition editing + class ConditionEditor extends Section { + constructor() { + super("Activation Condition"); + this.appendChild(new ConditionFunction()); + this.appendChild(new AssignmentInclusion()); + this.appendChild(new SpecialExclusion()); + this.appendChild(new SpecificInclusionExclusion()); } - r += `<span class="gray">${slave.origin}</span>`; } - - return SlaveSummaryUncached; -})(); - -/*:: colorModeJS [script]*/ -window.setColors = function(colorMap){ - let styleSheetArray = Array.from(document.styleSheets); - styleSheetArray.forEach( styleSheet => { - let cssRules = Array.from(styleSheet.cssRules); - cssRules.forEach( cssRule => { - if ( cssRule.type === 1 ){ - let color = cssRule.style.color; - let bgcolor = cssRule.style.backgroundColor; - if ( - color != "" && - color != "inherit" ){ - cssRule.style.color = colorMap[color] || color; - console.log('color: ',color); - } - if ( - bgcolor != "" && - bgcolor != "inherit" && - bgcolor != "transparent" ){ - cssRule.style.backgroundColor = colorMap[bgcolor] || bgcolor; - console.log('color: ',color); - } - } - }); - }); -} + class ConditionFunction extends Element { + constructor() { + super(); + const items = [ + ["Never", false], + ["Always", true], + ["Custom", "custom"], + ["Devotion", "devotion"], + ["Trust", "trust"], + ["Health", "health"], + ["Sex drive", "energy"], + ["Weight", "weight"], + ["Age", "actualAge"], + ["Body Age", "physicalAge"], + ["Visible Age", "visualAge"], + ["Muscles", "muscles"], + ["Lactation", "lactation"], + ["Pregnancy", "preg"], + ["Pregnancy Multiples", "pregType"], + ["Belly Implant", "bellyImplant"], + ["Belly Size", "belly"], + ["Education", "intelligenceImplant"], + ["Intelligence", "intelligence"], + ["Fetish", "fetish"], + ["Accent", "accent"], + ["Waist", "waist"], + ["Amputation", "amp"], + ]; + this.fnlist = new List("Activation function", items); + this.fnlist.setValue(current_rule.condition.function === "between" ? current_rule.condition.data.attribute : current_rule.condition.function); + this.fnlist.onchange = (value) => this.fnchanged(value); + this.appendChild(this.fnlist); + this.fneditor = null; -/*:: HTAG Macro JS [script]*/ + switch(current_rule.condition.function) { + case false: + case true: + break; + case "custom": + this.show_custom_editor(CustomEditor, current_rule.condition.data); + break; + case "between": + this.show_custom_editor(RangeEditor, current_rule.condition.function, current_rule.condition.data); + break; + case "belongs": + this.show_custom_editor(ItemEditor, current_rule.condition.function, current_rule.condition.data); + break; + } + } + + betweenP(attribute) { + return [ + "devotion", + "trust", + "health", + "energy", + "weight", + "actualAge", + "physicalAge", + "visualAge", + "muscles", + "lactation", + "preg", + "pregType", + "bellyImplant", + "belly", + "intelligenceImplant", + "intelligence", + "accent", + "waist", + ].includes(attribute); + } -/* - * <<htag>> macro - * A simple macro which allows to create wrapping html elements with dynamic IDs. - * idea blatantly robbed from the spanMacroJS.tw but expanded to a more generic - * case, allowing <div>, <button> or whatever you want. elements, default is for - * the div though. In addition, you can pass an object in as the first argument - * instead of an id, and each of the object's attributes will become attributes - * of the generate tag. - * - * Usage: <<htag id>>...<</htag>> - * Usage: <<htag id tag>>...<</htag>> - * Usage: <<htag atributes>>...<</htag>> - * Usage: <<htag atributes tag>>...<</htag>> - */ -Macro.add('htag', { - tags: null, - handler() { - const payload = this.payload[0].contents.replace(/(^\n+|\n+$)/, ''); - let htag = 'div'; - let attributes; - function munge (val, key) { - return key + '="' + val + '"'; + belongsP(attribute) { + return [ + "fetish", + "amp", + ].includes(attribute); } - - if (1 > this.args.length) - return this.error('invalid syntax, format: <<htag [id [ tag ] | attributes [ tag ] >>'); - if (1 < this.args.length) - htag = String(this.args[1]).trim(); - if ("object" === typeof this.args[0]) - attributes = $.map(this.args[0], munge).join(" "); - else - attributes = 'id="' + String(this.args[0]).trim() + '"'; - if (Config.debug) - this.debugView.modes({block: true}); - - jQuery('<' + htag + ' ' + attributes + ' />') - .wiki(payload) - .appendTo(this.output); - } -}); -/*:: Quick List [script]*/ + show_custom_editor(what, ...args) { + if (this.custom_editor !== null) this.hide_custom_editor(); + this.custom_editor = new what(...args); + this.appendChild(this.custom_editor); + } -window.sortDomObjects = function (objects, attrName, reverse = 0) { - reverse = (reverse) ? -1 : 1; - function sortingByAttr (a, b) { - var aVal = a.getAttribute(attrName); - var bVal = b.getAttribute(attrName); - var aInt = parseInt(aVal); - if (!isNaN(aInt)) - return ((parseInt(bVal) - aInt) * reverse); - else if (bVal > aVal) - return -1 * reverse; - return ((aVal == bVal) ? 0 : 1) * reverse; - } - return objects.toArray().sort(sortingByAttr); -}; + hide_custom_editor() { + if (this.custom_editor) { + this.custom_editor.remove(); + this.custom_editor = null; + } + } -window.sortButtonsByDevotion = function () { - var $sortedButtons = $('#qlWrapper button').remove(); - $sortedButtons = sortDomObjects($sortedButtons, 'data-devotion'); - $($sortedButtons).appendTo($('#qlWrapper')); - quickListBuildLinks(); -}; + render() { + const elem = document.createElement("div"); + return elem; + } -window.sortButtonsByTrust = function () { - var $sortedButtons = $('#qlWrapper button').remove(); - $sortedButtons = sortDomObjects($sortedButtons, 'data-trust'); - $($sortedButtons).appendTo($('#qlWrapper')); - quickListBuildLinks(); -}; + fnchanged(value) { + if (this.fneditor !== null) { + this.fneditor.element.remove(); + this.fneditor = null; + } + if (value === true || value === false) { + current_rule.condition.function = value; + current_rule.condition.data = {}; + this.hide_custom_editor(); + } else if (value === "custom") { + current_rule.condition.function = "custom"; + current_rule.condition.data = ""; + this.show_custom_editor(CustomEditor, current_rule.condition.data); + } else if (this.betweenP(value)) { + current_rule.condition.function = "between"; + current_rule.condition.data = { attribute: value, value: [null, null] }; + this.show_custom_editor(RangeEditor, current_rule.condition.function, current_rule.condition.data); + } else if (this.belongsP(value)) { + current_rule.condition.function = "belongs"; + current_rule.condition.data = { attribute: value, value: [] }; + this.show_custom_editor(ItemEditor, current_rule.condition.function, current_rule.condition.data); + } + } + } -window.quickListBuildLinks = function () { - $("[data-scroll-to]").click(function() { - var $this = $(this), $toElement = $this.attr('data-scroll-to'); - // note the * 1 enforces $offset to be an integer, without - // it we scroll to True, which goes nowhere fast. - var $offset = $this.attr('data-scroll-offset') * 1 || 0; - var $speed = $this.attr('data-scroll-speed') * 1 || 500; - // Use javascript scrollTop animation for in page navigation. - $('html, body').animate({ - scrollTop: $($toElement).offset().top + $offset - }, $speed); - }); -}; + class CustomEditor extends Element { + constructor(data) { + if (data.length === 0) data = "(slave) => slave.slaveName === 'Fancy Name'"; + super(data); + } -window.sortIncubatorPossiblesByName = function () { - var $sortedIncubatorPossibles = $('#qlIncubator div.possible').detach(); - $sortedIncubatorPossibles = sortDomObjects($sortedIncubatorPossibles, 'data-name'); - $($sortedIncubatorPossibles).appendTo($('#qlIncubator')); -}; + render(data) { + const elem = document.createElement("div"); + const textarea = document.createElement("textarea"); + textarea.innerHTML = data; + textarea.onblur = () => current_rule.condition.data = textarea.value; + elem.appendChild(textarea); + const explanation = document.createElement("div"); + explanation.innerHTML = "Insert a valid <a target='_blank' class='link-external' href='https://www.w3schools.com/js/js_comparisons.asp'>JavaScript comparison and/or logical operation</a>."; + elem.appendChild(explanation); + return elem; + } + } -window.sortIncubatorPossiblesByPregnancyWeek = function () { - var $sortedIncubatorPossibles = $('#qlIncubator div.possible').detach(); - $sortedIncubatorPossibles = sortDomObjects($sortedIncubatorPossibles, 'data-preg-week'); - $($sortedIncubatorPossibles).appendTo($('#qlIncubator')); -}; + class RangeEditor extends Element { + render(fn, data) { + const elem = document.createElement("div"); -window.sortIncubatorPossiblesByPregnancyCount = function () { - var $sortedIncubatorPossibles = $('#qlIncubator div.possible').detach(); - $sortedIncubatorPossibles = sortDomObjects($sortedIncubatorPossibles, 'data-preg-count'); - $($sortedIncubatorPossibles).appendTo($('#qlIncubator')); -}; + const minlabel = document.createElement("label"); + minlabel.innerHTML = "Lower bound: "; + elem.appendChild(minlabel); -window.sortIncubatorPossiblesByReservedSpots = function () { - var $sortedIncubatorPossibles = $('#qlIncubator div.possible').detach(); - $sortedIncubatorPossibles = sortDomObjects($sortedIncubatorPossibles, 'data-reserved-spots'); - $($sortedIncubatorPossibles).appendTo($('#qlIncubator')); -}; + const min = document.createElement("input"); + min.setAttribute("type", "text"); + min.value = "" + data.value[0]; + min.onkeypress = e => { if (returnP(e)) this.setmin(min.value); }; + min.onblur = e => this.setmin(min.value); + this.min = min; + elem.appendChild(min); -window.sortIncubatorPossiblesByPreviousSort = function () { - var sort = State.variables.sortIncubatorList; - console.log(State.variables); - console.log('sort', sort); - if ('unsorted' !== sort) { - console.log("sort isn't unsorted", sort); - if ('Name' === sort) { - console.log("sort is name", sort); - sortIncubatorPossiblesByName(); - } else if ('Reserved Incubator Spots' === sort) { - console.log("sort is spots", sort); - sortIncubatorPossiblesByReservedSpots(); - } else if ('Pregnancy Week' === sort) { - console.log("sort is week", sort); - sortIncubatorPossiblesByPregnancyWeek(); - } else if ('Number of Children' === sort) { - console.log("sort is count", sort); - sortIncubatorPossiblesByPregnancyCount(); - } - } -}; + elem.appendChild(document.createElement("br")); -/*:: DefaultRules [script]*/ -// this code applies RA rules onto slaves + const maxlabel = document.createElement("label"); + maxlabel.innerHTML = "Upper bound: "; + elem.appendChild(maxlabel); -window.DefaultRules = (function() { - "use strict"; - let V; - let r; + const max = document.createElement("input"); + max.setAttribute("type", "text"); + max.value = "" + data.value[1]; + max.onkeypress = e => { if (returnP(e)) this.setmax(max.value); }; + max.onblur = e => this.setmax(max.value); + this.max = max; + elem.appendChild(max); - function DefaultRules(slave) { - if (slave.useRulesAssistant === 0) return r; //exempted - - V = State.variables; - r = ""; - let rule = MergeRules(slave); - if (Object.keys(rule).length === 0) return r; // no rules apply + const infobar = document.createElement("div"); + infobar.innerHTML = this.info(data.attribute); + elem.appendChild(infobar); - AssignJobToSlave(slave, rule); - if(slave.fuckdoll === 0) { - ProcessClothing(slave, rule); - ProcessCollar(slave, rule); - ProcessEyewear(slave, rule); - ProcessDildos(slave, rule); - ProcessDickAccessories(slave, rule); - ProcessAnalAccessories(slave, rule); - ProcessShoes(slave, rule); - ProcessBellyAccessories(slave, rule); - ProcessLegAccessory(slave, rule); + return elem; } - ProcessBellyImplant(slave, rule); - if (isFertile(slave)) - ProcessContraceptives(slave, rule); - ProcessOtherDrugs(slave, rule); - ProcessAssetGrowthDrugs(slave, rule); - ProcessDiet(slave, rule); - ProcessCuratives(slave, rule); - ProcessAphrodisiacs(slave, rule); - ProcessPenisHormones(slave, rule); - ProcessFemaleHormones(slave, rule); - ProcessPregnancyDrugs(slave, rule); - if(slave.fuckdoll === 0) { - ProcessLivingStandard(slave, rule); - ProcessSpeech(slave, rule); - ProcessRelationship(slave, rule); - ProcessRelease(slave, rule); - ProcessPunishment(slave, rule); - ProcessReward(slave, rule); + + parse(value) { + value = value.trim(); + if (value === "null") value = null; + else { + value = parseInt(value); + if (isNaN(value)) value = null; + } + return value; } - ProcessDietCum(slave, rule); - ProcessDietMilk(slave, rule); - ProcessTeeth(slave, rule); - ProcessStyle(slave, rule); - ProcessPiercings(slave, rule); - ProcessSmartPiercings(slave, rule); - ProcessTattoos(slave, rule); - ProcessPorn(slave, rule); - return r; - } - function MergeRules(slave) { - // merge all rules applying on a slave into one big 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)))); - } + setmin(value) { + current_rule.condition.data.value[0] = this.parse(value); + this.min.value = ""+current_rule.condition.data.value[0]; + } - 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": - delete rule.setAssignment; - break; - - case "rest": - case "please you": - // slaves always qualify for this assignment - break; + setmax(value) { + current_rule.condition.data.value[1] = this.parse(value); + this.max.value = ""+current_rule.condition.data.value[1]; + } - case "live with your Head Girl": - if ((V.HGSuiteSlaves < 1 && slave.indentureRestrictions <= 0)) - break; - else { - RAFacilityRemove(slave, rule); // before deleting rule.setAssignment - delete rule.setAssignment; - } - break; + info(attribute) { + return ({ + "devotion": "Very Hateful: (-∞, -95), Hateful: [-95, -50), Resistant: [-50, -20), Ambivalent: [-20, 20], Accepting: (20, 50], Devoted: (50, 95], Worshipful: (95, ∞)", + "trust": "Extremely terrified: (-∞, -95), Terrified: [-95, -50), Frightened: [-50, -20), Fearful: [-20, 20], Careful: (20, 50], Trusting: (50, 95], Total trust: (95, ∞)", + "health": "Death: (-∞, -100), Near Death: [-100, -90), Extremely Unhealthy: [-90, -50), Unhealthy: [-50, -20), Healthy: [-20, 20], Very Healthy: (20, 50], Extremely Healthy: (50, 90], Unnaturally Healthy: (90, ∞)", + "energy": "Frigid: (-∞, 20], Poor: (20, 40], Average: (40, 60], Powerful: (60, 80], Sex Addict: (80, 100), Nympho: 100", + "weight": "Emaciated: (-∞, -95), Skinny: [-95, -30), Thin: [-30, -10), Average: [-10, 10], Plush: (10, 30], Fat: (30, 95], Overweight: (95, ∞)", + "lactation": "None: 0, 1: Natural, 2: Lactation implant", + "preg": "Barren: -2, On contraceptives: -1, Not pregnant: 0, Pregnancy weeks: [1, ∞)", + "pregType": "Fetus count, known only after the 10th week of pregnancy", + "bellyImplant": "Volume in CCs. None: -1", + "belly": "Volume in CCs, any source", + "intelligenceImplant": "Education level. 0: uneducated, 1: educated, (0, 1): incomplete education.", + "intelligence": "From moronic to brilliant: [-3, 3]", + "accent": "No accent: 0, Nice accent: 1, Bad accent: 2, Can't speak language: 3 and above", + "waist": "Masculine waist: (95, ∞), Ugly waist: (40, 95], Unattractive waist: (10, 40], Average waist: [-10, 10], Feminine waist: [-40, -10), Wasp waist: [-95, 40), Absurdly narrow: (-∞, -95)", + }[attribute] || " "); + } + } - case "be confined in the arcade": - if ((V.arcadeSlaves < V.arcade && slave.indentureRestrictions <= 0 && slave.breedingMark != 1)) - break; - else { - RAFacilityRemove(slave, rule); // before deleting rule.setAssignment - delete rule.setAssignment; - } - break; + class ItemEditor extends Element { + render(fn, data) { + const elem = document.createElement("div"); - case "serve in the master suite": - if ((V.masterSuiteSlaves < V.masterSuite && (slave.devotion > 20 || slave.trust < -50 || (slave.devotion >= -50 && slave.trust < -20)))) - break; - else { - RAFacilityRemove(slave, rule); // before deleting rule.setAssignment - delete rule.setAssignment; - } - break; + const input = document.createElement("input"); + input.setAttribute("type", "text"); + input.value = JSON.stringify(data.value); + input.onkeypress = e => { if (returnP(e)) this.setValue(input); }; + input.onblur = e => this.setValue(input); + this.input = input; + elem.appendChild(input); - case "get treatment in the clinic": - if ((V.clinicSlaves < V.clinic && (slave.health < 20 || (slave.chem > 15 && V.Nurse !== 0 && V.clinicUpgradeFilters == 1)) || ((slave.bellyImplant > -1) && (V.bellyImplants == 1)) || slave.preg > 1)) - break; - else { - RAFacilityRemove(slave, rule); // before deleting rule.setAssignment - delete rule.setAssignment; - } - break; + const infobar = document.createElement("div"); + infobar.innerHTML = this.info(data.attribute); + elem.appendChild(infobar); - case "rest in the spa": - if ((V.spaSlaves < V.spa) && (slave.health < 20) || (slave.trust < 60) || (slave.devotion <= 60) || (slave.fetish == "mindbroken") && (slave.devotion >= -20)) - break; - else { - RAFacilityRemove(slave,rule); // before deleting rule.setAssignment - delete rule.setAssignment; - } - break; + return elem; + } - case "work in the brothel": - if ((V.brothelSlaves < V.brothel && (slave.devotion > 50 || slave.trust > 50 || slave.trust < -50 || (slave.devotion >= -50 && slave.trust < -20)) && slave.breedingMark != 1)) - break; - else { - RAFacilityRemove(slave, rule); // before deleting rule.setAssignment - delete rule.setAssignment; - } - break; + info(attribute) { + return "Insert a valid JSON array. Known values: " + { + "fetish": "buttslut, cumslut, masochist, sadist, dom, submissive, boobs, pregnancy, none (AKA vanilla)", + "amp": "Amputated: 1, Not amputated: 0", + }[attribute]; + } + + setValue(input) { + try { + const arr = JSON.parse(input.value); + current_rule.condition.data.value = arr; + input.value = JSON.stringify(arr); + } catch (e) { + alert(e); + } + } + } - case "serve in the club": - if ((V.clubSlaves < V.club && (slave.devotion > 50 || slave.trust > 50 || slave.trust < -50 || (slave.devotion >= -50 && slave.trust < -20)) && slave.breedingMark != 1)) - break; - else { - RAFacilityRemove(slave, rule); // before deleting rule.setAssignment - delete rule.setAssignment; - } - break; - case "work in the dairy": - if ((V.dairy > V.dairySlaves+V.bioreactorsXY+V.bioreactorsXX+V.bioreactorsHerm+V.bioreactorsBarren)) { - if ((slave.indentureRestrictions > 0) && (V.dairyRestraintsSetting > 1)) - break; - else if (((slave.indentureRestrictions > 1) && (V.dairyRestraintsSetting > 0)) || (slave.breedingMark == 1 && V.dairyRestriantsSettings > 0) || ((V.dairyPregSetting > 0) && ((slave.bellyImplant != -1) || (slave.broodmother !== 0)))) - break; - else { - if ((slave.lactation > 0 || ((V.dairySlimMaintainUpgrade === 0 || V.dairySlimMaintain === 0) && (slave.boobs > 300 || slave.dick === 0 || V.dairyImplantsSetting == 1) && V.dairyImplantsSetting != 2)) || (slave.balls > 0)) { - if ((slave.devotion > 20) || ((slave.devotion >= -50) && (slave.trust < -20)) || (slave.trust < -50) || (slave.amp == 1) || (V.dairyRestraintsUpgrade == 1)) { - if ((V.dairyStimulatorsSetting < 2) || (slave.anus > 2) || (V.dairyPrepUpgrade == 1)) { - if ((V.dairyPregSetting < 2) || (slave.vagina > 2) || (slave.ovaries === 0) || (V.dairyPrepUpgrade == 1)) - break; - else { - RAFacilityRemove(slave,rule); // before deleting rule.setAssignment - delete rule.setAssignment; - } - } else { - RAFacilityRemove(slave,rule); // before deleting rule.setAssignment - delete rule.setAssignment; - } - } else { - RAFacilityRemove(slave,rule); // before deleting rule.setAssignment - delete rule.setAssignment; - } - } else { - RAFacilityRemove(slave,rule); // before deleting rule.setAssignment - delete rule.setAssignment; - } - } - } - break; + class AssignmentInclusion extends ButtonList { + constructor() { + super("Apply to assignments and facilities"); + const items = ["Rest", "Fucktoy", "Subordinate Slave", "House Servant", "Confined", "Whore", "Public Servant", "Classes", "Milked", "Gloryhole"]; + if (V.HGSuite > 0) items.push("Head Girl Suite"); + if (V.brothel > 0) items.push("Brothel"); + if (V.club > 0) items.push("Club"); + if (V.arcade > 0) items.push("Arcade"); + if (V.dairy > 0) items.push("Dairy"); + if (V.servantsQuarters > 0) items.push("Servant Quarters"); + if (V.masterSuite > 0) items.push("Master Suite"); + if (V.schoolroom > 0) items.push("Schoolroom"); + if (V.spa > 0) items.push("Spa"); + if (V.clinic > 0) items.push("Clinic"); + if (V.cellblock > 0) items.push("Cellblock"); + items.forEach( + i => this.appendChild(new ButtonItem(i, this.getAttribute(i), current_rule.condition.assignment.includes(this.getAttribute(i))))); + } - case "work as a servant": - if ((V.servantsQuartersSlaves < V.servantsQuarters && canSee(slave) && canWalk(slave) && (slave.devotion >= -20 || slave.trust < -20 || (slave.devotion >= -50 && slave.trust <= 20)))) - break; - else { - RAFacilityRemove(slave,rule); // before deleting rule.setAssignment - delete rule.setAssignment; - } - break; + onchange() { + current_rule.condition.assignment = this.getSelection(); + } - case "learn in the schoolroom": - if ((V.schoolroomSlaves < V.schoolroom && slave.fetish != "mindbroken" && (slave.devotion >= -20 || slave.trust < -50 || (slave.devotion >= -50 && slave.trust < -20)))) - if ((slave.intelligenceImplant < 1) || (slave.voice !== 0 && slave.accent+V.schoolroomUpgradeLanguage > 2) || (slave.oralSkill <= 10+V.schoolroomUpgradeSkills*20) || (slave.whoreSkill <= 10+V.schoolroomUpgradeSkills*20) || (slave.entertainSkill <= 10+V.schoolroomUpgradeSkills*20) || (slave.analSkill < 10+V.schoolroomUpgradeSkills*20) || ((slave.vagina >= 0) && (slave.vaginalSkill < 10+V.schoolroomUpgradeSkills*20))) - break; - else { - RAFacilityRemove(slave,rule); // before deleting rule.setAssignment - delete rule.setAssignment; - } - else { - RAFacilityRemove(slave,rule); // before deleting rule.setAssignment - delete rule.setAssignment; - } - break; + getAttribute(what) { + return { + "Rest": "rest", + "Fucktoy": "please you", + "Subordinate Slave": "be a subordinate slave", + "House Servant": "be a servant", + "Confined": "stay confined", + "Whore": "whore", + "Public Servant": "serve the public", + "Classes": "take classes", + "Milked": "get milked", + "Gloryhole": "work a glory hole", + "Head Girl Suite": "live with your Head Girl", + "Brothel": "work in the brothel", + "Club": "serve in the club", + "Arcade": "be confined in the arcade", + "Dairy": "work in the dairy", + "Servant Quarters": "work as a servant", + "Master Suite": "serve in the master suite", + "Schoolroom": "learn in the schoolroom", + "Spa": "rest in the spa", + "Clinic": "get treatment in the clinic", + "Cellblock": "be confined in the cellblock", + }[what]; + } + } + + class SpecialExclusion extends List { + constructor() { + const items = [ + ["Yes", true], + ["No", false] + ]; + super("Exclude special slaves", items); + this.setValue(current_rule.condition.excludeSpecialSlaves); + this.onchange = (value) => current_rule.condition.excludeSpecialSlaves = value; + } + } - case "be confined in the cellblock": - if ((V.cellblockSlaves < V.cellblock && ((slave.devotion < -20 && slave.trust >= -20) || (slave.devotion < -50 && slave.trust >= -50)))) - break; - else { - RAFacilityRemove(slave,rule); // before deleting rule.setAssignment - delete rule.setAssignment; - } - break; + class SpecificInclusionExclusion extends Options { + constructor() { + super(); + this.appendChild(new OptionsItem("Limit to specific slaves", () => this.show_slave_selection())); + this.appendChild(new OptionsItem("Exclude specific slaves", () => this.show_slave_exclusion())); + this.subwidget = null; + } - case "take classes": - if (slave.intelligenceImplant !== 1 && slave.fetish != "mindbroken" && (slave.devotion >= -20 || slave.trust < -50 || (slave.trust < -20 && slave.devotion >= -50))) - break; - else - delete rule.setAssignment; - break; + show_slave_selection() { + if (this.subwidget) this.subwidget.remove(); + this.subwidget = new SlaveSelection(); + this.appendChild(this.subwidget); + } - case "choose her own job": - if ((slave.fetish != "mindbroken")) - break; - else - delete rule.setAssignment; - break; + show_slave_exclusion() { + if (this.subwidget) this.subwidget.remove(); + this.subwidget = new SlaveExclusion(); + this.appendChild(this.subwidget); + } + } - case "get milked": - if ((slave.lactation > 0 || slave.balls > 0)) - break; - else - delete rule.setAssignment; - break; + class SlaveSelection extends ButtonList { + constructor() { + super("Include specific slaves"); + V.slaves.forEach(slave => this.appendChild(new ButtonItem( + [slave.slaveName, slave.slaveSurname].join(" "), + slave.ID, + current_rule.condition.selectedSlaves.includes(slave.ID)))); + } - case "be a servant": - if ((canWalk(slave) && canSee(slave) && (slave.devotion >= -20 || slave.trust < -50 || (slave.trust < -20 && slave.devotion >= -50)))) - break; - else - delete rule.setAssignment; - break; + onchange() { + current_rule.condition.selectedSlaves = this.getSelection(); + } + } - case "work a glory hole": - if (slave.indentureRestrictions <= 0 && slave.breedingMark != 1) - break; - else - delete rule.setAssignment; - break; + class SlaveExclusion extends ButtonList { + constructor() { + super("Exclude specific slaves"); + V.slaves.forEach(slave => this.appendChild(new ButtonItem( + [slave.slaveName, slave.slaveSurname].join(" "), + slave.ID, + current_rule.condition.excludedSlaves.includes(slave.ID)))); + } - case "whore": - case "serve the public": - case "stay confined": - if ((slave.fuckdoll === 0) && slave.breedingMark != 1) - break; - else - delete rule.setAssignment; - break; + onchange() { + current_rule.condition.excludedSlaves = this.getSelection(); + } + } - default: - r += `<span class="red">raWidgets missing case for assignment 'V.{rule.setAssignment}'</span>.`; - break; + // parent section for effect editing + 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()); + } + + render() { + const element = document.createElement("div"); + return element; } - return 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 == "choose her own job" && !slave.choosesOwnAssignment) || rule.setAssignment != slave.assignment)) { - switch (rule.setAssignment) { - case "live with your Head Girl": - r += `<br>${slave.slaveName} has been automatically assigned to live in your Head Girl's private suite.`; - break; - case "be confined in the arcade": - r += `<br>${slave.slaveName} has been automatically assigned to be confined in ${V.arcadeName}.`; - break; - case "serve in the master suite": - r += `<br>${slave.slaveName} has been automatically assigned to ${V.masterSuiteName}.`; - break; - case "get treatment in the clinic": - r += `<br>${slave.slaveName} has been automatically assigned to get treatment in ${V.clinicName}.`; - break; - case "rest in the spa": - r += `<br>${slave.slaveName} has been automatically assigned to rest in ${V.spaName}.`; - break; - case "work in the brothel": - r += `<br>${slave.slaveName} has been automatically assigned to work in ${V.brothelName}.`; - break; - case "serve in the club": - r += `<br>${slave.slaveName} has been automatically assigned to serve in ${V.clubName}.`; - break; - case "work in the dairy": - r += `<br>${slave.slaveName} has been automatically assigned to be milked in ${V.dairyName}.`; - break; - case "work as a servant": - r += `<br>${slave.slaveName} has been automatically assigned to work in ${V.servantsQuartersName}.`; - break; - case "learn in the schoolroom": - r += `<br>${slave.slaveName} has been automatically assigned to study in ${V.schoolroomName}.`; - break; - case "be confined in the cellblock": - r += `<br>${slave.slaveName} has been automatically assigned to be confined in ${V.cellblockName}.`; - break; - case "choose her own job": - r += `<br>${slave.slaveName} is now allowed to select her own assignments.`; - break; - default: - r += `<br>${slave.slaveName} has been automatically assigned to ${rule.setAssignment}.`; - break; - } - assignJob(slave, rule.setAssignment); + class AppearanceSection extends Section { + constructor() { + super("Appearance Settings"); + this.appendChild(new ClothesList()); + this.appendChild(new CollarList()); + this.appendChild(new ShoeList()); + this.appendChild(new CorsetList()); + this.appendChild(new LeggingsList()); + this.appendChild(new VagAccVirginsList()); + this.appendChild(new VagAccAVirginsList()); + this.appendChild(new VagAccOtherList()); + if (V.seeDicks !== 0 || V.makeDicks !== 0) { + this.appendChild(new DickAccVirginsList()); + this.appendChild(new DickAccOtherList()); } + this.appendChild(new ButtplugsVirginsList()); + this.appendChild(new ButtplugsOtherList()); + this.appendChild(new ImplantVolumeList()); + this.appendChild(new AutosurgerySwitch()); + } } - function ProcessClothing(slave, rule) { - // apply clothes to slave - if ((rule.clothes !== undefined) && (rule.clothes !== "no default setting")) { - if ((rule.clothes == "choosing her own clothes")) { - if ((slave.choosesOwnClothes === 0)) { - slave.clothes = "choosing her own clothes"; - slave.choosesOwnClothes = 1; - r += `<br>${slave.slaveName} is now allowed to choose her own clothes.`; - } - } else if ((slave.clothes !== rule.clothes)) { - slave.clothes = rule.clothes; - slave.choosesOwnClothes = 0; - r += `<br>${slave.slaveName} is now wearing ${slave.clothes}.`; - } + class RegimenSection extends Section { + constructor() { + super("Physical Regimen Settings"); + this.appendChild(new GrowthList()); + this.appendChild(new CurrativesList()); + this.appendChild(new AphrodisiacList()); + this.appendChild(new ContraceptiveList()); + if (V.pregSpeedControl) + this.appendChild(new PregDrugsList()); + this.appendChild(new FemaleHormonesList()); + this.appendChild(new ShemaleHormonesList()); + this.appendChild(new GeldingHormonesList()); + this.appendChild(new OtherDrugsList()); + this.appendChild(new DietList()); + this.appendChild(new DietGrowthList()); + this.appendChild(new DietBaseList()); + this.appendChild(new MuscleList()); + this.appendChild(new BraceList()); } } - function ProcessCollar(slave, rule) { - // apply collar to slave - if ((rule.collar !== undefined) && (rule.collar != "no default setting")) { - if ((slave.collar !== rule.collar)) { - r += '<br>'; - if ((rule.collar == "preg biometrics" && slave.preg <= -1)) { - slave.collar = "none"; - r += `${slave.slaveName} cannot utilize preg biometrics.`; - } else if ((rule.collar == "massive dildo gag" && slave.oralSkill <= 50)) { - slave.collar = "none"; - r += `${slave.slaveName} lacks the oral skill to successfully keep the massive dildo gag in her throat.`; - } else - slave.collar = rule.collar; - if ((slave.collar == "none")) - r += `${slave.slaveName} has been given no collar.`; - else - r += `${slave.slaveName} has been given a ${slave.collar} collar.`; - } + class BehaviourSection extends Section { + constructor() { + super("Behavior Settings"); + this.appendChild(new AutomaticAssignmentList()); + this.appendChild(new LivingStandardList()); + this.appendChild(new PunishmentList()); + this.appendChild(new RewardList()); + this.appendChild(new ReleaseList()); + this.appendChild(new SmartFetishList()); + this.appendChild(new SmartXYAttractionList()); + this.appendChild(new SmartXXAttractionList()); + this.appendChild(new SmartEnergyList()); + this.appendChild(new SpeechList()); + this.appendChild(new RelationshipList()); + if (V.studio === 1) + this.appendChild(new PornList()); + } + } + + class OtherSection extends Section { + constructor() { + super("Other Settings"); + this.appendChild(new LabelList()); + } + } + + class CosmeticSection extends Section { + constructor() { + super("Cosmetic Settings", true); + this.appendChild(new EyewearList()); + this.appendChild(new LensesList()); + this.appendChild(new MakeupList()); + this.appendChild(new NailsList()); + this.appendChild(new HairLengthList()); + this.appendChild(new HaircutsList()); + this.appendChild(new HairColourList()); + this.appendChild(new HairStyleList()); + this.appendChild(new PubicHairColourList()); + this.appendChild(new PubicHairStyleList()); + this.appendChild(new ArmpitHairColourList()); + this.appendChild(new ArmpitHairStyleList()); } } - function ProcessEyewear(slave, rule) { - // apply glasses, contacts to slave - if ((rule.eyewear !== undefined) && (rule.eyewear !== "no default setting")) { - switch (rule.eyewear) { - case "correct with glasses": - if (slave.eyes == -1) { - if (slave.eyewear != "corrective glasses") { - slave.eyewear = "corrective glasses"; - V.cash -= V.modCost; - r += `<br>${slave.slaveName} has been given corrective glasses.`; - } - } else { - if (slave.eyewear != "none") { - slave.eyewear = "none"; - r += `<br>${slave.slaveName}'s eyewear has been removed.`; - } - } - break; - - case "correct with contacts": - if (slave.eyes == -1) { - if (slave.eyewear != "corrective contacts") { - slave.eyewear = "corrective contacts"; - V.cash -= V.modCost; - r += `<br>${slave.slaveName} has been given corrective contacts.`; - } - } else { - if (slave.eyewear != "none") { - slave.eyewear = "none"; - r += `<br>${slave.slaveName}'s eyewear has been removed.`; - } - } - break; - - case "blur with glasses": - if (slave.eyes > -1) { - if (slave.eyewear != "blurring glasses") { - slave.eyewear = "blurring glasses"; - V.cash -= V.modCost; - r += `<br>${slave.slaveName} has been given blurring glasses.`; - } - } else { - if (slave.eyewear != "none") { - slave.eyewear = "none"; - r += `<br>${slave.slaveName}'s eyewear has been removed.`; - } - } - break; - - case "blur with contacts": - if (slave.eyes > -1) { - if (slave.eyewear != "blurring contacts") { - slave.eyewear = "blurring contacts"; - V.cash -= V.modCost; - r += `<br>${slave.slaveName} has been given blurring contacts.`; - } - } else { - if (slave.eyewear != "none") { - slave.eyewear = "none"; - r += `<br>${slave.slaveName}'s eyewear has been removed.`; - } - } - break; + class BodyModSection extends Section { + constructor() { + super("Body Mod Settings", true); + this.appendChild(new EarPiercingList()); + this.appendChild(new NosePiercingList()); + this.appendChild(new EyebrowPiercingList()); + this.appendChild(new NavelPiercingList()); + this.appendChild(new NipplePiercingList()); + this.appendChild(new AreolaPiercingList()); + this.appendChild(new LipPiercingList()); + this.appendChild(new TonguePiercingList()); + this.appendChild(new ClitPiercingList()); + this.appendChild(new LabiaPiercingList()); + this.appendChild(new ShaftPiercingList()); + this.appendChild(new PerineumPiercingList()); + this.appendChild(new CorsetPiercingList()); - case "universal glasses": - if (slave.eyes == -1) { - if (slave.eyewear != "corrective glasses") { - slave.eyewear = "corrective glasses"; - V.cash -= V.modCost; - r += `<br>${slave.slaveName} has been given corrective glasses.`; - } - } else { - if (slave.eyewear != "glasses") { - slave.eyewear = "glasses"; - V.cash -= V.modCost; - r += `<br>${slave.slaveName} has been given decorative glasses.`; - } - } - break; + this.appendChild(new AutoBrandingList()); + this.appendChild(new BrandingLocationList()); + this.appendChild(new BrandDesignList()); - default: - if (slave.eyewear != "none") { - slave.eyewear = "none"; - r += `<br>${slave.slaveName}'s eyewear has been removed.`; - } - break; - } + this.appendChild(new FaceTattooList()); + this.appendChild(new ShoulderTattooList()); + this.appendChild(new ChestTattooList()); + this.appendChild(new ArmTattooList()); + this.appendChild(new UpperBackTattooList()); + this.appendChild(new LowerBackTattooList()); + this.appendChild(new AbdomenTattooList()); + if (V.seeDicks || V.makeDicks) + this.appendChild(new DickTattooList()); + this.appendChild(new ButtockTattooList()); + this.appendChild(new AnalTattooList()); + this.appendChild(new LegTattooList()); } } - function ProcessDildos(slave, rule) { - // apply vaginal dildos to slave - if (slave.vagina === 0) - ProcessVVirginDildos(slave, rule); - else if ((slave.vagina > 0) && (slave.anus === 0)) - ProcessAVirginDildos(slave, rule); - else if (slave.vagina > 0) - ProcessNonVirginDildos(slave, rule); + class AutosurgerySection extends Section { + constructor() { + super("Autosurgery Settings", true); + this.appendChild(new VisionSurgeryList()); + this.appendChild(new LactationSurgeryList()); + if (V.seeDicks || V.makeDicks) { + this.appendChild(new SemenSurgeryList()); + this.appendChild(new VasectomyList()); + } + this.appendChild(new CosmeticSurgeryList()); + this.appendChild(new LipSurgeryList()); + this.appendChild(new ButtSurgeryList()); + this.appendChild(new BreastSurgeryList()); + this.appendChild(new TighteningSurgeryList()); + this.appendChild(new BodyHairSurgeryList()); + this.appendChild(new HairSurgeryList()); + if (V.bellyImplants > 0) + this.appendChild(new BellyImplantList()); + } } - function ProcessVVirginDildos(slave, rule) { - // apply vaginal dildos to varginal virgins - if ((rule.virginAccessory !== undefined) && (rule.virginAccessory !== "no default setting")) { - if (slave.vaginalAccessory !== rule.virginAccessory) { - slave.vaginalAccessory = rule.virginAccessory; - switch (slave.vaginalAccessory) { - case "huge dildo": - r += `<br>${slave.slaveName} is a virgin and has been given a`; - if (slave.vagina >= 2) - r += `massive dildo to permanently gape her cunt.`; - else { - r += `large dildo for her pussy, since it must be stretched before it can accommodate a huge one.`; - slave.vaginalAccessory = "large dildo"; - } - break; - - case "long dildo": - if (slave.breedingMark == 1) { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length dildo for her pussy.`; - slave.vaginalAccessory = "dildo"; - } - break; - - case "long, large dildo": - if (slave.breedingMark == 1) { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length large dildo for her pussy.`; - slave.vaginalAccessory = "large dildo"; - } - break; + class ClothesList extends List { + constructor() { + const items = [ + ["Select her own outfit", "choosing her own clothes"] + ]; + super("Clothes", items); - case "long, huge dildo": - if (slave.breedingMark == 1) { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length huge dildo for her pussy.`; - slave.vaginalAccessory = "huge dildo"; - } else { - r += `<br>slave.slaveName is a virgin and has been given a`; - if (slave.vagina >= 2) - r += `massive and oversized dildo to permanently gape her cunt.`; - else { - r += `long, large dildo for her pussy, since it must be stretched before it can accommodate a huge one.`; - slave.vaginalAccessory = "long, large dildo"; - } - } - break; + const nclothes = [ + ["No default clothes setting", "no default setting"], + ["Apron", "an apron"], + ["Bangles", "slutty jewelry"], + ["Bodysuit", "a comfortable bodysuit"], + ["Cheerleader outfit", "a cheerleader outfit"], + ["Clubslut netting", "clubslut netting"], + ["Cybersuit", "a cybersuit"], + ["Cutoffs and a t-shirt", "cutoffs and a t-shirt"], + ["Fallen nun", "a fallen nuns habit"], + ["Halter top", "a halter top dress"], + ["Hijab and abaya", "a hijab and abaya"], + ["Latex catsuit", "a latex catsuit"], + ["Leotard", "a leotard"], + ["Long Qipao", "a long qipao"], + ["Lederhosen", "lederhosen"], + ["Battlearmor", "battlearmor"], + ["Mounty outfit", "a mounty outfit"], + ["Dirndl", "a dirndl"], + ["Biyelgee costume", "a biyelgee costume"], + ["Maid (nice)", "a nice maid outfit"], + ["Maid (slutty)", "a slutty maid outfit"], + ["Military uniform", "a military uniform"], + ["Schutzstaffel uniform", "a schutzstaffel uniform"], + ["Schutzstaffel uniform (slutty)", "a slutty schutzstaffel uniform"], + ["Red Army uniform", "a red army uniform"], + ["Mini dress", "a mini dress"], + ["Monokini", "a monokini"], + ["Nice lingerie", "attractive lingerie"], + ["Nurse (nice)", "a nice nurse outfit"], + ["Schoolgirl", "a schoolgirl outfit"], + ["Silken ballgown", "a ball gown"], + ["Skimpy battledress", "battledress"], + ["Slave gown", "a slave gown"], + ["Slutty outfit", "a slutty outfit"], + ["String bikini", "a string bikini"], + ["Scalemail bikini", "a scalemail bikini"], + ["Succubus costume", "a succubus outfit"], + ["Suit (nice)", "nice business sattire"], + ["Suit (slutty", "slutty business attire"], + ["Spats and tank top", "spats and a tank top"] + ]; + const fsnclothes = [ + ["Body oil (FS)", "body oil"], + ["Bunny outfit (FS)", "a bunny outfit"], + ["Chattel habit (FS)", "a chattel habit"], + ["Conservative clothing (FS)", "conservative clothing"], + ["Harem gauze (FS)", "harem gauze"], + ["Huipil (FS)", "a huipil"], + ["Kimono (FS)", "a kimono"], + ["Maternity dress (FS)", "a maternity dress"], + ["Maternity lingerie (FS)", "attractive lingerie for a pregnant woman"], + ["Slutty qipao (FS)", "a slutty qipao"], + ["Stretch pants and a crop-top (FS)", "stretch pants and a crop-top"], + ["Toga (FS)", "a toga"], + ["Western clothing (FS)", "Western clothing"], + ]; + fsnclothes.forEach(pair => { if (isItemAccessible(pair[1])) nclothes.push(pair); }); + const nice = new ListSubSection(this, "Nice", nclothes); + this.appendChild(nice); - case "none": - r += `<br>${slave.slaveName} is a virgin and has been instructed not to use a vaginal accessory.`; - break; + const hclothes = [ + ["Nude", "no clothing"], + ["Penitent nun", "a penitent nuns habit"], + ["Restrictive latex", "restrictive latex"], + ["Shibari ropes", "shibari ropes"], + ["Uncomfortable straps", "uncomfortable straps"] + ]; + const fshclothes = [ + ["Chains (FS)", "chains"], + ]; + fshclothes.forEach(pair => { if (isItemAccessible(pair[1])) hclothes.push(pair); }); - default: - r += `<br>${slave.slaveName} is a virgin and has been given a ${slave.vaginalAccessory} for her pussy.`; - break; - } - } + const harsh = new ListSubSection(this, "Harsh", hclothes); + this.appendChild(harsh); + + this.setValue(current_rule.set.clothes); + this.onchange = (value) => current_rule.set.clothes = value; } } - function ProcessAVirginDildos(slave, rule) { - // apply vaginal dildos to anal virgins - if ((rule.aVirginAccessory !== undefined) && (rule.aVirginAccessory !== "no default setting")) { - if (slave.vaginalAccessory !== rule.aVirginAccessory) { - slave.vaginalAccessory = rule.aVirginAccessory; - switch (slave.vaginalAccessory) { - case "huge dildo": - r += `<br>${slave.slaveName} is a virgin and has been given a`; - if (slave.vagina >= 2) - r += `massive dildo to permanently gape her cunt.`; - else { - r += `large dildo for her pussy, since it must be stretched before it can accommodate a huge one.`; - slave.vaginalAccessory = "large dildo"; - } - break; - - case "long dildo": - if (slave.breedingMark == 1) { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length dildo for her pussy.`; - slave.vaginalAccessory = "dildo"; - } - break; - - case "long, large dildo": - if (slave.breedingMark == 1) { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length large dildo for her pussy.`; - slave.vaginalAccessory = "large dildo"; - } - break; + class CollarList extends List { + constructor() { + const items = [ + ["No default collar setting", "no default setting"], + ["No collar", "none"], + ]; + super("Collar", items); - case "long, huge dildo": - if (slave.breedingMark == 1) { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length huge dildo for her pussy.`; - slave.vaginalAccessory = "huge dildo"; - } else { - r += `<br>${slave.slaveName} is a virgin and has been given a`; - if (slave.vagina >= 2) - r += `massive and oversized dildo to permanently gape her cunt.`; - else { - r += `long, large dildo for her pussy, since it must be stretched before it can accommodate a huge one.`; - slave.vaginalAccessory = "long, large dildo"; - } - } - break; + const ncollars = [ + ["Stylish leather", "stylish leather"], + ["Satin choker", "satin choker"], + ["Silken Ribbon", "silk ribbon"], + ["Heavy Gold", "heavy gold"], + ["Pretty jewelry", "pretty jewelry"], + ["Cowbell", "leather with cowbell"] + ]; + if (V.seeAge !== 0) + ncollars.push(["Nice retirement counter", "nice retirement counter"]); + const fsncollars = [ + ["Bowtie collar", "bowtie"], + ["ancient Egyptian", "ancient Egyptian"], + ]; + fsncollars.forEach(pair => { if (isItemAccessible(pair[1])) ncollars.push(pair); }); + const nice = new ListSubSection(this, "Nice", ncollars); + this.appendChild(nice); - case "none": - r += `<br>slave.slaveName is a virgin and has been instructed not to use a vaginal accessory.`; - break; + const hcollars = []; + setup.harshCollars.forEach(item => { + if (item.fs === "seeage" && V.seeAge === 0) return; + else if (item.rs === "buyGag" && V.toysBoughtGags !== 1) return; + else hcollars.push([item.name, item.value]); + }); + const harsh = new ListSubSection(this, "Harsh", hcollars); + this.appendChild(harsh); - default: - r += `<br>slave.slaveName is a virgin and has been given a slave.vaginalAccessory for her pussy.`; - break; - } - } + this.setValue(current_rule.set.collar); + this.onchange = (value) => current_rule.set.collar = value; } } - function ProcessNonVirginDildos(slave, rule) { - // apply vaginal dildos to non-virgins - if ((rule.vaginalAccessory !== undefined) && (rule.vaginalAccessory !== "no default setting")) { - if (slave.vaginalAccessory !== rule.vaginalAccessory) { - slave.vaginalAccessory = rule.vaginalAccessory; - switch (slave.vaginalAccessory) { - case "huge dildo": - r += `<br>${slave.slaveName} has been given a`; - if (slave.vagina >= 2) - r += `massive dildo to permanently gape her cunt.`; - else { - r += `large dildo for her pussy, since it must be stretched before it can accommodate a huge one.`; - slave.vaginalAccessory = "large dildo"; - } - break; - - case "long dildo": - if (slave.breedingMark == 1) { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so ${slave.slaveName} has been given a standard length dildo for her pussy.`; - slave.vaginalAccessory = "dildo"; - } - break; - - case "long, large dildo": - if (slave.breedingMark == 1) { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so ${slave.slaveName} has been given a standard length large dildo for her pussy.`; - slave.vaginalAccessory = "large dildo"; - } - break; - - case "long, huge dildo": - if (slave.breedingMark == 1) { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so ${slave.slaveName} has been given a standard length huge dildo for her pussy.`; - slave.vaginalAccessory = "huge dildo"; - } else { - r += `<br>${slave.slaveName} has been given a`; - if (slave.vagina >= 2) - r += `massive and oversized dildo to permanently gape her cunt.`; - else { - r += `long, large dildo for her pussy, since it must be stretched before it can accommodate a huge one.`; - slave.vaginalAccessory = "long, large dildo"; - } - } - break; - case "none": - r += `<br>${slave.slaveName} has been instructed not to use a vaginal accessory.`; - break; + class ShoeList extends List { + constructor() { + super("Shoes", setup.shoes.map(i => [i.name, i.value])); + this.setValue(current_rule.set.shoes); + this.onchange = (value) => current_rule.set.shoes = value; + } + } - default: - r += `<br>${slave.slaveName} has been given a slave.vaginalAccessory for her pussy.`; - break; - } - } + class CorsetList extends List { + constructor() { + const bellies = []; + setup.bellyAccessories.forEach(acc => { + if (acc.fs === undefined && acc.rs === undefined) + bellies.push([acc.name, acc.value]); + else if (acc.fs === "repopulation" && V.arcologies[0].FSRepopulationFocus !== "unset") + bellies.push([acc.name + " (FS)", acc.value]); + else if (acc.rs === "boughtBelly" && V.clothesBoughtBelly === 1) + bellies.push([acc.name + " (Purchased)", acc.value]); + }); + super("Corsetage", bellies); + this.setValue(current_rule.set.bellyAccessory); + this.onchange = (value) => current_rule.set.bellyAccessory = value; } } - function ProcessDickAccessories(slave, rule) { - // apply dick accessories to slave - if ((slave.dick > 0)) { - if (slave.anus === 0) { - if ((rule.aVirginDickAccessory !== undefined) && (rule.aVirginDickAccessory !== "no default setting")) { - if ((slave.dickAccessory !== rule.aVirginDickAccessory)) { - slave.dickAccessory = rule.aVirginDickAccessory; - if (slave.dickAccessory == "none") - r += `<br>${slave.slaveName} is a virgin and has been instructed not to wear a dick accessory.`; - else - r += `<br>${slave.slaveName} is a virgin and has been given a ${slave.dickAccessory} accessory for her cock.`; - } - } - } else { - if ((rule.dickAccessory !== undefined) && (rule.dickAccessory !== "no default setting")) { - if ((slave.dickAccessory !== rule.dickAccessory)) { - slave.dickAccessory = rule.dickAccessory; - if (slave.dickAccessory == "none") - r += `<br>${slave.slaveName} has been instructed not to wear a dick accessory.`; - else - r += `<br>${slave.slaveName} has been given a ${slave.dickAccessory} accessory for her cock.`; - } - } - } + class LeggingsList extends List { + constructor() { + const items = [ + ["no default settings"], + ["none"], + ["short stockings"], + ["long stockings"], + ]; + super("Leg accessory", items); + this.setValue(current_rule.set.legAccessory); + this.onchange = (value) => current_rule.set.legAccessory = value; } } - function ProcessShoes(slave, rule) { - // apply shoes to slave - if ((rule.shoes !== undefined) && (rule.shoes !== "no default setting")) { - if ((slave.shoes !== rule.shoes)) { - if ((slave.amp != 1)) { - slave.shoes = rule.shoes; - r += `<br>${slave.slaveName}'s shoes have been set to ${slave.shoes}.`; - } - } + class VagAccVirginsList extends List { + constructor() { + const accs = []; + setup.vaginalAccessories.forEach(acc => { + if (acc.fs === undefined && acc.rs === undefined) + accs.push([acc.name, acc.value]); + else if (acc.rs === "buyBigDildos" && V.toysBoughtDildos === 1) + accs.push([acc.name + " (Purchased)", acc.value]); + }); + super("Vaginal accessories for virgins", accs); + this.setValue(current_rule.set.virginAccessory); + this.onchange = (value) => current_rule.set.virginAccessory = value; } } - function ProcessBellyAccessories(slave, rule) { - // apply belly accessories to slave - if ((rule.bellyAccessory !== undefined) && (rule.bellyAccessory !== "no default setting")) { - 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.`; - slave.bellyAccessory = "none"; - } else { - slave.bellyAccessory = rule.bellyAccessory; - if (slave.bellyAccessory == "none") - r += `<br>${slave.slaveName} has been instructed not to wear a torso accessory.`; - else - r += `<br>${slave.slaveName} has been given ${slave.bellyAccessory} to wear.`; - } - } + class VagAccAVirginsList extends List { + constructor() { + const accs = []; + setup.vaginalAccessories.forEach(acc => { + if (acc.fs === undefined && acc.rs === undefined) + accs.push([acc.name, acc.value]); + else if (acc.rs === "buyBigDildos" && V.toysBoughtDildos === 1) + accs.push([acc.name + " (Purchased)", acc.value]); + }); + super("Vaginal accessories for anal virgins", accs); + this.setValue(current_rule.set.aVirginAccessory); + this.onchange = (value) => current_rule.set.aVirginAccessory = value; } } - function ProcessLegAccessory(slave, rule) { - if (rule.legAccessory !== undefined && rule.legAccessory !== "no default setting" && slave.amp !== 1 && slave.legAccessory !== rule.legAccessory) { - slave.legAccessory = rule.legAccessory; - r += `<br>${slave.slaveName}'s leg accessory was set to ${rule.legAccessory}.`; + class VagAccOtherList extends List { + constructor() { + const accs = []; + setup.vaginalAccessories.forEach(acc => { + if (acc.fs === undefined && acc.rs === undefined) + accs.push([acc.name, acc.value]); + else if (acc.rs === "buyBigDildos" && V.toysBoughtDildos === 1) + accs.push([acc.name + " (Purchased)", acc.value]); + }); + super("Vaginal accessories for other slaves", accs); + this.setValue(current_rule.set.vaginalAccessory); + this.onchange = (value) => current_rule.set.vaginalAccessory = value; } } - function ProcessAnalAccessories(slave, rule) { - // apply buttplugs to slave - if ((slave.vaginalAccessory !== "anal chastity") && (slave.vaginalAccessory !== "combined chastity") && (slave.dickAccessory !== "anal chastity") && (slave.dickAccessory !== "combined chastity")) { - if (slave.anus === 0) - ProcessAnalVirginButtplugs(slave, rule); - else - ProcessNonVirginButtplugs(slave, rule); + class DickAccVirginsList extends List { + constructor() { + super("Dick accessories for anal virgins", setup.dickAccessories.map(i => [i.name, i.value])); + this.setValue(current_rule.set.aVirginDickAccessory); + this.onchange = (value) => current_rule.set.aVirginDickAccessory = value; } } - function ProcessAnalVirginButtplugs(slave, rule) { - // apply buttplugs to virgins - if ((rule.aVirginButtplug !== undefined) && (rule.aVirginButtplug !== "no default setting")) { - if ((slave.buttplug !== rule.aVirginButtplug)) { - slave.buttplug = rule.aVirginButtplug; - switch (slave.buttplug) { - case "huge plug": - r += `<br>${slave.slaveName} is an anal virgin and has been given a`; - if ((slave.anus >= 2)) - r += `massive plug to permanently gape her asshole.`; - else { - slave.buttplug = "large plug"; - r += `large buttplug for her asshole, since it must be stretched before it can accommodate a huge one.`; - } - break; - - case "long plug": - if (slave.breedingMark == 1) { - r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so the anal virgin ${slave.slaveName} has been given a standard length plug for her anus.`; - slave.buttplug = "plug"; - } - break; - - case "long, large plug": - if (slave.breedingMark == 1) { - r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so the anal virgin ${slave.slaveName} has been given a standard length large plug for her anus.`; - slave.buttplug = "large plug"; - } - break; - - case "long, huge plug": - if (slave.breedingMark == 1) { - r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so the anal virgin ${slave.slaveName} has been given a standard length huge plug for her anus.`; - slave.buttplug = "huge plug"; - } else { - r += `<br>slave.slaveName is an anal virgin and has been given a`; - if (slave.anus >= 2) - r += `massive and oversized plug to permanently gape her asshole.`; - else { - r += `long, large buttplug for her asshole, since it must be stretched before it can accommodate a huge one.`; - slave.buttplug = "long, large plug"; - } - } - break; - - case "none": - r += `<br>${slave.slaveName} is an anal virgin and has been instructed not to use an anal accessory.`; - break; - - default: - r += `<br>${slave.slaveName} is an anal virgin and has been given a slave.buttplug for her asshole.`; - break; - } - } + class DickAccOtherList extends List { + constructor() { + super("Dick accessories for other slaves", setup.dickAccessories.map(i => [i.name, i.value])); + this.setValue(current_rule.set.dickAccessory); + this.onchange = (value) => current_rule.set.dickAccessory = value; } } - function ProcessNonVirginButtplugs(slave, rule) { - // apply buttplugs to non-virgins - if ((rule.buttplug !== undefined) && (rule.buttplug !== "no default setting")) { - if ((slave.buttplug !== rule.buttplug)) { - slave.buttplug = rule.buttplug; - switch (slave.buttplug) { - case "huge plug": - r += `<br>${slave.slaveName} has been given a`; - if ((slave.anus >= 2)) - r += `massive plug to permanently gape her asshole.`; - else { - slave.buttplug = "large plug"; - r += `large buttplug for her asshole, since it must be stretched before it can accommodate a huge one.`; - } - break; - - case "long plug": - if (slave.breedingMark == 1) { - r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so ${slave.slaveName} has been given a standard length plug for her anus.`; - slave.buttplug = "plug"; - } - break; - - case "long, large plug": - if (slave.breedingMark == 1) { - r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so ${slave.slaveName} has been given a standard length large plug for her anus.`; - slave.buttplug = "large plug"; - } - break; - - case "long, huge plug": - if (slave.breedingMark == 1) { - r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so ${slave.slaveName} has been given a standard length huge plug for her anus.`; - slave.buttplug = "huge plug"; - } else { - r += `<br>${slave.slaveName} has been given a`; - if (slave.anus >= 2) - r += `massive and oversized plug to permanently gape her asshole.`; - else { - r += `long, large buttplug for her asshole, since it must be stretched before it can accommodate a huge one.`; - slave.buttplug = "long, large plug"; - } - } - break; - - case "none": - r += `<br>${slave.slaveName} has been instructed not to use an anal accessory.`; - break; - - default: - r += `<br>${slave.slaveName} has been given a slave.buttplug for her asshole.`; - break; - } - } + class ButtplugsVirginsList extends List { + constructor() { + const accs = []; + setup.buttplugs.forEach(acc => { + if (acc.fs === undefined && acc.rs === undefined) + accs.push([acc.name, acc.value]); + else if (acc.rs === "buyBigPlugs" && V.toysBoughtButtPlugs === 1) + accs.push([acc.name + " (Purchased)", acc.value]); + }); + super("Buttplugs for anal virgins", accs); + this.setValue(current_rule.set.aVirginButtplug); + this.onchange = (value) => current_rule.set.aVirginButtplug = value; } } - function ProcessBellyImplant(slave, rule) { - // Here is belly implant size control, it's used in Surgery Degradation passage to setup devotion and trust changes. - // silent calls to surgery degradation have been replaced with a js function, which is less hacky - if ((rule.bellyImplantVol !== undefined) && slave.bellyImplant >= 0 && rule.bellyImplantVol >= 0) { - r += "<br>"; - if (slave.health > -10 ) { - let diff = rule.bellyImplantVol - slave.bellyImplant; - if (diff >= 5000 && slave.bellyPain === 0 && slave.health > 50) { - r += `${slave.slaveName}'s belly is way too small, so she has been directed to have intensive belly implant filling procedures throughout this week.`; - slave.bellyImplant += 1000; - slave.bellyPain += 2; - BellySurgery(slave, diff); - } else if (diff >= 500 && slave.bellyPain < 2 ) { - r += `${slave.slaveName}'s belly has not reached the desired size, so she has been directed to have belly implant filling procedures throughout this week.`; - slave.bellyImplant += 500; - slave.bellyPain += 1; - BellySurgery(slave, diff); - } else if (diff <= -5000 ) { - r += `${slave.slaveName}'s belly is way too big, so she has been directed to have intensive belly implant draining procedures throughout this week.`; - slave.bellyImplant -= 1000; - BellySurgery(slave, diff); - } else if (diff <= -500 ) { - r += `${slave.slaveName}'s belly is too big, so she has been directed to have belly implant draining procedures throughout this week.`; - slave.bellyImplant -= 500; - BellySurgery(slave, diff); - } - } else { - r += `${slave.slaveName} is not healthy enough to safely adjust her belly implant.`; - } + class ButtplugsOtherList extends List { + constructor() { + const accs = []; + setup.buttplugs.forEach(acc => { + if (acc.fs === undefined && acc.rs === undefined) + accs.push([acc.name, acc.value]); + else if (acc.rs === "buyBigPlugs" && V.toysBoughtButtPlugs === 1) + accs.push([acc.name + " (Purchased)", acc.value]); + }); + super("Buttplugs for other slaves", accs); + this.setValue(current_rule.set.buttplug); + this.onchange = (value) => current_rule.set.buttplug = value; } } - function BellySurgery(slave, volume) { - // this is a port of the belly implant portion of surgeryDegradation.tw - // that way, we don't have to use ugly hacks - // the original still exists, and may be worth replacing - if (volume > 0) { // bellyUp - SetBellySize(slave); - if (slave.bellyPain === 1) { - if (slave.devotion > 50) { - slave.devotion += 4; - } else if (slave.devotion >= -20) { - slave.trust -= 5; - } else { - slave.trust -= 10; - slave.devotion -= 5; - } - } else if (slave.bellyPain === 2) { - if (slave.devotion > 50) { - slave.devotion += 2; - } else if (slave.devotion >= -20) { - slave.trust -= 7; - } else { - slave.trust -= 12; - slave.devotion -= 7; - } - } - } else { // bellyDown - if (slave.bellyImplant < 0) - slave.bellyImplant = 0; - SetBellySize(slave); - if (slave.devotion > 50) { - slave.devotion += 3; - slave.trust += 3; - } else if (slave.devotion >= -20) { - slave.trust += 2; - } else { - slave.devotion += 1; - slave.trust -= 10; - } + class ImplantVolumeList extends List { + constructor() { + const pairs = [ + ["No changes", -1], + ["Empty implant", 0], + ["Early pregnancy", 1500], + ["Second trimester pregnancy", 5000], + ["Full-term pregnancy", 15000], + ["Full-term with twins", 30000], + ["Full-term with triplets", 45000], + ["Full-term with quadruplets", 60000], + ["Full-term with quintuplets", 75000], + ["Full-term with sextuplets", 90000], + ["Full-term with septuplets", 105000], + ["Full-term with octuplets", 120000] + ]; + super("Belly implant target volume (if present)", pairs); + this.setValue(current_rule.set.bellyImplantVol); + this.onchange = (value) => current_rule.set.bellyImplantVol = value; } } - function ProcessContraceptives(slave, rule) { - if ((rule.preg !== undefined) && (rule.preg !== "no default setting")) { - if (rule.preg === true && slave.preg === 0) { - r += `<br>${slave.slaveName} is being given contraceptives.`; - slave.preg = -1; - } else if (slave.preg === -1 && rule.preg === false) { - r += `<br>${slave.slaveName} is no longer being put on contraceptives.`; - slave.preg = 0; - } + class AutosurgerySwitch extends List { + constructor() { + const pairs = [ + ["Activate", 1], + ["Off", 0], + ]; + super("Assistant-applied implants (Autosurgery global switch)", pairs); + this.setValue(current_rule.set.autoSurgery); + this.onchange = (value) => current_rule.set.autoSurgery = value; } } - function ProcessAssetGrowthDrugs(slave, rule) { - // Asset Growth - const growth_drugs = new Set(["breast injections", "intensive breast injections", "breast redistributors", "butt injections", "intensive butt injections", "butt redistributors", "lip injections", "lip atrophiers", "penis enhancement", "intensive penis enhancement", "penis atrophiers", "testicle enhancement", "intensive testicle enhancement", "testicle atrophiers", "hyper breast injections", "hyper butt injections", "hyper penis enhancement", "hyper 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")) { - return; - } - if (slave.assignmentVisible) { // More resource intensive version with prioritizing. Possible to give this a toggle rather than basing it on visibility. - 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 > rule.growth_boobs+200) && slave.weight < 100 && (V.arcologies[0].FSSlimnessEnthusiastResearch == 1)) { - _priority = { - drug: "breast redistributors", - weight: (1+((slave.boobs-slave.boobsImplant-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 she's healthy enough to take them, and `; - } else { - r += `${slave.drugs}, since `; - } - r += `that part of her body is ${Math.trunc(_priorities[0].weight*100)}% `; - if (_priorities[0].weight < 1) r+= "below "; - else r+= "above "; - r += "the targeted size."; - } - return; - } 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 she's healthy enough to take them, and `; - } else - r += `${slave.drugs}, since `; - r += `that is the only part of her body that does not meet the targeted size.`; - } - return; - } else if (growth_drugs.has(slave.drugs)) { - slave.drugs = "no drugs"; - r += `<br>${slave.slaveName}'s body has met all relevant growth targets, so her pharmaceutical regime has been ended.`; - return; - } - } else { - let _hyper; - if (V.arcologies[0].FSAssetExpansionistResearch == 1) - _hyper = "hyper "; - else - _hyper = ""; - 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 (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; - } - } - 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 (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; - } - } - 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 (V.arcologies[0].FSSlimnessEnthusiastResearch == 1) { - if (rule.growth_boobs != "no default setting") { - if (slave.boobs-slave.boobsImplant > 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 (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 (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 (growth_drugs.has(slave.drugs)) { - slave.drugs = "no drugs"; - r += `<br>${slave.slaveName} has met all relevant growth targets, so her pharmaceutical regime has been ended.`; - return; + class GrowthList extends Options { + constructor() { + super(); + this.sublists = []; + const pairs = [ + ["No default setting", () => this.nds()], + ["Girlish figure", () => this.girlish()], + ["Stacked figure", () => this.stacked()], + ["Huge but functional", () => this.huge()], + ["Unlimited", () => this.unlimited()], + ["None", () => this.none()] + ]; + pairs.forEach(pair => this.appendChild(new OptionsItem(...pair))); + + this.breasts = new BreastGrowthList(); + this.butts = new ButtGrowthList(); + this.lips = new LipGrowthList(); + this.sublists.push(this.breasts, this.butts, this.lips); + + if (V.seeDicks > 0 || V.makeDicks > 0) { + this.dicks = new DickGrowthList(); + this.balls = new BallGrowthList(); + this.sublists.push(this.dicks, this.balls); } + + this.sublists.forEach(i => this.appendChild(i)); } - } - function ProcessOtherDrugs(slave, rule) { - // Other Drugs - if (slave.indentureRestrictions < 2 && rule.drug !== "no default setting" && slave.drugs !== rule.drug) { - let flag = true; - switch (rule.drug) { - case "anti-aging cream": - if (slave.visualAge < 18) - flag = false; - break; + render() { + const elem = document.createElement("div"); + const span = document.createElement("span"); + span.innerHTML = "Growth hormone regimes for healthy slaves: "; + elem.appendChild(span); + return elem; + } - case "growth stimulants": - if (!(slave.height < 274 && slave.height < Math.clamp((Height.mean(slave) * 1.25),0,274))) - flag = false; - break; + nds() { + [this.breasts, this.butts, this.lips, this.dicks, this.balls].forEach(i => { + i.setValue("no default change"); + i.propagateChange(); + }); + } - case "sag-B-gone": - if (!(slave.boobs > 250 && slave.boobShape != "saggy")) - flag = false; - break; + 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.sublists.forEach(i => i.propagateChange()); + } - case "female hormone injections": - if (!(slave.breedingMark != 1 && (slave.ovaries == 1 || slave.mpreg == 1) && slave.pubertyXX === 0)) - flag = false; - break; + stacked() { + this.breasts.setValue(1000); + this.butts.setValue(4); + this.lips.setValue(25); + if (this.dicks) this.dicks.setValue(4); + if (this.balls) this.balls.setValue(4); + this.sublists.forEach(i => i.propagateChange()); + } - case "male hormone injections": - if (!(slave.breedingMark != 1 && slave.balls > 0 && slave.pubertyXY === 0)) - flag = false; - break; - - case "psychosuppressants": - if (!(slave.intelligence > -2 && slave.indentureRestrictions < 1)) - flag = false; - break; - - case "breast injections": - if (!(slave.boobs < 48000)) - flag = false; - break; - - case "hyper breast injections": - if (!(slave.boobs < 25000)) - flag = false; - break; - - case "breast redistributors": - if (!(slave.boobs - slave.boobsImplant > 100)) - flag = false; - break; - - case "butt injections": - if (!(slave.butt < 9)) - flag = false; - break; - - case "hyper butt injections": - if (!(slave.butt < 20)) - flag = false; - break; - - case "hyper butt injections": - if (!(slave.butt < 20)) - flag = false; - break; - - case "nipple atrophiers": - if (!(["huge", "puffy", "cute"].includes(slave.nipples))) - flag = false; - break; - - case "butt redistributors": - if (!(slave.buttImplant > 0)) - flag = false; - break; - - case "lip injections": - if (!(slave.lips <= 95 || (slave.lips <= 85 && V.seeExtreme !== 1))) - flag = false; - break; - - case "lip atrophiers": - if (!(slave.lips - slave.lipsImplant > 0)) - flag = false; - break; - - case "super fertility drugs": - if (!(slave.indentureRestrictions < 1 && slave.breedingMark !== 1)) - flag = false; - break; - - case "penis enhancement": - if (!((slave.dick > 0 && slave.dick < 10) || slave.clit < 5)) - flag = false; - break; - - case "hyper penis enhancement": - if (!((slave.dick > 0 && slave.dick < 31) || slave.clit < 5)) - flag = false; - break; - - case "penis atrophiers": - if (!(slave.dick > 1)) - flag = false; - break; - - case "testicle enhancement": - if (!(slave.balls > 0)) - flag = false; - break; - - case "hyper testicle enhancement": - if (!(slave.balls > 0)) - flag = false; - break; - - case "testicle atrophiers": - if (!(slave.balls > 1)) - flag = false; - break; - - case "clitoris atrophiers": - if (!(slave.clit > 0)) - flag = false; - break; - - case "labia atrophiers": - if (!(slave.labia > 0)) - flag = false; - break; - - case "appetite suppressors": - if (!(slave.weight > -95)) - flag = false; - break; - - case "female hormone injections": - if (!(slave.breedingMark !== 1 && (slave.ovaries === 1 || slave.mpreg === 1) && slave.pubertyXX === 0)) - flag = false; - break; - - case "male hormone injections": - if (!(slave.balls > 0 && slave.pubertyXY === 0)) - flag = false; - break; - - default: - break; - } - if (flag) { - slave.drugs = rule.drug; - r += `<br>${slave.slaveName} has been put on ${slave.drugs}.`; - } else { - slave.drugs = "no drugs"; - r += `<br>${slave.slaveName} cannot benefit from her assigned drug and has been defaulted to ${slave.drugs}`; - } + 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.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.sublists.forEach(i => i.propagateChange()); + } + + none() { + this.sublists.forEach(i => { + i.setValue(0); + i.propagateChange(); + }); + } + } + + class BreastGrowthList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["B Cup", 350], + ["D Cup", 1000], + ["Monstrous", 9000], + ["Unlimited", 48000], + ["None", 0] + ]; + super("Breasts", pairs, true); + this.setValue(current_rule.set.growth_boobs); + this.onchange = (value) => current_rule.set.growth_boobs = value; + } + } + + class ButtGrowthList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Cute", 2], + ["Big", 4], + ["Huge", 6], + ["Unlimited", 20], + ["None", 0] + ]; + super("Butts", pairs, true); + this.setValue(current_rule.set.growth_butt); + this.onchange = (value) => current_rule.set.growth_butt = value; + } + } + + class LipGrowthList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Plump", 25], + ["Beestung", 45], + ["Facepussy", 100], + ["None", 0] + ]; + super("Lips", pairs, true); + this.setValue(current_rule.set.growth_lips); + this.onchange = (value) => current_rule.set.growth_lips = value; + } + } + + class DickGrowthList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Above average", 4], + ["Pornstar", 6], + ["Unlimited", 30], + ["None", 0] + ]; + super("Dicks, if present", pairs, true); + this.setValue(current_rule.set.growth_dick); + this.onchange = (value) => current_rule.set.growth_dick = value; } } - function ProcessDiet(slave, rule) { - // Diet Setting - if (rule.diet !== undefined && rule.diet !== "no default setting") { - /* - if ((slave.boobs >= 1600) && (slave.muscles <= 5) && (slave.amp != 1) && ((rule.muscles == "no default setting") || (rule.muscles === 0))) { - if ((slave.diet !== "muscle building")) { - slave.diet = "muscle building" - r += `<br>${slave.slaveName} has big tits and no back muscles, so she'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))) { - */ - 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))) { - slave.diet = "healthy"; - r += `<br>${slave.slaveName} has huge boobs, but she already has the back muscles to bear them, so she'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)) { - if (slave.diet !== "fattening") { - slave.diet = "fattening"; - r += `<br>${slave.slaveName} is on drugs designed to expand major body parts, so she's been put on a fattening diet to provide her body as much fuel for growth as possible.`; - } - } else { - if (!(isNaN(rule.diet))) { - if ((slave.weight - rule.diet) > 5) { - if ((slave.diet !== "restricted")) { - slave.diet = "restricted"; - r += `<br>${slave.slaveName} is too fat so her diet has been set to restricted.`; - } - - } else if ((slave.weight - rule.diet) < -5) { - if ((slave.diet !== "fattening")) { - slave.diet = "fattening"; - r += `<br>${slave.slaveName} is too skinny so her 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)) { - 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)) { - if ((slave.diet !== "muscle building")) { - slave.diet = "muscle building"; - r += `<br>${slave.slaveName} has been put on a muscle building exercise regime.`; - } - } else { - if ((slave.diet !== "healthy")) { - slave.diet = "healthy"; - r += `<br>${slave.slaveName} is at the target weight, so her diet has been normalized.`; - } - } - } else { - if ((slave.diet !== "healthy")) { - slave.diet = "healthy"; - r += `<br>${slave.slaveName} is at the target weight, so her diet has been normalized.`; - } - } - } else if ((rule.diet == "attractive")) { - if (((slave.weight > 95) || ((slave.weight > 30) && (slave.hips < 2)))) { - if ((slave.diet !== "restricted")) { - slave.diet = "restricted"; - r += `<br>${slave.slaveName} is too fat so her diet has been set to restricted.`; - } - } else if (((slave.weight < -95) || ((slave.weight < -30) && (slave.hips > -2)))) { - if ((slave.diet !== "fattening")) { - slave.diet = "fattening"; - r += `<br>${slave.slaveName} is too skinny so her 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)) { - 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)) { - if ((slave.diet !== "muscle building")) { - slave.diet = "muscle building"; - r += `<br>${slave.slaveName} has been put on a muscle building exercise regime.`; - } - } else { - if ((slave.diet !== "healthy")) { - slave.diet = "healthy"; - r += `<br>${slave.slaveName} is at the target weight, so her diet has been normalized.`; - } - } - } else { - if ((slave.diet !== "healthy")) { - slave.diet = "healthy"; - r += `<br>${slave.slaveName} is at the target weight, so her diet has been normalized.`; - } - } - } else if ((rule.diet == "XX")) { - if ((slave.diet !== "XX")) { - slave.diet = "XX"; - r += `<br>${slave.slaveName} has been put on a diet that favors feminine development.`; - } - } else if ((rule.diet == "XY")) { - if ((slave.diet !== "XY")) { - slave.diet = "XY"; - r += `<br>${slave.slaveName} has been put on a diet that favors masculine development.`; - } - } else if ((rule.diet == "XXY")) { - if (slave.balls > 0 && (slave.ovaries == 1 || slave.mpreg == 1)) { - if ((slave.diet !== "XXY")) { - slave.diet = "XXY"; - r += `<br>${slave.slaveName} has been put on a diet that enhances a herm's unique sexuality.`; - } - } else { - if ((slave.diet !== "healthy")) { - slave.diet = "healthy"; - r += `<br>${slave.slaveName} has been put on a standard diet since she is not a hermaphrodite.`; - } - } - } else if ((rule.diet == "cleansing")) { - if (((slave.diet !== "cleansing") && (slave.health < 100))) { - slave.diet = "cleansing"; - r += `<br>${slave.slaveName} has been put on a diet of cleansers.`; - } - } else if ((rule.diet == "fertility")) { - if (canGetPregnant(slave)) { - if ((slave.diet !== "fertility")) { - slave.diet = "fertility"; - r += `<br>${slave.slaveName} has been put on a diet to enhance fertility.`; - } - } else { - if ((slave.diet !== "healthy")) { - slave.diet = "healthy"; - if (slave.pregKnown === 0 && slave.preg > 0) { - r += `<br>${slave.slaveName} has been put on a standard diet since tests reveal she has become pregnant.`; - slave.pregKnown = 1; - } else { - r += `<br>${slave.slaveName} has been put on a standard diet since she is currently unable to become pregnant.`; - } - } - } - } else if ((rule.diet == "cum production")) { - if ((slave.balls > 0)) { - if ((slave.diet !== "cum production")) { - slave.diet = "cum production"; - r += `<br>${slave.slaveName} has been put on a diet to promote cum production.`; - } - } else { - if ((slave.diet !== "healthy")) { - slave.diet = "healthy"; - r += `<br>${slave.slaveName} has been put on a standard diet since she is no longer able to produce cum.`; - } - } - } - } - } else if ((rule.muscles !== undefined) && (rule.muscles !== "no default setting") && (slave.amp != 1)) { // no diet rule, muscles only - if ((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)) { - if ((slave.diet !== "muscle building")) { - slave.diet = "muscle building"; - r += `<br>${slave.slaveName} has been put on a muscle building exercise regime.`; - } - } else { - if ((slave.diet !== "healthy")) { - slave.diet = "healthy"; - r += `<br>${slave.slaveName} has achieved the target musculature, so her exercise regime has been normalized.`; - } - } + class BallGrowthList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Sizeable", 4], + ["Cumslave", 6], + ["Unlimited", 125], + ["None", 0] + ]; + super("Balls, if present", pairs, true); + this.setValue(current_rule.set.growth_balls); + this.onchange = (value) => current_rule.set.growth_balls = value; } + } - if (slave.drugs === "appetite suppressors" && slave.diet !== "restricted") { - slave.drugs = "no drugs"; - r += `<br>${slave.slaveName} is no longer losing weight, so she's no longer being given appetite suppressors.`; - } else if (slave.diet === "restricted" && V.arcologies[0].FSSlimnessEnthusiastResearch == 1 && (slave.drugs == "no drugs" || slave.drugs == "none")) { - slave.drugs = "appetite suppressors"; - r += `<br>${slave.slaveName} is losing weight so she will be given weight loss pills.`; + class CurrativesList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Preventatives", 1], + ["Curatives", 2], + ]; + super("Health drugs", pairs); + this.setValue(current_rule.set.curatives); + this.onchange = (value) => current_rule.set.curatives = value; + } + } + + class AphrodisiacList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Standard", 1], + ["Extreme", 2], + ["Anaphrodisiacs", -1] + ]; + super("Aphrodisiacs", pairs); + this.setValue(current_rule.set.aphrodisiacs); + this.onchange = (value) => current_rule.set.aphrodisiacs = value; + } + } + + class ContraceptiveList extends List { + constructor() { + const drugs = [ + ["No default setting", "no default setting"], + ["Contraceptives", true], + ["Fertile", false], + ]; + super("Contraceptives for fertile slaves", drugs); + this.setValue(current_rule.set.preg); + this.onchange = (value) => current_rule.set.preg = value; + } + } + + class PregDrugsList extends List { + constructor() { + const pairs = [ + ["No changes", "no default setting"], + ["None", "none"], + ["Fast gestation", "fast"], + ["Slow gestation", "slow"], + ["Birth supressors", "suppress"], + ["Birth stimulators", "stimulate"] + ]; + super("Pregnancy control agents for pregnant slaves", pairs); + this.setValue(current_rule.set.pregSpeed); + this.onchange = (value) => current_rule.set.pregSpeed = value; + } + } + + class FemaleHormonesList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Intensive Female", 2], + ["Female", 1], + ["None", 0], + ["Male", -1], + ["Intensive Male", -2] + ]; + super("Hormones for female slaves", pairs); + this.setValue(current_rule.set.XX); + this.onchange = (value) => current_rule.set.XX = value; } } - function ProcessCuratives(slave, rule) { - if ((rule.curatives !== undefined) && (rule.curatives !== "no default setting")) { - if (slave.curatives !== rule.curatives) { - if (rule.curatives === 2) { - if (slave.health > 100) { - if ((slave.curatives != 1)) { - r += `<br>${slave.slaveName} has been put on preventatives, since curatives cannot improve her health further.`; - slave.curatives = 1; - } - } else { - r += `<br>${slave.slaveName} has been put on curatives.`; - slave.curatives = rule.curatives; - } - } else { - r += `<br>${slave.slaveName} has been ${rule.curatives > 0 ? `put on preventatives` : `taken off health drugs`}`; - slave.curatives = rule.curatives; - } - } + class GeldingHormonesList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Intensive Female", 2], + ["Female", 1], + ["None", 0], + ["Male", -1], + ["Intensive Male", -2] + ]; + super("Hormones for geldings", pairs); + this.setValue(current_rule.set.gelding); + this.onchange = (value) => current_rule.set.gelding = value; } } - function ProcessAphrodisiacs(slave, rule) { - if ((rule.aphrodisiacs !== undefined) && (rule.aphrodisiacs != "no default setting")) { - 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; - } + class ShemaleHormonesList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Intensive Female", 2], + ["Female", 1], + ["None", 0], + ["Male", -1], + ["Intensive Male", -2] + ]; + super("Hormones for shemales", pairs); + this.setValue(current_rule.set.XY); + this.onchange = (value) => current_rule.set.XY = value; } } - function ProcessPenisHormones(slave, rule) { - if ((slave.dick > 0)) { - if ((slave.balls === 0)) { - if ((rule.gelding !== undefined) && (rule.gelding !== "no default setting")) { - if ((slave.hormones !== rule.gelding)) { - const _oldHormones = slave.hormones; - slave.hormones = rule.gelding; - if (slave.indentureRestrictions >= 2) { - slave.hormones = Math.clamp(slave.hormones, -1, 1); - } - if (slave.hormones != _oldHormones) { - r += `<br>${slave.slaveName} is a gelding, so she has been put on the appropriate hormonal regime.`; - } - } - } - } else if ((slave.balls > 0)) { - if ((rule.XY !== undefined) && (rule.XY !== "no default setting")) { - if ((slave.hormones !== rule.XY)) { - if ((slave.assignment != "recruit girls")) { - if ((slave.assignment != "be the Wardeness")) { - if ((slave.assignment != "be the Madam")) { - const _oldHormones = slave.hormones; - slave.hormones = rule.XY; - if (slave.indentureRestrictions >= 2) { - slave.hormones = Math.clamp(slave.hormones, -1, 1); - } - if (slave.hormones != _oldHormones) { - r += `<br>${slave.slaveName} is a shemale, so she has been put on the appropriate hormonal regime.`; - } - } - } - } - } - } + class OtherDrugsList extends List { + constructor() { + const drugs = [ + ["No default setting", "no default setting"], + ["None", "none"], + ["Fertility drugs", "fertility drugs"], + ["Psychosuppressants", "psychosuppressants"], + ["Steroids", "steroids"], + ["Natural hormone enhancers", "hormone enhancers"], + ["Hormone blockers", "hormone blockers"], + ["breast injections"], + ["intensive breast injections"], + ["butt injections"], + ["intensive butt injections"], + ["lip injections"], + ["penis enhancement"], + ["intensive penis enhancement"], + ["testicle enhancement"], + ["intensive testicle enhancement"], + ]; + + if (V.growthStim === 1) + drugs.push(["Growth Stimulants (Research)", "growth stimulants"]); + if (V.precociousPuberty === 1 && V.pubertyHormones) { + drugs.push(["Female hormone injections (Research)", "female hormone injections"]); + drugs.push(["Male hormone injections (Research)", "male hormone injections"]); + } + if (V.purchasedSagBGone === 1) + drugs.push(["Sag-B-gone (Product)", "sag-B-gone"]); + if (V.arcologies[0].FSSlimnessEnthusiastResearch === 1) { + drugs.push(["Weight loss pills (FS)", "appetite suppressors"]); + drugs.push(["breast redistributors"]); + drugs.push(["butt redistributors"]); + drugs.push(["lip atrophiers"]); + drugs.push(["penis atrophiers"]); + drugs.push(["testicle atrophiers"]); + } + if (V.arcologies[0].FSAssetExpansionistResearch === 1) { + drugs.push(["hyper breast injections"]); + drugs.push(["hyper butt injections"]); + drugs.push(["hyper penis enhancement"]); + drugs.push(["hyper testicle enhancement"]); } + if (V.arcologies[0].FSYouthPreferentialistResearch === 1) + drugs.push(["Anti-aging cream (FS)", "anti-aging cream"]); + if (V.seeHyperPreg === 1 && V.superFertilityDrugs === 1) + drugs.push(["Super fertility drugs", "super fertility drugs"]); + super("Other drugs", drugs); + this.setValue(current_rule.set.drug); + this.onchange = (value) => current_rule.set.drug = value; } } - function ProcessFemaleHormones(slave, rule) { - if ((slave.vagina > -1) && (slave.dick === 0) && (rule.XX !== undefined) && (rule.XX !== "no default setting")) { - if ((slave.hormones !== rule.XX)) { - const _oldHormones = slave.hormones; - slave.hormones = rule.XX; - if (slave.indentureRestrictions >= 2) { - slave.hormones = Math.clamp(slave.hormones, -1, 1); - } - if (slave.hormones != _oldHormones) { - r += `<br>${slave.slaveName} is a female, so she has been put on the appropriate hormonal regime.`; - } + class DietList extends List { + constructor() { + const diets = [ + ["no default setting", "no default setting"], + ["Healthy diet", "healthy"], + ["Fix fat and skinny slaves", "attractive"], + ["Curvy", 30], + ["Average", 0], + ["Thin", -30] + ]; + if (V.feeder === 1) { + diets.push( + ["Feminine", "XX"], + ["Masculine", "XY"] + ); + if (V.dietXXY === 1) + diets.push(["Futanari", "XXY"]); } + if (V.dietCleanse === 1) + diets.push(["Cleansing", "cleansing"]); + if (V.dietFertility === 1) + diets.push(["Fertility", "fertility"]); + if (V.cumProDiet === 1) + diets.push(["Cum production", "cum production"]); + + super("Slave diets", diets, true); + this.setValue(current_rule.set.diet); + this.onchange = (value) => current_rule.set.diet = value; } } - function ProcessPregnancyDrugs(slave, rule) { - if (slave.pregKnown == 1 && rule.pregSpeed != "no default setting" && slave.breedingMark != 1 && slave.indentureRestrictions < 1 && slave.broodmother === 0) { - if (rule.pregSpeed == "slow" && slave.preg < 35) { - slave.pregControl = "slow gestation"; - r += `<br>${slave.slaveName} is pregnant, so she has been put on the gestation slowing agents.`; - } else if (rule.pregSpeed == "fast" && slave.preg < 35 && slave.health > -50) { - slave.pregControl = "speed up"; - r += `<br>${slave.slaveName} is pregnant, so she has been put on rapid gestation agents. CAUTION! Can be dangerous. Clinic supervision is recommended.`; - } else if (rule.pregSpeed == "suppress" && slave.preg > 34 && slave.health > -50) { - slave.pregControl = "labor supressors"; - r += `<br>${slave.slaveName} is ready to birth, so she has been put on labor suppressing agents.`; - } else if (rule.pregSpeed == "stimulate" && slave.preg >= 37 && slave.health > -50) { - slave.labor = 1; - slave.induce = 1; - V.birthee = 1; - r += `<br>slave.slaveName is ready to birth, so her labor has been stimulated.`; - } else if (rule.pregSpeed == "fast" && slave.pregControl == "speed up" && slave.health <= -50) { - slave.pregControl = "none"; - r += `<br>${slave.slaveName} is on rapid gestation agents and dangerously unhealthy, so her agent regimen has been stopped.`; - } else if (rule.pregSpeed == "suppress" && slave.pregControl == "labor supressors" && slave.health <= -50) { - slave.pregControl = "none"; - r += `<br>${slave.slaveName} is on labor suppression agents and unhealthy, so her agent regimen has been stopped.`; - } + class DietGrowthList extends List { + constructor() { + const pairs = [ + ["On", 1], + ["Off", 0] + ]; + super("Diet support for growth drugs", pairs); + this.setValue(current_rule.set.dietGrowthSupport); + this.onchange = (value) => current_rule.set.dietGrowthSupport = value; } } - function ProcessLivingStandard(slave, rule) { - if ((rule.livingRules !== undefined) && (rule.livingRules !== "no default setting")) { - if (setup.facilityCareers.includes(slave.assignment)) { - r += ``; // `<br>${slave.slaveName}'s living standards are controlled by her assignment.`; - } else if (((slave.assignment == "be your Head Girl") && (V.HGSuite == 1)) || ((slave.assignment == "guard you") && (V.dojo > 1))) { - r += `<br>${slave.slaveName} has a private room.`; - } else if ((slave.fetish == "mindbroken")) { - if ((slave.livingRules !== "spare")) { - slave.livingRules = "spare"; - r += `<br>Since ${slave.slaveName} is mindbroken her living standard has been set to spare.`; - } - } else if (slave.livingRules !== rule.livingRules) { - if (rule.livingRules !== "luxurious") { - if (V.roomsPopulation <= V.rooms-0.5) { - slave.livingRules = rule.livingRules; - r += `<br>${slave.slaveName}'s living standard has been set to ${rule.livingRules}.`; - if (slave.relationship >= 4) - V.roomsPopulation += 0.5; - else - V.roomsPopulation += 1; - } else { - slave.livingRules = "normal"; - r += `<br>${slave.slaveName}'s living standard has been set to normal, since there is no room for her to occupy.`; - } - } else { - slave.livingRules = rule.livingRules; - r += `<br>${slave.slaveName}'s living standard has been set to ${rule.livingRules}.`; - } - } + class DietBaseList extends List { + constructor() { + // TODO: better data structure? + const pairs = [ + ["No default setting", {cum: "no default setting", milk: "no default setting"}], + ["Normal Diet", {cum: 0, milk: 0}], + ["Cum Added", {cum: 1, milk: 0}], + ["Milk Added", {cum: 0, milk: 1}], + ["Cum & Milk Added", {cum: 1, milk: 1}], + ["Cum-Based", {cum: 2, milk: 0}], + ["Milk-Based", {cum: 0, milk: 2}], + ]; + super("Diet base", pairs); + this.setValue(this.value2string(current_rule.set.dietCum, current_rule.set.dietMilk)); + this.onchange = (value) => { + current_rule.set.dietCum = value.cum; + current_rule.set.dietMilk = value.milk; + }; + } + + value2string(cum, milk) { + return `cum: ${cum}, milk: ${milk}`; + } + + setValue(what) { + what = this.value2string(what.cum, what.milk); + super.setValue(what); } + } - function ProcessSpeech(slave, rule) { - if ((rule.speechRules !== undefined) && (rule.speechRules !== "no default setting")) { - if ((slave.fetish == "mindbroken")) { - if ((slave.speechRules !== "restrictive")) { - slave.speechRules = "restrictive"; - r += `<br>Since ${slave.slaveName} is mindbroken her speech rules have been set to restrictive.`; - } - } else if ((slave.speechRules !== rule.speechRules)) { - slave.speechRules = rule.speechRules; - r += `<br>${slave.slaveName}'s speech rules have been set to ${rule.speechRules}.`; - } + class MuscleList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Toned", 20], + ["Ripped", 50], + ["Massive", 100], + ["Weak", -20] + ]; + super("Muscles", pairs, true); + this.setValue(current_rule.set.muscles); + this.onchange = (value) => current_rule.set.muscles = value; } } - function ProcessRelationship(slave, rule) { - if ((slave.fetish !== "mindbroken")) { - if ((rule.relationshipRules !== undefined) && (rule.relationshipRules !== "no default setting")) { - if ((slave.relationshipRules !== rule.relationshipRules )) { - slave.relationshipRules = rule.relationshipRules ; - r += `<br>${slave.slaveName}'s relationship rules have been set to ${rule.relationshipRules}.`; - } - } + class BraceList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", "none"], + ["Straighten", "straighten"], + ["Universal", "universal"] + ]; + super("Braces", pairs); + this.setValue(current_rule.set.teeth); + this.onchange = (value) => current_rule.set.teeth = value; } } - function ProcessRelease(slave, rule) { - if ((rule.releaseRules !== undefined) && (rule.releaseRules !== "no default setting")) { - let _release = 0; - if (rule.releaseRules === "restrictive" && - !(["serve the public", "serve in the club", "whore", "work in the brothel", "please you", "serve in the master suite", "be a subordinate slave", "work a glory hole", "be confined in the arcade", "get milked", "work in the dairy", "be your Head Girl"].contains(slave.assignment))) - _release = 1; - else - _release = 1; - if ((slave.fetish == "mindbroken") && (slave.releaseRules !== "permissive")) { - slave.releaseRules = "permissive"; - r += `<br>Since ${slave.slaveName} is mindbroken her masturbation rules have been set to permissive.`; - } else if ((slave.amp === 1 || slave.fuckdoll > 0) && (slave.releaseRules === "masturbation")) { - slave.releaseRules = "restrictive"; - r += `<br>Since ${slave.slaveName} is unable to masturbate, her masturbation rules have been set to restrictive.`; - } else if ((_release !== 0) && (slave.releaseRules !== rule.releaseRules)) { - slave.releaseRules = rule.releaseRules; - r += `<br>${slave.slaveName}'s masturbation rules have been set to ${rule.releaseRules}.`; - } + class LivingStandardList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Luxurious", "luxurious"], + ["Normal", "normal"], + ["Spare", "spare"] + ]; + super("Living standard", pairs); + this.setValue(current_rule.set.livingRules); + this.onchange = (value) => current_rule.set.livingRules = value; } } - function ProcessPunishment(slave, rule) { - if ((rule.standardPunishment !== undefined) && (rule.standardPunishment !== "no default setting")) { - if ((slave.standardPunishment !== rule.standardPunishment)) { - slave.standardPunishment = rule.standardPunishment ; - r += `<br>${slave.slaveName}'s typical punishment has been updated to ${rule.standardPunishment}.`; - } + class PunishmentList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Confinement", "confinement"], + ["Whipping", "whipping"], + ["Chastity", "chastity"], + ["Situational", "situational"] + ]; + super("Typical punishment", pairs); + this.setValue(current_rule.set.standardPunishment); + this.onchange = (value) => current_rule.set.standardPunishment = value; } } - function ProcessReward(slave, rule) { - if ((rule.standardReward !== undefined) && (rule.standardReward !== "no default setting")) { - if ((slave.standardReward !== rule.standardReward)) { - slave.standardReward = rule.standardReward ; - r += `<br>${slave.slaveName}'s typical reward has been updated to ${rule.standardReward}.`; - } + class RewardList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Relaxation", "relaxation"], + ["Drugs", "drugs"], + ["Orgasm", "orgasm"], + ["Situational", "situational"] + ]; + super("Typical reward", pairs); + this.setValue(current_rule.set.standardReward); + this.onchange = (value) => current_rule.set.standardReward = value; } } - function ProcessDietCum(slave, rule) { - if ((rule.dietCum !== undefined) && (rule.dietCum !== "no default setting")) { - if (slave.dietCum != rule.dietCum) { - slave.dietCum = rule.dietCum; - if (slave.dietCum == 2) { - r += `<br>${slave.slaveName} has been put on a diet based on cum.`; - slave.dietMilk = 0; - } - if (slave.dietCum == 1) - r += `<br>${slave.slaveName} has had cum added to her diet.`; - else - r += `<br>${slave.slaveName} has had cum removed from her diet.`; - } + class ReleaseList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Permissive", "permissive"], + ["Sapphic", "sapphic"], + ["Masturbation", "masturbation"], + ["Restrictive", "restrictive"] + ]; + super("Release rules", pairs); + this.setValue(current_rule.set.releaseRules); + this.onchange = (value) => current_rule.set.releaseRules = value; } } - function ProcessDietMilk(slave, rule) { - if ((rule.dietMilk !== undefined) && (rule.dietMilk !== "no default setting")) { - if (slave.dietMilk != rule.dietMilk) { - slave.dietMilk = rule.dietMilk; - if (slave.dietMilk == 2) { - r += `<br>${slave.slaveName} has been put on a diet based on human milk.`; - slave.dietCum = 0; - } - if (slave.dietMilk == 1) - r += `<br>${slave.slaveName} has had human milk added to her diet.`; - else - r += `<br>${slave.slaveName} has had human milk removed from her diet.`; - } + class SmartFetishList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Vanilla", "vanilla"], + ["Oral", "oral"], + ["Anal", "anal"], + ["Boobs", "boobs"], + ["Sub", "submissive"], + ["Dom", "dom"], + ["Humiliation", "humiliation"], + ["Preg", "pregnancy"], + ["Pain", "masochist"], + ["Sadism", "sadist"] + ]; + super("Smart piercing fetish target", pairs); + this.setValue(current_rule.set.clitSetting); + this.onchange = (value) => current_rule.set.clitSetting = value; } } - function ProcessTeeth(slave, rule) { - if ((rule.teeth !== undefined) && (rule.teeth !== "no default setting")) { - if ((rule.teeth == "universal")) { - if ((slave.teeth == "crooked")) { - slave.teeth = "straightening braces"; - V.cash -= V.surgeryCost; - r += `<br>${slave.slaveName} has been given braces for her crooked teeth.`; - } else if ((slave.teeth == "normal")) { - slave.teeth = "cosmetic braces"; - V.cash -= V.surgeryCost; - r += `<br>${slave.slaveName} has been given cosmetic braces.`; - } - } else if ((rule.teeth == "straighten")) { - if ((slave.teeth == "crooked")) { - slave.teeth = "straightening braces"; - V.cash -= V.surgeryCost; - r += `<br>${slave.slaveName} has been given braces for her crooked teeth.`; - } else if ((slave.teeth == "cosmetic braces")) { - slave.teeth = "normal"; - r += `<br>${slave.slaveName} has gotten her braces off, since her teeth are straight.`; - } - } else if ((rule.teeth == "none")) { - if ((slave.teeth == "straightening braces")) { - slave.teeth = "crooked"; - r += `<br>${slave.slaveName} has gotten her braces off.`; - } else if ((slave.teeth == "cosmetic braces")) { - slave.teeth = "normal"; - r += `<br>${slave.slaveName} has gotten her braces off.`; - } - } + class SmartXYAttractionList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Passionate", 100], + ["Attracted", 75], + ["Indifferent", 45], + ["None", 0] + ]; + super("Smart piercing XY attraction target", pairs); + this.setValue(current_rule.set.clitSettingXY); + this.onchange = (value) => current_rule.set.clitSettingXY = value; } } - function ProcessStyle(slave, rule) { - if (rule.eyeColor !== undefined && (rule.eyeColor !== "no default setting")) { - if ((slave.eyeColor !== rule.eyeColor)) { - slave.eyeColor = rule.eyeColor; - V.cash -= V.modCost; - r += `<br>${slave.slaveName} has been given ${slave.eyeColor} contact lenses.`; - } + class SmartXXAttractionList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Passionate", 100], + ["Attracted", 75], + ["Indifferent", 45], + ["None", 0] + ]; + super("Smart piercing XX attraction target", pairs); + this.setValue(current_rule.set.clitSettingXX); + this.onchange = (value) => current_rule.set.clitSettingXX = value; } + } - if (rule.makeup !== undefined && (rule.makeup !== "no default setting")) { - if ((slave.makeup !== rule.makeup)) { - slave.makeup = rule.makeup; - V.cash -= V.modCost; - r += `<br>${slave.slaveName} has been assigned the standard makeup.`; - } + class SmartEnergyList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Nympho", 100], + ["Sex Addict", 85], + ["Powerful", 65], + ["Healthy", 45], + ["Weak", 25], + ["Frigid", 0] + ]; + super("Smart piercing sex drive target", pairs); + this.setValue(current_rule.set.clitSettingEnergy); + this.onchange = (value) => current_rule.set.clitSettingEnergy = value; } + } - if ((slave.amp != 1)) { - if (rule.nails !== undefined && (rule.nails !== "no default setting")) { - if ((slave.nails !== rule.nails)) { - slave.nails = rule.nails; - V.cash -= V.modCost; - r += `<br>${slave.slaveName} has been assigned the standard nails.`; - } - } + class SpeechList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["Permissive", "permissive"], + ["Suppress accents", "accent elimination"], + ["Restrictive", "restrictive"] + ]; + super("Speech rules", pairs); + this.setValue(current_rule.set.speechRules); + this.onchange = (value) => current_rule.set.speechRules = value; } + } - if (rule.hColor !== undefined && (rule.hColor !== "no default setting")) { - if (slave.bald != 1) { - if ((slave.hColor !== rule.hColor)) { - slave.hColor = rule.hColor; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s hair has been dyed ${rule.hColor}.`; - } - } + class RelationshipList extends List { + constructor() { + const pairs =[ + ["No default setting", "no default setting"], + ["Permissive", "permissive"], + ["Just friends", "just friends"], + ["Restrictive", "restrictive"] + ]; + super("Relationship rules", pairs); + this.setValue(current_rule.set.relationshipRules); + this.onchange = (value) => current_rule.set.relationshipRules = value; } + } - if (rule.hStyle !== undefined && (rule.hStyle !== "no default setting")) { - if (slave.bald != 1) { - if ((slave.hStyle !== rule.hStyle)) { - slave.hStyle = rule.hStyle; - V.cash -= V.modCost; - if ((rule.hStyle == "shaved")) { - slave.hLength = 0; - r += `<br>${slave.slaveName}'s hair has been shaved.`; - } else - r += `<br>${slave.slaveName}'s hair has been restyled.`; - } - } + class PornList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["No broadcasting", -1], + ["No subsidy", 0], + ["1000", 1000], + ["2000", 2000], + ["3000", 3000], + ["4000", 4000], + ["5000", 5000] + ]; + super("Weekly porn publicity subsidy", pairs); + this.setValue(current_rule.set.pornFameSpending); + this.onchange = (value) => current_rule.set.pornFameSpending = value; } + } - if (rule.hLength !== undefined && (rule.hLength !== "no default setting")) { - if (slave.bald != 1) { - if ((slave.hLength !== rule.hLength)) { - if ((slave.hLength > rule.hLength)) { - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s hair has been cut; it `; - } else { - V.cash -= V.modCost*Math.trunc((rule.hLength-slave.hLength)/10); - r += `<br>${slave.slaveName} has been given extensions; her hair `; - } - r += `is now ${rule.hLength} cm long.`; - slave.hLength = rule.hLength; - } - } + class EyewearList extends List { + constructor() { + const pairs = [ + ["no default setting"], + ["correct with glasses"], + ["correct with contacts"], + ["universal glasses"], + ["blur with glasses"], + ["blur with contacts"] + ]; + super("Eyewear", pairs); + this.setValue(current_rule.set.eyewear); + this.onchange = (value) => current_rule.set.eyewear = value; } + } - if (rule.pubicHColor !== undefined && (rule.pubicHColor !== "no default setting")) { - if (slave.pubicHStyle != "bald" && slave.pubicHStyle != "hairless") { - if ((slave.pubicHColor !== rule.pubicHColor)) { - slave.pubicHColor = rule.pubicHColor; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s pubic hair, if present, has been dyed ${rule.pubicHColor}.`; - } - } + class LensesList extends Element { + constructor() { + super(current_rule.set.eyeColor); + this.appendChild(new OptionsItem("No default Setting", () => this.setValue("no default setting"))); + this.colourlist = new LensesColourList(); + this.shapelist = new LensesShapeList(); + this.appendChild(this.colourlist); + this.appendChild(this.shapelist); } - if (rule.pubicHStyle !== undefined && (rule.pubicHStyle !== "no default setting")) { - if (slave.pubicHStyle != "bald" && slave.pubicHStyle != "hairless") { - if ((slave.pubicHStyle !== rule.pubicHStyle)) { - slave.pubicHStyle = rule.pubicHStyle; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s pubic hair has been restyled; it is now ${rule.pubicHStyle}.`; - } - } + render(color) { + const elem = document.createElement("div"); + elem.innerHTML = "Eye coloring: "; + this.label = document.createElement("strong"); + this.label.innerText = color; + elem.appendChild(this.label); + return elem; } - if (rule.underArmHColor !== undefined && (rule.underArmHColor !== "no default setting")) { - if (slave.underArmHStyle != "bald" && slave.underArmHStyle != "hairless") { - if ((slave.underArmHColor !== rule.underArmHColor)) { - slave.underArmHColor = rule.underArmHColor; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s underarm hair, if present, has been dyed ${rule.underArmHColor}.`; - } - } + combine() { + const lst = []; + if (this.colourlist.value !== "no default setting") + lst.push(this.colourlist.value); + if (this.shapelist.value !== "no default setting") + lst.push(this.shapelist.value); + if (lst.length === 0) return "no default value"; + else return lst.join(" "); } - if (rule.underArmHStyle !== undefined && (rule.underArmHStyle !== "no default setting")) { - if (slave.underArmHStyle != "bald" && slave.underArmHStyle != "hairless") { - if ((slave.underArmHStyle !== rule.underArmHStyle)) { - slave.underArmHStyle = rule.underArmHStyle; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s underarm hair has been restyled; it is now ${rule.underArmHStyle}.`; - } - } + setValue(val) { + if (val === undefined) val = this.combine(); + this.label.innerText = val; + current_rule.set.eyeColor = val; } } - function ProcessPiercings(slave, rule) { - if (rule.nipplesPiercing !== undefined && (rule.nipplesPiercing !== "no default setting")) { - if ((slave.nipplesPiercing !== rule.nipplesPiercing)) { - if ((rule.nipplesPiercing === 0)) { - slave.nipplesPiercing = 0; - r += `<br>${slave.slaveName}'s nipple piercings have been removed.`; - } else if (slave.nipples !== "fuckable") { - slave.nipplesPiercing = rule.nipplesPiercing; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s nipples have been pierced.`; - } else { - r += `<br>${slave.slaveName}'s nipples are inverted and cannot be pierced.`; - } - } + class LensesColourList extends Options { + constructor() { + const items = []; + [ + "no default setting", + "blue", + "black", + "brown", + "green", + "turquoise", + "sky-blue", + "hazel", + "pale-grey", + "white", + "pink", + "amber", + "red" + ].forEach(i => items.push(new OptionsItem(i, item => { + this.value = item.label; + this.parent.setValue(); + }))); + super(items); } + } - if (rule.areolaePiercing !== undefined && (rule.areolaePiercing !== "no default setting")) { - if ((slave.areolaePiercing !== rule.areolaePiercing)) { - if ((rule.areolaePiercing === 0)) { - slave.areolaePiercing = 0; - r += `<br>${slave.slaveName}'s areolae piercings have been removed.`; - } else { - slave.areolaePiercing = rule.areolaePiercing; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s areolae have been given stud piercings.`; - } - } + class LensesShapeList extends Options { + constructor() { + const items = []; + [ + "no default setting", + "catlike", + "serpent-like", + "devilish", + "demonic", + "hypnotic", + "heart-shaped", + "wide-eyed", + "almond-shaped", + "bright", + "teary", + "vacant" + ].forEach(i => items.push(new OptionsItem(i, item => { + this.value = item.label; + this.parent.setValue(); + }))); + super(items); } + } - if (rule.clitPiercing !== undefined && (rule.clitPiercing !== "no default setting")) { - if ((slave.clitPiercing !== rule.clitPiercing)) { - if ((rule.clitPiercing === 0)) { - slave.clitPiercing = 0; - if (slave.dick > 0) - r += `<br>${slave.slaveName}'s frenulum piercing has been removed.`; - else - r += `<br>${slave.slaveName}'s clit piercing has been removed.`; - - } else if ((slave.vagina != -1) || (slave.dick !== 0)) { - slave.clitPiercing = rule.clitPiercing; - if (slave.dick > 0) - r += `<br>${slave.slaveName}'s frenulum has been pierced.`; - else - r += `<br>${slave.slaveName}'s clit has been pierced.`; + class MakeupList extends List { + constructor() { + super("Makeup"); + [ + ["no default setting"], + ["makeup-free", 0], + ["nice", 1], + ["gorgeous", 2], + ["color-coordinate with hair", 3], + ["slutty", 4] + ].forEach(pair => this.appendChild(new ListItem(...pair))); + this.setValue(current_rule.set.makeup); + this.onchange = (value) => current_rule.set.makeup = value; + } + } - if (rule.clitPiercing == 3) - V.cash -= 1000; - else - V.cash -= V.modCost; - } - } + class NailsList extends List { + constructor() { + super("Nails"); + [ + ["no default setting"], + ["clipped", 0], + ["extended", 1], + ["color-coordinate with hair", 2], + ["sharp and claw-like", 3], + ["bright and glittery", 4], + ["hooker nails", 5] + ].forEach(pair => this.appendChild(new ListItem(...pair))); + this.setValue(current_rule.set.nails); + this.onchange = (value) => current_rule.set.nails = value; } + } - if ((slave.vagina != -1)) { - if (rule.vaginaPiercing !== undefined && (rule.vaginaPiercing !== "no default setting")) { - if ((slave.vaginaPiercing !== rule.vaginaPiercing)) { - if ((rule.vaginaPiercing === 0)) { - slave.vaginaPiercing = 0; - r += `<br>${slave.slaveName}'s labia piercings have been removed.`; - } else { - slave.vaginaPiercing = rule.vaginaPiercing; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s pussylips have been pierced.`; - } - } - } + class HairLengthList extends List { + constructor() { + const pairs = [ + ["no default setting"], + ["very short", 5], + ["short", 10], + ["shoulder length", 30], + ["long", 60], + ["very long", 100], + ["floor length", 150] + ]; + super("Hair length", pairs); + this.setValue(current_rule.set.hLength); + this.onchange = (value) => current_rule.set.hLength = value; } + } - if ((slave.dick > 0)) { - if (rule.dickPiercing !== undefined && (rule.dickPiercing !== "no default setting")) { - if ((slave.dickPiercing !== rule.dickPiercing)) { - if ((rule.dickPiercing === 0)) { - slave.dickPiercing = 0; - r += `<br>${slave.slaveName}'s shaft piercings have been removed.`; - } else { - slave.dickPiercing = rule.dickPiercing; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s shaft has been pierced.`; - } - } - } + class HaircutsList extends List { + constructor() { + const pairs = [ + ["no default setting"], + ["maintain hair length", 1], + ["do not maintain hair length", 0] + ]; + super("Hair length maintenance", pairs); + this.setValue(current_rule.set.haircuts); + this.onchange = (value) => current_rule.set.haircuts = value; } + } - if (rule.anusPiercing !== undefined && (rule.anusPiercing !== "no default setting")) { - if ((slave.anusPiercing !== rule.anusPiercing)) { - if ((rule.anusPiercing === 0)) { - slave.anusPiercing = 0; - r += `<br>${slave.slaveName}'s asshole piercings have been removed.`; - } else { - slave.anusPiercing = rule.anusPiercing; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s asshole has been pierced.`; - } - } + class HairColourList extends List { + constructor() { + const pairs = [ + ["no default setting"], + ["blonde"], + ["golden"], + ["platinum blonde"], + ["strawbery-blonde"], + ["copper"], + ["ginger"], + ["red"], + ["green"], + ["blue"], + ["pink"], + ["dark brown"], + ["brown"], + ["auburn"], + ["burgundy"], + ["chocolate"], + ["chestnut"], + ["hazel"], + ["black"], + ["grey"], + ["silver"], + ["white"], + ["blue-violet"], + ["blazing red"], + ["neon green"], + ["neon blue"], + ["neon pink"] + ]; + super("Hair color", pairs); + this.setValue(current_rule.set.hColor); + this.onchange = (value) => current_rule.set.hColor = value; } + } - if (rule.lipsPiercing !== undefined && (rule.lipsPiercing !== "no default setting")) { - if ((slave.lipsPiercing !== rule.lipsPiercing)) { - if ((rule.lipsPiercing === 0)) { - slave.lipsPiercing = 0; - r += `<br>${slave.slaveName}'s lip piercings have been removed.`; - } else { - slave.lipsPiercing = rule.lipsPiercing; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s lips have been pierced.`; - } - } + class HairStyleList extends List { + constructor() { + const pairs = [ + ["no default setting"], + ["neat"], + ["shaved"], + ["trimmed"], + ["buzzcut"], + ["up"], + ["ponytail"], + ["bun"], + ["messy bun"], + ["curled"], + ["permed"], + ["luxurious"], + ["dreadlocks"], + ["cornrows"], + ["braided"], + ["tails"], + ["afro"], + ["strip"] + ]; + super("Hair style", pairs); + this.setValue(current_rule.set.hStyle); + this.onchange = (value) => current_rule.set.hStyle = value; } + } - if (rule.tonguePiercing !== undefined && (rule.tonguePiercing !== "no default setting")) { - if ((slave.tonguePiercing !== rule.tonguePiercing)) { - if ((rule.tonguePiercing === 0)) { - slave.tonguePiercing = 0; - r += `<br>${slave.slaveName}'s tongue piercings have been removed.`; - } else { - slave.tonguePiercing = rule.tonguePiercing; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s tongue has been pierced.`; - } - } + class PubicHairColourList extends List { + constructor() { + const pairs = [ + ["no default setting"], + ["blonde"], + ["golden"], + ["platinum blonde"], + ["strawerry-blonde"], + ["copper"], + ["ginger"], + ["red"], + ["green"], + ["blue"], + ["pink"], + ["dark brown"], + ["brown"], + ["auburn"], + ["burgundy"], + ["chocolate"], + ["chestnut"], + ["hazel"], + ["black"], + ["grey"], + ["silver"], + ["white"], + ["blue-violet"], + ["blazing red"], + ["neon green"], + ["neon blue"], + ["neon pink"] + ]; + super("Pubic hair color, when present", pairs); + this.setValue(current_rule.set.pubicHColor); + this.onchange = (value) => current_rule.set.pubicHColor = value; } + } - if (rule.earPiercing !== undefined && (rule.earPiercing !== "no default setting")) { - if ((slave.earPiercing !== rule.earPiercing)) { - if ((rule.earPiercing === 0)) { - slave.earPiercing = 0; - r += `<br>${slave.slaveName}'s ear piercings have been removed.`; - } else { - slave.earPiercing = rule.earPiercing; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s ears have been pierced.`; - } - } + class PubicHairStyleList extends List { + constructor() { + const pairs = [ + ["no default setting"], + ["waxed"], + ["in a strip"], + ["neat"], + ["bushy"], + ["bushy in the front and neat in the rear"], + ["very bushy"] + ]; + super("Pubic hairstyle", pairs); + this.setValue(current_rule.set.pubicHStyle); + this.onchange = (value) => current_rule.set.pubicHStyle = value; } + } - if (rule.nosePiercing !== undefined && (rule.nosePiercing !== "no default setting")) { - if ((slave.nosePiercing !== rule.nosePiercing)) { - if ((rule.nosePiercing === 0)) { - slave.nosePiercing = 0; - r += `<br>${slave.slaveName}'s nose piercing has been removed.`; - } else { - slave.nosePiercing = rule.nosePiercing; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s nose has been pierced.`; - } - } + class ArmpitHairColourList extends List { + constructor() { + const pairs = [ + ["no default setting"], + ["blonde"], + ["golden"], + ["platinum blonde"], + ["strawberry-blonde"], + ["copper"], + ["ginger"], + ["red"], + ["green"], + ["blue"], + ["pink"], + ["dark brown"], + ["brown"], + ["auburn"], + ["burgundry"], + ["chocolate"], + ["chestnut"], + ["hazel"], + ["black"], + ["grey"], + ["silver"], + ["white"], + ["blue-violet"], + ]; + super("Underarm hair color, when present", pairs); + this.setValue(current_rule.set.underArmHColor); + this.onchange = (value) => current_rule.set.underArmHColor = value; } + } - if (rule.eyebrowPiercing !== undefined && (rule.eyebrowPiercing !== "no default setting")) { - if ((slave.eyebrowPiercing !== rule.eyebrowPiercing)) { - if ((rule.eyebrowPiercing === 0)) { - slave.eyebrowPiercing = 0; - r += `<br>${slave.slaveName}'s eyebrow piercings have been removed.`; - } else { - slave.eyebrowPiercing = rule.eyebrowPiercing; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s eyebrows have been pierced.`; - } - } + class ArmpitHairStyleList extends List { + constructor() { + const pairs = [ + ["no default setting"], + ["waxed"], + ["shaved"], + ["neat"], + ["bushy"] + ]; + super("Underarm hair style", pairs); + this.setValue(current_rule.set.underArmHStyle); + this.onchange = (value) => current_rule.set.underArmHStyle = value; } + } - if (rule.navelPiercing !== undefined && (rule.navelPiercing !== "no default setting")) { - if ((slave.navelPiercing !== rule.navelPiercing)) { - if ((rule.navelPiercing === 0)) { - slave.navelPiercing = 0; - r += `<br>${slave.slaveName}'s navel piercing have been removed.`; - } else { - slave.navelPiercing = rule.navelPiercing; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s navel has been pierced.`; - } - } + class EarPiercingList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Light", 1], + ["Heavy", 2] + ]; + super("Ear piercings", pairs); + this.setValue(current_rule.set.earPiercing); + this.onchange = (value) => current_rule.set.earPiercing = value; } + } - if (rule.corsetPiercing !== undefined && (rule.corsetPiercing !== "no default setting")) { - if ((slave.corsetPiercing !== rule.corsetPiercing)) { - if ((rule.corsetPiercing === 0)) { - slave.corsetPiercing = 0; - r += `<br>${slave.slaveName}'s corset piercings have been removed.`; - } else { - slave.corsetPiercing = rule.corsetPiercing; - V.cash -= V.modCost; - r += `<br>${slave.slaveName} has been given a set of corset piercings.`; - } - } + class NosePiercingList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Light", 1], + ["Heavy", 2] + ]; + super("Nasal piercings", pairs); + this.setValue(current_rule.set.nosePiercing); + this.onchange = (value) => current_rule.set.earPiercing = value; } } - function ProcessSmartPiercings(slave, rule) { - if ((slave.clitPiercing == 3)) { - let _used = 0; - if (rule.clitSetting !== undefined && (rule.clitSetting !== "no default setting")) { - if (slave.clitSetting !== rule.clitSetting) { - slave.clitSetting = rule.clitSetting; - _used = 1; - r += `<br>${slave.slaveName}'s smart piercing has been set to ${slave.clitSetting}.`; - } else if (slave.fetishStrength < 100) { - _used = 1; - } - } - if (_used === 0) { - if (rule.clitSettingEnergy !== undefined && (rule.clitSettingEnergy !== "no default setting")) { - if (slave.energy < rule.clitSettingEnergy) { - if (slave.clitSetting !== "all") { - r += `<br>${slave.slaveName}'s smart piercing has been set to enhance libido.`; - } - slave.clitSetting = "all"; - _used = 1; - } else if (slave.energy >= rule.clitSettingEnergy + 10) { - if (slave.clitSetting !== "none") { - r += `<br>${slave.slaveName}'s smart piercing has been set to suppress libido.`; - } - slave.clitSetting = "none"; - _used = 1; - } - } - } - if (_used === 0) { - if (rule.clitSettingXY !== undefined && (rule.clitSettingXY !== "no default setting")) { - if (slave.attrXY < rule.clitSettingXY) { - if (slave.clitSetting !== "men") { - r += `<br>${slave.slaveName}'s smart piercing has been set to encourage attraction to men.`; - } - slave.clitSetting = "men"; - _used = 1; - } else if (slave.attrXY >= rule.clitSettingXY + 10) { - if (slave.clitSetting !== "anti-men") { - r += `<br>${slave.slaveName}'s smart piercing has been set to discourage attraction to men.`; - } - slave.clitSetting = "anti-men"; - _used = 1; - } - } - } - if (_used === 0) { - if (rule.clitSettingXX !== undefined && (rule.clitSettingXX !== "no default setting")) { - if (slave.attrXX < rule.clitSettingXX) { - if (slave.clitSetting !== "women") { - r += `<br>${slave.slaveName}'s smart piercing has been set to encourage attraction to women.`; - } - slave.clitSetting = "women"; - _used = 1; - } else if (slave.attrXX >= rule.clitSettingXX + 10) { - if (slave.clitSetting !== "anti-women") { - r += `<br>${slave.slaveName}'s smart piercing has been set to discourage attraction to women.`; - } - slave.clitSetting = "anti-women"; - _used = 1; - } - } - } + class EyebrowPiercingList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Light", 1], + ["Heavy", 2] + ]; + super("Eyebrow piercings", pairs); + this.setValue(current_rule.set.eyebrowPiercing); + this.onchange = (value) => current_rule.set.eyebrowPiercing = value; } } - function ProcessTattoos(slave, rule) { - if (rule.boobsTat !== undefined && (rule.boobsTat !== "no default setting")) { - if ((slave.boobsTat !== rule.boobsTat)) { - slave.boobsTat = rule.boobsTat; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s chest has been tattooed.`; - } + class NavelPiercingList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Light", 1], + ["Heavy", 2] + ]; + super("Navel piercings", pairs); + this.setValue(current_rule.set.navelPiercing); + this.onchange = (value) => current_rule.set.navelPiercing = value; } + } - if (rule.buttTat !== undefined && (rule.buttTat !== "no default setting")) { - if ((slave.buttTat !== rule.buttTat)) { - slave.buttTat = rule.buttTat; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s butt has been tattooed.`; - } + class NipplePiercingList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Light", 1], + ["Heavy", 2] + ]; + super("Nipple piercings", pairs); + this.setValue(current_rule.set.nipplesPiercing); + this.onchange = (value) => current_rule.set.nipplesPiercing = value; } + } - if (rule.vaginaTat !== undefined && (rule.vaginaTat !== "no default setting")) { - if ((slave.vaginaTat !== rule.vaginaTat)) { - slave.vaginaTat = rule.vaginaTat; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s abdomen has been tattooed.`; - } + class AreolaPiercingList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Studded", 1] + ]; + super("Areola studs", pairs); + this.setValue(current_rule.set.areolaePiercing); + this.onchange = (value) => current_rule.set.areolaePiercing = value; } + } - if ((slave.dick > 0)) { - if (rule.dickTat !== undefined && (rule.dickTat !== "no default setting")) { - if ((slave.dickTat !== rule.dickTat)) { - slave.dickTat = rule.dickTat; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s dick has been tattooed.`; - } - } + class LipPiercingList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Light", 1], + ["Heavy", 2] + ]; + super("Lip piercings", pairs); + this.setValue(current_rule.set.lipsPiercing); + this.onchange = (value) => current_rule.set.lipsPiercing = value; } + } - if (rule.lipsTat !== undefined && (rule.lipsTat !== "no default setting")) { - if ((slave.lipsTat !== rule.lipsTat)) { - slave.lipsTat = rule.lipsTat; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s face has been tattooed.`; - } + class TonguePiercingList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Light", 1], + ["Heavy", 2] + ]; + super("Tongue piercing", pairs); + this.setValue(current_rule.set.tonguePiercing); + this.onchange = (value) => current_rule.set.tonguePiercing = value; } + } - if (rule.anusTat !== undefined && (rule.anusTat !== "no default setting")) { - if ((slave.anusTat !== rule.anusTat)) { - slave.anusTat = rule.anusTat; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s asshole has been modded.`; - } + class ClitPiercingList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Light", 1], + ["Heavy", 2], + ["Smart (expensive)", 3] + ]; + super("Clit piercing", pairs); + this.setValue(current_rule.set.clitPiercing); + this.onchange = (value) => current_rule.set.clitPiercing = value; } + } - if (rule.shouldersTat !== undefined && (rule.shouldersTat !== "no default setting")) { - if ((slave.shouldersTat !== rule.shouldersTat)) { - slave.shouldersTat = rule.shouldersTat; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s shoulders have been tattooed.`; - } + class LabiaPiercingList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Light", 1], + ["Heavy", 2] + ]; + super("Pussylips piercings", pairs); + this.setValue(current_rule.set.vaginaPiercing); + this.onchange = (value) => current_rule.set.vaginaPiercing = value; } + } - if (rule.armsTat !== undefined && (rule.armsTat !== "no default setting")) { - if ((slave.armsTat !== rule.armsTat)) { - slave.armsTat = rule.armsTat; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s arms have been tattooed.`; - } + class ShaftPiercingList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Light", 1], + ["Heavy", 2] + ]; + super("Shaft piercings", pairs); + this.setValue(current_rule.set.dickPiercing); + this.onchange = (value) => current_rule.set.dickPiercing = value; } + } - if (rule.legsTat !== undefined && (rule.legsTat !== "no default setting")) { - if ((slave.legsTat !== rule.legsTat)) { - slave.legsTat = rule.legsTat; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s legs have been tattooed.`; - } + class PerineumPiercingList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Light", 1], + ["Heavy", 2] + ]; + super("Perianal piercings", pairs); + this.setValue(current_rule.set.anusPiercing); + this.onchange = (value) => current_rule.set.anusPiercing = value; } + } - if (rule.stampTat !== undefined && (rule.stampTat !== "no default setting")) { - if ((slave.stampTat !== rule.stampTat)) { - slave.stampTat = rule.stampTat; - V.cash -= V.modCost; - r += `<br>${slave.slaveName}'s lower back has been tattooed.`; - } - } - if ((rule.autoBrand == 1)) { - if ((slave.brand === 0)) { - if ((slave.health > -20)) { - slave.brand = V.brandDesign; - slave.brandLocation = V.brandTarget; - if ((slave.devotion < 18)) - slave.devotion -= 5; - slave.trust -= 5; - slave.health -= 10; - r += `<br>${slave.slaveName} has been branded, with <span class="gold">fear</span>${slave.devotion < 18? `, <span class="mediumorchid">regard,</span>`:``} and <span class="red">health</span> consequences.`; - } - } + class CorsetPiercingList extends List { + constructor() { + const pairs = [ + ["No default setting", "no default setting"], + ["None", 0], + ["Apply", 1] + ]; + super("Corset piercings", pairs); + this.setValue(current_rule.set.corsetPiercing); + this.onchange = (value) => current_rule.set.corsetPiercing = value; } } - function ProcessPorn(slave, rule) { - if ((rule.pornFameSpending !== undefined) && (rule.pornFameSpending !== "no default setting")) { - if ((slave.prestige < 3)) { - if ((slave.pornFameSpending !== rule.pornFameSpending)) { - slave.pornFameSpending = rule.pornFameSpending; - r += `<br>${slave.slaveName}'s porn publicity has been corrected.`; - } - } + class AutoBrandingList extends List { + constructor() { + const pairs = [ + ["Activate", 1], + ["Off", 0], + ]; + super("Automatic branding", pairs); + this.setValue(current_rule.set.autoBrand); + this.onchange = (value) => current_rule.set.autoBrand = value; } } - return DefaultRules; -})(); + class BrandingLocationList extends List { + constructor() { + super("Your preferred location for brands is", []); -/*:: Rules Assistant Options [script]*/ -// rewrite of the rules assistant options page in javascript -// uses an object-oriented widget pattern -// wrapped in a closure so as not to polute the global namespace -// the widgets are generic enough to be reusable; if similar user interfaces are ported to JS, we could move the classes to the global scope + const ears = new ListSubSection(this, "Ears", [ + ["Left", "left ear"], + ["Right", "right ear"], + ["Both", "ears"] + ]); + this.appendChild(ears); -window.rulesAssistantOptions = (function() { - "use strict"; - let V, current_rule; + const cheeks = new ListSubSection(this, "Cheeks", [ + ["Left", "left cheek"], + ["Right", "right cheek"], + ["Both", "cheeks"] + ]); + this.appendChild(cheeks); - function rulesAssistantOptions(element) { - V = State.variables; - V.nextButton = "Back to Main"; - V.nextLink = "Main"; - V.returnTo = "Main"; - V.showEncyclopedia = 1; - V.encyclopedia = "Personal Assistant"; - if (V.currentRule !== null) { - const idx = V.defaultRules.findIndex(rule => rule.ID === V.currentRule); - if (idx === -1) - current_rule = V.defaultRules[0]; - else - current_rule = V.defaultRules[idx]; - } - const root = new Root(element); - } + const shoulders = new ListSubSection(this, "Shoulders", [ + ["Left", "left shoulder"], + ["Right", "right shoulder"], + ["Both", "shoulders"] + ]); + this.appendChild(shoulders); - function returnP(e) { return e.keyCode === 13; } + const breasts = new ListSubSection(this, "Breasts", [ + ["Left", "right breast"], + ["Right", "left breast"], + ["Both", "breasts"] + ]); + this.appendChild(breasts); - function newRule(root) { - const rule = emptyDefaultRule(); - V.defaultRules.push(rule); - V.currentRule = rule.ID; - reload(root); - } + const upper_arms = new ListSubSection(this, "Arms, upper", [ + ["Left", "left upper arm"], + ["Right", "right upper arm"], + ["Both", "upper arms"] + ]); + this.appendChild(upper_arms); - function removeRule(root) { - const idx = V.defaultRules.findIndex(rule => rule.ID === current_rule.ID); - V.defaultRules.splice(idx, 1); - if (V.defaultRules.length > 0) { - const new_idx = idx < V.defaultRules.length ? idx : V.defaultRules.length - 1; - V.currentRule = V.defaultRules[new_idx].ID; - } else V.currentRule = null; - reload(root); - } + const lower_arms = new ListSubSection(this, "Arms, lower", [ + ["Left", "left lower arm"], + ["Right", "right lower arm"], + ["Both", "lower arms"] + ]); + this.appendChild(lower_arms); - function lowerPriority(root) { - if (V.defaultRules.length === 1) return; // nothing to swap with - const idx = V.defaultRules.findIndex(rule => rule.ID === current_rule.ID); - if (idx === 0) return; // no lower rule - arraySwap(V.defaultRules, idx, idx-1); - reload(root); - } + const wrist = new ListSubSection(this, "Wrist", [ + ["Left", "left wrist"], + ["Right", "right wrist"], + ["Both", "wrists"] + ]); + this.appendChild(wrist); + + const hand = new ListSubSection(this, "Hand", [ + ["Left", "left hand"], + ["Right", "right hand"], + ["Both", "hands"] + ]); + this.appendChild(hand); + + const buttocks = new ListSubSection(this, "Buttocks", [ + ["Left", "left buttock"], + ["Right", "right buttock"], + ["Both", "buttocks"] + ]); + this.appendChild(buttocks); + + const thigh = new ListSubSection(this, "Thigh", [ + ["Left", "left thigh"], + ["Right", "right thigh"], + ["Both", "thighs"] + ]); + this.appendChild(thigh); + + const calf = new ListSubSection(this, "Calf", [ + ["Left", "left calf"], + ["Right", "right calf"], + ["Both", "calves"] + ]); + this.appendChild(calf); + + const ankle = new ListSubSection(this, "Ankle", [ + ["Left", "left ankle"], + ["Right", "right ankle"], + ["Both", "ankles"] + ]); + this.appendChild(ankle); + + const feet = new ListSubSection(this, "Feet", [ + ["Left", "left foot"], + ["Right", "right foot"], + ["Both", "feet"] + ]); + this.appendChild(feet); + + const other = new ListSubSection(this, "Other", [ + ["Neck", "neck"], + ["Chest", "chest"], + ["Belly", "belly"], + ["Pubic mound", "pubic mound"], + ["Back", "back"], + ["Lower Back", "lower back"] + ]); + this.appendChild(other); - function higherPriority(root) { - if (V.defaultRules.length === 1) return; // nothing to swap with - const idx = V.defaultRules.findIndex(rule => rule.ID === current_rule.ID); - if (idx === V.defaultRules.length - 1) return; // no higher rule - arraySwap(V.defaultRules, idx, idx+1); - reload(root); + this.setValue(V.brandTarget); + this.onchange = (value) => V.brandTarget = value; + } } - function changeName(name, root) { - if (name === current_rule.name) return; - current_rule.name = name; - reload(root); - } + class BrandDesignList extends List { + constructor() { + const items = [ + ["Your slaving emblem", "your personal symbol"], + ["Your initials", "your initials"], + ["SLUT"], + ["WHORE"], + ["SLAVE"], + ["COW"], + ["MEAT"], + ["CUMDUMP"], + ["LOVER"], + ["Pussy symbol", "a pussy symbol"], + ["Anus symbol", "an anus symbol"], + ["Penis symbol", "a penis symbol"], + ["Lady", "a lady silhouette"], + ["Princess", "a princess silhouette"], + ["Queen", "a queen silhouette"], + ["Angel", "an angel silhouette"], + ["Devil", "a devil silhouette"] + ]; + + if (V.arcologies[0].FSSupremacist !== "unset" || V.arcologies[0].FSSubjugationist !== "unset") + items.push(["(FS) Racial Slur", "a racial slur"]); + + if (V.arcologies[0].FSSupremacist !== "unset" && V.arcologies[0].FSSupremacistRace === "white") + items.push(["(FS) Swastika", "a swastika"]); + + if (V.arcologies[0].FSSubjugationist !== "unset" && V.arcologies[0].FSSubjugationistRace === "semitic") + items.push(["(FS) Star of David", "a Star of David"]); - // reload the passage - function reload(root) { - const elem = root.element; - elem.innerHTML = ""; - rulesAssistantOptions(elem); - } + if (V.arcologies[0].FSGenderRadicalist !== "unset" || V.arcologies.FSGenderFundamentalist !== "unset") + items.push(["(FS) Gender Symbol", "a gender symbol"]); - const parse = { - integer(string) { - let n = parseInt(string, 10); - return isNaN(n)? 0: n; - }, - boobs(string) { - return Math.clamp(parse.integer(string), 0, 48000); - }, - butt(string) { - return Math.clamp(parse.integer(string), 0, 20); - }, - lips(string) { - return Math.clamp(parse.integer(string), 0, 100); - }, - dick(string) { - return Math.clamp(parse.integer(string), 0, 30); - }, - balls(string) { - return Math.clamp(parse.integer(string), 0, 125); - }, - }; + if (V.arcologies[0].FSPaternalist !== "unset") + items.push(["(FS) Personal Symbol", "her own personal symbol"]); - // the Element class wraps around a DOM element and adds extra functionality - // this is safer than extending DOM objects directly - // it also turns DOM manipulation into an implementation detail - class Element { - constructor(...args) { - this.parent = null; - this.element = this.render(...args); - this.children = []; - } + if (V.arcologies[0].FSDegradationist !== "unset") + items.push(["(FS) Chain Symbol", "a chain symbol"]); - appendChild(child) { - child.parent = this; - this.children.push(child); - this.element.appendChild(child.element); - } + if (V.arcologies[0].FSBodyPurist !== "unset") + items.push(["(FS) Vitruvian Man", "a Vitruvian man"]); - // return the first argument to simplify creation of basic container items - render(...args) { - return args[0]; - } + if (V.arcologies[0].FSTransformationFetishist !== "unset") + items.push(["(FS) Most Desired Implants", "a shortlist of desired implants"]); - remove() { - const idx = this.parent.children.findIndex(child => child === this); - this.parent.children.slice(idx, 1); - this.element.remove(); - } - } - - class Section extends Element { - constructor(header, hidden=false) { - super(header); - this.hidey = this.element.querySelector("div"); - if (hidden) this.toggle_hidey(); - } - - render(header) { - const section = document.createElement("section"); - section.classList.add("rajs-section"); - const h1 = document.createElement("h1"); - h1.onclick = () => { this.toggle_hidey(); }; - h1.innerHTML = header; - const hidey = document.createElement("div"); - section.appendChild(h1); - section.appendChild(hidey); - return section; - } + if (V.arcologies[0].FSYouthPreferentialist !== "unset") + items.push(["(FS) Virginity Status", "her virginity status"]); - appendChild(child) { - child.parent = this; - this.children.push(child); - this.hidey.appendChild(child.element); - } + if (V.arcologies[0].FSMaturityPreferentialist !== "unset") + items.push(["(FS) Sexual Skill Info", "her sexual skills"]); - toggle_hidey() { - switch(this.hidey.style.display) { - case "none": - this.hidey.style.display = "initial"; - break; - default: - this.hidey.style.display = "none"; - break; - } - } - } + if (V.arcologies[0].FSSlimnessEnthusiast !== "unset") + items.push(["(FS) Breast Ceiling", "her absolute maximum breast size"]); - // list of clickable elements - // has a short explanation (the prefix) and a value display - // value display can optionally be an editable text input field - // it can be "bound" to a variable by setting its "onchange" method - class List extends Element { - constructor(prefix, data=[], textinput=false) { - super(prefix + ": ", textinput); - this.selectedItem = null; - data.forEach(item => this.appendChild(new ListItem(...item))); - } + if (V.arcologies[0].FSAssetExpansionist !== "unset") + items.push(["(FS) Breast Floor", "her absolute minimum breast size"]); - render(prefix, textinput) { - const elem = document.createElement("div"); - const label = document.createElement("span"); - label.innerHTML = prefix; - let value; - if (textinput) { - value = document.createElement("input"); - value.setAttribute("type", "text"); - value.classList.add("rajs-value"); // - // call the variable binding when the input field is no longer being edited, and when the enter key is pressed - value.onblur = () => {this.inputEdited(); }; - value.onkeypress = (e) => { if (returnP(e)) this.inputEdited(); }; - } else { - value = document.createElement("strong"); - } - this.value = value; - elem.appendChild(label); - elem.appendChild(value); - elem.classList.add("rajs-list"); - return elem; - } + if (V.arcologies[0].FSPastoralist !== "unset") + items.push(["(FS) Product Quality", "her body product quality"]); - inputEdited() { - if (this.selectedItem) this.selectedItem.deselect(); - this.propagateChange(); - } + if (V.arcologies[0].FSPhysicalIdelist !== "unset") + items.push(["(FS) Deadlift Info", "her deadlift record"]); - selectItem(item) { - if (this.selectedItem) this.selectedItem.deselect(); - this.selectedItem = item; - this.setValue(item.data); - this.propagateChange(); - } + if (V.arcologies[0].FSHedonisticDecadence !== "unset") + items.push(["(FS) Weight Record", "her highest weigh-in"]); - setValue(what) { - if (this.value.tagName === "INPUT") - this.value.value = ""+what; - else - this.value.innerHTML = ""+what; - } + if (V.arcologies[0].FSHedonisticDecadence && V.PC.refreshmentType == 2) + items.push(["(FS) Favorite Food", `a big helping of ${V.PC.refreshment}`]); - getData(what) { - return (this.value.tagName === "INPUT" ? this.parse(this.value.value): this.selectedItem.data); - } + if (V.arcologies[0].FSRepopulationFocus !== "unset") + items.push(["(FS) Birth Count", "the number of children she has birthed"]); - // customisable input field parser / sanity checker - parse(what) { return what; } + if (V.arcologies[0].FSChattelReligionist !== "unset") + items.push(["(FS) Religious Symbol", "a religious symbol"]); - propagateChange() { - if (this.onchange instanceof Function) - this.onchange(this.getData()); - } - } + if (V.arcologies[0].FSRomanRevivalist !== "unset") + items.push(["(FS) Republican Crest", "a small crest of your Republic"]); - // a clickable item of a list - class ListItem extends Element { - constructor(displayvalue, data) { - super(displayvalue); - this.data = data !== undefined ? data: displayvalue; - this.selected = false; - } + if (V.arcologies[0].FSAztecRevivalist !== "unset") + items.push(["(FS) Seven Serpents", "a small symbol of the Aztec gods"]); - render(displayvalue) { - const elem = document.createElement("span"); - elem.classList.add("rajs-listitem"); - elem.innerHTML = displayvalue; - elem.onclick = () => { return this.select(); }; - return elem; - } + if (V.arcologies[0].FSEgyptianRevivalist !== "unset") + items.push(["(FS) Dynastic Sigil", "a small sigil of your Dynasty"]); - select() { - if (this.selected) return false; - this.parent.selectItem(this); - this.element.classList.add("selected"); - this.selected = true; - return true; - } + if (V.arcologies[0].FSEdoRevivalist !== "unset") + items.push(["(FS) Mon", "a small image of the Shogunate's mon"]); - deselect() { - this.element.classList.remove("selected"); - this.selected = false; + if (V.arcologies[0].FSArabianRevivalist !== "unset") + items.push(["(FS) Caliphate Symbol", "a small symbol of the Caliphate"]); + + if (V.arcologies[0].FSChineseRevivalist !== "unset") + items.push(["(FS) Imperial Seal", "a small image of your Imperial Seal"]); + + super("Your brand design is", items, true); } } - // a way to organise lists with too many elements in subsections - // children are bound to the master list - class ListSubSection extends Element { - constructor(parent, label, pairs) { - super(label); - this.parent = parent; - pairs.forEach(item => this.appendChild(new ListItem(...item))); + class FaceTattooList extends List { + constructor() { + const items = [ + ["no default setting"], + ["none", 0], + ["tribal patterns"], + ["flowers"], + ["counting"], + ["advertisements"], + ["rude words"], + ["degradation"], + ["bovine patterns"], + ["Asian art"], + ["permanent makeup"], + ["sacrament"], + ["sacrilege"], + ["possessive"], + ["paternalist"] + ]; + super("Facial tattoos", items); + this.setValue(current_rule.set.lipsTat); + this.onchange = (value) => current_rule.set.lipsTat = value; } - - render(label) { - const elem = document.createElement("div"); - const lelem = document.createElement("em"); - lelem.innerText = label + ": "; - elem.appendChild(lelem); - return elem; + } + + class ShoulderTattooList extends List { + constructor() { + const items = [ + ["no default setting"], + ["none", 0], + ["tribal patterns"], + ["flowers"], + ["counting"], + ["advertisements"], + ["rude words"], + ["degradation"], + ["bovine patterns"], + ["Asian art"], + ["scenes"], + ["sacrament"], + ["sacrilege"], + ["possessive"], + ["paternalist"] + ]; + super("Shoulder tattoos", items); + this.setValue(current_rule.set.shouldersTat); + this.onchange = (value) => current_rule.set.shouldersTat = value; } + } - appendChild(child) { - super.appendChild(child); - child.parent = this.parent; - this.parent.children.push(child); + class ChestTattooList extends List { + constructor() { + const items = [ + ["no default setting"], + ["none", 0], + ["tribal patterns"], + ["flowers"], + ["counting"], + ["advertisements"], + ["rude words"], + ["degradation"], + ["bovine patterns"], + ["Asian art"], + ["scenes"], + ["sacrament"], + ["sacrilege"], + ["possessive"], + ["paternalist"] + ]; + super("Chest tattoos", items); + this.setValue(current_rule.set.boobsTat); + this.onchange = (value) => current_rule.set.boobsTat = value; } } - // similar to list, but is just a collection of buttons - class Options extends Element { - constructor(elements=[]) { - super(); - elements.forEach(element => { this.appendChild(element); }); + class ArmTattooList extends List { + constructor() { + const items = [ + ["no default setting"], + ["none", 0], + ["tribal patterns"], + ["flowers"], + ["counting"], + ["advertisements"], + ["rude words"], + ["degradation"], + ["bovine patterns"], + ["Asian art"], + ["scenes"], + ["sacrament"], + ["sacrilege"], + ["possessive"], + ["paternalist"] + ]; + super("Arm tattoos", items); + this.setValue(current_rule.set.armsTat); + this.onchange = (value) => current_rule.set.armsTat = value; } + } - render() { - const elem = document.createElement("div"); - elem.classList.add("rajs-list"); - return elem; + class UpperBackTattooList extends List { + constructor() { + const items = [ + ["no default setting"], + ["none", 0], + ["tribal patterns"], + ["flowers"], + ["counting"], + ["advertisements"], + ["rude words"], + ["degradation"], + ["bovine patterns"], + ["Asian art"], + ["scenes"], + ["sacrament"], + ["sacrilege"], + ["possessive"], + ["paternalist"], + ]; + super("Upper back tattoos", items); + this.setValue(current_rule.set.backTat); + this.onchange = (value) => current_rule.set.backTat = value; } } - // options equivalent of ListItem - class OptionsItem extends Element { - constructor(label, onclick) { - super(label); - this.label = label; - this.onclick = onclick; + class LowerBackTattooList extends List { + constructor() { + const items = [ + ["no default setting"], + ["none", 0], + ["tribal patterns"], + ["flowers"], + ["counting"], + ["advertisements"], + ["rude words"], + ["degradation"], + ["bovine patterns"], + ["Asian art"], + ["scenes"], + ["sacrament"], + ["sacrilege"], + ["possessive"], + ["paternalist"] + ]; + super("Lower back tattoos", items); + this.setValue(current_rule.set.stampTat); + this.onchange = (value) => current_rule.set.stampTat = value; } - render(label, onclick) { - const elem = document.createElement("span"); - elem.classList.add("rajs-listitem"); - elem.innerHTML = label; - elem.onclick = () => { return this.onclick(this); }; - return elem; + } + + class AbdomenTattooList extends List { + constructor() { + const items = [ + ["no default setting"], + ["none", 0], + ["tribal patterns"], + ["flowers"], + ["counting"], + ["advertisements"], + ["rude words"], + ["degradation"], + ["bovine patterns"], + ["Asian art"], + ["scenes"], + ["sacrament"], + ["sacrilege"], + ["possessive"], + ["paternalist"], + ]; + super("Abdomen tattoos", items); + this.setValue(current_rule.set.vaginaTat); + this.onchange = (value) => current_rule.set.vaginaTat = value; } } - class ButtonList extends Element { - render(label) { - const elem = document.createElement("div"); - const labelel = document.createElement("span"); - labelel.innerHTML = label += ": "; - elem.appendChild(labelel); - return elem; + class DickTattooList extends List { + constructor() { + const items = [ + ["no default setting"], + ["none", 0], + ["tribal patterns"], + ["flowers"], + ["counting"], + ["advertisements"], + ["rude words"], + ["degradation"], + ["bovine patterns"], + ["Asian art"], + ["sacrament"], + ["sacrilege"], + ["possessive"], + ["paternalist"], + ]; + super("Dick tattoos", items); + this.setValue(current_rule.set.dickTat); + this.onchange = (value) => current_rule.set.dickTat = value; } + } - getSelection() { - return (this.children - .filter(child => child.selected) - .map(child => child.setvalue) - ); + class ButtockTattooList extends List { + constructor() { + const items = [ + ["no default setting"], + ["none", 0], + ["tribal patterns"], + ["flowers"], + ["counting"], + ["advertisements"], + ["rude words"], + ["degradation"], + ["bovine patterns"], + ["Asian art"], + ["scenes"], + ["sacrament"], + ["sacrilege"], + ["possessive"], + ["paternalist"], + ]; + super("Buttock tattoos:", items); + this.setValue(current_rule.set.buttTat); + this.onchange = (value) => current_rule.set.buttTat = value; } - - onchange() { return; } } - class ButtonItem extends Element { - constructor(label, setvalue, selected=false) { - super(label, selected); - this.selected = selected; - this.setvalue = setvalue ? setvalue : label; + class AnalTattooList extends List { + constructor() { + const items = [ + ["no default setting"], + ["none", 0], + ["tribal patterns"], + ["flowers"], + ["counting"], + ["advertisements"], + ["rude words"], + ["degradation"], + ["bovine patterns"], + ["bleached"], + ["sacrament"], + ["sacrilege"], + ["possessive"], + ["paternalist"], + ]; + super("Anal tattoo or bleaching", items); + this.setValue(current_rule.set.anusTat); + this.onchange = (value) => current_rule.set.anusTat = value; } + } - render(label, selected) { - const container = document.createElement("div"); - container.classList.add("rajs-listitem"); - - const labelel = document.createElement("span"); - labelel.innerHTML = label; - - const button = document.createElement("input"); - button.setAttribute("type", "checkbox"); - button.checked = selected; - button.onchange = () => this.onchange(button.checked); - labelel.onclick = () => button.click(); - - container.appendChild(labelel); - container.appendChild(button); - - return container; + class LegTattooList extends List { + constructor() { + const items = [ + ["no default setting"], + ["none", 0], + ["tribal patterns"], + ["flowers"], + ["counting"], + ["advertisements"], + ["rude words"], + ["degradation"], + ["bovine patterns"], + ["Asian art"], + ["scenes"], + ["sacrament"], + ["sacrilege"], + ["possessive"], + ["paternalist"], + ]; + super("Leg tattoos", items); + this.setValue(current_rule.set.legsTat); + this.onchange = (value) => current_rule.set.legsTat = value; } + } - onchange(value) { - this.selected = value; - this.parent.onchange(this); + class VisionSurgeryList extends List { + constructor() { + const items = [ + ["no default setting"], + ["fixed", 1], + ["blurred", -1], + ]; + super("Vision correction", items); + this.setValue(current_rule.set.surgery_eyes); + this.onchange = (value) => current_rule.set.surgery_eyes = value; } } - // rule import field - class NewRuleField extends Element { - constructor(root) { - super(); - this.root = root; + class LactationSurgeryList extends List { + constructor() { + const items = [ + ["no default setting"], + ["implanted", 1], + ["removed", 0], + ]; + super("Lactation drug implants", items); + this.setValue(current_rule.set.surgery_lactation); + this.onchange = (value) => current_rule.set.surgery_lactation = value; } + } - render() { - let element = document.getElementById("importfield"); - if (element !== null) { return element; } - const container = document.createElement("div"); - container.id = "importfield"; - const textarea = document.createElement("textarea"); - textarea.placeholder = "Paste your rule here"; - container.appendChild(textarea); - this.textarea = textarea; - const button = document.createElement("button"); - button.name = "Load"; - button.innerHTML = "Load"; - button.onclick = () => { this.loadNewRule(); }; - container.appendChild(button); - return container; + class SemenSurgeryList extends List { + constructor() { + const items = [ + ["no default setting"], + ["implanted", 1], + ["removed", 0], + ]; + super("Prostate production enhancing drug implants", items); + this.setValue(current_rule.set.surgery_prostate); + this.onchange = (value) => current_rule.set.surgery_prostate = value; } + } - loadNewRule() { - const text = this.textarea.value; - try { - const rule = JSON.parse(text); - if (rule instanceof Array) - rule.forEach(r => V.defaultRules.push(r)); - else - V.defaultRules.push(rule); - reload(this.root); - } catch (e) { - alert("Couldn't import that rule:\n" + e.message); - } + class VasectomyList extends List { + constructor() { + const items = [ + ["no default setting"], + ["apply vasectomy", true], + ["undo vasectomy", false], + ]; + super("Apply or undo vasectomy for slaves with testicles", items); + this.setValue(current_rule.set.surgery_vasectomy); + this.onchange = (value) => current_rule.set.surgery_vasectomy = value; } } - // the base element, parent of all elements - class Root extends Element { - constructor(element) { - super(element); - if(V.defaultRules.length === 0) { - const paragraph = document.createElement("p"); - paragraph.innerHTML = "<strong>No rules</strong>"; - this.appendChild(new Element(paragraph)); - this.appendChild(new NoRules(this)); - return; - } - this.appendChild(new RuleSelector(this)); - this.appendChild(new RuleOptions(this)); - this.appendChild(new ConditionEditor(this)); - this.appendChild(new EffectEditor(this)); + class CosmeticSurgeryList extends List { + constructor() { + const items = [ + ["none", 0], + ["subtle", 1], + ["invasive", 2], + ]; + super("Cosmetic Surgery", items); + this.setValue(current_rule.set.surgery_cosmetic); + this.onchange = (value) => current_rule.set.surgery_cosmetic = value; } + } - render(element) { - const greeting = document.createElement("p"); - greeting.innerHTML = `<em>${properTitle()}, I will review your slaves and make changes that will have a beneficial effect. Apologies, ${properTitle()}, but this function is... not fully complete. It may have some serious limitations. Please use the 'no default setting' option to identify areas I should not address.</em>`; - element.appendChild(greeting); - return element; + class LipSurgeryList extends List { + constructor() { + const items = [ + ["no default setting"], + ["removed", 0], + ["plush", 20], + ["big", 40], + ["huge", 70], + ["facepussy", 95], + ]; + super("Lip implants", items); + this.setValue(current_rule.set.surgery_lips); + this.onchange = (value) => current_rule.set.surgery_lips = value; } } - // optoins displayed when there are no rules - class NoRules extends Options { - constructor(root) { - super(); - this.root = root; - const newrule = new OptionsItem("Add a new rule", () => { newRule(this.root); }); - this.appendChild(newrule); - const importrule = new OptionsItem("Import a rule", () => { this.root.appendChild(new NewRuleField(this.root)); }); - this.appendChild(importrule); + class ButtSurgeryList extends List { + constructor() { + const items = [ + ["no default setting"], + ["removed", 0], + ["slim", 2], + ["stacked", 4], + ["huge", 6], + ["maximised", 9], + ]; + super("Buttock implants", items); + this.setValue(current_rule.set.surgery_butt); + this.onchange = (value) => current_rule.set.surgery_butt = value; } } - // buttons for selecting the current rule - class RuleSelector extends List { - constructor(root) { - super("Current rule", V.defaultRules.map(i => [i.name, i])); - this.setValue(current_rule.name); - this.onchange = function (rule) { - V.currentRule = rule.ID; - reload(root); - }; + class BreastSurgeryList extends List { + constructor() { + const items = [ + ["no default setting"], + ["removed", 0], + ["slim", 400], + ["stacked", 1000], + ["huge", 2000], + ["barely functional", 9000], + ["maximised", 48000] + ]; + super("Breast implants", items); + this.setValue(current_rule.set.surgery_boobs); + this.onchange = (value) => current_rule.set.surgery_boobs = value; } } - // buttons for doing transformations on rules - class RuleOptions extends Options { - constructor(root) { - super(); - this.appendChild(new OptionsItem("New Rule", () => newRule(root))); - this.appendChild(new OptionsItem("Remove Rule", () => removeRule(root))); - this.appendChild(new OptionsItem("Apply rules", () => this.appendChild(new ApplicationLog()))); - this.appendChild(new OptionsItem("Lower Priority", () => lowerPriority(root))); - this.appendChild(new OptionsItem("Higher Priority", () => higherPriority(root))); - this.appendChild(new OptionsItem("Rename", () => this.appendChild(new RenameField(root)))); - this.appendChild(new OptionsItem("Export this rule", () => this.appendChild(new ExportField(current_rule)))); - this.appendChild(new OptionsItem("Export all rules", () => this.appendChild(new ExportField(...V.defaultRules)))); - this.appendChild(new OptionsItem("Import rule(s)", () => this.appendChild(new NewRuleField(root)))); + class TighteningSurgeryList extends List { + constructor() { + const items = [ + ["no default setting"], + ["tightening", 1], + ["virginity restoration", 2], + ]; + super("Orifice Tightening", items); + this.setValue(current_rule.set.surgery_holes); + this.onchange = (value) => current_rule.set.surgery_holes = value; } } - class ApplicationLog extends Element { - render() { - const elem = document.createElement("div"); - clearSummaryCache(); - elem.innerHTML = V.slaves.map(slave => DefaultRules(slave)).join(""); - return elem; + class BodyHairSurgeryList extends List { + constructor() { + const items = [ + ["no default setting"], + ["keep", 1], + ["removal", 2], + ]; + super("Body Hair", items); + this.setValue(current_rule.set.surgery_bodyhair); + this.onchange = (value) => current_rule.set.surgery_bodyhair = value; } } - class RenameField extends Element { - constructor(root) { - super(); - this.element.onblur = () => changeName(this.element.value, root); - this.element.onkeypress = (e) => { if (returnP(e)) changeName(this.element.value, root); }; - } - - render() { - const elem = document.createElement("input"); - elem.setAttribute("type", "text"); - elem.setAttribute("value", current_rule.name); - return elem; + class HairSurgeryList extends List { + constructor() { + const items = [ + ["no default setting"], + ["keep", 1], + ["removal", 2], + ]; + super("Hair", items); + this.setValue(current_rule.set.surgery_hair); + this.onchange = (value) => current_rule.set.surgery_hair = value; } } - class ExportField extends Element { - render(...args) { - let element = document.getElementById("exportfield"); - if (element === null) { - element = document.createElement("textarea"); - element.id = "exportfield"; - } - element.value = JSON.stringify(args, null, 2); - return element; + class AutomaticAssignmentList extends List { + constructor() { + const items = [ + ["No default setting", "no default setting"], + ["Rest", "rest"], + ["Fucktoy", "please you"], + ["Subordinate Slave", "be a subordinate slave"], + ["House Servant", "be a servant"], + ["Confined", "stay confined"], + ["Whore", "whore"], + ["Public Servant", "serve the public"], + ["Classes", "take classes"], + ["Milked", "get milked"], + ["Gloryhole", "work a glory hole"] + ]; + + if (V.HGSuite > 0) items.push(["Head Girl Suite", "live with your Head Girl"]); + if (V.brothel > 0) items.push(["Brothel", "work in the brothel"]); + if (V.club > 0) items.push(["Club", "serve in the club"]); + if (V.arcade > 0) items.push(["Arcade", "be confined in the arcade"]); + if (V.dairy > 0) items.push(["Dairy", "work in the dairy"]); + if (V.servantsQuarters > 0) items.push(["Servant Quarters", "work as a servant"]); + if (V.masterSuite > 0) items.push(["Master Suite", "serve in the master suite"]); + if (V.schoolroom > 0) items.push(["Schoolroom", "learn in the schoolroom"]); + if (V.spa > 0) items.push(["Spa", "rest in the spa"]); + if (V.clinic > 0) items.push(["Clinic", "get treatment in the clinic"]); + if (V.cellblock > 0) items.push(["Cellblock", "be confined in the cellblock"]); + + super("Automatically set assignment", items); + this.setValue(current_rule.set.setAssignment); + this.onchange = (value) => current_rule.set.setAssignment = value; } } - // parent section for condition editing - class ConditionEditor extends Section { + class BellyImplantList extends List { constructor() { - super("Activation Condition"); - this.appendChild(new ConditionFunction()); - this.appendChild(new AssignmentInclusion()); - this.appendChild(new SpecialExclusion()); - this.appendChild(new SpecificInclusionExclusion()); + const items = [ + ["no default setting"], + ["install", "install"], + ["remove", "remove"], + ]; + super("Belly implant", items); + this.setValue(current_rule.set.surgery_bellyImplant); + this.onchange = (value) => current_rule.set.surgery_bellyImplant = value; } } - - class ConditionFunction extends Element { + + class LabelList extends List { constructor() { - super(); const items = [ - ["Never", false], - ["Always", true], - ["Custom", "custom"], - ["Devotion", "devotion"], - ["Trust", "trust"], - ["Health", "health"], - ["Sex drive", "energy"], - ["Weight", "weight"], - ["Age", "actualAge"], - ["Body Age", "physicalAge"], - ["Visible Age", "visualAge"], - ["Muscles", "muscles"], - ["Lactation", "lactation"], - ["Pregnancy", "preg"], - ["Pregnancy Multiples", "pregType"], - ["Belly Implant", "bellyImplant"], - ["Belly Size", "belly"], - ["Education", "intelligenceImplant"], - ["Intelligence", "intelligence"], - ["Fetish", "fetish"], - ["Accent", "accent"], - ["Waist", "waist"], - ["Amputation", "amp"], + ["no default setting"], ]; - this.fnlist = new List("Activation function", items); - this.fnlist.setValue(current_rule.condition.function === "between" ? current_rule.condition.data.attribute : current_rule.condition.function); - this.fnlist.onchange = (value) => this.fnchanged(value); - this.appendChild(this.fnlist); - this.fneditor = null; + super("Custom label", items, true); + this.setValue(current_rule.set.label); + this.onchange = (value) => current_rule.set.label = value; + } + } + + return rulesAssistantOptions; +})(); - switch(current_rule.condition.function) { - case false: - case true: - break; - case "custom": - this.show_custom_editor(CustomEditor, current_rule.condition.data); - break; - case "between": - this.show_custom_editor(RangeEditor, current_rule.condition.function, current_rule.condition.data); - break; - case "belongs": - this.show_custom_editor(ItemEditor, current_rule.condition.function, current_rule.condition.data); - break; +/*:: rules autosurgery js [script]*/ + +window.rulesAutosurgery = (function() { + "use strict"; + let V; + let r; + return rulesAutoSurgery; + + function rulesAutoSurgery(slave) { + V = State.variables; + r = ""; + const surgeries = []; + const thisSurgery = ProcessHGTastes(slave); + if (slave.health > 20) + CommitSurgery(slave, thisSurgery, surgeries); + if (surgeries.length > 0) + PrintResult(slave, thisSurgery, surgeries); + return r; + } + + function autoSurgerySelector(slave, ruleset) { + const surgery = {}; + ruleset.forEach(rule => { + Object.keys(rule) + .filter(key => key.startsWith("surgery_") && rule[key] !== "no default setting") + .forEach(key => { + surgery[key] = rule[key]; + }); + }); + return surgery; + } + + function ProcessHGTastes(slave) { + let thisSurgery; + switch (V.HGTastes) { + case 1: + thisSurgery = { + surgery_lactation: 0, + surgery_cosmetic: 1, + surgery_faceShape: "cute", + surgery_lips: 10, + surgery_hips: 0, + surgery_hipsImplant: 0, + surgery_butt: 0, + surgery_accent: 0, + surgery_shoulders: 0, + surgery_shouldersImplant: 0, + surgery_boobs: 0, + surgery_holes: 0 + }; + break ; + case 2: + thisSurgery = { + surgery_lactation: 0, + surgery_cosmetic: 1, + surgery_faceShape: "cute", + surgery_lips: 60, + surgery_hips: 0, + surgery_hipsImplant: 0, + surgery_butt: 4, + surgery_accent: 0, + surgery_shoulders: 0, + surgery_shouldersImplant: 0, + surgery_boobs: 1200, + surgery_holes: 0 + }; + break; + case 3: + thisSurgery = { + surgery_lactation: 0, + surgery_cosmetic: 1, + surgery_faceShape: "cute", + surgery_lips: 95, + surgery_hips: 0, + surgery_hipsImplant: 0, + surgery_butt: 8, + surgery_accent: 0, + surgery_shoulders: 0, + surgery_shouldersImplant: 0, + surgery_boobs: 10000, + surgery_holes: 2 + }; + break; + case 4: + thisSurgery = { + surgery_lactation: 1, + surgery_cosmetic: 1, + surgery_faceShape: "cute", + surgery_lips: 10, + surgery_hips: 3, + surgery_hipsImplant: 0, + surgery_butt: 0, + surgery_accent: 0, + surgery_shoulders: 0, + surgery_shouldersImplant: 0, + surgery_boobs: 0, + surgery_holes: 0 + }; + break; + default: + thisSurgery = autoSurgerySelector( + slave, + 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 (slave.hips < -1) { + if (thisSurgery.surgery_butt > 2) + thisSurgery.surgery_butt = 2; + } else if (slave.hips < 0) { + if (thisSurgery.surgery_butt > 4) + thisSurgery.surgery_butt = 4; + } else if (slave.hips > 0) { + if (thisSurgery.surgery_butt > 8) + thisSurgery.surgery_butt = 8; + } else if (slave.hips > 1) { + true; + } else { + if (thisSurgery.surgery_butt > 6) + thisSurgery.surgery_butt = 6; + } } + break; } + return thisSurgery; + } - betweenP(attribute) { - return [ - "devotion", - "trust", - "health", - "energy", - "weight", - "actualAge", - "physicalAge", - "visualAge", - "muscles", - "lactation", - "preg", - "pregType", - "bellyImplant", - "belly", - "intelligenceImplant", - "intelligence", - "accent", - "waist", - ].includes(attribute); - } - - belongsP(attribute) { - return [ - "fetish", - "amp", - ].includes(attribute); - } - - show_custom_editor(what, ...args) { - if (this.custom_editor !== null) this.hide_custom_editor(); - this.custom_editor = new what(...args); - this.appendChild(this.custom_editor); - } - - hide_custom_editor() { - if (this.custom_editor) { - this.custom_editor.remove(); - this.custom_editor = null; + function CommitSurgery(slave, thisSurgery, surgeries) { + if ((slave.eyes == -1) && (thisSurgery.surgery_eyes == 1)) { + surgeries.push("surgery to correct her vision"); + slave.eyes = 1; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.eyes == 1) && (thisSurgery.surgery_eyes == -1)) { + surgeries.push("surgery to blur her vision"); + slave.eyes = -1; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.lactation == 2) && (thisSurgery.surgery_lactation == 0)) { + surgeries.push("surgery to remove her lactation implants"); + slave.lactation = 0; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if (slave.lactation != 2 && (thisSurgery.surgery_lactation == 1)) { + surgeries.push("lactation inducing implanted drugs"); + slave.lactation = 2; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.prostate == 2) && (thisSurgery.surgery_prostate == 0)) { + surgeries.push("surgery to remove her prostate implant"); + slave.prostate = 0; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if (slave.prostate == 1 && (thisSurgery.surgery_prostate == 1)) { + surgeries.push("a precum production enhancing drug implant"); + slave.prostate = 2; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.anus > 3) && (thisSurgery.surgery_cosmetic > 0)) { + surgeries.push("a restored anus"); + slave.anus = 3; + if (slave.analSkill > 10) + slave.analSkill -= 10; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.vagina > 3) && (thisSurgery.surgery_cosmetic > 0)) { + surgeries.push("a restored pussy"); + slave.vagina = 3; + if (slave.vaginalSkill > 10) + slave.vaginalSkill -= 10; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else 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); + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } 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; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } 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"; + V.cash -= V.surgeryCost; + + } else if ((slave.bald == 0 || slave.hStyle != "bald") && (thisSurgery.surgery_hair == 2)) { + surgeries.push("hair removal"); + slave.hStyle = "bald"; + slave.bald = 1; + V.cash -= V.surgeryCost; + + } else if ((slave.weight >= 10) && (thisSurgery.surgery_cosmetic > 0)) { + surgeries.push("liposuction"); + slave.weight -= 50; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.voice == 1) && (slave.voiceImplant == 0) && (thisSurgery.surgery_cosmetic > 0)) { + surgeries.push("a feminine voice"); + slave.voice += 1; + slave.voiceImplant += 1; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.waist >= -10) && (thisSurgery.surgery_cosmetic > 0)) { + surgeries.push("a narrower waist"); + slave.waist -= 20; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if (((slave.boobShape == "saggy") || (slave.boobShape == "downward-facing")) && (thisSurgery.surgery_cosmetic > 0) && (slave.breastMesh != 1)) { + surgeries.push("a breast lift"); + slave.boobShape = "normal"; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } 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"); + V.cash -= V.surgeryCost; + 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.oralSkill > 10) + slave.oralSkill -= 10; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.lips <= 95) && (slave.lips < thisSurgery.surgery_lips)) { + if (thisSurgery.surgery_lips !== "no default setting") { + surgeries.push("bigger lips"); + slave.lipsImplant += 10; + slave.lips += 10; + if (slave.oralSkill > 10) + slave.oralSkill -= 10; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + } + + } 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); + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.hips < 1) && (slave.hips < thisSurgery.surgery_hips) && (V.surgeryUpgrade == 1)) { + surgeries.push("wider hips"); + slave.hips++; + slave.hipsImplant++; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } 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; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.waist >= -95) && (thisSurgery.surgery_cosmetic == 2) && (V.seeExtreme == 1)) { + surgeries.push("a narrower waist"); + slave.waist = Math.clamp(slave.waist-20,-100,100); + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.voice < 3) && (slave.voiceImplant == 0) && (thisSurgery.surgery_cosmetic == 2)) { + surgeries.push("a bimbo's voice"); + slave.voice += 1; + slave.voiceImplant += 1; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else 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; + V.cash -= V.surgeryCost; + 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; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + } else if ((slave.butt <= 3) && (slave.butt < thisSurgery.surgery_butt)) { + if (thisSurgery.surgery_butt !== "no default setting") { + surgeries.push("a bigger butt"); + slave.buttImplant = 1; + slave.butt += 1; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; } - } - - render() { - const elem = document.createElement("div"); - return elem; - } - - fnchanged(value) { - if (this.fneditor !== null) { - this.fneditor.element.remove(); - this.fneditor = null; + } else if ((slave.boobs <= 600) && (slave.lactation < 2) && (slave.boobs+400 <= thisSurgery.surgery_boobs)) { + if (thisSurgery.surgery_boobs !== "no default setting") { + surgeries.push("bigger boobs"); + slave.boobsImplant += 400; + slave.boobs += 400; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; } - if (value === true || value === false) { - current_rule.condition.function = value; - current_rule.condition.data = {}; - this.hide_custom_editor(); - } else if (value === "custom") { - current_rule.condition.function = "custom"; - current_rule.condition.data = ""; - this.show_custom_editor(CustomEditor, current_rule.condition.data); - } else if (this.betweenP(value)) { - current_rule.condition.function = "between"; - current_rule.condition.data = { attribute: value, value: [null, null] }; - this.show_custom_editor(RangeEditor, current_rule.condition.function, current_rule.condition.data); - } else if (this.belongsP(value)) { - current_rule.condition.function = "belongs"; - current_rule.condition.data = { attribute: value, value: [] }; - this.show_custom_editor(ItemEditor, current_rule.condition.function, current_rule.condition.data); + } else if ((slave.boobs <= 600) && (slave.lactation < 2) && (slave.boobs+200 <= thisSurgery.surgery_boobs)) { + if (thisSurgery.surgery_boobs !== "no default setting") { + surgeries.push("modestly bigger boobs"); + slave.boobsImplant += 200; + slave.boobs += 200; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; } - } - } - - class CustomEditor extends Element { - constructor(data) { - if (data.length === 0) data = "(slave) => slave.slaveName === 'Fancy Name'"; - super(data); - } - - render(data) { - const elem = document.createElement("div"); - const textarea = document.createElement("textarea"); - textarea.innerHTML = data; - textarea.onblur = () => current_rule.condition.data = textarea.value; - elem.appendChild(textarea); - const explanation = document.createElement("div"); - explanation.innerHTML = "Insert a valid <a target='_blank' class='link-external' href='https://www.w3schools.com/js/js_comparisons.asp'>JavaScript comparison and/or logical operation</a>."; - elem.appendChild(explanation); - return elem; - } - } - - class RangeEditor extends Element { - render(fn, data) { - const elem = document.createElement("div"); - - const minlabel = document.createElement("label"); - minlabel.innerHTML = "Lower bound: "; - elem.appendChild(minlabel); - - const min = document.createElement("input"); - min.setAttribute("type", "text"); - min.value = "" + data.value[0]; - min.onkeypress = e => { if (returnP(e)) this.setmin(min.value); }; - min.onblur = e => this.setmin(min.value); - this.min = min; - elem.appendChild(min); - - elem.appendChild(document.createElement("br")); - - const maxlabel = document.createElement("label"); - maxlabel.innerHTML = "Upper bound: "; - elem.appendChild(maxlabel); - - const max = document.createElement("input"); - max.setAttribute("type", "text"); - max.value = "" + data.value[1]; - max.onkeypress = e => { if (returnP(e)) this.setmax(max.value); }; - max.onblur = e => this.setmax(max.value); - this.max = max; - elem.appendChild(max); - - const infobar = document.createElement("div"); - infobar.innerHTML = this.info(data.attribute); - elem.appendChild(infobar); - - return elem; - } - - parse(value) { - value = value.trim(); - if (value === "null") value = null; - else { - value = parseInt(value); - if (isNaN(value)) value = null; + + } else if ((slave.butt <= 5) && (slave.butt < thisSurgery.surgery_butt)) { + if (thisSurgery.surgery_butt !== "no default setting") { + surgeries.push("a bigger butt"); + slave.buttImplant = 1; + slave.butt += 1; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; } - return value; - } - - setmin(value) { - current_rule.condition.data.value[0] = this.parse(value); - this.min.value = ""+current_rule.condition.data.value[0]; - } - - setmax(value) { - current_rule.condition.data.value[1] = this.parse(value); - this.max.value = ""+current_rule.condition.data.value[1]; - } - - info(attribute) { - return ({ - "devotion": "Very Hateful: (-∞, -95), Hateful: [-95, -50), Resistant: [-50, -20), Ambivalent: [-20, 20], Accepting: (20, 50], Devoted: (50, 95], Worshipful: (95, ∞)", - "trust": "Extremely terrified: (-∞, -95), Terrified: [-95, -50), Frightened: [-50, -20), Fearful: [-20, 20], Careful: (20, 50], Trusting: (50, 95], Total trust: (95, ∞)", - "health": "Death: (-∞, -100), Near Death: [-100, -90), Extremely Unhealthy: [-90, -50), Unhealthy: [-50, -20), Healthy: [-20, 20], Very Healthy: (20, 50], Extremely Healthy: (50, 90], Unnaturally Healthy: (90, ∞)", - "energy": "Frigid: (-∞, 20], Poor: (20, 40], Average: (40, 60], Powerful: (60, 80], Sex Addict: (80, 100), Nympho: 100", - "weight": "Emaciated: (-∞, -95), Skinny: [-95, -30), Thin: [-30, -10), Average: [-10, 10], Plush: (10, 30], Fat: (30, 95], Overweight: (95, ∞)", - "lactation": "None: 0, 1: Natural, 2: Lactation implant", - "preg": "Barren: -2, On contraceptives: -1, Not pregnant: 0, Pregnancy weeks: [1, ∞)", - "pregType": "Fetus count, known only after the 10th week of pregnancy", - "bellyImplant": "Volume in CCs. None: -1", - "belly": "Volume in CCs, any source", - "intelligenceImplant": "Education level. 0: uneducated, 1: educated, (0, 1): incomplete education.", - "intelligence": "From moronic to brilliant: [-3, 3]", - "accent": "No accent: 0, Nice accent: 1, Bad accent: 2, Can't speak language: 3 and above", - "waist": "Masculine waist: (95, ∞), Ugly waist: (40, 95], Unattractive waist: (10, 40], Average waist: [-10, 10], Feminine waist: [-40, -10), Wasp waist: [-95, 40), Absurdly narrow: (-∞, -95)", - }[attribute] || " "); - } - } - - class ItemEditor extends Element { - render(fn, data) { - const elem = document.createElement("div"); - - const input = document.createElement("input"); - input.setAttribute("type", "text"); - input.value = JSON.stringify(data.value); - input.onkeypress = e => { if (returnP(e)) this.setValue(input); }; - input.onblur = e => this.setValue(input); - this.input = input; - elem.appendChild(input); - - const infobar = document.createElement("div"); - infobar.innerHTML = this.info(data.attribute); - elem.appendChild(infobar); - - return elem; - } - - info(attribute) { - return "Insert a valid JSON array. Known values: " + { - "fetish": "buttslut, cumslut, masochist, sadist, dom, submissive, boobs, pregnancy, none (AKA vanilla)", - "amp": "Amputated: 1, Not amputated: 0", - }[attribute]; - } - - setValue(input) { - try { - const arr = JSON.parse(input.value); - current_rule.condition.data.value = arr; - input.value = JSON.stringify(arr); - } catch (e) { - alert(e); + + } else if ((slave.boobs <= 2000) && (slave.lactation < 2) && (slave.boobs+400 < thisSurgery.surgery_boobs)) { + if (thisSurgery.surgery_boobs !== "no default setting") { + surgeries.push("bigger boobs"); + slave.boobsImplant += 400; + slave.boobs += 400; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + } + + } else if ((slave.anus > 0) && (V.surgeryUpgrade == 1) && (thisSurgery.surgery_holes == 2)) { + surgeries.push("a virgin anus"); + slave.anus = 0; + if (slave.analSkill > 10) { + slave.analSkill -= 10; + } + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.vagina > 0) && (V.surgeryUpgrade == 1) && (thisSurgery.surgery_holes == 2)) { + surgeries.push("a virgin pussy"); + slave.vagina = 0; + if (slave.vaginalSkill > 10) + slave.vaginalSkill -= 10; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.hips < 2) && (slave.hips < thisSurgery.surgery_hips) && (V.surgeryUpgrade == 1)) { + surgeries.push("wider hips"); + slave.hips++; + slave.hipsImplant++; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.anus > 1) && (thisSurgery.surgery_holes == 1)) { + surgeries.push("a tighter anus"); + slave.anus = 1; + if (slave.analSkill > 10) { + slave.analSkill -= 10; } - } - } - - - class AssignmentInclusion extends ButtonList { - constructor() { - super("Apply to assignments and facilities"); - const items = ["Rest", "Fucktoy", "Subordinate Slave", "House Servant", "Confined", "Whore", "Public Servant", "Classes", "Milked", "Gloryhole"]; - if (V.HGSuite > 0) items.push("Head Girl Suite"); - if (V.brothel > 0) items.push("Brothel"); - if (V.club > 0) items.push("Club"); - if (V.arcade > 0) items.push("Arcade"); - if (V.dairy > 0) items.push("Dairy"); - if (V.servantsQuarters > 0) items.push("Servant Quarters"); - if (V.masterSuite > 0) items.push("Master Suite"); - if (V.schoolroom > 0) items.push("Schoolroom"); - if (V.spa > 0) items.push("Spa"); - if (V.clinic > 0) items.push("Clinic"); - if (V.cellblock > 0) items.push("Cellblock"); - items.forEach( - i => this.appendChild(new ButtonItem(i, this.getAttribute(i), current_rule.condition.assignment.includes(this.getAttribute(i))))); - } - - onchange() { - current_rule.condition.assignment = this.getSelection(); - } - - getAttribute(what) { - return { - "Rest": "rest", - "Fucktoy": "please you", - "Subordinate Slave": "be a subordinate slave", - "House Servant": "be a servant", - "Confined": "stay confined", - "Whore": "whore", - "Public Servant": "serve the public", - "Classes": "take classes", - "Milked": "get milked", - "Gloryhole": "work a glory hole", - "Head Girl Suite": "live with your Head Girl", - "Brothel": "work in the brothel", - "Club": "serve in the club", - "Arcade": "be confined in the arcade", - "Dairy": "work in the dairy", - "Servant Quarters": "work as a servant", - "Master Suite": "serve in the master suite", - "Schoolroom": "learn in the schoolroom", - "Spa": "rest in the spa", - "Clinic": "get treatment in the clinic", - "Cellblock": "be confined in the cellblock", - }[what]; - } - } - - class SpecialExclusion extends List { - constructor() { - const items = [ - ["Yes", true], - ["No", false] - ]; - super("Exclude special slaves", items); - this.setValue(current_rule.condition.excludeSpecialSlaves); - this.onchange = (value) => current_rule.condition.excludeSpecialSlaves = value; - } - } - - class SpecificInclusionExclusion extends Options { - constructor() { - super(); - this.appendChild(new OptionsItem("Limit to specific slaves", () => this.show_slave_selection())); - this.appendChild(new OptionsItem("Exclude specific slaves", () => this.show_slave_exclusion())); - this.subwidget = null; - } - - show_slave_selection() { - if (this.subwidget) this.subwidget.remove(); - this.subwidget = new SlaveSelection(); - this.appendChild(this.subwidget); - } - - show_slave_exclusion() { - if (this.subwidget) this.subwidget.remove(); - this.subwidget = new SlaveExclusion(); - this.appendChild(this.subwidget); - } - } - - class SlaveSelection extends ButtonList { - constructor() { - super("Include specific slaves"); - V.slaves.forEach(slave => this.appendChild(new ButtonItem( - [slave.slaveName, slave.slaveSurname].join(" "), - slave.ID, - current_rule.condition.selectedSlaves.includes(slave.ID)))); - } - - onchange() { - current_rule.condition.selectedSlaves = this.getSelection(); - } - } - - class SlaveExclusion extends ButtonList { - constructor() { - super("Exclude specific slaves"); - V.slaves.forEach(slave => this.appendChild(new ButtonItem( - [slave.slaveName, slave.slaveSurname].join(" "), - slave.ID, - current_rule.condition.excludedSlaves.includes(slave.ID)))); - } - - onchange() { - current_rule.condition.excludedSlaves = this.getSelection(); - } - } - - // parent section for effect editing - 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()); - } - - render() { - const element = document.createElement("div"); - return element; - } - } - - class AppearanceSection extends Section { - constructor() { - super("Appearance Settings"); - this.appendChild(new ClothesList()); - this.appendChild(new CollarList()); - this.appendChild(new ShoeList()); - this.appendChild(new CorsetList()); - this.appendChild(new LeggingsList()); - this.appendChild(new VagAccVirginsList()); - this.appendChild(new VagAccAVirginsList()); - this.appendChild(new VagAccOtherList()); - if (V.seeDicks !== 0 || V.makeDicks !== 0) { - this.appendChild(new DickAccVirginsList()); - this.appendChild(new DickAccOtherList()); + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.vagina > 1) && (thisSurgery.surgery_holes == 1)) { + surgeries.push("a tighter pussy"); + slave.vagina = 1; + if (slave.vaginalSkill > 10) { + slave.vaginalSkill -= 10; } - this.appendChild(new ButtplugsVirginsList()); - this.appendChild(new ButtplugsOtherList()); - this.appendChild(new ImplantVolumeList()); - this.appendChild(new AutosurgerySwitch()); - - } - } - - class RegimenSection extends Section { - constructor() { - super("Physical Regimen Settings"); - this.appendChild(new GrowthList()); - this.appendChild(new CurrativesList()); - this.appendChild(new AphrodisiacList()); - this.appendChild(new ContraceptiveList()); - if (V.pregSpeedControl) - this.appendChild(new PregDrugsList()); - this.appendChild(new FemaleHormonesList()); - this.appendChild(new ShemaleHormonesList()); - this.appendChild(new GeldingHormonesList()); - this.appendChild(new OtherDrugsList()); - this.appendChild(new DietList()); - this.appendChild(new DietGrowthList()); - this.appendChild(new DietBaseList()); - this.appendChild(new MuscleList()); - this.appendChild(new BraceList()); + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if ((slave.butt <= 8) && (slave.butt < thisSurgery.surgery_butt)) { + if (thisSurgery.surgery_butt !== "no default setting") { + surgeries.push("a bigger butt"); + slave.buttImplant = 1; + slave.butt += 1; + V.cash -= V.surgeryCost; + 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)) { + if (thisSurgery.surgery_boobs !== "no default setting") { + surgeries.push("bigger boobs"); + slave.boobsImplant += 200; + slave.boobs += 200; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + } + + } else if ((slave.hips < 3) && (slave.hips < thisSurgery.surgery_hips) && (V.surgeryUpgrade == 1)) { + surgeries.push("wider hips"); + slave.hips++; + slave.hipsImplant++; + V.cash -= V.surgeryCost; + if (V.PC.medicine >= 100) slave.health -= 5; + else slave.health -= 10; + + } else if (slave.bellyImplant < 0 && V.bellyImplants > 0 && thisSurgery.surgery_bellyImplant == "install" && slave.womb.length == 0 && slave.broodmother == 0) { + slave.bellyImplant = 100; + slave.preg = -2; + V.cash -= V.surgeryCost; + 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; + } else { + surgeries.push("male belly implant"); + V.surgeryType = "bellyInMale"; + if (V.PC.medicine >= 100) slave.health -= 25; + else slave.health -= 50; + } + bellyIn(slave); + + } else if (slave.bellyImplant >= 0 && thisSurgery.surgery_bellyImplant == "remove") { + surgeries.push("belly implant removal"); + V.surgeryType = "bellyOut"; + if (V.PC.medicine >= 100) + slave.health -= 5; + else + slave.health -= 10; + slave.preg = 0; + slave.bellyImplant = -1; + V.cash -= V.surgeryCost; + } else if (slave.balls > 0 && slave.vasectomy === 0 && thisSurgery.surgery_vasectomy === true) { + surgeries.push("vasectomy"); + V.surgeryType = "vasectomy"; + if (V.PC.medicine >= 100) + slave.health -= 5; + else + slave.health -= 10; + slave.vasectomy = 1; + V.cash -= V.surgeryCost; + } else if (slave.balls > 0 && slave.vasectomy === 1 && thisSurgery.surgery_vasectomy === false) { + surgery.push("undo vasectomy"); + V.surgeryType = "vasectomy undo"; + if (V.PC.medicine >= 100) + slave.health -=5; + else + slave.health -= 10; + slave.vasectomy = 0; + V.cash -= V.surgeryCost; } } - class BehaviourSection extends Section { - constructor() { - super("Behavior Settings"); - this.appendChild(new AutomaticAssignmentList()); - this.appendChild(new LivingStandardList()); - this.appendChild(new PunishmentList()); - this.appendChild(new RewardList()); - this.appendChild(new ReleaseList()); - this.appendChild(new SmartFetishList()); - this.appendChild(new SmartXYAttractionList()); - this.appendChild(new SmartXXAttractionList()); - this.appendChild(new SmartEnergyList()); - this.appendChild(new SpeechList()); - this.appendChild(new RelationshipList()); - if (V.studio === 1) - this.appendChild(new PornList()); + function PrintResult(slave, thisSurgery, surgeries) { + let surgeriesDisplay = ""; + if (surgeries.length === 1) + surgeriesDisplay = surgeries[0]; + else { + surgeriesDisplay = surgeries.slice(0, surgeries.length - 1).join(", "); + surgeriesDisplay += ", and" + surgeries[surgeries.length - 1]; } + r += `${V.assistantName === "your personal assistant" ? "Your personal assistant" : V.assistantName}, ordered to apply surgery, gives ${slave.slaveName} <span class="lime">${surgeriesDisplay}.</span>`; } - class CosmeticSection extends Section { - constructor() { - super("Cosmetic Settings", true); - this.appendChild(new EyewearList()); - this.appendChild(new LensesList()); - this.appendChild(new MakeupList()); - this.appendChild(new NailsList()); - this.appendChild(new HairLengthList()); - this.appendChild(new HairColourList()); - this.appendChild(new HairStyleList()); - this.appendChild(new PubicHairColourList()); - this.appendChild(new PubicHairStyleList()); - this.appendChild(new ArmpitHairColourList()); - this.appendChild(new ArmpitHairStyleList()); + function bellyIn(slave) { + // less hacky version of calling surgery degradation silently + if (slave.devotion > 50) + slave.devotion += 4; + else if (slave.devotion >= -20) + slave.trust -= 5; + else { + slave.trust -= 5; + slave.devotion -= 5; } } +})(); - class BodyModSection extends Section { - constructor() { - super("Body Mod Settings", true); - this.appendChild(new EarPiercingList()); - this.appendChild(new NosePiercingList()); - this.appendChild(new EyebrowPiercingList()); - this.appendChild(new NavelPiercingList()); - this.appendChild(new NipplePiercingList()); - this.appendChild(new AreolaPiercingList()); - this.appendChild(new LipPiercingList()); - this.appendChild(new TonguePiercingList()); - this.appendChild(new ClitPiercingList()); - this.appendChild(new LabiaPiercingList()); - this.appendChild(new ShaftPiercingList()); - this.appendChild(new PerineumPiercingList()); - this.appendChild(new CorsetPiercingList()); - - this.appendChild(new AutoBrandingList()); - this.appendChild(new BrandingLocationList()); - this.appendChild(new BrandDesignList()); - this.appendChild(new FaceTattooList()); - this.appendChild(new ShoulderTattooList()); - this.appendChild(new ChestTattooList()); - this.appendChild(new ArmTattooList()); - this.appendChild(new UpperBackTattooList()); - this.appendChild(new LowerBackTattooList()); - this.appendChild(new AbdomenTattooList()); - if (V.seeDicks || V.makeDicks) - this.appendChild(new DickTattooList()); - this.appendChild(new ButtockTattooList()); - this.appendChild(new AnalTattooList()); - this.appendChild(new LegTattooList()); - } - } +/*:: sexActJS [script]*/ - class AutosurgerySection extends Section { - constructor() { - super("Autosurgery Settings", true); - this.appendChild(new VisionSurgeryList()); - this.appendChild(new LactationSurgeryList()); - if (V.seeDicks || V.makeDicks) { - this.appendChild(new SemenSurgeryList()); - this.appendChild(new VasectomyList()); +/* + times is how many times to increment the anal counts. + if left undefined it will assume it to be 1. +*/ +window.AnalVCheck = function AnalVCheck(times) { + const V = State.variables; + const slave = V.activeSlave; + let r = ``; + if (canDoAnal(slave) && slave.anus === 0) { + r += `@@.lime;This breaks in ${slave.slaveName}'s virgin ass.@@ `; + if (slave.devotion > 50 || slave.career == "a slave since birth") { + r += `Since it's her first time, you gently ease yourself into her butthole and gradually increase the intensity of your thrusts. Before long she's moaning loudly as you continue working away at her butthole. `; + if (slave.tankBaby == 2) { + r += `She thinks of losing her anal virginity to her ${WrittenMaster(slave)} a @@.hotpink;necessity.@@ She expects her asshole to be seeing a lot more attention now.`; } - this.appendChild(new CosmeticSurgeryList()); - this.appendChild(new LipSurgeryList()); - this.appendChild(new ButtSurgeryList()); - this.appendChild(new BreastSurgeryList()); - this.appendChild(new TighteningSurgeryList()); - this.appendChild(new BodyHairSurgeryList()); - this.appendChild(new HairSurgeryList()); - if (V.bellyImplants > 0) - this.appendChild(new BellyImplantList()); - } - } - - class ClothesList extends List { - constructor() { - const items = [ - ["Select her own outfit", "choosing her own clothes"] - ]; - super("Clothes", items); - - const nclothes = [ - ["No default clothes setting", "no default setting"], - ["Apron", "an apron"], - ["Bangles", "slutty jewelry"], - ["Bodysuit", "a comfortable bodysuit"], - ["Cheerleader outfit", "a cheerleader outfit"], - ["Clubslut netting", "clubslut netting"], - ["Cybersuit", "a cybersuit"], - ["Cutoffs and a t-shirt", "cutoffs and a t-shirt"], - ["Fallen nun", "a fallen nuns habit"], - ["Halter top", "a halter top dress"], - ["Hijab and abaya", "a hijab and abaya"], - ["Latex catsuit", "a latex catsuit"], - ["Leotard", "a leotard"], - ["Long Qipao", "a long qipao"], - ["Lederhosen", "lederhosen"], - ["Battlearmor", "battlearmor"], - ["Mounty outfit", "a mounty outfit"], - ["Dirndl", "a dirndl"], - ["Biyelgee costume", "a biyelgee costume"], - ["Maid (nice)", "a nice maid outfit"], - ["Maid (slutty)", "a slutty maid outfit"], - ["Military uniform", "a military uniform"], - ["Schutzstaffel uniform", "a schutzstaffel uniform"], - ["Schutzstaffel uniform (slutty)", "a slutty schutzstaffel uniform"], - ["Red Army uniform", "a red army uniform"], - ["Mini dress", "a mini dress"], - ["Monokini", "a monokini"], - ["Nice lingerie", "attractive lingerie"], - ["Nurse (nice)", "a nice nurse outfit"], - ["Schoolgirl", "a schoolgirl outfit"], - ["Silken ballgown", "a ball gown"], - ["Skimpy battledress", "battledress"], - ["Slave gown", "a slave gown"], - ["Slutty outfit", "a slutty outfit"], - ["String bikini", "a string bikini"], - ["Scalemail bikini", "a scalemail bikini"], - ["Succubus costume", "a succubus outfit"], - ["Suit (nice)", "nice business sattire"], - ["Suit (slutty", "slutty business attire"], - ["Spats and tank top", "spats and a tank top"] - ]; - const fsnclothes = [ - ["Body oil (FS)", "body oil"], - ["Bunny outfit (FS)", "a bunny outfit"], - ["Chattel habit (FS)", "a chattel habit"], - ["Conservative clothing (FS)", "conservative clothing"], - ["Harem gauze (FS)", "harem gauze"], - ["Huipil (FS)", "a huipil"], - ["Kimono (FS)", "a kimono"], - ["Maternity dress (FS)", "a maternity dress"], - ["Maternity lingerie (FS)", "attractive lingerie for a pregnant woman"], - ["Slutty qipao (FS)", "a slutty qipao"], - ["Stretch pants and a crop-top (FS)", "stretch pants and a crop-top"], - ["Toga (FS)", "a toga"], - ["Western clothing (FS)", "Western clothing"], - ]; - fsnclothes.forEach(pair => { if (isItemAccessible(pair[1])) nclothes.push(pair); }); - const nice = new ListSubSection(this, "Nice", nclothes); - this.appendChild(nice); - - const hclothes = [ - ["Nude", "no clothing"], - ["Penitent nun", "a penitent nuns habit"], - ["Restrictive latex", "restrictive latex"], - ["Shibari ropes", "shibari ropes"], - ["Uncomfortable straps", "uncomfortable straps"] - ]; - const fshclothes = [ - ["Chains (FS)", "chains"], - ]; - fshclothes.forEach(pair => { if (isItemAccessible(pair[1])) hclothes.push(pair); }); - - const harsh = new ListSubSection(this, "Harsh", hclothes); - this.appendChild(harsh); - - this.setValue(current_rule.set.clothes); - this.onchange = (value) => current_rule.set.clothes = value; + else { + r += `She thinks of losing her anal virginity to you as a @@.hotpink;connection@@ with her beloved ${WrittenMaster(slave)}. `; + if ((slave.fetishKnown && slave.fetish == "buttslut") || (slave.energy > 95) || (slave.attrXX >= 85 && V.PC.dick === 0)) { + r += `She can't wait to be fucked in the ass by you again.`; + } + else { + r += `She looks forward to having her asshole fucked by you again.`; + } + } + slave.devotion += 4; } - } - - class CollarList extends List { - constructor() { - const items = [ - ["No default collar setting", "no default setting"], - ["No collar", "none"], - ]; - super("Collar", items); - - const ncollars = [ - ["Stylish leather", "stylish leather"], - ["Satin choker", "satin choker"], - ["Silken Ribbon", "silk ribbon"], - ["Heavy Gold", "heavy gold"], - ["Pretty jewelry", "pretty jewelry"], - ["Cowbell", "leather with cowbell"] - ]; - if (V.seeAge !== 0) - ncollars.push(["Nice retirement counter", "nice retirement counter"]); - const fsncollars = [ - ["Bowtie collar", "bowtie"], - ["ancient Egyptian", "ancient Egyptian"], - ]; - fsncollars.forEach(pair => { if (isItemAccessible(pair[1])) ncollars.push(pair); }); - const nice = new ListSubSection(this, "Nice", ncollars); - this.appendChild(nice); - - const hcollars = []; - setup.harshCollars.forEach(item => { - if (item.fs === "seeage" && V.seeAge === 0) return; - else if (item.rs === "buyGag" && V.toysBoughtGags !== 1) return; - else hcollars.push([item.name, item.value]); - }); - const harsh = new ListSubSection(this, "Harsh", hcollars); - this.appendChild(harsh); - - this.setValue(current_rule.set.collar); - this.onchange = (value) => current_rule.set.collar = value; + else if (slave.devotion > 20) { + r += `Since it's her first time, you gently ease yourself into her butthole and gradually increase the intensity of your thrusts. Her moans become louder and louder as you continue working away at her butthole. She accepts the pain and humiliation of anal sex as part of her sexual servitude, though she hopes that her next time will be less painful.`; } - } - - class ShoeList extends List { - constructor() { - super("Shoes", setup.shoes.map(i => [i.name, i.value])); - this.setValue(current_rule.set.shoes); - this.onchange = (value) => current_rule.set.shoes = value; + else if (slave.devotion >= -20) { + r += `You force yourself into her butthole. She sobs and cries with disgust while you continue thrusting into her ass. She @@.gold;fears@@ her next anal sex, remembering the pain of losing her anal virginity. She dreads having her ass violated by you again.`; + slave.trust -= 5; } - } - - class CorsetList extends List { - constructor() { - const bellies = []; - setup.bellyAccessories.forEach(acc => { - if (acc.fs === undefined && acc.rs === undefined) - bellies.push([acc.name, acc.value]); - else if (acc.fs === "repopulation" && V.arcologies[0].FSRepopulationFocus !== "unset") - bellies.push([acc.name + " (FS)", acc.value]); - else if (acc.rs === "boughtBelly" && V.clothesBoughtBelly === 1) - bellies.push([acc.name + " (Purchased)", acc.value]); - }); - super("Corsetage", bellies); - this.setValue(current_rule.set.bellyAccessory); - this.onchange = (value) => current_rule.set.bellyAccessory = value; + else { + r += `You force yourself into her butthole. She sobs and cries with disgust while you continue thrusting into her ass. She @@.mediumorchid;hates@@ and @@.gold;fears@@ you for violating her virgin butt. She dreads having her ass fucked by you again.`; + slave.trust -= 5; + slave.devotion -= 5; } + slave.anus = 1; } - - class LeggingsList extends List { - constructor() { - const items = [ - ["no default settings"], - ["none"], - ["short stockings"], - ["long stockings"], - ]; - super("Leg accessory", items); - this.setValue(current_rule.set.legAccessory); - this.onchange = (value) => current_rule.set.legAccessory = value; + if (canDoAnal(slave)) { + if (V.PC.dick === 1 && canGetPregnant(slave) && slave.eggType == "human") { + r += knockMeUp(slave, 10, 1, -1, 1); + } + if (!times) { + V.analTotal += 1; + slave.analCount += 1; + } + else { + V.analTotal += times; + slave.analCount += times; } } + return r; +} - class VagAccVirginsList extends List { - constructor() { - const accs = []; - setup.vaginalAccessories.forEach(acc => { - if (acc.fs === undefined && acc.rs === undefined) - accs.push([acc.name, acc.value]); - else if (acc.rs === "buyBigDildos" && V.toysBoughtDildos === 1) - accs.push([acc.name + " (Purchased)", acc.value]); - }); - super("Vaginal accessories for virgins", accs); - this.setValue(current_rule.set.virginAccessory); - this.onchange = (value) => current_rule.set.virginAccessory = value; +/* + times is how many times to increment the vaginal counts. + if left undefined it will assume it to be 1. +*/ +window.VaginalVCheck = function VaginalVCheck(times) { + const V = State.variables; + const slave = V.activeSlave; + let r = ``; + if (canDoVaginal(slave) && slave.vagina === 0) { + r += `@@.lime;This breaks in ${slave.slaveName}'s virgin pussy.@@ `; + if (slave.devotion > 50 || slave.career == "a slave since birth") { + r += `You ease yourself into her pussy, since it's her first time, then gradually speed up your thrusts while she slowly learns to move her hips along with you. She moans loudly. `; + if (slave.tankBaby == 2) { + r += `She thinks of losing her virginity to her ${WrittenMaster(slave)} a @@.hotpink;necessity to be happy.@@ She expects her pussy to be seeing a lot more attention in the future.`; + } + else { + r += `@@.hotpink;She enjoys losing her cherry to you.@@ `; + if ((slave.fetishKnown && slave.fetish == "pregnancy") || (slave.energy > 95) || (slave.attrXY >= 85 && V.PC.dick === 1)) { + r += `She can't wait to have her pussy fucked by you again.`; + } + else { + r += `She looks forward to having her pussy fucked by you again.`; + } + } + slave.devotion += 4; } - } + else if (slave.devotion > 20) { + r += `You ease yourself into her pussy, since it's her first time, then gradually speed up your thrusts while she slowly learns to move her hips along with you. She accepts losing her virginity to her owner and she looks forward to having her pussy fucked by you again.`; + } + else if (slave.devotion >= -20) { + r += `You force yourself into her pussy. She sobs and cries with disgust while you continue thrusting into her fuck hole. She @@.mediumorchid;hates@@ losing her virginity this way and @@.gold;fears@@ the next time you'll conquer her. She dreads getting violated by you again.`; + slave.trust -= 5; + slave.devotion -= 5; + } + else { + r += `You force yourself into her pussy. She sobs and cries with disgust while you continue working her fuck hole. She tries to struggle, but you only pound harder. She @@.mediumorchid;hates@@ and @@.gold;fears@@ you for robbing her of her virginity. She dreads getting fucked by you again.`; + slave.trust -= 10; + slave.devotion -= 15; + } + slave.vagina = 1; - class VagAccAVirginsList extends List { - constructor() { - const accs = []; - setup.vaginalAccessories.forEach(acc => { - if (acc.fs === undefined && acc.rs === undefined) - accs.push([acc.name, acc.value]); - else if (acc.rs === "buyBigDildos" && V.toysBoughtDildos === 1) - accs.push([acc.name + " (Purchased)", acc.value]); - }); - super("Vaginal accessories for anal virgins", accs); - this.setValue(current_rule.set.aVirginAccessory); - this.onchange = (value) => current_rule.set.aVirginAccessory = value; + if (V.PC.dick === 1 && canGetPregnant(slave) && slave.eggType == "human") { + r += knockMeUp(slave, 10, 0, -1, 1); + } + if (!times) { + V.vaginalTotal += 1; + slave.vaginalCount += 1; + } + else { + V.vaginalTotal += times; + slave.vaginalCount += times; } } + return r; +} - class VagAccOtherList extends List { - constructor() { - const accs = []; - setup.vaginalAccessories.forEach(acc => { - if (acc.fs === undefined && acc.rs === undefined) - accs.push([acc.name, acc.value]); - else if (acc.rs === "buyBigDildos" && V.toysBoughtDildos === 1) - accs.push([acc.name + " (Purchased)", acc.value]); - }); - super("Vaginal accessories for other slaves", accs); - this.setValue(current_rule.set.vaginalAccessory); - this.onchange = (value) => current_rule.set.vaginalAccessory = value; +/* + analTimes is how many times to increment the anal counts, if there is no vagina available. + bothTimes is how many times to increment both holes counts (usually it is half of analTimes). + In both cases if left undefined it will assume it to be 1. +*/ +window.BothVCheck = function BothVCheck(analTimes, bothTimes) { + const V = State.variables; + const slave = V.activeSlave; + let r = ``; + if (canDoVaginal(slave)) { + if (slave.vagina === 0) { + if (canDoAnal(slave) && slave.anus == 0) { + r += `@@.lime;This breaks in ${slave.slaveName}'s virgin holes.@@ `; + if (slave.devotion > 50 || slave.career == "a slave since birth") { + r += `As it's her first time, you ease yourself into her pussy before gradually working your way into her ass and alternate between the two holes while she moans. `; + if (slave.tankBaby == 2) { + r += `She believes you taking her virgin holes @@.hotpink;will keep her from suffering.@@ She expects you to require her holes as tribute again soon.`; + } + else { + r += `@@.hotpink;She's so devoted she enjoys being fucked in both holes for the first time.@@ She looks forward to having her holes fucked by you again.`; + } + slave.devotion += 4; + } + else if (slave.devotion <= 20) { + r += `You force yourself into her pussy before working your way into her ass. She sobs and cries with disgust while you alternate between the two holes. She @@.mediumorchid;hates@@ losing her virginity and anal virginity in one @@.gold;brutal@@ incident. She dreads having her holes violated by you again.`; + slave.trust -= 5; + slave.devotion -= 5; + } + else { + r += `As it's her first time, you ease yourself into her pussy before gradually working your way into her ass and alternate between the two holes while she moans. She accepts being fucked in both holes for the first time. She looks forward to having her holes fucked by you again.`; + } + slave.anus = 1; + } + else { + r += `@@.lime;This breaks in ${slave.slaveName}'s virgin pussy.@@ `; + if (slave.devotion > 50 || slave.career == "a slave since birth") { + r += `As it's her first time, you ease yourself into her pussy and gradually speed up your thrusts while she slowly learns to move her hips along with you. She moans loudly. `; + if (slave.tankBaby == 2) { + r += `She thinks of losing her virginity to her ${WrittenMaster(slave)} a @@.hotpink;necessity to be happy.@@ She expects her pussy to be seeing a lot more attention in the future.`; + } + else { + r += `@@.hotpink;She enjoys losing her cherry to you.@@ She looks forward to having her pussy fucked by you again.`; + } + slave.devotion += 4; + } + else if (slave.devotion <= 20) { + r += `You force yourself into her pussy. She sobs and cries with disgust while you continue working her fuck hole. She @@.mediumorchid;hates@@ and @@.gold;fears@@ you for taking her virginity. She dreads having her pussy violated by you again.`; + slave.trust -= 5; + slave.devotion -= 5; + } + else { + r += `As it's her first time, you ease yourself into her pussy before gradually increasing the intensity of your thrusts while she softly moans. She accepts losing her virginity to her owner and she looks forward to having her pussy fucked by you again.`; + } + } + slave.vagina = 1; + } + else if (canDoAnal(slave) && slave.anus == 0) { + r += `@@.lime;This breaks in ${slave.slaveName}'s virgin ass.@@ `; + if (slave.devotion > 50 || slave.career == "a slave since birth") { + r += `As it's her first time, you ease yourself into her butthole and gradually speed up your thrusts while she slowly learns to move her hips along with you. She moans loudly. `; + if (slave.tankBaby == 2) { + r += `She thinks of losing her anal virginity to her ${WrittenMaster(slave)} a @@.hotpink;necessity.@@ She expects her asshole to be seeing a lot more attention now.`; + } + else { + r += `She thinks of losing her anal virginity to you as a @@.hotpink;connection@@ with her beloved ${WrittenMaster(slave)}. She looks forward to having her asshole fucked by you again.` + } + slave.devotion += 4; + } + else if (slave.devotion > 20){ + r += `As it's her first time, you ease yourself into her butthole and gradually increase the intensity of your thrusts. She accepts the pain and humiliation of anal sex as part of her sexual servitude, though she hopes that her next time will be less painful.`; + } + else if (slave.devotion >= -20) { + r += `You force yourself into her butthole. She sobs and cries with disgust while you continue thrusting into her ass. She @@.gold;fears@@ her next anal sex, remembering the pain of losing her anal virginity. She dreads having her ass violated by you again.`; + slave.trust -= 5; + } + else { + r += `You force yourself into her butthole. She sobs and cries with disgust while you continue thrusting into her ass. She @@.mediumorchid;hates@@ and @@.gold;fears@@ you for violating her virgin butt. She dreads having her ass fucked by you again.`; + slave.trust -= 5; + slave.devotion -= 5; + } + slave.anus = 1; + } + if (canDoAnal(slave)) { + if (!bothTimes) { + V.vaginalTotal += 1; + V.analTotal += 1; + slave.vaginalCount += 1; + slave.analCount += 1; + } + else { + V.vaginalTotal += bothTimes; + V.analTotal += bothTimes; + slave.vaginalCount += bothTimes; + slave.analCount += bothTimes; + } + if (V.PC.dick === 1 && canGetPregnant(slave) && slave.eggType == "human") { + r += knockMeUp(slave, 10, 2, -1, 1); + } + } + else { + if (!bothTimes) { + V.vaginalTotal += 1; + slave.vaginalCount += 1; + } + else { + V.vaginalTotal += bothTimes; + slave.vaginalCount += bothTimes; + } + if (V.PC.dick == 1 && canGetPregnant(slave) && slave.eggType == "human") { + r += knockMeUp(slave, 10, 0, -1, 1); + } } } - - class DickAccVirginsList extends List { - constructor() { - super("Dick accessories for anal virgins", setup.dickAccessories.map(i => [i.name, i.value])); - this.setValue(current_rule.set.aVirginDickAccessory); - this.onchange = (value) => current_rule.set.aVirginDickAccessory = value; + else if (canDoAnal(slave)) { + if (slave.anus == 0) { + r += `@@.lime;This breaks in ${slave.slaveName}'s virgin ass.@@ `; + if (slave.devotion > 50 || slave.career == "a slave since birth") { + r += `As it's her first time, you ease yourself into her butthole and gradually speed up your thrusts while she slowly learns to move her hips along with you. She moans loudly. `; + if (slave.tankBaby == 2) { + r += `She thinks of losing her anal virginity to her ${WrittenMaster(slave)} a @@.hotpink;necessity.@@ She expects her asshole to be seeing a lot more attention now.`; + } + else { + r += `She thinks of losing her anal virginity to you as a @@.hotpink;connection@@ with her beloved ${WrittenMaster(slave)}. She looks forward to having her asshole fucked by you again.`; + } + slave.devotion += 4; + } + else if (slave.devotion > 20) { + r += `As it's her first time, you ease yourself into her butthole and gradually increase the intensity of your thrusts. She accepts the pain and humiliation of anal sex as part of her sexual servitude, though she hopes that her next time will be less painful.`; + } + else if (slave.devotion >= -20) { + r += `You force yourself into her butthole. She sobs and cries with disgust while you continue thrusting into her ass. She @@.gold;fears@@ her next anal sex, remembering the pain of losing her anal virginity. She dreads having her ass violated by you again.`; + slave.trust -= 5; + } + else { + r += `You force yourself into her butthole. She sobs and cries with disgust while you continue thrusting into her ass. She @@.mediumorchid;hates@@ and @@.gold;fears@@ you for violating her virgin butt. She dreads having her ass fucked by you again.` + slave.trust -= 5; + slave.devotion -= 5; + } + slave.anus = 1; } - } - - class DickAccOtherList extends List { - constructor() { - super("Dick accessories for other slaves", setup.dickAccessories.map(i => [i.name, i.value])); - this.setValue(current_rule.set.dickAccessory); - this.onchange = (value) => current_rule.set.dickAccessory = value; + if (!analTimes) { + V.analTotal += 1; + slave.analCount += 1; } - } - - class ButtplugsVirginsList extends List { - constructor() { - const accs = []; - setup.buttplugs.forEach(acc => { - if (acc.fs === undefined && acc.rs === undefined) - accs.push([acc.name, acc.value]); - else if (acc.rs === "buyBigPlugs" && V.toysBoughtButtPlugs === 1) - accs.push([acc.name + " (Purchased)", acc.value]); - }); - super("Buttplugs for anal virgins", accs); - this.setValue(current_rule.set.aVirginButtplug); - this.onchange = (value) => current_rule.set.aVirginButtplug = value; + else { + V.analTotal += analTimes; + slave.analCount += analTimes; } - } - - class ButtplugsOtherList extends List { - constructor() { - const accs = []; - setup.buttplugs.forEach(acc => { - if (acc.fs === undefined && acc.rs === undefined) - accs.push([acc.name, acc.value]); - else if (acc.rs === "buyBigPlugs" && V.toysBoughtButtPlugs === 1) - accs.push([acc.name + " (Purchased)", acc.value]); - }); - super("Buttplugs for other slaves", accs); - this.setValue(current_rule.set.buttplug); - this.onchange = (value) => current_rule.set.buttplug = value; + if (V.PC.dick === 1 && canGetPregnant(slave) && slave.eggType == "human") { + r += knockMeUp(slave, 10, 1, -1, 1); } } + return r; +} - class ImplantVolumeList extends List { - constructor() { - const pairs = [ - ["No changes", -1], - ["Empty implant", 0], - ["Early pregnancy", 1500], - ["Second trimester pregnancy", 5000], - ["Full-term pregnancy", 15000], - ["Full-term with twins", 30000], - ["Full-term with triplets", 45000], - ["Full-term with quadruplets", 60000], - ["Full-term with quintuplets", 75000], - ["Full-term with sextuplets", 90000], - ["Full-term with septuplets", 105000], - ["Full-term with octuplets", 120000] - ]; - super("Belly implant target volume (if present)", pairs); - this.setValue(current_rule.set.bellyImplantVol); - this.onchange = (value) => current_rule.set.bellyImplantVol = value; - } +/* + times is how many times to increment either the Vaginal or the Anal counts, if there is no Vagina available. + If left undefined it will assume it to be 1. +*/ +window.SimpleVCheck = function SimpleVCheck(times) { + let r = ``; + if (canDoVaginal(State.variables.activeSlave)) { + r += VaginalVCheck(times); } - - class AutosurgerySwitch extends List { - constructor() { - const pairs = [ - ["Activate", 1], - ["Off", 0], - ]; - super("Assistant-applied implants (Autosurgery global switch)", pairs); - this.setValue(current_rule.set.autoSurgery); - this.onchange = (value) => current_rule.set.autoSurgery = value; - } + else if (canDoAnal(State.variables.activeSlave)) { + r += AnalVCheck(times); } + return r; +} - class GrowthList extends Options { - constructor() { - super(); - this.sublists = []; - const pairs = [ - ["No default setting", () => this.nds()], - ["Girlish figure", () => this.girlish()], - ["Stacked figure", () => this.stacked()], - ["Huge but functional", () => this.huge()], - ["Unlimited", () => this.unlimited()], - ["None", () => this.none()] - ]; - pairs.forEach(pair => this.appendChild(new OptionsItem(...pair))); - - this.breasts = new BreastGrowthList(); - this.butts = new ButtGrowthList(); - this.lips = new LipGrowthList(); - this.sublists.push(this.breasts, this.butts, this.lips); - - if (V.seeDicks > 0 || V.makeDicks > 0) { - this.dicks = new DickGrowthList(); - this.balls = new BallGrowthList(); - this.sublists.push(this.dicks, this.balls); +/* + Before using this function, set $partner to the index of the partner in the $slaves array + analTimes is how many times to increment the Anal counts, if there is no Vagina available. + bothTimes is how many times to increment both holes counts (usually it is half of Anal). + In both cases if left undefined it will assume it to be 1. + This also checks for a valid Vagina/Accessory, though most code I've seen does this already, you + never know when someone might use the routine and forget to do such. +*/ +window.PartnerVCheck = function PartnerVCheck(analTimes, bothTimes) { + const V = State.variables; + const partner = V.slaves[V.partner]; + let r = ``; + + if (V.partner < 0 || V.partner >= V.slaves.length) { + r += `@@.red;PartnerVCheck called with invalid partner '$partner' from passage ${passage()}.@@`; + } + else if (canDoVaginal(partner)) { + if (partner.vagina === 0) { + if (canDoAnal(partner) && partner.anus === 0) { + r += `Since it's ${partner.slaveName}'s first time, you take your time and gently ease yourself into her pussy before gradually working your way into her butthole, alternating between her holes. @@.lime;This breaks in ${partner.slaveName}'s virgin holes.@@ `; + partner.vagina = 1; + partner.anus = 1; + } + else { + r += `Since it's ${partner.slaveName}'s first time, you take your time and gently ease yourself into her pussy before gradually increasing the intensity of your thrusts. @@.lime;This breaks in partner.slaveName's virgin pussy.@@ `; + partner.vagina = 1; } - - this.sublists.forEach(i => this.appendChild(i)); } - - render() { - const elem = document.createElement("div"); - const span = document.createElement("span"); - span.innerHTML = "Growth hormone regimes for healthy slaves: "; - elem.appendChild(span); - return elem; + else if (canDoAnal(partner) && partner.anus == 0) { + r += `Since it's ${partner.slaveName}'s first time, you take your time and gently ease yourself into her butthole before gradually increasing the intensity of your thrusts into her ass. @@.lime;This breaks in ${partner.slaveName}'s virgin ass.@@ `; + partner.anus = 1; } - - nds() { - [this.breasts, this.butts, this.lips, this.dicks, this.balls].forEach(i => { - i.setValue("no default change"); - i.propagateChange(); - }); + + if (canDoAnal(partner)) { + if (!bothTimes) { + V.vaginalTotal += 1; + V.analTotal += 1; + partner.vaginalCount += 1; + partner.analCount += 1; + } + else { + V.vaginalTotal += bothTimes; + V.analTotal += bothTimes; + partner.vaginalCount += bothTimes; + partner.analCount += bothTimes; + } + if (V.PC.dick === 1 && canGetPregnant(partner) && partner.eggType == "human") { + r += knockMeUp(partner, 10, 2, -1); + } } - - 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.sublists.forEach(i => i.propagateChange()); + else { + if (!bothTimes) { + V.vaginalTotal += 1; + partner.vaginalCount += 1; + } + else { + V.vaginalTotal += bothTimes; + partner.vaginalCount += bothTimes; + } + if (V.PC.dick === 1 && canGetPregnant(partner) && partner.eggType == "human") { + r += knockMeUp(partner, 10, 0, -1); + } } - - stacked() { - this.breasts.setValue(1000); - this.butts.setValue(4); - this.lips.setValue(25); - if (this.dicks) this.dicks.setValue(4); - if (this.balls) this.balls.setValue(4); - this.sublists.forEach(i => i.propagateChange()); + } + else if (canDoAnal(partner)) { + if (partner.anus === 0) { + r += `Since it's ${partner.slaveName}'s first time, you take your time and gently ease yourself into her butthole before gradually increasing the intensity of your thrusts into her ass. @@.lime;This breaks in ${partner.slaveName}'s virgin ass.@@ `; + partner.anus = 1; } - - 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.sublists.forEach(i => i.propagateChange()); + if (!analTimes) { + V.analTotal += analTimes; + partner.analCount += analTimes; } - - 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.sublists.forEach(i => i.propagateChange()); + else { + V.analTotal += 1; + partner.analCount += 1; } - - none() { - this.sublists.forEach(i => { - i.setValue(0); - i.propagateChange(); - }); + if (V.PC.dick === 1 && canGetPregnant(partner) && partner.eggType == "human") { + r += knockMeUp(partner, 10, 1, -1); } } + return r; +} - class BreastGrowthList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["B Cup", 350], - ["D Cup", 1000], - ["Monstrous", 9000], - ["Unlimited", 48000], - ["None", 0] - ]; - super("Breasts", pairs, true); - this.setValue(current_rule.set.growth_boobs); - this.onchange = (value) => current_rule.set.growth_boobs = value; - } +/* + count is how many times to increment either the Vaginal, Anal, or Oral counts, depending on availability of slave. + If count is left undefined it will assume it to be 1. + Intended to be a simple "I want to fuck x and not have to code a bunch of logic for it". +*/ +window.SimpleSexAct = function SimpleSexAct(slave, count) { + const V = State.variables; + let fuckTarget = 0; + let fuckCount = 1; + let r = ``; + if (count) { + fuckCount = count; } - - class ButtGrowthList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Cute", 2], - ["Big", 4], - ["Huge", 6], - ["Unlimited", 20], - ["None", 0] - ]; - super("Butts", pairs, true); - this.setValue(current_rule.set.growth_butt); - this.onchange = (value) => current_rule.set.growth_butt = value; + for (var i = 0; i < fuckCount; i++) { + fuckTarget = jsRandom(1,100); + if (slave.nipples == "fuckable" && V.PC.dick === 1 && fuckTarget > 80) { + V.mammaryTotal += 1; + slave.mammaryCount += 1; } - } - - class LipGrowthList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Plump", 25], - ["Beestung", 45], - ["Facepussy", 100], - ["None", 0] - ]; - super("Lips", pairs, true); - this.setValue(current_rule.set.growth_lips); - this.onchange = (value) => current_rule.set.growth_lips = value; + else if (canDoVaginal(slave) && slave.vagina > 0 && fuckTarget > 33) { + V.vaginalTotal += 1; + slave.vaginalCount += 1; + if (V.PC.dick === 1 && canGetPregnant(slave) && slave.eggType == "human") { + r += knockMeUp(slave, 10, 0, -1, 1); + } } - } - - class DickGrowthList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Above average", 4], - ["Pornstar", 6], - ["Unlimited", 30], - ["None", 0] - ]; - super("Dicks, if present", pairs, true); - this.setValue(current_rule.set.growth_dick); - this.onchange = (value) => current_rule.set.growth_dick = value; + else if (canDoAnal(slave) && slave.anus > 0 && fuckTarget > 10) { + V.analTotal += 1; + slave.analCount += 1; + if (V.PC.dick == 1 && canGetPregnant(slave) && slave.eggType == "human") { + r += knockMeUp(slave, 10, 1, -1, 1); + } } - } - - class BallGrowthList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Sizeable", 4], - ["Cumslave", 6], - ["Unlimited", 125], - ["None", 0] - ]; - super("Balls, if present", pairs, true); - this.setValue(current_rule.set.growth_balls); - this.onchange = (value) => current_rule.set.growth_balls = value; + else { + V.oralTotal += 1; + slave.oralCount += 1; } } + return r; +} - class CurrativesList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Preventatives", 1], - ["Curatives", 2], - ]; - super("Health drugs", pairs); - this.setValue(current_rule.set.curatives); - this.onchange = (value) => current_rule.set.curatives = value; +/* + count is how many times to increment either the Vaginal, Anal, or Oral counts, depending on availability of slave. + If count is left undefined it will assume it to be 1. + Intended to be a simple "x got fucked y times and I don't want to keep coding it". + Pregnancy chance is handled in saLongTermEffects.tw. +*/ +window.SimpleSlaveFucking = function SimpleSlaveFucking(slave, count) { + const V = State.variables; + let fuckTarget = 0; + let fuckCount = 1; + if (count) { + fuckCount = count; + } + for (var i = 0; i < fuckCount; i++) { + fuckTarget = jsRandom(1,100); + if (slave.nipples == "fuckable" && fuckTarget > 80) { + V.mammaryTotal += 1; + slave.mammaryCount += 1; + } + else if (canDoVaginal(slave) && slave.vagina > 0 && fuckTarget > 33) { + V.vaginalTotal += 1; + slave.vaginalCount += 1; + } + else if (canDoAnal(slave) && slave.anus > 0 && fuckTarget > 10) { + V.analTotal += 1; + slave.analCount += 1; + } + else { + V.oralTotal += 1; + slave.oralCount += 1; } } + return; +} - class AphrodisiacList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Standard", 1], - ["Extreme", 2], - ["Anaphrodisiacs", -1] - ]; - super("Aphrodisiacs", pairs); - this.setValue(current_rule.set.aphrodisiacs); - this.onchange = (value) => current_rule.set.aphrodisiacs = value; +/* + count is how many times to increment either the Vaginal, Anal, or Oral counts, depending on availability of slave. + If count is left undefined it will assume it to be 1. + Intended to be a simple "x got fucked y times by z and I don't want to keep coding it". +*/ +window.SimpleSlaveSlaveFucking = function SimpleSlaveSlaveFucking(subslave, domslave, count) { + const V = State.variables; + let fuckTarget = 0; + let fuckCount = 1; + let r = ``; + if (count) { + fuckCount = count; + } + for (var j = 0; j < fuckCount; j++) { + //there is a reason randomization happens inside cycle - to spread fuck around, otherwise cycle isn't even needed + fuckTarget = jsRandom(1,100); + if (subslave.nipples === "fuckable" && canPenetrate(domslave) && fuckTarget > 80) { + if (passage() === "SA serve your other slaves") { + if (subslave.ID == V.slaves[V.i].ID) { + V.slaves[V.i].mammaryCount++; + V.mammaryTotal++; + domslave.penetrativeCount++; + V.penetrativeTotal++; + } + else { + subslave.mammaryCount++; + V.mammaryTotal++; + V.slaves[V.i].penetrativeCount++; + V.penetrativeTotal++; + } + } + else { + V.mammaryTotal++; + V.penetrativeTotal++; + subslave.mammaryCount++; + domslave.penetrativeCount++; + } + } + else if (canDoVaginal(subslave) && subslave.vagina > 0 && canPenetrate(domslave) && fuckTarget > 33) { + if (passage() === "SA serve your other slaves") { + if (subslave.ID == V.slaves[V.i].ID) { + V.slaves[V.i].vaginalCount++; + V.vaginalTotal++; + V.penetrativeTotal++; + domslave.penetrativeCount++; + } + else { + V.slaves[V.i].penetrativeCount++; + V.penetrativeTotal++; + subslave.vaginalCount++; + V.vaginalTotal++; + } + } + else { + V.vaginalTotal++; + subslave.vaginalCount++; + V.penetrativeTotal++; + domslave.penetrativeCount++; + } + if (canImpreg(subslave, domslave)) { + r += knockMeUp(subslave, 3, 0, domslave.ID, 1); + } + } + else if (canDoAnal(subslave) && subslave.anus > 0 && canPenetrate(domslave) && fuckTarget > 10) { + //i think would impregnate from anal here even without .mpreg? same in original widget too + if (canImpreg(subslave, domslave) && subslave.mpreg == 1) { + r += knockMeUp(subslave, 3, 1, domslave.ID, 1); + } + if (passage() === "SA serve your other slaves") { + if (subslave.ID == V.slaves[V.i].ID) { + V.slaves[V.i].analCount++; + V.analTotal++; + V.penetrativeTotal++; + domslave.penetrativeCount++; + } + else { + V.slaves[V.i].penetrativeCount++; + V.penetrativeTotal++; + V.analTotal++; + subslave.analCount++; + } + } + else { + V.analTotal++; + subslave.analCount++; + V.penetrativeTotal++; + domslave.penetrativeCount++; + } } - } - - class ContraceptiveList extends List { - constructor() { - const drugs = [ - ["No default setting", "no default setting"], - ["Contraceptives", true], - ["Fertile", false], - ]; - super("Contraceptives for fertile slaves", drugs); - this.setValue(current_rule.set.preg); - this.onchange = (value) => current_rule.set.preg = value; + else { + V.oralTotal++; + subslave.oralCount++; } } + return r; +} - class PregDrugsList extends List { - constructor() { - const pairs = [ - ["No changes", "no default setting"], - ["None", "none"], - ["Fast gestation", "fast"], - ["Slow gestation", "slow"], - ["Birth supressors", "suppress"], - ["Birth stimulators", "stimulate"] - ]; - super("Pregnancy control agents for pregnant slaves", pairs); - this.setValue(current_rule.set.pregSpeed); - this.onchange = (value) => current_rule.set.pregSpeed = value; - } +window.SimpleVaginaFuck = function SimpleVaginaFuck(slave, count) { + if (count) { + State.variables.vaginalTotal += count; + slave.vaginalCount += count; + } + else { + State.variables.vaginalTotal++; + slave.vaginalCount++; } +} - class FemaleHormonesList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Intensive Female", 2], - ["Female", 1], - ["None", 0], - ["Male", -1], - ["Intensive Male", -2] - ]; - super("Hormones for female slaves", pairs); - this.setValue(current_rule.set.XX); - this.onchange = (value) => current_rule.set.XX = value; - } +window.SimpleAssFuck = function SimpleAssFuck(slave, count) { + if (count) { + State.variables.analTotal += count; + slave.analCount += count; + } + else { + State.variables.analTotal++; + slave.analCount++; } +} - class GeldingHormonesList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Intensive Female", 2], - ["Female", 1], - ["None", 0], - ["Male", -1], - ["Intensive Male", -2] - ]; - super("Hormones for geldings", pairs); - this.setValue(current_rule.set.gelding); - this.onchange = (value) => current_rule.set.gelding = value; +/*:: PenthouseNaming [script]*/ + +window.MS = function() { + const V = State.variables; + var name = ""; + if (V.masterSuiteNameCaps === "The Master Suite") + name = "Master Suite" + else + name = V.masterSuiteNameCaps; + return `<<link "${name}""Master Suite">><</link>> `} +window.HS = function() { + const V = State.variables; + var name = ""; + if (V.HGSuiteNameCaps === "The Head Girl Suite") + name = "Head Girl Suite" + else + name = V.HGSuiteNameCaps; + return `<<link "${name}""Head Girl Suite">><</link>> `} +window.SQ = function() { + const V = State.variables; + var name = ""; + if (V.servantsQuartersNameCaps === "The Servants' Quarters") + name = "Servants' Quarters" + else + name = V.servantsQuartersNameCaps; + return `<<link "${name}""Servants' Quarters">><</link>> `} +window.S = function() { + const V = State.variables; + var name = ""; + if (V.spaNameCaps === "The Spa") + name = "Spa" + else + name = V.spaNameCaps; + return `<<link "${name}""Spa">><</link>> `} +window.CI = function() { + const V = State.variables; + var name = ""; + if (V.clinicNameCaps === "The Clinic") + name = "Clinic" + else + name = V.clinicNameCaps; + return `<<link "${name}""Clinic">><</link>> `} +window.SC = function() { + const V = State.variables; + var name = ""; + if (V.schoolroomNameCaps === "The Schoolroom") + name = "Schoolroom" + else + name = V.schoolroomNameCaps; + return `<<link "${name}""Schoolroom">><</link>> `} +window.CB = function() { + const V = State.variables; + var name = ""; + if (V.cellblockNameCaps === "The Cellblock") + name = "Cellblock" + else + name = V.cellblockNameCaps; + return `<<link "${name}""Cellblock">><</link>> `} +window.I = function() { + const V = State.variables; + var name = ""; + if (V.incubatorNameCaps === "The Incubator") + name = "Incubator" + else + name = V.incubatorNameCaps; + return `<<link "${name}""Incubator">><</link>> `} + +/*:: Slave Summary Widgets JS [script]*/ + +window.clearSummaryCache = function clearSummaryCache(slave) { + if (!slave) + setup.summaryCache = {}; + else if (slave instanceof Object && slave.ID !== Infinity && slave.ID !== -Infinity) + setup.summaryCache[slave.ID] = undefined; + else + setup.summaryCache[slave] = undefined; +}; + +window.SlaveSummary = function SlaveSummary(slave) { + const V = State.variables; + if(V.useSummaryCache) { + if (setup.summaryCache[slave.ID] === undefined) + setup.summaryCache[slave.ID] = SlaveSummaryUncached(slave); + //this.output.appendChild(setup.summaryCache[State.temporary.Slave.ID].cloneNode(true)) + return setup.summaryCache[slave.ID]; + } else return SlaveSummaryUncached(slave); +}; + +window.SlaveSummaryUncached = (function(){ + "use strict"; + let V, r; + + function SlaveSummaryUncached(slave) { + V = State.variables; + r = ""; + if (V.abbreviateDevotion === 1) + short_devotion(slave); + else if (V.abbreviateDevotion === 2) + long_devotion(slave); + if (slave.fuckdoll === 0) { + if (V.abbreviateRules === 1) + short_rules(slave); + else if (V.abbreviateRules === 2) + long_rules(slave); + } + if (slave.tired !== 0) + r += `Tired.`; + if (V.abbreviateDiet === 1) + short_weight(slave); + else if (V.abbreviateDiet === 2) + long_weight(slave); + if (V.abbreviateDiet === 1) + short_diet(slave); + else if (V.abbreviateDiet === 2) + long_diet(slave); + if (V.abbreviateHealth === 1) + short_health(slave); + else if (V.abbreviateHealth === 2) + long_health(slave); + if (V.abbreviateDrugs === 1) + short_drugs(slave); + else if (V.abbreviateDrugs === 2) + long_drugs(slave); + if (V.abbreviateNationality + V.abbreviateGenitalia + V.abbreviatePhysicals + V.abbreviateSkills + V.abbreviateMental !== 0) { + r += `<br>`; + if (V.seeImages !== 1 || V.seeSummaryImages !== 1 || V.imageChoice === 1) + r += ` `; + } + V.desc = SlaveTitle(slave); + V.seed = V.desc.substring(0, 1); + V.seed = V.seed.toUpperCase(); + V.desc = V.seed + V.desc.substring(1); + r += `<strong><span class="coral">${V.desc}${V.abbreviatePhysicals === 2? '.' : ''}</span></strong> `; + if (V.seeRace === 1) { + r += `<span class="tan">`; + if (V.abbreviateRace === 1) + short_race(slave); + else if (V.abbreviateRace === 2) + long_race(slave); + r += `</span> `; + } + if (V.abbreviateNationality === 1) + short_nationality(slave); + else if (V.abbreviateNationality === 2) + long_nationality(slave); + if (V.abbreviatePhysicals === 1) + short_skin(slave); + else + r += `<span class="pink">${slave.skin.charAt(0).toUpperCase() + slave.skin.slice(1)} skin.</span> `; + if (V.abbreviateGenitalia === 1) + short_genitals(slave); + else if (V.abbreviateGenitalia === 2) + long_genitals(slave); + if (V.abbreviatePhysicals === 1) { + short_age(slave); + short_face(slave); + short_eyes(slave); + if (slave.markings !== "none") + r += `Markings`; + short_lips(slave); + short_teeth(slave); + short_muscles(slave); + short_limbs(slave); + short_voice(slave); + short_tits_ass(slave); + short_hips(slave); + short_waist(slave); + short_implants(slave); + short_lactation(slave); + short_mods(slave); + r += `</span>`; + } else if (V.abbreviatePhysicals === 2) { + long_age(slave); + long_face(slave); + long_eyes(slave); + long_lips(slave); + long_teeth(slave); + long_muscles(slave); + long_limbs(slave); + long_voice(slave); + long_tits_ass(slave); + long_hips(slave); + long_waist(slave); + long_implants(slave); + long_lactation(slave); + long_mods(slave); + if (slave.brand !== 0) + r += `Branded.`; + r += `</span>`; } - } - - class ShemaleHormonesList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Intensive Female", 2], - ["Female", 1], - ["None", 0], - ["Male", -1], - ["Intensive Male", -2] - ]; - super("Hormones for shemales", pairs); - this.setValue(current_rule.set.XY); - this.onchange = (value) => current_rule.set.XY = value; + r += `<br>`; + if (V.seeImages !== 1 || V.seeSummaryImages !== 1 || V.imageChoice === 1) + r += ` `; + if (V.abbreviateSkills === 1) { + short_intelligence(slave); + short_sex_skills(slave); + if (slave.combatSkill > 0) + r += `C`; + r += `</span> `; + short_prestige(slave); + } else if (V.abbreviateSkills === 2) { + long_intelligence(slave); + long_sex_skills(slave); + if (slave.combatSkill > 0) + r += `Trained fighter.`; + r += `</span> `; + long_prestige(slave); } - } - - class OtherDrugsList extends List { - constructor() { - const drugs = [ - ["No default setting", "no default setting"], - ["None", "none"], - ["Fertility drugs", "fertility drugs"], - ["Psychosuppressants", "psychosuppressants"], - ["Steroids", "steroids"], - ["Natural hormone enhancers", "hormone enhancers"], - ["Hormone blockers", "hormone blockers"], - ["breast injections"], - ["intensive breast injections"], - ["butt injections"], - ["intensive butt injections"], - ["lip injections"], - ["penis enhancement"], - ["intensive penis enhancement"], - ["testicle enhancement"], - ["intensive testicle enhancement"], - ]; - - if (V.growthStim === 1) - drugs.push(["Growth Stimulants (Research)", "growth stimulants"]); - if (V.precociousPuberty === 1 && V.pubertyHormones) { - drugs.push(["Female hormone injections (Research)", "female hormone injections"]); - drugs.push(["Male hormone injections (Research)", "male hormone injections"]); + if (V.abbreviateMental === 1) { + if (slave.fetish !== "mindbroken") { + if (slave.fetishKnown === 1) + short_fetish(slave); + if (slave.attrKnown === 1) + short_attraction(slave); } - if (V.purchasedSagBGone === 1) - drugs.push(["Sag-B-gone (Product)", "sag-B-gone"]); - if (V.arcologies[0].FSSlimnessEnthusiastResearch === 1) { - drugs.push(["Weight loss pills (FS)", "appetite suppressors"]); - drugs.push(["breast redistributors"]); - drugs.push(["butt redistributors"]); - drugs.push(["lip atrophiers"]); - drugs.push(["penis atrophiers"]); - drugs.push(["testicle atrophiers"]); + if (slave.clitPiercing === 3) { + short_smart_fetish(slave); + short_smart_attraction(slave); } - if (V.arcologies[0].FSAssetExpansionistResearch === 1) { - drugs.push(["hyper breast injections"]); - drugs.push(["hyper butt injections"]); - drugs.push(["hyper penis enhancement"]); - drugs.push(["hyper testicle enhancement"]); + short_behavior_flaw(slave); + short_sex_flaw(slave); + short_behavior_quirk(slave); + short_sex_quirk(slave); + } else if (V.abbreviateMental === 2) { + if (slave.fetish !== "mindbroken") { + if (slave.fetishKnown === 1) + long_fetish(slave); + if (slave.attrKnown === 1) + long_attraction(slave); } - if (V.arcologies[0].FSYouthPreferentialistResearch === 1) - drugs.push(["Anti-aging cream (FS)", "anti-aging cream"]); - if (V.seeHyperPreg === 1 && V.superFertilityDrugs === 1) - drugs.push(["Super fertility drugs", "super fertility drugs"]); - super("Other drugs", drugs); - this.setValue(current_rule.set.drug); - this.onchange = (value) => current_rule.set.drug = value; - } - } - - class DietList extends List { - constructor() { - const diets = [ - ["no default setting", "no default setting"], - ["Healthy diet", "healthy"], - ["Fix fat and skinny slaves", "attractive"], - ["Curvy", 30], - ["Average", 0], - ["Thin", -30] - ]; - if (V.feeder === 1) { - diets.push( - ["Feminine", "XX"], - ["Masculine", "XY"] - ); - if (V.dietXXY === 1) - diets.push(["Futanari", "XXY"]); + if (slave.clitPiercing === 3) { + long_smart_fetish(slave); + long_smart_attraction(slave); } - if (V.dietCleanse === 1) - diets.push(["Cleansing", "cleansing"]); - if (V.dietFertility === 1) - diets.push(["Fertility", "fertility"]); - if (V.cumProDiet === 1) - diets.push(["Cum production", "cum production"]); - - super("Slave diets", diets, true); - this.setValue(current_rule.set.diet); - this.onchange = (value) => current_rule.set.diet = value; - } - } - - class DietGrowthList extends List { - constructor() { - const pairs = [ - ["On", 1], - ["Off", 0] - ]; - super("Diet support for growth drugs", pairs); - this.setValue(current_rule.set.dietGrowthSupport); - this.onchange = (value) => current_rule.set.dietGrowthSupport = value; + long_behavior_flaw(slave); + long_sex_flaw(slave); + long_behavior_quirk(slave); + long_sex_quirk(slave); } - } - - class DietBaseList extends List { - constructor() { - // TODO: better data structure? - const pairs = [ - ["No default setting", {cum: "no default setting", milk: "no default setting"}], - ["Normal Diet", {cum: 0, milk: 0}], - ["Cum Added", {cum: 1, milk: 0}], - ["Milk Added", {cum: 0, milk: 1}], - ["Cum & Milk Added", {cum: 1, milk: 1}], - ["Cum-Based", {cum: 2, milk: 0}], - ["Milk-Based", {cum: 0, milk: 2}], - ]; - super("Diet base", pairs); - this.setValue(this.value2string(current_rule.set.dietCum, current_rule.set.dietMilk)); - this.onchange = (value) => { - current_rule.set.dietCum = value.cum; - current_rule.set.dietMilk = value.milk; - }; + if (slave.customLabel != "") + r += `<strong><span class="yellow">${slave.customLabel}</span></strong>`; + if ((slave.relationship !== 0) || (slave.relation !== 0) || (V.abbreviateClothes === 2) || (V.abbreviateRulesets === 2)) { + r += `<br>`; + if (V.seeImages !== 1 || V.seeSummaryImages !== 1 || V.imageChoice === 1) + r += ` `; } - - value2string(cum, milk) { - return `cum: ${cum}, milk: ${milk}`; + if (V.abbreviateMental === 1) { + r += `<span class="lightgreen">`; + if (V.familyTesting === 1) + short_extended_family(slave); + else + short_legacy_family(slave); + r += `</span>`; + short_rival(slave); + } else if (V.abbreviateMental === 2) { + if (V.familyTesting === 1) + long_extended_family(slave); + else + long_legacy_family(slave); + long_rival(slave); } - - setValue(what) { - what = this.value2string(what.cum, what.milk); - super.setValue(what); + if (slave.fuckdoll === 0) { + if (V.abbreviateClothes === 2) { + r += ` `; + if (slave.choosesOwnClothes === 1) + r += `Dressing herself. `; + long_clothes(slave); + long_collar(slave); + long_belly(slave); + if (slave.amp !== 1) + long_legs(slave); + if (canWalk(slave)) + long_shoes(slave); + long_vaginal_acc(slave); + long_dick_acc(slave); + long_buttplug(slave); + } } - + r += ` `; + rules_assistant(slave); + if (V.abbreviateOrigins === 2 && slave.origin !== 0) + origins(slave); + return r; } - - class MuscleList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Toned", 20], - ["Ripped", 50], - ["Massive", 100], - ["Weak", -20] - ]; - super("Muscles", pairs, true); - this.setValue(current_rule.set.muscles); - this.onchange = (value) => current_rule.set.muscles = value; + + function short_devotion(slave) { + if (slave.fetish === "mindbroken") { + r += `<span class="red">MB</span>`; + } else if (slave.devotion < -95) { + r += `<span class="darkviolet">Hate${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; + } else if (slave.devotion < -50) { + r += `<span class="darkviolet">Hate${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; + } else if (slave.devotion < -20) { + r += `<span class="mediumorchid">Res${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; + } else if (slave.devotion <= 20) { + r += `<span class="yellow">Ambiv${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; + } else if (slave.devotion <= 50) { + r += `<span class="hotpink">Accept${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; + } else if (slave.devotion <= 95) { + r += `<span class="deeppink">Devo${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; + } else { + r += `<span class="magenta">Wor${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; } - } - - class BraceList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", "none"], - ["Straighten", "straighten"], - ["Universal", "universal"] - ]; - super("Braces", pairs); - this.setValue(current_rule.set.teeth); - this.onchange = (value) => current_rule.set.teeth = value; + r += " "; + if (slave.fetish === "mindbroken") { + return; + } else if (slave.trust < -95) { + r += `<span class="darkgoldenrod">ETerr${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + } else if (slave.trust < -50) { + r += `<span class="goldenrod">Terr${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + } else if (slave.trust < -20) { + r += `<span class="gold">Fright${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + } else if (slave.trust <= 20) { + r += `<span class="yellow">Fear${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + } else if (slave.trust <= 50) { + if (slave.devotion < -20) { + r += `<span class="orange">Caref${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + } else { + r += `<span class="mediumaquamarine">Caref${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + } + } else if (slave.trust < 95) { + if (slave.devotion < -20) { + r += `<span class="orangered">Bold${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + } else { + r += `<span class="mediumseagreen">Trust${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + } + } else { + if (slave.devotion < -20) { + r += `<span class="darkred">Defiant${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + } else { + r += `<span class="seagreen">VTrust ${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + } } + r += " "; } - - class LivingStandardList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Luxurious", "luxurious"], - ["Normal", "normal"], - ["Spare", "spare"] - ]; - super("Living standard", pairs); - this.setValue(current_rule.set.livingRules); - this.onchange = (value) => current_rule.set.livingRules = value; + + function long_devotion(slave) { + if (slave.fetish === "mindbroken") { + r += `<span class="red">Mindbroken.</span>`; + } else if (slave.devotion < -95) { + r += `<span class="darkviolet">Very hateful${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; + } else if (slave.devotion < -50) { + r += `<span class="darkviolet">Hateful${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; + } else if (slave.devotion < -20) { + r += `<span class="mediumorchid">Resistant${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; + } else if (slave.devotion <= 20) { + r += `<span class="yellow">Ambivalent${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; + } else if (slave.devotion <= 50) { + r += `<span class="hotpink">Accepting${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; + } else if (slave.devotion <= 95) { + r += `<span class="deeppink">Devoted${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; + } else { + r += `<span class="magenta">Worshipful${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; } - } - - class PunishmentList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Confinement", "confinement"], - ["Whipping", "whipping"], - ["Chastity", "chastity"], - ["Situational", "situational"] - ]; - super("Typical punishment", pairs); - this.setValue(current_rule.set.standardPunishment); - this.onchange = (value) => current_rule.set.standardPunishment = value; + r += " "; + if (slave.fetish === "mindbroken") { + return; + } else if (slave.trust < -95) { + r += `<span class="darkgoldenrod">Extremely terrified${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + } else if (slave.trust < -50) { + r += `<span class="goldenrod">Terrified${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + } else if (slave.trust < -20) { + r += `<span class="gold">Frightened${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + } else if (slave.trust <= 20) { + r += `<span class="yellow">Fearful${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + } else if (slave.trust <= 50) { + if (slave.devotion < -20) { + r += `<span class="orange">Careful${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + } else { + r += `<span class="mediumaquamarine">Careful${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + } + } else if (slave.trust < 95) { + if (slave.devotion < -20) { + r += `<span class="orangered">Bold${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + } else { + r += `<span class="mediumseagreen">Trusting${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + } + } else { + if (slave.devotion < -20) { + r += `<span class="darkred">Defiant${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + } else { + r += `<span class="seagreen">Profoundly trusting${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + } } + r += " "; } - - class RewardList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Relaxation", "relaxation"], - ["Drugs", "drugs"], - ["Orgasm", "orgasm"], - ["Situational", "situational"] - ]; - super("Typical reward", pairs); - this.setValue(current_rule.set.standardReward); - this.onchange = (value) => current_rule.set.standardReward = value; + + function short_rules(slave) { + switch (slave.livingRules) { + case "luxurious": + r += `<strong>LS:Lux</strong>`; + break; + case "normal": + r += `<strong>LS:Nor</strong>`; + break; + default: + r += `<strong>LS:Spa</strong>`; + break; } - } - - class ReleaseList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Permissive", "permissive"], - ["Sapphic", "sapphic"], - ["Masturbation", "masturbation"], - ["Restrictive", "restrictive"] - ]; - super("Release rules", pairs); - this.setValue(current_rule.set.releaseRules); - this.onchange = (value) => current_rule.set.releaseRules = value; + r += " "; + if (canTalk(slave)) { + switch (slave.speechRules) { + case "permissive": + r += `<strong>SpR:P</strong>`; + break; + case "accent elimination": + r += `<strong>SpR:NoAcc</strong>`; + break; + case "language lessons": + r += `<strong>SpR:LL</strong>`; + break; + default: + r += `<strong>SpR:R</strong>`; + break; + } + r += " "; } - } - - class SmartFetishList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Vanilla", "vanilla"], - ["Oral", "oral"], - ["Anal", "anal"], - ["Boobs", "boobs"], - ["Sub", "submissive"], - ["Dom", "dom"], - ["Humiliation", "humiliation"], - ["Preg", "pregnancy"], - ["Pain", "masochist"], - ["Sadism", "sadist"] - ]; - super("Smart piercing fetish target", pairs); - this.setValue(current_rule.set.clitSetting); - this.onchange = (value) => current_rule.set.clitSetting = value; + switch (slave.relationshipRules) { + case "permissive": + r += `<strong>ReR:P</strong>`; + break; + case "just friends": + r += `<strong>ReR:Fr</strong>`; + break; + default: + r += `<strong>ReR:R</strong>`; + break; } - } - - class SmartXYAttractionList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Passionate", 100], - ["Attracted", 75], - ["Indifferent", 45], - ["None", 0] - ]; - super("Smart piercing XY attraction target", pairs); - this.setValue(current_rule.set.clitSettingXY); - this.onchange = (value) => current_rule.set.clitSettingXY = value; + r += " "; + switch (slave.standardPunishment) { + case "confinement": + r += `<strong>Pun:Conf</strong>`; + break; + case "whipping": + r += `<strong>Pun:Whip</strong>`; + break; + case "chastity": + r += `<strong>Pun:Chas</strong>`; + break; + default: + r += `<strong>Pun:Situ</strong>`; + break; } - } - - class SmartXXAttractionList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Passionate", 100], - ["Attracted", 75], - ["Indifferent", 45], - ["None", 0] - ]; - super("Smart piercing XX attraction target", pairs); - this.setValue(current_rule.set.clitSettingXX); - this.onchange = (value) => current_rule.set.clitSettingXX = value; + r += " "; + switch (slave.standardReward) { + case "relaxation": + r += `<strong>Rew:Relx</strong>`; + break; + case "drugs": + r += `<strong>Rew:Drug</strong>`; + break; + case "orgasm": + r += `<strong>Rew:Orga</strong>`; + break; + default: + r += `<strong>Rew:Situ</strong>`; + break; } - } - - class SmartEnergyList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Nympho", 100], - ["Sex Addict", 85], - ["Powerful", 65], - ["Healthy", 45], - ["Weak", 25], - ["Frigid", 0] - ]; - super("Smart piercing sex drive target", pairs); - this.setValue(current_rule.set.clitSettingEnergy); - this.onchange = (value) => current_rule.set.clitSettingEnergy = value; + r += " "; + switch (slave.releaseRules) { + case "permissive": + r += `<strong>MaR:P</strong>`; + break; + case "sapphic": + r += `<strong>MaR:S</strong>`; + break; + case "masturbation": + r += `<strong>MaR:M</strong>`; + break; + default: + r += `<strong>MaR:R</strong>`; + break; } + r += " "; } - - class SpeechList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["Permissive", "permissive"], - ["Suppress accents", "accent elimination"], - ["Restrictive", "restrictive"] - ]; - super("Speech rules", pairs); - this.setValue(current_rule.set.speechRules); - this.onchange = (value) => current_rule.set.speechRules = value; + + function long_rules(slave) { + r += `Living standard: ${slave.livingRules}. `; + if (canTalk(slave)) { + r += `Speech rules: ${slave.speechRules}. `; } + r += `Relationship rules: ${slave.relationshipRules}. `; + r += `Typical punishment: ${slave.standardPunishment}. `; + r += `Typical reward: ${slave.standardReward}. `; + r += `Release rules: ${slave.releaseRules}. `; } - - class RelationshipList extends List { - constructor() { - const pairs =[ - ["No default setting", "no default setting"], - ["Permissive", "permissive"], - ["Just friends", "just friends"], - ["Restrictive", "restrictive"] - ]; - super("Relationship rules", pairs); - this.setValue(current_rule.set.relationshipRules); - this.onchange = (value) => current_rule.set.relationshipRules = value; + + function short_weight(slave) { + if (slave.weight < -95) { + r += `<strong><span class="red">W---${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; + } else if (slave.weight < -30) { + if (slave.hips < -1) { + r += `<strong>W--${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + } else { + r += `<strong><span class="red">W--${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; + } + } else if (slave.weight < -10) { + r += `<strong>W-${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + } else if (slave.weight <= 10) { + r += `<strong>W${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + } else if (slave.weight <= 30) { + r += `<strong>W+${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + } else if (slave.weight <= 95) { + if (slave.hips > 1 || V.arcologies[0].FSHedonisticDecadence !== "unset") { + r += `<strong>W++${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + } else { + r += `<strong><span class="red">W++${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; + } + } else if (slave.weight <= 130) { + if (slave.hips > 2 || V.arcologies[0].FSHedonisticDecadence !== "unset") { + r += `<strong>W+++${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + } else { + r += `<strong><span class="red">W+++${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; + } + } else if (slave.weight <= 160) { + if (V.arcologies[0].FSHedonisticDecadence !== "unset") { + r += `<strong>W++++${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + } else { + r += `<strong><span class="red">W++++${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; + } + } else if (slave.weight <= 190) { + if (V.arcologies[0].FSHedonisticDecadence !== "unset") { + r += `<strong>W+++++${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + } else { + r += `<strong><span class="red">W+++++${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; + } + } else { + if (V.arcologies[0].FSHedonisticDecadence !== "unset") { + r += `<strong>W++++++${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + } else { + r += `<strong><span class="red">W++++++${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; + } } + r += " "; } - - class PornList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["No broadcasting", -1], - ["No subsidy", 0], - ["1000", 1000], - ["2000", 2000], - ["3000", 3000], - ["4000", 4000], - ["5000", 5000] - ]; - super("Weekly porn publicity subsidy", pairs); - this.setValue(current_rule.set.pornFameSpending); - this.onchange = (value) => current_rule.set.pornFameSpending = value; + + function long_weight(slave) { + if (slave.weight < -95) { + r += `<span class="red">Emaciated${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; + } else if (slave.weight < -30) { + if (slave.hips < -1) { + r += `Model-thin${V.summaryStats? `[${slave.weight}]`: ''}.`; + } else { + r += `<span class="red">Very thin${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; + } + } else if (slave.weight < -10) { + r += `Thin${V.summaryStats? `[${slave.weight}]`: ''}.`; + } else if (slave.weight <= 10) { + r += `Trim${V.summaryStats? `[${slave.weight}]`: ''}.`; + } else if (slave.weight <= 30) { + r += `Plush${V.summaryStats? `[${slave.weight}]`: ''}.`; + } else if (slave.weight <= 95) { + if (slave.hips > 1 || V.arcologies[0].FSHedonisticDecadence !== "unset") { + r += `Nicely chubby${V.summaryStats? `[${slave.weight}]`: ''}.`; + } else { + r += `<span class="red">Overweight${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; + } + } else if (slave.weight <= 130) { + if (slave.hips > 2 || V.arcologies[0].FSHedonisticDecadence !== "unset") { + r += `Pleasantly soft and shapely${V.summaryStats? `[${slave.weight}]`: ''}.`; + } else { + r += `<span class="red">Fat${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; + } + } else if (slave.weight <= 160) { + if (V.arcologies[0].FSHedonisticDecadence !== "unset") { + r += `Amazingly voluptuous${V.summaryStats? `[${slave.weight}]`: ''}.`; + } else { + r += `<span class="red">Obese${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; + } + } else if (slave.weight <= 190) { + if (V.arcologies[0].FSHedonisticDecadence !== "unset") { + r += `SSBBW${V.summaryStats? `[${slave.weight}]`: ''}.`; + } else { + r += `<span class="red">Super Obese${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; + } + } else { + if (V.arcologies[0].FSHedonisticDecadence !== "unset") { + r += `Perfectly massive${V.summaryStats? `[${slave.weight}]`: ''}.`; + } else { + r += `<span class="red">Dangerously Obese${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; + } } - } + r += " "; - class EyewearList extends List { - constructor() { - const pairs = [ - ["no default setting"], - ["correct with glasses"], - ["correct with contacts"], - ["universal glasses"], - ["blur with glasses"], - ["blur with contacts"] - ]; - super("Eyewear", pairs); - this.setValue(current_rule.set.eyewear); - this.onchange = (value) => current_rule.set.eyewear = value; - } } - - class LensesList extends Element { - constructor() { - super(current_rule.set.eyeColor); - this.appendChild(new OptionsItem("No default Setting", () => this.setValue("no default setting"))); - this.colourlist = new LensesColourList(); - this.shapelist = new LensesShapeList(); - this.appendChild(this.colourlist); - this.appendChild(this.shapelist); + + function short_diet(slave) { + r += `<span class="teal">`; + switch (slave.diet) { + case "restricted": + r += `<strong>Di:W-</strong>`; + break; + case "fattening": + r += `<strong>Di:W+</strong>`; + break; + case "XX": + r += `<strong>Di:XX+</strong>`; + break; + case "XY": + r += `<strong>Di:XY+</strong>`; + break; + case "XXY": + r += `<strong>Di:XXY+</strong>`; + break; + case "muscle building": + r += `<strong>Di:M+</strong>`; + break; + case "slimming": + r += `<strong>Di:M-</strong>`; + break; + case "cum production": + r += `<strong>Di:C+</strong>`; + break; + case "cleansing": + r += `<strong>Di:H+</strong>`; + break; + case "fertility": + r += `<strong>Di:F+</strong>`; + break; } - - render(color) { - const elem = document.createElement("div"); - elem.innerHTML = "Eye coloring: "; - this.label = document.createElement("strong"); - this.label.innerText = color; - elem.appendChild(this.label); - return elem; + r += `</span> `; + r += `<span class="cyan">`; + if (slave.dietCum === 2) { + r += `<strong>Cum++</strong>`; + } else if (((slave.dietCum === 1) && (slave.dietMilk === 0))) { + r += `<strong>Cum+</strong>`; + } else if (((slave.dietCum === 1) && (slave.dietMilk === 1))) { + r += `<strong>Cum+ Milk+</strong>`; + } else if (((slave.dietCum === 0) && (slave.dietMilk === 1))) { + r += `<strong>Milk+</strong>`; + } else if ((slave.dietMilk === 2)) { + r += `<strong>Milk++</strong>`; } - - combine() { - const lst = []; - if (this.colourlist.value !== "no default setting") - lst.push(this.colourlist.value); - if (this.shapelist.value !== "no default setting") - lst.push(this.shapelist.value); - if (lst.length === 0) return "no default value"; - else return lst.join(" "); + r += `</span> `; + } + + function long_diet(slave) { + r += `<span class="teal">`; + switch (slave.diet) { + case "restricted": + r += `Dieting.`; + break; + case "fattening": + r += `Gaining weight.`; + break; + case "XX": + r += `Estrogen rich.`; + break; + case "XY": + r += `Testosterone rich.`; + break; + case "XXY": + r += `Futanari mix.`; + break; + case "muscle building": + r += `Pumping iron.`; + break; + case "slimming": + r += `Slimming down.`; + break; + case "cum production": + r += `Cum production.`; + break; + case "cleansing": + r += `Cleansing.`; + break; + case "fertility": + r += `Fertility.`; + break; } - - setValue(val) { - if (val === undefined) val = this.combine(); - this.label.innerText = val; - current_rule.set.eyeColor = val; + r += `</span> `; + if (slave.dietCum === 2) { + r += `Diet Base: <span class="cyan">Cum Based.</span>`; + } else if (((slave.dietCum === 1) && (slave.dietMilk === 0))) { + r += `Diet Base: <span class="cyan">Cum Added.</span>`; + } else if (((slave.dietCum === 1) && (slave.dietMilk === 1))) { + r += `Diet Base: <span class="cyan">Milk & Cum Added.</span>`; + } else if (((slave.dietCum === 0) && (slave.dietMilk === 1))) { + r += `Diet Base: <span class="cyan">Milk Added.</span>`; + } else if ((slave.dietMilk === 2)) { + r += `Diet Base: <span class="cyan">Milk Based.</span>`; } + r += " "; } - - class LensesColourList extends Options { - constructor() { - const items = []; - [ - "no default setting", - "blue", - "black", - "brown", - "green", - "turquoise", - "sky-blue", - "hazel", - "pale-grey", - "white", - "pink", - "amber", - "red" - ].forEach(i => items.push(new OptionsItem(i, item => { - this.value = item.label; - this.parent.setValue(); - }))); - super(items); + + function short_health(slave) { + if (slave.health < -20) { + r += `<strong><span class="red">H${V.summaryStats? `[${slave.health}]` : ''}</span></strong>`; + } else if (slave.health <= 20) { + r += `<strong><span class="yellow">H${V.summaryStats? `[${slave.health}]` : ''}</span></strong>`; + } else if (slave.health > 20) { + r += `<strong><span class="green">H${V.summaryStats? `[${slave.health}]` : ''}</span></strong>`; } + r += " "; } - - class LensesShapeList extends Options { - constructor() { - const items = []; - [ - "no default setting", - "catlike", - "serpent-like", - "devilish", - "demonic", - "hypnotic", - "heart-shaped", - "wide-eyed", - "almond-shaped", - "bright", - "teary", - "vacant" - ].forEach(i => items.push(new OptionsItem(i, item => { - this.value = item.label; - this.parent.setValue(); - }))); - super(items); + + function long_health(slave) { + if (slave.health < -90) { + r += `<span class="red">On the edge of death${V.summaryStats? `[${slave.health}]` : ''}.</span>`; + } else if (slave.health < -50) { + r += `<span class="red">Extremely unhealthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; + } else if (slave.health < -20) { + r += `<span class="red">Unhealthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; + } else if (slave.health <= 20) { + r += `<span class="yellow">Healthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; + } else if (slave.health <= 50) { + r += `<span class="green">Very healthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; + } else if (slave.health <= 90) { + r += `<span class="green">Extremely healthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; + } else { + r += `<span class="green">Unnaturally healthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; } + r += " "; } - - class MakeupList extends List { - constructor() { - super("Makeup"); - [ - ["no default setting"], - ["makeup-free", 0], - ["nice", 1], - ["gorgeous", 2], - ["color-coordinate with hair", 3], - ["slutty", 4] - ].forEach(pair => this.appendChild(new ListItem(...pair))); - this.setValue(current_rule.set.makeup); - this.onchange = (value) => current_rule.set.makeup = value; + + function short_drugs(slave) { + r += `<span class="tan">`; + switch (slave.drugs) { + case "breast injections": + r += `<strong>Dr:Boobs+</strong>`; + break; + case "intensive breast injections": + r += `<strong>Dr:Boobs++</strong>`; + break; + case "hyper breast injections": + r += `<strong>Dr:Boobs+++</strong>`; + break; + case "butt injections": + r += `<strong>Dr:Butt+</strong>`; + break; + case "intensive butt injections": + r += `<strong>Dr:Butt++</strong>`; + break; + case "hyper butt injections": + r += `<strong>Dr:Butt+++</strong>`; + break; + case "lip injections": + r += `<strong>Dr:Lip+</strong>`; + break; + case "fertility drugs": + r += `<strong>Dr:Fert+</strong>`; + break; + case "super fertility drugs": + r += `<strong>Dr:Fert++</strong>`; + break; + case "penis enhancement": + r += `<strong>Dr:Dick+</strong>`; + break; + case "intensive penis enhancement": + r += `<strong>Dr:Dick++</strong>`; + break; + case "hyper penis enhancement": + r += `<strong>Dr:Dick+++</strong>`; + break; + case "testicle enhancement": + r += `<strong>Dr:Balls+</strong>`; + break; + case "intensive testicle enhancement": + r += `<strong>Dr:Balls++</strong>`; + break; + case "hyper testicle enhancement": + r += `<strong>Dr:Balls+++</strong>`; + break; + case "psychosuppressants": + r += `<strong>Dr:Psych</strong>`; + break; + case "steroids": + r += `<strong>Dr:Ster</strong>`; + break; + case "female hormone injections": + r += `<strong>Dr:HormXX++</strong>`; + break; + case "male hormone injections": + r += `<strong>Dr:HormXY++</strong>`; + break; + case "hormone enhancers": + r += `<strong>Dr:Horm+</strong>`; + break; + case "hormone blockers": + r += `<strong>Dr:Horm-</strong>`; + break; + case "anti-aging cream": + r += `<strong>Dr:Age-</strong>`; + break; + case "appetite suppressors": + r += `<strong>Dr:ApSup</strong>`; + break; + case "penis atrophiers": + r += `<strong>Dr:Dick-</strong>`; + break; + case "testicle atrophiers": + r += `<strong>Dr:Balls-</strong>`; + break; + case "clitoris atrophiers": + r += `<strong>Dr:Clit-</strong>`; + break; + case "labia atrophiers": + r += `<strong>Dr:Labia-</strong>`; + break; + case "nipple atrophiers": + r += `<strong>Dr:Nipple-</strong>`; + break; + case "lip atrophiers": + r += `<strong>Dr:Lip-</strong>`; + break; + case "breast redistributors": + r += `<strong>Dr:Breast-</strong>`; + break; + case "butt redistributors": + r += `<strong>Dr:Butt-</strong>`; + break; + case "sag-B-gone": + r += `<strong>Dr:AntiSag</strong>`; + break; + case "growth stimulants": + r += `<strong>Dr:groStim</strong>`; + break; + } + r += `</span> `; + r += `<span class="lightgreen">`; + if (slave.curatives === 2) { + r += `<strong>Cura</strong>`; + } else if (slave.curatives === 1) { + r += `<strong>Prev</strong>`; } - } - - class NailsList extends List { - constructor() { - super("Nails"); - [ - ["no default setting"], - ["clipped", 0], - ["extended", 1], - ["color-coordinate with hair", 2], - ["sharp and claw-like", 3], - ["bright and glittery", 4], - ["hooker nails", 5] - ].forEach(pair => this.appendChild(new ListItem(...pair))); - this.setValue(current_rule.set.nails); - this.onchange = (value) => current_rule.set.nails = value; + r += `</span> `; + if (slave.aphrodisiacs !== 0) { + r += `<span class="lightblue">`; + if (slave.aphrodisiacs === 1) { + r += `<strong>Aph</strong>`; + } else if (slave.aphrodisiacs === 2) { + r += `<strong>Aph++</strong>`; + } else { + r += `<strong>Anaph</strong>`; + } + r += `</span> `; } - } - - class HairLengthList extends List { - constructor() { - const pairs = [ - ["no default setting"], - ["very short", 5], - ["short", 10], - ["shoulder length", 30], - ["long", 60], - ["very long", 100], - ["floor length", 150] - ]; - super("Hair length", pairs); - this.setValue(current_rule.set.hLength); - this.onchange = (value) => current_rule.set.hLength = value; + if (slave.addict !== 0) { + r += `<span class="cyan">Add</span>`; } - } - class HairColourList extends List { - constructor() { - const pairs = [ - ["no default setting"], - ["blonde"], - ["golden"], - ["platinum blonde"], - ["strawbery-blonde"], - ["copper"], - ["ginger"], - ["red"], - ["green"], - ["blue"], - ["pink"], - ["dark brown"], - ["brown"], - ["auburn"], - ["burgundy"], - ["chocolate"], - ["chestnut"], - ["hazel"], - ["black"], - ["grey"], - ["silver"], - ["white"], - ["blue-violet"], - ["blazing red"], - ["neon green"], - ["neon blue"], - ["neon pink"] - ]; - super("Hair color", pairs); - this.setValue(current_rule.set.hColor); - this.onchange = (value) => current_rule.set.hColor = value; + r += `<span class="lightsalmon">`; + if (slave.hormones > 1) { + r += `<strong>Ho:F+</strong>`; + } else if (slave.hormones > 0) { + r += `<strong>Ho:F</strong>`; + } else if (slave.hormones < -1) { + r += `<strong>Ho:M+</strong>`; + } else if (slave.hormones < 0) { + r += `<strong>Ho:M</strong>`; } - } - - class HairStyleList extends List { - constructor() { - const pairs = [ - ["no default setting"], - ["neat"], - ["shaved"], - ["trimmed"], - ["buzzcut"], - ["up"], - ["ponytail"], - ["bun"], - ["messy bun"], - ["curled"], - ["permed"], - ["luxurious"], - ["dreadlocks"], - ["cornrows"], - ["braided"], - ["tails"], - ["afro"], - ["strip"] - ]; - super("Hair style", pairs); - this.setValue(current_rule.set.hStyle); - this.onchange = (value) => current_rule.set.hStyle = value; + r += `</span> `; + r += `<span class="mediumseagreen">`; + if ((slave.bellyImplant > -1)) { + r += `<strong>Belly Imp</strong>`; + } else if (((slave.preg <= -2) || (slave.ovaries === 0)) && (slave.vagina !== -1)) { + r += `<strong>Barr</strong>`; + } else if (slave.pubertyXX === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) { + r += `<strong>Prepub</strong>`; + } else if (slave.ovaryAge >= 47 && (slave.ovaries === 1 || slave.mpreg === 1)) { + r += `<strong>Meno</strong>`; + } else if (slave.pregWeek < 0) { + r += `<strong>Postpartum</strong>`; + } else if (slave.preg === -1) { + r += `<strong>CC</strong>`; + } else if (slave.preg === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) { + r += `<strong>Fert+</strong>`; + } else if (((slave.preg < 4) && (slave.preg > 0) && slave.pregKnown === 0) || slave.pregWeek === 1) { + r += `<strong>Preg?</strong>`; + } else if ((slave.preg >= 36) && (slave.broodmother > 0)) { + r += `<strong>Perm preg</strong>`; + } else if (slave.pregKnown === 1) { + r += `<strong>${slave.pregWeek} wks preg</strong>`; } - } - - class PubicHairColourList extends List { - constructor() { - const pairs = [ - ["no default setting"], - ["blonde"], - ["golden"], - ["platinum blonde"], - ["strawerry-blonde"], - ["copper"], - ["ginger"], - ["red"], - ["green"], - ["blue"], - ["pink"], - ["dark brown"], - ["brown"], - ["auburn"], - ["burgundy"], - ["chocolate"], - ["chestnut"], - ["hazel"], - ["black"], - ["grey"], - ["silver"], - ["white"], - ["blue-violet"], - ["blazing red"], - ["neon green"], - ["neon blue"], - ["neon pink"] - ]; - super("Pubic hair color, when present", pairs); - this.setValue(current_rule.set.pubicHColor); - this.onchange = (value) => current_rule.set.pubicHColor = value; + r += `</span> `; + if (slave.induce === 1) { + r += `<span class="orange"><strong>Early Labor</strong></span>`; } - } - - class PubicHairStyleList extends List { - constructor() { - const pairs = [ - ["no default setting"], - ["waxed"], - ["in a strip"], - ["neat"], - ["bushy"], - ["bushy in the front and neat in the rear"], - ["very bushy"] - ]; - super("Pubic hairstyle", pairs); - this.setValue(current_rule.set.pubicHStyle); - this.onchange = (value) => current_rule.set.pubicHStyle = value; + if (slave.pubertyXY === 0 && slave.balls > 0) { + r += `<strong>Prepub balls</strong>`; } - } - - class ArmpitHairColourList extends List { - constructor() { - const pairs = [ - ["no default setting"], - ["blonde"], - ["golden"], - ["platinum blonde"], - ["strawberry-blonde"], - ["copper"], - ["ginger"], - ["red"], - ["green"], - ["blue"], - ["pink"], - ["dark brown"], - ["brown"], - ["auburn"], - ["burgundry"], - ["chocolate"], - ["chestnut"], - ["hazel"], - ["black"], - ["grey"], - ["silver"], - ["white"], - ["blue-violet"], - ]; - super("Underarm hair color, when present", pairs); - this.setValue(current_rule.set.underArmHColor); - this.onchange = (value) => current_rule.set.underArmHColor = value; + if (slave.balls > 0 && slave.vasectomy === 1) { + r += `<strong>Vasect</strong>`; } - } - - class ArmpitHairStyleList extends List { - constructor() { - const pairs = [ - ["no default setting"], - ["waxed"], - ["shaved"], - ["neat"], - ["bushy"] - ]; - super("Underarm hair style", pairs); - this.setValue(current_rule.set.underArmHStyle); - this.onchange = (value) => current_rule.set.underArmHStyle = value; + r += `<span class="springgreen">`; + if (slave.inflation === 3) { + r += `<strong>8 ltr ${slave.inflationType}</strong>`; + } else if (slave.inflation === 2) { + r += `<strong>4 ltr ${slave.inflationType}</strong>`; + } else if (slave.inflation === 1) { + r += `<strong>2 ltr ${slave.inflationType}</strong>`; + } else if (slave.bellyFluid > 0) { + r += `<strong>${slave.bellyFluid}ccs ${slave.inflationType}</strong>`; } + r += `</span> `; } - - class EarPiercingList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Light", 1], - ["Heavy", 2] - ]; - super("Ear piercings", pairs); - this.setValue(current_rule.set.earPiercing); - this.onchange = (value) => current_rule.set.earPiercing = value; + + function long_drugs(slave) { + if ((slave.drugs !== "no drugs") && (slave.drugs !== "none")) { + r += `<span class="tan">On ${slave.drugs}.</span> `; } - } - - class NosePiercingList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Light", 1], - ["Heavy", 2] - ]; - super("Nasal piercings", pairs); - this.setValue(current_rule.set.nosePiercing); - this.onchange = (value) => current_rule.set.earPiercing = value; + r += `<span class="lightgreen">`; + if (slave.curatives === 2) { + r += `On curatives.`; + } else if (slave.curatives === 1) { + r += `On preventatives.`; } - } - - class EyebrowPiercingList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Light", 1], - ["Heavy", 2] - ]; - super("Eyebrow piercings", pairs); - this.setValue(current_rule.set.eyebrowPiercing); - this.onchange = (value) => current_rule.set.eyebrowPiercing = value; + r += `</span> `; + r += `<span class="lightblue">`; + if (slave.aphrodisiacs > 0) { + r += `On ${slave.aphrodisiacs > 1 ? 'extreme': ''} aphrodisiacs.`; + } else if (slave.aphrodisiacs === -1) { + r += `On anaphrodisiacs.`; } - } - - class NavelPiercingList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Light", 1], - ["Heavy", 2] - ]; - super("Navel piercings", pairs); - this.setValue(current_rule.set.navelPiercing); - this.onchange = (value) => current_rule.set.navelPiercing = value; + r += `</span> `; + if (slave.addict !== 0) { + r += `<span class="cyan">Addict.</span>`; } - } - - class NipplePiercingList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Light", 1], - ["Heavy", 2] - ]; - super("Nipple piercings", pairs); - this.setValue(current_rule.set.nipplesPiercing); - this.onchange = (value) => current_rule.set.nipplesPiercing = value; + r += `<span class="lightsalmon">`; + if (slave.hormones > 1) { + r += `Heavy female hormones.`; + } else if (slave.hormones > 0) { + r += `Female hormones.`; + } else if (slave.hormones < -1) { + r += `Heavy male hormones.`; + } else if (slave.hormones < 0) { + r += `Male hormones.`; + } + r += `</span> `; + r += `<span class="mediumseagreen">`; + if ((slave.bellyImplant > -1)) { + r += `Belly Implant.`; + } else if (((slave.preg <= -2) || (slave.ovaries === 0)) && (slave.vagina !== -1)) { + r += `Barren.`; + } else if (slave.pubertyXX === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) { + r += `Not ovulating yet.`; + } else if (slave.ovaryAge >= 47 && (slave.ovaries === 1 || slave.mpreg === 1)) { + r += `Menopausal.`; + } else if (slave.pregWeek < 0) { + r += `Postpartum.`; + } else if (slave.preg === -1) { + r += `On contraceptives.`; + } else if (slave.preg === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) { + r += `Fertile.`; + } else if (((slave.preg < 4) && (slave.preg > 0) && slave.pregKnown === 0) || slave.pregWeek === 1) { + r += `May be pregnant.`; + } else if ((slave.preg >= 36) && (slave.broodmother > 0)) { + r += `Permanently pregnant.`; + } else if (slave.pregKnown === 1) { + if (slave.pregType < 2 || slave.broodmother > 0) { + r += `${slave.pregWeek} weeks pregnant.`; + } else { + r += `${slave.pregWeek} weeks pregnant with `; + if (slave.pregType >= 40) { + r += `a tremendous brood of offspring.`; + } else if (slave.pregType >= 20) { + r += `a brood of offspring.`; + } else if (slave.pregType >= 10) { + r += `${slave.pregType} babies.`; + } else if (slave.pregType === 9) { + r += `nonuplets.`; + } else if (slave.pregType === 8) { + r += `octuplets.`; + } else if (slave.pregType === 7) { + r += `septuplets.`; + } else if (slave.pregType === 6) { + r += `sextuplets.`; + } else if (slave.pregType === 5) { + r += `quintuplets.`; + } else if (slave.pregType === 4) { + r += `quadruplets.`; + } else if (slave.pregType === 3) { + r += `triplets.`; + } else { + r += `twins.`; + } + } + } + r += `</span> `; + if (slave.induce === 1) { + r += `<span class="orange">Showing signs of early labor.</span>`; + } + if (slave.pubertyXY === 0 && slave.balls > 0) { + r += `Has not had first ejaculation.`; + } + if (slave.balls > 0 && slave.vasectomy === 1) { + r += `Vasectomy.`; + } + r += `<span class="springgreen">`; + if (slave.inflation === 3) { + r += `Filled with 8 liters of ${slave.inflationType}.`; + } else if (slave.inflation === 2) { + r += `Filled with 4 liters of ${slave.inflationType}.`; + } else if (slave.inflation === 1) { + r += `Filled with 2 liters of ${slave.inflationType}.`; + } else if (slave.bellyFluid > 0) { + r += `Stuffed with ${slave.bellyFluid}ccs of ${slave.inflationType}.`; } + r += `</span> `; } - - class AreolaPiercingList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Studded", 1] - ]; - super("Areola studs", pairs); - this.setValue(current_rule.set.areolaePiercing); - this.onchange = (value) => current_rule.set.areolaePiercing = value; + + function long_race(slave) { + switch (slave.race) { + case "white": + r += `Caucasian.`; + break; + case "asian": + r += `Asian.`; + break; + case "indo-aryan": + r += `Indo-aryan.`; + break; + case "latina": + r += `Latina.`; + break; + case "middle eastern": + r += `Middle Eastern.`; + break; + case "black": + r += `Black.`; + break; + case "pacific islander": + r += `Pacific Islander.`; + break; + case "malay": + r += `Malay.`; + break; + case "amerindian": + r += `Amerindian.`; + break; + case "semitic": + r += `Semitic.`; + break; + case "southern european": + r += `Southern European.`; + break; + case "mixed race": + r += `Mixed race.`; + break; + default: + r += `${slave.race.charAt(0).toUpperCase() + slave.race.slice(1)}.`; + break; } + r += " "; } - - class LipPiercingList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Light", 1], - ["Heavy", 2] - ]; - super("Lip piercings", pairs); - this.setValue(current_rule.set.lipsPiercing); - this.onchange = (value) => current_rule.set.lipsPiercing = value; + + function short_race(slave) { + switch (slave.race) { + case "white": + r += `C`; + break; + case "asian": + r += `A`; + break; + case "indo-aryan": + r += `I`; + break; + case "latina": + r += `L`; + break; + case "middle eastern": + r += `ME`; + break; + case "black": + r += `B`; + break; + case "pacific islander": + r += `PI`; + break; + case "malay": + r += `M`; + break; + case "amerindian": + r += `AI`; + break; + case "semitic": + r += `S`; + break; + case "southern european": + r += `SE`; + break; + case "mixed race": + r += `MR`; + break; + default: + r += `${slave.race.charAt(0).toUpperCase() + slave.race.charAt(1) + slave.race.charAt(2)}`; + break; } + r += " "; } - - class TonguePiercingList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Light", 1], - ["Heavy", 2] - ]; - super("Tongue piercing", pairs); - this.setValue(current_rule.set.tonguePiercing); - this.onchange = (value) => current_rule.set.tonguePiercing = value; + + function short_nationality(slave) { + r += `<span class="tan">`; + switch (slave.nationality) { + case "Afghan": + r += `Afg`; + break; + case "Albanian": + r += `Alb`; + break; + case "Algerian": + r += `Alg`; + break; + case "American": + r += `USA`; + break; + case "Andorran": + r += `And`; + break; + case "Angolan": + r += `Ang`; + break; + case "Antiguan": + r += `AB`; + break; + case "Argentinian": + r += `Arg`; + break; + case "Armenian": + r += `Arm`; + break; + case "Aruban": + r += `Aru`; + break; + case "Australian": + r += `Aus`; + break; + case "Austrian": + r += `Aut`; + break; + case "Azerbaijani": + r += `Aze`; + break; + case "Bahamian": + r += `Bah`; + break; + case "Bahraini": + r += `Bah`; + break; + case "Bangladeshi": + r += `Bgd`; + break; + case "Barbadian": + r += `Bar`; + break; + case "Belarusian": + r += `Ber`; + break; + case "Belgian": + r += `Bel`; + break; + case "Belizean": + r += `Blz`; + break; + case "Beninese": + r += `Ben`; + break; + case "Bermudian": + r += `Bmd`; + break; + case "Bhutanese": + r += `Bhu`; + break; + case "Bissau-Guinean": + r += `GB`; + break; + case "Bolivian": + r += `Bol`; + break; + case "Bosnian": + r += `Bos`; + break; + case "Brazilian": + r += `Bra`; + break; + case "British": + r += `UK`; + break; + case "Bruneian": + r += `Bru`; + break; + case "Bulgarian": + r += `Bul`; + break; + case "Burkinabé": + r += `BF`; + break; + case "Burmese": + r += `Bur`; + break; + case "Burundian": + r += `Bnd`; + break; + case "Cambodian": + r += `Kam`; + break; + case "Cameroonian": + r += `Cam`; + break; + case "Canadian": + r += `Can`; + break; + case "Cape Verdean": + r += `CV`; + break; + case "Catalan": + r += `Cat`; + break; + case "Central African": + r += `CAR`; + break; + case "Chadian": + r += `Cha`; + break; + case "Chilean": + r += `Chl`; + break; + case "Chinese": + r += `Chi`; + break; + case "Colombian": + r += `Col`; + break; + case "Comorian": + r += `Com`; + break; + case "Congolese": + r += `RC`; + break; + case "a Cook Islander": + r += `CI`; + break; + case "Costa Rican": + r += `CR`; + break; + case "Croatian": + r += `Cro`; + break; + case "Cuban": + r += `Cub`; + break; + case "Cypriot": + r += `Cyp`; + break; + case "Czech": + r += `Cze`; + break; + case "Danish": + r += `Den`; + break; + case "Djiboutian": + r += `Dji`; + break; + case "Dominican": + r += `DR`; + break; + case "Dominiquais": + r += `Dom`; + break; + case "Dutch": + r += `Nld`; + break; + case "East Timorese": + r += `ET`; + break; + case "Ecuadorian": + r += `Ecu`; + break; + case "Egyptian": + r += `Egy`; + break; + case "Emirati": + r += `UAE`; + break; + case "Equatoguinean": + r += `EG`; + break; + case "Eritrean": + r += `Eri`; + break; + case "Estonian": + r += `Est`; + break; + case "Ethiopian": + r += `Eth`; + break; + case "Fijian": + r += `Fij`; + break; + case "Filipina": + r += `Phl`; + break; + case "Finnish": + r += `Fin`; + break; + case "French": + r += `Fra`; + break; + case "French Guianan": + r += `FG`; + break; + case "French Polynesian": + r += `FP`; + break; + case "Gabonese": + r += `Gab`; + break; + case "Gambian": + r += `Gam`; + break; + case "Georgian": + r += `Geo`; + break; + case "German": + r += `Ger`; + break; + case "Ghanan": + r += `Gha`; + break; + case "Greek": + r += `Gre`; + break; + case "Greenlandic": + r += `Grn`; + break; + case "Grenadian": + r += `Gda`; + break; + case "Guamanian": + r += `Gua`; + break; + case "Guatemalan": + r += `Gtm`; + break; + case "Guinean": + r += `Gui`; + break; + case "Guyanese": + r += `Guy`; + break; + case "Haitian": + r += `Hai`; + break; + case "Honduran": + r += `Hon`; + break; + case "Hungarian": + r += `Hun`; + break; + case "I-Kiribati": + r += `Kir`; + break; + case "Icelandic": + r += `Ice`; + break; + case "Indian": + r += `Ind`; + break; + case "Indonesian": + r += `Idn`; + break; + case "Iranian": + r += `Irn`; + break; + case "Iraqi": + r += `Irq`; + break; + case "Irish": + r += `Irl`; + break; + case "Israeli": + r += `Isr`; + break; + case "Italian": + r += `Ita`; + break; + case "Ivorian": + r += `IC`; + break; + case "Jamaican": + r += `Jam`; + break; + case "Japanese": + r += `Jpn`; + break; + case "Jordanian": + r += `Jor`; + break; + case "Kazakh": + r += `Kaz`; + break; + case "Kenyan": + r += `Ken`; + break; + case "Kittitian": + r += `SKN`; + break; + case "Korean": + r += `Kor`; + break; + case "Kosovan": + r += `Kos`; + break; + case "Kurdish": + r += `Kur`; + break; + case "Kuwaiti": + r += `Kuw`; + break; + case "Kyrgyz": + r += `Kyr`; + break; + case "Laotian": + r += `Lao`; + break; + case "Latvian": + r += `Lat`; + break; + case "Lebanese": + r += `Lbn`; + break; + case "Liberian": + r += `Lib`; + break; + case "Libyan": + r += `Lby`; + break; + case "a Liechtensteiner": + r += `Lie`; + break; + case "Lithuanian": + r += `Lit`; + break; + case "Luxembourgian": + r += `Lux`; + break; + case "Macedonian": + r += `Mac`; + break; + case "Malagasy": + r += `Mad`; + break; + case "Malawian": + r += `Mwi`; + break; + case "Malaysian": + r += `Mys`; + break; + case "Maldivian": + r += `Mdv`; + break; + case "Malian": + r += `Mal`; + break; + case "Maltese": + r += `Mlt`; + break; + case "Marshallese": + r += `MI`; + break; + case "Mauritanian": + r += `Mta`; + break; + case "Mauritian": + r += `Mts`; + break; + case "Mexican": + r += `Mex`; + break; + case "Micronesian": + r += `FSM`; + break; + case "Moldovan": + r += `Mol`; + break; + case "Monégasque": + r += `Mnc`; + break; + case "Mongolian": + r += `Mon`; + break; + case "Montenegrin": + r += `Mng`; + break; + case "Moroccan": + r += `Mor`; + break; + case "Mosotho": + r += `Les`; + break; + case "Motswana": + r += `Bot`; + break; + case "Mozambican": + r += `Moz`; + break; + case "Namibian": + r += `Nam`; + break; + case "Nauruan": + r += `Nau`; + break; + case "Nepalese": + r += `Npl`; + break; + case "New Caledonian": + r += `NC`; + break; + case "a New Zealander": + r += `NZ`; + break; + case "Ni-Vanuatu": + r += `Van`; + break; + case "Nicaraguan": + r += `Nic`; + break; + case "Nigerian": + r += `Nga`; + break; + case "Nigerien": + r += `Ngr`; + break; + case "Niuean": + r += `Niu`; + break; + case "Norwegian": + r += `Nor`; + break; + case "Omani": + r += `Omn`; + break; + case "Pakistani": + r += `Pak`; + break; + case "Palauan": + r += `Plu`; + break; + case "Palestinian": + r += `Pal`; + break; + case "Panamanian": + r += `Pan`; + break; + case "Papua New Guinean": + r += `PNG`; + break; + case "Paraguayan": + r += `Par`; + break; + case "Peruvian": + r += `Per`; + break; + case "Polish": + r += `Pol`; + break; + case "Portuguese": + r += `Por`; + break; + case "Puerto Rican": + r += `PR`; + break; + case "Qatari": + r += `Qat`; + break; + case "Romanian": + r += `Rom`; + break; + case "Russian": + r += `Rus`; + break; + case "Rwandan": + r += `Rwa`; + break; + case "Sahrawi": + r += `Sah`; + break; + case "Saint Lucian": + r += `SL`; + break; + case "Salvadoran": + r += `ES`; + break; + case "Sammarinese": + r += `SM`; + break; + case "Samoan": + r += `Sam`; + break; + case "São Toméan": + r += `STP`; + break; + case "Saudi": + r += `Sau`; + break; + case "Scottish": + r += `Sco`; + break; + case "Senegalese": + r += `Sen`; + break; + case "Serbian": + r += `Srb`; + break; + case "Seychellois": + r += `Sey`; + break; + case "Sierra Leonean": + r += `Sie`; + break; + case "Singaporean": + r += `Sng`; + break; + case "Slovak": + r += `Svk`; + break; + case "Slovene": + r += `Svn`; + break; + case "a Solomon Islander": + r += `SI`; + break; + case "Somali": + r += `Som`; + break; + case "South African": + r += `RSA`; + break; + case "South Sudanese": + r += `SS`; + break; + case "Spanish": + r += `Spa`; + break; + case "Sri Lankan": + r += `Sri`; + break; + case "Sudanese": + r += `Sud`; + break; + case "Surinamese": + r += `Sur`; + break; + case "Swazi": + r += `Swa`; + break; + case "Swedish": + r += `Swe`; + break; + case "Swiss": + r += `Swi`; + break; + case "Syrian": + r += `Syr`; + break; + case "Taiwanese": + r += `Tai`; + break; + case "Tajik": + r += `Taj`; + break; + case "Tanzanian": + r += `Tza`; + break; + case "Thai": + r += `Tha`; + break; + case "Tibetan": + r += `Tib`; + break; + case "Togolese": + r += `Tog`; + break; + case "Tongan": + r += `Ton`; + break; + case "Trinidadian": + r += `TT`; + break; + case "Tunisian": + r += `Tun`; + break; + case "Turkish": + r += `Tur`; + break; + case "Turkmen": + r += `Tkm`; + break; + case "Tuvaluan": + r += `Tuv`; + break; + case "Ugandan": + r += `Uga`; + break; + case "Ukrainian": + r += `Ukr`; + break; + case "Uruguayan": + r += `Uru`; + break; + case "Uzbek": + r += `Uzb`; + break; + case "Vatican": + r += `VC`; + break; + case "Venezuelan": + r += `Ven`; + break; + case "Vietnamese": + r += `Vnm`; + break; + case "Vincentian": + r += `SVG`; + break; + case "Yemeni": + r += `Yem`; + break; + case "Zairian": + r += `DRC`; + break; + case "Zambian": + r += `Zam`; + break; + case "Zimbabwean": + if (slave.race === "white") { + r += `Rho`; + } else { + r += `Zwe`; + } + break; + case "Ancient Chinese Revivalist": + r += `Chi Rev`; + break; + case "Ancient Egyptian Revivalist": + r += `Egy Rev`; + break; + case "Arabian Revivalist": + r += `Ara Rev`; + break; + case "Aztec Revivalist": + r += `Azt Rev`; + break; + case "Edo Revivalist": + r += `Edo Rev`; + break; + case "Roman Revivalist": + r += `Rom Rev`; + break; + case "": + case "none": + case "slave": + case "Stateless": + r += `None`; + break; + default: + r += `${slave.nationality.charAt(0) + slave.nationality.charAt(1) + slave.nationality.charAt(2)}`; + break; } + r += `</span> `; } - - class ClitPiercingList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Light", 1], - ["Heavy", 2], - ["Smart (expensive)", 3] - ]; - super("Clit piercing", pairs); - this.setValue(current_rule.set.clitPiercing); - this.onchange = (value) => current_rule.set.clitPiercing = value; + + function long_nationality(slave) { + r += `<span class="tan">`; + switch (slave.nationality) { + case "Zimbabwean": + if (slave.race === "white") { + r += `Rhodesian.`; + } else { + r += `${slave.nationality}.`; + } + break; + case "slave": + case "none": + case "": + case "Stateless": + r += `Stateless.`; + break; + default: + r += `${slave.nationality}.`; + break; } + r += `</span> `; } - - class LabiaPiercingList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Light", 1], - ["Heavy", 2] - ]; - super("Pussylips piercings", pairs); - this.setValue(current_rule.set.vaginaPiercing); - this.onchange = (value) => current_rule.set.vaginaPiercing = value; + + function short_skin(slave) { + r += `<span class="pink">`; + switch (slave.skin) { + case "light brown": + r += `L. Br`; + break; + case "dark brown": + r += `D. Br`; + break; + case "light olive": + r += `L. Oli`; + break; + case "dark olive": + r += `D. Oli`; + break; + case "extremely pale": + r += `Ex. Pa`; + break; + case "pure white": + r += `P. Whi`; + break; + case "tanned": + r += `Tan`; + break; + case "dark": + case "fair": + case "pale": + r += `${slave.skin.charAt(0).toUpperCase() + slave.skin.slice(1)}`; + break; + default: + r += `${slave.skin.charAt(0).toUpperCase() + slave.skin.charAt(1) + slave.skin.charAt(2)}`; + break; } + r += `</span> `; } - - class ShaftPiercingList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Light", 1], - ["Heavy", 2] - ]; - super("Shaft piercings", pairs); - this.setValue(current_rule.set.dickPiercing); - this.onchange = (value) => current_rule.set.dickPiercing = value; + + function short_genitals(slave) { + if (slave.dick > 0) { + r += `<span class="pink">`; + if (slave.balls === 0) { + r += `Geld`; + } + if ((slave.dick > 8) && (slave.balls > 8)) { + r += `Junk+++`; + } else if ((slave.dick > 5) && (slave.balls > 5)) { + r += `Junk++`; + } else if ((slave.dick > 4) && (slave.balls > 4)) { + r += `Junk+`; + } else if ((slave.dick > 3) && (slave.balls > 3)) { + r += `Junk`; + } else if (slave.dick > 8) { + r += `Dick+++`; + } else if (slave.dick > 5) { + r += `Dick++`; + } else if (slave.dick > 4) { + r += `Dick+`; + } else if (slave.dick > 3) { + r += `Dick`; + } else if (slave.balls > 10) { + r += `Balls+++`; + } else if (slave.balls > 5) { + r += `Balls++`; + } else if (slave.balls > 4) { + r += `Balls+`; + } else if (slave.balls > 3) { + r += `Balls`; + } + r += `</span> `; } - } - - class PerineumPiercingList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Light", 1], - ["Heavy", 2] - ]; - super("Perianal piercings", pairs); - this.setValue(current_rule.set.anusPiercing); - this.onchange = (value) => current_rule.set.anusPiercing = value; + if (slave.vagina === 0) { + r += `<span class="lime">VV</span>`; + } else if ((slave.pregKnown === 1) && canWalk(slave) && (slave.clothes === "no clothing" || slave.clothes === "body oil") && (slave.shoes === "none")) { + r += `<span class="pink">NBP</span>`; } - } - - class CorsetPiercingList extends List { - constructor() { - const pairs = [ - ["No default setting", "no default setting"], - ["None", 0], - ["Apply", 1] - ]; - super("Corset piercings", pairs); - this.setValue(current_rule.set.corsetPiercing); - this.onchange = (value) => current_rule.set.corsetPiercing = value; + if (slave.anus === 0) { + r += ` <span class="lime">AV</span>`; } - } - - class AutoBrandingList extends List { - constructor() { - const pairs = [ - ["Activate", 1], - ["Off", 0], - ]; - super("Automatic branding", pairs); - this.setValue(current_rule.set.autoBrand); - this.onchange = (value) => current_rule.set.autoBrand = value; + r += `<span class="pink">`; + if ((slave.vagina > 3) && (slave.anus > 3)) { + r += ` V++A++`; + } else if ((slave.vagina > 2) && (slave.anus > 2)) { + r += ` V+A+`; + } else if (slave.vagina > 3) { + r += ` V++`; + } else if (slave.vagina > 2) { + r += ` V+`; + } else if (slave.anus > 3) { + r += ` A++`; + } else if (slave.anus > 2) { + r += ` A+`; } + r += `</span> `; } - - class BrandingLocationList extends List { - constructor() { - super("Your preferred location for brands is", []); - - const ears = new ListSubSection(this, "Ears", [ - ["Left", "left ear"], - ["Right", "right ear"], - ["Both", "ears"] - ]); - this.appendChild(ears); - - const cheeks = new ListSubSection(this, "Cheeks", [ - ["Left", "left cheek"], - ["Right", "right cheek"], - ["Both", "cheeks"] - ]); - this.appendChild(cheeks); - - const shoulders = new ListSubSection(this, "Shoulders", [ - ["Left", "left shoulder"], - ["Right", "right shoulder"], - ["Both", "shoulders"] - ]); - this.appendChild(shoulders); - - const breasts = new ListSubSection(this, "Breasts", [ - ["Left", "right breast"], - ["Right", "left breast"], - ["Both", "breasts"] - ]); - this.appendChild(breasts); - - const upper_arms = new ListSubSection(this, "Arms, upper", [ - ["Left", "left upper arm"], - ["Right", "right upper arm"], - ["Both", "upper arms"] - ]); - this.appendChild(upper_arms); - - const lower_arms = new ListSubSection(this, "Arms, lower", [ - ["Left", "left lower arm"], - ["Right", "right lower arm"], - ["Both", "lower arms"] - ]); - this.appendChild(lower_arms); - - const wrist = new ListSubSection(this, "Wrist", [ - ["Left", "left wrist"], - ["Right", "right wrist"], - ["Both", "wrists"] - ]); - this.appendChild(wrist); - - const hand = new ListSubSection(this, "Hand", [ - ["Left", "left hand"], - ["Right", "right hand"], - ["Both", "hands"] - ]); - this.appendChild(hand); - - const buttocks = new ListSubSection(this, "Buttocks", [ - ["Left", "left buttock"], - ["Right", "right buttock"], - ["Both", "buttocks"] - ]); - this.appendChild(buttocks); - - const thigh = new ListSubSection(this, "Thigh", [ - ["Left", "left thigh"], - ["Right", "right thigh"], - ["Both", "thighs"] - ]); - this.appendChild(thigh); - - const calf = new ListSubSection(this, "Calf", [ - ["Left", "left calf"], - ["Right", "right calf"], - ["Both", "calves"] - ]); - this.appendChild(calf); - - const ankle = new ListSubSection(this, "Ankle", [ - ["Left", "left ankle"], - ["Right", "right ankle"], - ["Both", "ankles"] - ]); - this.appendChild(ankle); - - const feet = new ListSubSection(this, "Feet", [ - ["Left", "left foot"], - ["Right", "right foot"], - ["Both", "feet"] - ]); - this.appendChild(feet); - - const other = new ListSubSection(this, "Other", [ - ["Neck", "neck"], - ["Chest", "chest"], - ["Belly", "belly"], - ["Pubic mound", "pubic mound"], - ["Back", "back"], - ["Lower Back", "lower back"] - ]); - this.appendChild(other); - - this.setValue(V.brandTarget); - this.onchange = (value) => V.brandTarget = value; + + function long_genitals(slave) { + if (slave.dick > 0) { + r += `<span class="pink">`; + if (slave.balls === 0) { + r += `Gelded.`; + } + if ((slave.dick > 8) && (slave.balls > 8)) { + r += `Hyper dick & balls.`; + } else if ((slave.dick > 5) && (slave.balls > 5)) { + r += `Monster dick & balls.`; + } else if ((slave.dick > 4) && (slave.balls > 4)) { + r += `Huge dick & balls.`; + } else if ((slave.dick > 3) && (slave.balls > 3)) { + r += `Big dick & balls.`; + } else if (slave.dick > 8) { + r += `Hyper dong.`; + } else if (slave.dick > 5) { + r += `Monster dong.`; + } else if (slave.dick > 4) { + r += `Huge dick.`; + } else if (slave.dick > 3) { + r += `Big dick.`; + } else if (slave.balls > 8) { + r += `Hyper balls.`; + } else if (slave.balls > 5) { + r += `Monstrous balls.`; + } else if (slave.balls > 4) { + r += `Huge balls.`; + } else if (slave.balls > 3) { + r += `Big balls.`; + } + r += `</span> `; + } + if (slave.vagina === 0) { + r += `<span class="lime">Virgin.</span> `; + } else if ((slave.pregKnown === 1) && canWalk(slave) && (slave.clothes === "no clothing" || slave.clothes === "body oil") && (slave.shoes === "none")) { + r += `<span class="pink">Naked, barefoot, and pregnant.</span> `; + } + if (slave.anus === 0) { + r += `<span class="lime">Anal virgin.</span> `; + } + r += `<span class="pink">`; + if ((slave.vagina > 3) && (slave.anus > 3)) { + r += `Blown out holes.`; + } else if ((slave.vagina > 2) && (slave.anus > 2)) { + r += `High mileage.`; + } else if (slave.vagina > 3) { + r += `Cavernous pussy.`; + } else if (slave.vagina > 2) { + r += `Loose pussy.`; + } else if (slave.anus > 3) { + r += `Permagaped anus.`; + } else if (slave.anus > 2) { + r += `Gaping anus.`; } + r += `</span> `; } - - class BrandDesignList extends List { - constructor() { - const items = [ - ["Your slaving emblem", "your personal symbol"], - ["Your initials", "your initials"], - ["SLUT"], - ["WHORE"], - ["SLAVE"], - ["COW"], - ["MEAT"], - ["CUMDUMP"], - ["LOVER"], - ["Pussy symbol", "a pussy symbol"], - ["Anus symbol", "an anus symbol"], - ["Penis symbol", "a penis symbol"], - ["Lady", "a lady silhouette"], - ["Princess", "a princess silhouette"], - ["Queen", "a queen silhouette"], - ["Angel", "an angel silhouette"], - ["Devil", "a devil silhouette"] - ]; - - if (V.arcologies[0].FSSupremacist !== "unset" || V.arcologies[0].FSSubjugationist !== "unset") - items.push(["(FS) Racial Slur", "a racial slur"]); - - if (V.arcologies[0].FSSupremacist !== "unset" && V.arcologies[0].FSSupremacistRace === "white") - items.push(["(FS) Swastika", "a swastika"]); - - if (V.arcologies[0].FSSubjugationist !== "unset" && V.arcologies[0].FSSubjugationistRace === "semitic") - items.push(["(FS) Star of David", "a Star of David"]); - - if (V.arcologies[0].FSGenderRadicalist !== "unset" || V.arcologies.FSGenderFundamentalist !== "unset") - items.push(["(FS) Gender Symbol", "a gender symbol"]); - - if (V.arcologies[0].FSPaternalist !== "unset") - items.push(["(FS) Personal Symbol", "her own personal symbol"]); - - if (V.arcologies[0].FSDegradationist !== "unset") - items.push(["(FS) Chain Symbol", "a chain symbol"]); - - if (V.arcologies[0].FSBodyPurist !== "unset") - items.push(["(FS) Vitruvian Man", "a Vitruvian man"]); - - if (V.arcologies[0].FSTransformationFetishist !== "unset") - items.push(["(FS) Most Desired Implants", "a shortlist of desired implants"]); - - if (V.arcologies[0].FSYouthPreferentialist !== "unset") - items.push(["(FS) Virginity Status", "her virginity status"]); - - if (V.arcologies[0].FSMaturityPreferentialist !== "unset") - items.push(["(FS) Sexual Skill Info", "her sexual skills"]); - - if (V.arcologies[0].FSSlimnessEnthusiast !== "unset") - items.push(["(FS) Breast Ceiling", "her absolute maximum breast size"]); - - if (V.arcologies[0].FSAssetExpansionist !== "unset") - items.push(["(FS) Breast Floor", "her absolute minimum breast size"]); - - if (V.arcologies[0].FSPastoralist !== "unset") - items.push(["(FS) Product Quality", "her body product quality"]); - - if (V.arcologies[0].FSPhysicalIdelist !== "unset") - items.push(["(FS) Deadlift Info", "her deadlift record"]); - - if (V.arcologies[0].FSHedonisticDecadence !== "unset") - items.push(["(FS) Weight Record", "her highest weigh-in"]); - - if (V.arcologies[0].FSHedonisticDecadence && V.PC.refreshmentType == 2) - items.push(["(FS) Favorite Food", `a big helping of ${V.PC.refreshment}`]); - - if (V.arcologies[0].FSRepopulationFocus !== "unset") - items.push(["(FS) Birth Count", "the number of children she has birthed"]); - - if (V.arcologies[0].FSChattelReligionist !== "unset") - items.push(["(FS) Religious Symbol", "a religious symbol"]); - - if (V.arcologies[0].FSRomanRevivalist !== "unset") - items.push(["(FS) Republican Crest", "a small crest of your Republic"]); - - if (V.arcologies[0].FSAztecRevivalist !== "unset") - items.push(["(FS) Seven Serpents", "a small symbol of the Aztec gods"]); - - if (V.arcologies[0].FSEgyptianRevivalist !== "unset") - items.push(["(FS) Dynastic Sigil", "a small sigil of your Dynasty"]); - - if (V.arcologies[0].FSEdoRevivalist !== "unset") - items.push(["(FS) Mon", "a small image of the Shogunate's mon"]); - - if (V.arcologies[0].FSArabianRevivalist !== "unset") - items.push(["(FS) Caliphate Symbol", "a small symbol of the Caliphate"]); - - if (V.arcologies[0].FSChineseRevivalist !== "unset") - items.push(["(FS) Imperial Seal", "a small image of your Imperial Seal"]); - - super("Your brand design is", items, true); + + function short_age(slave) { + r += `<span class="pink">`; + if (V.showAgeDetail === 1) { + r += slave.actualAge; + } else if (slave.actualAge >= 40) { + r += `40s`; + } else if (slave.actualAge >= 35) { + r += `Lt30s`; + } else if (slave.actualAge >= 30) { + r += `Ea30s`; + } else if (slave.actualAge >= 25) { + r += `Lt20s`; + } else if (slave.actualAge >= 20) { + r += `Ea20s`; + } else if (slave.actualAge >= 18) { + r += slave.actualAge; + } + if (slave.actualAge !== slave.physicalAge) { + r += `${slave.physicalAge}y-bdy`; + } + if (slave.visualAge !== slave.physicalAge) { + r += `Lks${slave.visualAge}`; } + r += " "; } - - class FaceTattooList extends List { - constructor() { - const items = [ - ["no default setting"], - ["none", 0], - ["tribal patterns"], - ["flowers"], - ["counting"], - ["advertisements"], - ["rude words"], - ["degradation"], - ["bovine patterns"], - ["Asian art"], - ["permanent makeup"], - ["sacrament"], - ["sacrilege"], - ["possessive"], - ["paternalist"] - ]; - super("Facial tattoos", items); - this.setValue(current_rule.set.lipsTat); - this.onchange = (value) => current_rule.set.lipsTat = value; + + function short_face(slave) { + if (slave.face < -95) { + r += `<span class="red">Face---${V.summaryStats? `[${slave.face}]` : ''}</span>`; + } else if (slave.face < -40) { + r += `<span class="red">Face--${V.summaryStats? `[${slave.face}]` : ''}</span>`; + } else if (slave.face < -10) { + r += `<span class="red">Face-${V.summaryStats? `[${slave.face}]` : ''}</span>`; + } else if (slave.face <= 10) { + r += `Face${V.summaryStats? `[${slave.face}]` : ''}`; + } else if (slave.face <= 40) { + r += `<span class="pink">Face+${V.summaryStats? `[${slave.face}]` : ''}</span>`; + } else if (slave.face <= 95) { + r += `<span class="pink">Face++${V.summaryStats? `[${slave.face}]` : ''}</span>`; + } else { + r += `<span class="pink">Face+++${V.summaryStats? `[${slave.face}]` : ''}</span>`; } + r += " "; } - class ShoulderTattooList extends List { - constructor() { - const items = [ - ["no default setting"], - ["none", 0], - ["tribal patterns"], - ["flowers"], - ["counting"], - ["advertisements"], - ["rude words"], - ["degradation"], - ["bovine patterns"], - ["Asian art"], - ["scenes"], - ["sacrament"], - ["sacrilege"], - ["possessive"], - ["paternalist"] - ]; - super("Shoulder tattoos", items); - this.setValue(current_rule.set.shouldersTat); - this.onchange = (value) => current_rule.set.shouldersTat = value; + function short_eyes(slave) { + if (slave.eyes === -2) { + r += `<span class="red">Blind</span>`; + } else if (((slave.eyes === -1) && (slave.eyewear !== "corrective glasses") && (slave.eyewear !== "corrective contacts"))) { + r += `<span class="yellow">Sight-</span>`; + } + r += " "; + } + + function short_lips(slave) { + if (slave.lips > 95) { + r += `Facepussy`; + } else if (slave.lips > 70) { + r += `Lips+++${V.summaryStats? `[${slave.lips}]` : ''}`; + } else if (slave.lips > 40) { + r += `Lips++${V.summaryStats? `[${slave.lips}]` : ''}`; + } else if (slave.lips > 20) { + r += `Lips+${V.summaryStats? `[${slave.lips}]` : ''}`; + } else if (slave.lips > 10) { + r += `Lips${V.summaryStats? `[${slave.lips}]` : ''}`; + } else { + r += `<span class="red">Lips-</span>${V.summaryStats? `[${slave.lips}]` : ''}`; + } + r += " "; + } + + function short_teeth(slave) { + if (slave.teeth === "crooked") { + r += `<span class="yellow">Cr Teeth</span>`; + } else if (slave.teeth === "cosmetic braces") { + r += `Cos Braces`; + } else if (slave.teeth === "straightening braces") { + r += `Braces`; + } else if (slave.teeth === "removable") { + r += `Rem Teeth`; + } else if (slave.teeth === "pointy") { + r += `Fangs`; + } + r += " "; + } + + function short_muscles(slave) { + if (slave.muscles > 95) { + r += `Musc++${V.summaryStats? `[${slave.muscles}]`: ''}`; + } else if (slave.muscles > 50) { + r += `Musc+${V.summaryStats? `[${slave.muscles}]`: ''}`; + } else if (slave.muscles > 5) { + r += `Fit${V.summaryStats? `[${slave.muscles}]`: ''}`; + } else if (slave.muscles > -6) { + r += `Soft${V.summaryStats? `[${slave.muscles}]`: ''}`; + } else if (slave.muscles > -31) { + if (V.arcologies[0].FSPhysicalIdealist === "unset") { + r += `<span class="red">Weak</span>${V.summaryStats? `[${slave.muscles}]`: ''}`; + } else { + r += `Soft${V.summaryStats? `[${slave.muscles}]`: ''}`; + } + } else if (slave.muscles > -96) { + if (V.arcologies[0].FSPhysicalIdealist === "unset") { + r += `<span class="red">Weak+</span>${V.summaryStats? `[${slave.muscles}]`: ''}`; + } else { + r += `Soft+${V.summaryStats? `[${slave.muscles}]`: ''}`; + } + } else { + r += `<span class="red">Weak++</span>${V.summaryStats? `[${slave.muscles}]`: ''}`; } + r += " "; } - - class ChestTattooList extends List { - constructor() { - const items = [ - ["no default setting"], - ["none", 0], - ["tribal patterns"], - ["flowers"], - ["counting"], - ["advertisements"], - ["rude words"], - ["degradation"], - ["bovine patterns"], - ["Asian art"], - ["scenes"], - ["sacrament"], - ["sacrilege"], - ["possessive"], - ["paternalist"] - ]; - super("Chest tattoos", items); - this.setValue(current_rule.set.boobsTat); - this.onchange = (value) => current_rule.set.boobsTat = value; + + function short_limbs(slave) { + if (slave.amp !== 0) { + if (slave.amp === -1) { + r += `P-Limbs`; + } else if (slave.amp === -2) { + r += `Sex P-Limbs`; + } else if (slave.amp === -3) { + r += `Beauty P-Limbs`; + } else if (slave.amp === -4) { + r += `Combat P-Limbs`; + } else if (slave.amp === -5) { + r += `Cyber P-Limbs`; + } else { + r += `Amp`; + } + r += " "; } - } - - class ArmTattooList extends List { - constructor() { - const items = [ - ["no default setting"], - ["none", 0], - ["tribal patterns"], - ["flowers"], - ["counting"], - ["advertisements"], - ["rude words"], - ["degradation"], - ["bovine patterns"], - ["Asian art"], - ["scenes"], - ["sacrament"], - ["sacrilege"], - ["possessive"], - ["paternalist"] - ]; - super("Arm tattoos", items); - this.setValue(current_rule.set.armsTat); - this.onchange = (value) => current_rule.set.armsTat = value; + if (!canWalk(slave)) { + r += `Immob`; } + if (slave.heels === 1) { + r += `Heel`; + } + r += `</span> `; } - - class UpperBackTattooList extends List { - constructor() { - const items = [ - ["no default setting"], - ["none", 0], - ["tribal patterns"], - ["flowers"], - ["counting"], - ["advertisements"], - ["rude words"], - ["degradation"], - ["bovine patterns"], - ["Asian art"], - ["scenes"], - ["sacrament"], - ["sacrilege"], - ["possessive"], - ["paternalist"], - ]; - super("Upper back tattoos", items); - this.setValue(current_rule.set.backTat); - this.onchange = (value) => current_rule.set.backTat = value; + + function short_voice(slave) { + if (slave.voice === 0) { + r += `<span class="pink">Mute</span>`; + } else { + if (slave.accent === 3) { + r += `<span class="red">Acc--</span>`; + } else if (slave.accent === 2) { + r += `Acc-`; + } else if (slave.accent === 4) { + r += `Acc--`; + } else if (slave.accent === 1) { + r += `<span class="pink">Acc</span>`; + } } + r += " "; } - - class LowerBackTattooList extends List { - constructor() { - const items = [ - ["no default setting"], - ["none", 0], - ["tribal patterns"], - ["flowers"], - ["counting"], - ["advertisements"], - ["rude words"], - ["degradation"], - ["bovine patterns"], - ["Asian art"], - ["scenes"], - ["sacrament"], - ["sacrilege"], - ["possessive"], - ["paternalist"] - ]; - super("Lower back tattoos", items); - this.setValue(current_rule.set.stampTat); - this.onchange = (value) => current_rule.set.stampTat = value; + + function short_tits_ass(slave) { + r += `<span class="pink">`; + if ((slave.boobs >= 12000) && (slave.butt > 9)) { + r += `T&A+++`; + } else if ((slave.boobs > 4000) && (slave.butt > 8)) { + r += `T&A++`; + } else if ((slave.boobs > 2000) && (slave.butt > 6)) { + r += `T&A+`; + } else if ((slave.boobs > 800) && (slave.butt > 4)) { + r += `T&A`; + } else if ((slave.boobs < 500) && (slave.butt < 3) && (slave.weight <= 10) && (slave.muscles <= 30)) { + r += `Girlish`; + } else if (slave.boobs >= 12000) { + r += `Boobs+++`; + } else if (slave.boobs > 4000) { + r += `Boobs++`; + } else if (slave.boobs > 2000) { + r += `Boobs+`; + } else if (slave.boobs > 800) { + r += `Boobs`; + } else if (slave.butt > 9) { + r += `Ass+++`; + } else if (slave.butt > 8) { + r += `Ass++`; + } else if (slave.butt > 6) { + r += `Ass+`; + } else if (slave.butt > 4) { + r += `Ass`; } + r += `</span> `; } - - class AbdomenTattooList extends List { - constructor() { - const items = [ - ["no default setting"], - ["none", 0], - ["tribal patterns"], - ["flowers"], - ["counting"], - ["advertisements"], - ["rude words"], - ["degradation"], - ["bovine patterns"], - ["Asian art"], - ["scenes"], - ["sacrament"], - ["sacrilege"], - ["possessive"], - ["paternalist"], - ]; - super("Abdomen tattoos", items); - this.setValue(current_rule.set.vaginaTat); - this.onchange = (value) => current_rule.set.vaginaTat = value; + + function short_hips(slave) { + r += `<span class="red">`; + if (slave.hips < -1) { + if (slave.butt > 2 && (V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { + r += `Disp+`; + } + } else if (slave.hips < 0) { + if (slave.butt > 4 && (V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { + r += `Disp+`; + } + } else if (slave.hips > 2) { + if (slave.butt <= 8) { + r += `Disp-`; + } + } else if (slave.hips > 1) { + if (slave.butt <= 3 && (V.arcologies[0].FSSlimnessEnthusiast === "unset" || (slave.boobs >= 500))) { + r += `Disp-`; + } + } else if (slave.hips > 0) { + if (slave.butt > 8) { + if ((V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { + r += `Disp+`; + } + } else if (slave.butt <= 2 && (V.arcologies[0].FSSlimnessEnthusiast === "unset" || (slave.boobs >= 500))) { + r += `Disp-`; + } + } else { + if (slave.butt > 6) { + if ((V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { + r += `Disp+`; + } + } else if (slave.butt <= 1 && (V.arcologies[0].FSSlimnessEnthusiast === "unset" || (slave.boobs >= 500))) { + r += `Disp-`; + } } + r += `</span> `; } - - class DickTattooList extends List { - constructor() { - const items = [ - ["no default setting"], - ["none", 0], - ["tribal patterns"], - ["flowers"], - ["counting"], - ["advertisements"], - ["rude words"], - ["degradation"], - ["bovine patterns"], - ["Asian art"], - ["sacrament"], - ["sacrilege"], - ["possessive"], - ["paternalist"], - ]; - super("Dick tattoos", items); - this.setValue(current_rule.set.dickTat); - this.onchange = (value) => current_rule.set.dickTat = value; + + function short_waist(slave) { + if (slave.waist > 95) { + r += `<span class="red">Wst---${V.summaryStats? `[${slave.waist}]` : ''}</span>`; + } else if (slave.waist > 40) { + r += `<span class="red">Wst--${V.summaryStats? `[${slave.waist}]`: ''}</span>`; + } else if (slave.waist > 10) { + r += `<span class="red">Wst-${V.summaryStats? `[${slave.waist}]` : ''}</span>`; + } else if (slave.waist >= -10) { + r += `Wst${V.summaryStats? `[${slave.waist}]`: ''}`; + } else if (slave.waist >= -40) { + r += `<span class="pink">Wst+${V.summaryStats? `[${slave.waist}]` : ''}</span>`; + } else if (slave.waist >= -95) { + r += `<span class="pink">Wst++${V.summaryStats? `[${slave.waist}]` : ''}</span>`; + } else { + r += `<span class="pink">Wst+++${V.summaryStats? `[${slave.waist}]`: ''}</span>`; } + r += " "; } - - class ButtockTattooList extends List { - constructor() { - const items = [ - ["no default setting"], - ["none", 0], - ["tribal patterns"], - ["flowers"], - ["counting"], - ["advertisements"], - ["rude words"], - ["degradation"], - ["bovine patterns"], - ["Asian art"], - ["scenes"], - ["sacrament"], - ["sacrilege"], - ["possessive"], - ["paternalist"], - ]; - super("Buttock tattoos:", items); - this.setValue(current_rule.set.buttTat); - this.onchange = (value) => current_rule.set.buttTat = value; + + function short_implants(slave) { + r += `<span class="pink">`; + if ((slave.boobsImplant === 0) && (slave.buttImplant === 0) && (slave.waist >= -95) && (slave.lipsImplant === 0) && (slave.faceImplant <= 5) && (slave.bellyImplant === -1)) { + r += `Natr`; + } else { + r += `Impl`; } + r += " "; } - - class AnalTattooList extends List { - constructor() { - const items = [ - ["no default setting"], - ["none", 0], - ["tribal patterns"], - ["flowers"], - ["counting"], - ["advertisements"], - ["rude words"], - ["degradation"], - ["bovine patterns"], - ["bleached"], - ["sacrament"], - ["sacrilege"], - ["possessive"], - ["paternalist"], - ]; - super("Anal tattoo or bleaching", items); - this.setValue(current_rule.set.anusTat); - this.onchange = (value) => current_rule.set.anusTat = value; + + function short_lactation(slave) { + if (slave.lactation === 1) { + r += `Lact`; + } else if (slave.lactation === 2) { + r += `Lact++`; } + r += " "; } - - class LegTattooList extends List { - constructor() { - const items = [ - ["no default setting"], - ["none", 0], - ["tribal patterns"], - ["flowers"], - ["counting"], - ["advertisements"], - ["rude words"], - ["degradation"], - ["bovine patterns"], - ["Asian art"], - ["scenes"], - ["sacrament"], - ["sacrilege"], - ["possessive"], - ["paternalist"], - ]; - super("Leg tattoos", items); - this.setValue(current_rule.set.legsTat); - this.onchange = (value) => current_rule.set.legsTat = value; + + function short_mods(slave) { + modScore(slave); + if (slave.corsetPiercing === 0 && V.piercingScore < 3 && V.tatScore < 2) { + return; + } else if (V.modScore > 15 || (V.piercingScore > 8 && V.tatScore > 5)) { + r += `Mods++`; + } else if (V.modScore > 7) { + r += `Mods+`; + } else { + r += `Mods`; + } + if (slave.brand !== 0) { + r += `Br`; } + r += " "; } - - class VisionSurgeryList extends List { - constructor() { - const items = [ - ["no default setting"], - ["fixed", 1], - ["blurred", -1], - ]; - super("Vision correction", items); - this.setValue(current_rule.set.surgery_eyes); - this.onchange = (value) => current_rule.set.surgery_eyes = value; + + function long_age(slave) { + r += `<span class="pink">`; + if (V.showAgeDetail === 1) { + r += `Age ${slave.actualAge}.`; + } else if (slave.actualAge >= 40) { + r += `Forties.`; + } else if (slave.actualAge >= 35) { + r += `Late thirties.`; + } else if (slave.actualAge >= 30) { + r += `Early thirties.`; + } else if (slave.actualAge >= 25) { + r += `Late twenties.`; + } else if (slave.actualAge >= 20) { + r += `Early twenties.`; + } else if (slave.actualAge >= 19) { + r += `Nineteen.`; + } else if (slave.actualAge >= 18) { + r += `Eighteen.`; + } else { + r += `Underage.`; + } + r += " "; + /* + ** No NCS, then do the standard, However because of the wrinkes of Incubators, as long as visual age is greater + ** than or equal to physical age, we do the old physical body/Looks for fresh out of the can NCS slaves. + */ + if (((slave.inducedNCS === 0) || (slave.visualAge >= slave.physicalAge))) { + if (slave.actualAge !== slave.physicalAge) { + r += `${slave.physicalAge} year old body. `; + } + if (slave.visualAge !== slave.physicalAge) { + r += `Looks ${slave.visualAge}. `; + } + } else { + /* + ** Now the rub. The use of physical Age for the year old body above, basically conflicts with the changes + ** that NCS introduces, so here to *distinguish* the changes, we use visual age with the 'year old body' + ** and appears, for example: Slave release from incubator at age 10, Her summary would show, 'Age 0. 10 + ** year old body.' But if she's given NCS a few weeks after release, while she's still before her first + ** birthday, it'll appear the same. But once her birthday fires, if we ran with the above code it would + ** say: 'Age 1. 11 year old body.' -- this conflicts with the way NCS works though, because she hasn't + ** visually aged, so our change here makes it say 'Age 1. Appears to have a 10 year old body.' + */ + r += `Appears to have a ${slave.visualAge} year old body. `; + } + if (slave.inducedNCS === 1) { + r += `(<span class="orange">NCS</span>) `; } } - - class LactationSurgeryList extends List { - constructor() { - const items = [ - ["no default setting"], - ["implanted", 1], - ["removed", 0], - ]; - super("Lactation drug implants", items); - this.setValue(current_rule.set.surgery_lactation); - this.onchange = (value) => current_rule.set.surgery_lactation = value; + + function long_face(slave) { + if (slave.face < -95) { + r += `<span class="red">Very ugly${V.summaryStats? `[${slave.face}]`: ''}</span>`; + } else if (slave.face < -40) { + r += `<span class="red">Ugly${V.summaryStats? `[${slave.face}]`: ''}</span>`; + } else if (slave.face < -10) { + r += `<span class="red">Unattractive${V.summaryStats? `[${slave.face}]`: ''}</span>`; + } else if (slave.face <= 10) { + r += `Average${V.summaryStats? `[${slave.face}]`: ''}`; + } else if (slave.face <= 40) { + r += `<span class="pink">Attractive${V.summaryStats? `[${slave.face}]`: ''}</span>`; + } else if (slave.face <= 95) { + r += `<span class="pink">Beautiful${V.summaryStats? `[${slave.face}]`: ''}</span>`; + } else { + r += `<span class="pink">Very beautiful${V.summaryStats? `[${slave.face}]`: ''}</span>`; } + r += ` ${slave.faceShape} face.`; } - - class SemenSurgeryList extends List { - constructor() { - const items = [ - ["no default setting"], - ["implanted", 1], - ["removed", 0], - ]; - super("Prostate production enhancing drug implants", items); - this.setValue(current_rule.set.surgery_prostate); - this.onchange = (value) => current_rule.set.surgery_prostate = value; + + function long_eyes(slave) { + if (slave.eyes <= -2) { + r += `<span class="red">Blind.</span>`; + } else if (((slave.eyes <= -1) && (slave.eyewear !== "corrective glasses") && (slave.eyewear !== "corrective contacts"))) { + r += `<span class="yellow">Nearsighted.</span>`; } + r += " "; } - - class VasectomyList extends List { - constructor() { - const items = [ - ["no default setting"], - ["apply vasectomy", true], - ["undo vasectomy", false], - ]; - super("Apply or undo vasectomy for slaves with testicles", items); - this.setValue(current_rule.set.surgery_vasectomy); - this.onchange = (value) => current_rule.set.surgery_vasectomy = value; + + function long_lips(slave) { + if (slave.lips > 95) { + r += `Facepussy${V.summaryStats? `[${slave.lips}]`: ''}.`; + } else if (slave.lips > 70) { + r += `Huge lips${V.summaryStats? `[${slave.lips}]`: ''}.`; + } else if (slave.lips > 40) { + r += `Big lips${V.summaryStats? `[${slave.lips}]`: ''}.`; + } else if (slave.lips > 20) { + r += `Pretty lips${V.summaryStats? `[${slave.lips}]`: ''}.`; + } else if (slave.lips > 10) { + r += `Normal lips${V.summaryStats? `[${slave.lips}]`: ''}.`; + } else { + r += `<span class="red">Thin lips${V.summaryStats? `[${slave.lips}]`: ''}.</span>`; } + r += " "; } - - class CosmeticSurgeryList extends List { - constructor() { - const items = [ - ["none", 0], - ["subtle", 1], - ["invasive", 2], - ]; - super("Cosmetic Surgery", items); - this.setValue(current_rule.set.surgery_cosmetic); - this.onchange = (value) => current_rule.set.surgery_cosmetic = value; + + function long_teeth(slave) { + if (slave.teeth === "crooked") { + r += `<span class="yellow">Crooked teeth.</span>`; + } else if (slave.teeth === "cosmetic braces") { + r += `Cosmetic braces.`; + } else if (slave.teeth === "straightening braces") { + r += `Braces.`; + } else if (slave.teeth === "removable") { + r += `Removable teeth.`; + } else if (slave.teeth === "pointy") { + r += `Sharp fangs.`; } + r += " "; } - - class LipSurgeryList extends List { - constructor() { - const items = [ - ["no default setting"], - ["removed", 0], - ["plush", 20], - ["big", 40], - ["huge", 70], - ["facepussy", 95], - ]; - super("Lip implants", items); - this.setValue(current_rule.set.surgery_lips); - this.onchange = (value) => current_rule.set.surgery_lips = value; + + function long_muscles(slave) { + if (slave.muscles > 95) { + r += `Hugely muscular${V.summaryStats? `[${slave.muscles}]` : ''}.`; + } else if (slave.muscles > 50) { + r += `Muscular${V.summaryStats? `[${slave.muscles}]`: ''}.`; + } else if (slave.muscles > 5) { + r += `Fit${V.summaryStats? `[${slave.muscles}]`: ''}.`; + } else if (slave.muscles > -6) { + r += `Soft${V.summaryStats? `[${slave.muscles}]`: ''}.`; + } else if (slave.muscles > -31) { + if (V.arcologies[0].FSPhysicalIdealist === "unset") { + r += `<span class="red">Weak${V.summaryStats? `[${slave.muscles}]`: ''}.</span>`; + } else { + r += `Weak${V.summaryStats? `[${slave.muscles}]`: ''}.`; + } + } else if (slave.muscles > -96) { + if (V.arcologies[0].FSPhysicalIdealist === "unset") { + r += `<span class="red">Very weak${V.summaryStats? `[${slave.muscles}]`: ''}.</span>`; + } else { + r += `Very weak${V.summaryStats? `[${slave.muscles}]`: ''}.`; + } + } else { + r += `<span class="red">Frail${V.summaryStats? `[${slave.muscles}]`: ''}.</span>`; } + r += " "; } - - class ButtSurgeryList extends List { - constructor() { - const items = [ - ["no default setting"], - ["removed", 0], - ["slim", 2], - ["stacked", 4], - ["huge", 6], - ["maximised", 9], - ]; - super("Buttock implants", items); - this.setValue(current_rule.set.surgery_butt); - this.onchange = (value) => current_rule.set.surgery_butt = value; + + function long_limbs(slave) { + if (slave.amp !== 0) { + if (slave.amp === -1) { + r += `Prosthetic limbs.`; + } else if (slave.amp === -2) { + r += `Sexy prosthetic limbs.`; + } else if (slave.amp === -3) { + r += `Beautiful prosthetic limbs.`; + } else if (slave.amp === -4) { + r += `Deadly prosthetic limbs.`; + } else if (slave.amp === -5) { + r += `Cyber prosthetic limbs.`; + } else { + r += `Amputee.`; + } } - } - - class BreastSurgeryList extends List { - constructor() { - const items = [ - ["no default setting"], - ["removed", 0], - ["slim", 400], - ["stacked", 1000], - ["huge", 2000], - ["barely functional", 9000], - ["maximised", 48000] - ]; - super("Breast implants", items); - this.setValue(current_rule.set.surgery_boobs); - this.onchange = (value) => current_rule.set.surgery_boobs = value; + r += " "; + if (!canWalk(slave)) { + r += `Immobile. `; + } + if (slave.heels === 1) { + r += `Heeled. `; } + r += `</span> `; } - - class TighteningSurgeryList extends List { - constructor() { - const items = [ - ["no default setting"], - ["tightening", 1], - ["virginity restoration", 2], - ]; - super("Orifice Tightening", items); - this.setValue(current_rule.set.surgery_holes); - this.onchange = (value) => current_rule.set.surgery_holes = value; + + function long_voice(slave) { + if (slave.voice === 0) { + r += `<span class="pink">Mute.</span>`; + } else { + if (slave.accent === 3) { + r += `<span class="red">Bad accent.</span>`; + } else if (slave.accent === 4) { + r += `<span class="red">No language skills.</span>`; + } else if (slave.accent === 2) { + r += `Accent.`; + } else if (slave.accent === 1) { + r += `<span class="pink">Cute accent.</span>`; + } } + r += " "; } - - class BodyHairSurgeryList extends List { - constructor() { - const items = [ - ["no default setting"], - ["keep", 1], - ["removal", 2], - ]; - super("Body Hair", items); - this.setValue(current_rule.set.surgery_bodyhair); - this.onchange = (value) => current_rule.set.surgery_bodyhair = value; + + function long_tits_ass(slave) { + r += `<span class="pink">`; + if ((slave.boobs >= 12000) && (slave.butt > 9)) { + r += `Hyper T&A.`; + } else if ((slave.boobs > 4000) && (slave.butt > 8)) { + r += `Enormous T&A.`; + } else if ((slave.boobs > 2000) && (slave.butt > 6)) { + r += `Huge T&A.`; + } else if ((slave.boobs > 800) && (slave.butt > 4)) { + r += `Big T&A.`; + } else if ((slave.boobs < 500) && (slave.butt < 3) && (slave.weight <= 10) && (slave.muscles <= 30)) { + r += `Girlish figure.`; + } else if (slave.boobs >= 12000) { + r += `Immobilizing tits.`; + } else if (slave.boobs > 4000) { + r += `Monstrous tits.`; + } else if (slave.boobs > 2000) { + r += `Huge tits.`; + } else if (slave.boobs > 800) { + r += `Big tits.`; + } else if (slave.butt > 9) { + r += `Hyper ass.`; + } else if (slave.butt > 8) { + r += `Titanic ass.`; + } else if (slave.butt > 6) { + r += `Huge ass.`; + } else if (slave.butt > 4) { + r += `Big ass.`; } + r += `</span> `; } - - class HairSurgeryList extends List { - constructor() { - const items = [ - ["no default setting"], - ["keep", 1], - ["removal", 2], - ]; - super("Hair", items); - this.setValue(current_rule.set.surgery_hair); - this.onchange = (value) => current_rule.set.surgery_hair = value; + + function long_hips(slave) { + r += `<span class="red">`; + if (slave.hips < -1) { + if (slave.butt > 2 && (V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { + r += `Disproportionately big butt.`; + } + } else if (slave.hips < 0) { + if (slave.butt > 4 && (V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { + r += `Disproportionately big butt.`; + } + } else if (slave.hips > 2) { + if (slave.butt <= 8) { + r += `Disproportionately small butt.`; + } + } else if (slave.hips > 1) { + if (slave.butt <= 3 && ((V.arcologies[0].FSSlimnessEnthusiast === "unset") || (slave.boobs >= 500))) { + r += `Disproportionately small butt.`; + } + } else if (slave.hips > 0) { + if (slave.butt > 8) { + if ((V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { + r += `Disproportionately big butt.`; + } + } else if (slave.butt <= 2 && ((V.arcologies[0].FSSlimnessEnthusiast === "unset") || (slave.boobs >= 500))) { + r += `Disproportionately small butt.`; + } + } else { + if (slave.butt > 6) { + if ((V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { + r += `Disproportionately big butt.`; + } + } else if (slave.butt <= 1 && ((V.arcologies[0].FSSlimnessEnthusiast === "unset") || (slave.boobs >= 500))) { + r += `Disproportionately small butt.`; + } } + r += `</span> `; } - - class AutomaticAssignmentList extends List { - constructor() { - const items = [ - ["No default setting", "no default setting"], - ["Rest", "rest"], - ["Fucktoy", "please you"], - ["Subordinate Slave", "be a subordinate slave"], - ["House Servant", "be a servant"], - ["Confined", "stay confined"], - ["Whore", "whore"], - ["Public Servant", "serve the public"], - ["Classes", "take classes"], - ["Milked", "get milked"], - ["Gloryhole", "work a glory hole"] - ]; - - if (V.HGSuite > 0) items.push(["Head Girl Suite", "live with your Head Girl"]); - if (V.brothel > 0) items.push(["Brothel", "work in the brothel"]); - if (V.club > 0) items.push(["Club", "serve in the club"]); - if (V.arcade > 0) items.push(["Arcade", "be confined in the arcade"]); - if (V.dairy > 0) items.push(["Dairy", "work in the dairy"]); - if (V.servantsQuarters > 0) items.push(["Servant Quarters", "work as a servant"]); - if (V.masterSuite > 0) items.push(["Master Suite", "serve in the master suite"]); - if (V.schoolroom > 0) items.push(["Schoolroom", "learn in the schoolroom"]); - if (V.spa > 0) items.push(["Spa", "rest in the spa"]); - if (V.clinic > 0) items.push(["Clinic", "get treatment in the clinic"]); - if (V.cellblock > 0) items.push(["Cellblock", "be confined in the cellblock"]); - - super("Automatically set assignment", items); - this.setValue(current_rule.set.setAssignment); - this.onchange = (value) => current_rule.set.setAssignment = value; + + function long_waist(slave) { + if (slave.waist > 95) { + r += `<span class="red">Masculine waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; + } else if (slave.waist > 40) { + r += `<span class="red">Ugly waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; + } else if (slave.waist > 10) { + r += `<span class="red">Unattractive waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; + } else if (slave.waist >= -10) { + r += `Average waist${V.summaryStats? `[${slave.waist}]`: ''}.`; + } else if (slave.waist >= -40) { + r += `<span class="pink">Feminine waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; + } else if (slave.waist >= -95) { + r += `<span class="pink">Hourglass waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; + } else { + r += `<span class="pink">Absurdly narrow waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; } + r += " "; } - - class BellyImplantList extends List { - constructor() { - const items = [ - ["no default setting"], - ["install", "install"], - ["remove", "remove"], - ]; - super("Belly implant", items); - this.setValue(current_rule.set.surgery_bellyImplant); - this.onchange = (value) => current_rule.set.surgery_bellyImplant = value; + + function long_implants(slave) { + r += `<span class="pink">`; + if ((slave.boobsImplant !== 0) || (slave.buttImplant !== 0) || (slave.lipsImplant !== 0) || (slave.bellyImplant !== -1)) { + r += `Implants.`; + } else if ((slave.faceImplant >= 30) || (slave.waist < -95)) { + r += `Surgery enhanced.`; + } else { + r += `All natural.`; } + r += " "; } - return rulesAssistantOptions; -})(); - -/*:: rules autosurgery js [script]*/ - -window.rulesAutosurgery = (function() { - "use strict"; - let V; - let r; - return rulesAutoSurgery; - - function rulesAutoSurgery(slave) { - V = State.variables; - r = ""; - const surgeries = []; - const thisSurgery = ProcessHGTastes(slave); - if (slave.health > 20) - CommitSurgery(slave, thisSurgery, surgeries); - if (surgeries.length > 0) - PrintResult(slave, thisSurgery, surgeries); - return r; + function long_lactation(slave) { + if (slave.lactation === 1) { + r += `Lactating naturally.`; + } else if (slave.lactation === 2) { + r += `Heavy lactation.`; + } + r += " "; } - function autoSurgerySelector(slave, ruleset) { - const surgery = {}; - ruleset.forEach(rule => { - Object.keys(rule) - .filter(key => key.startsWith("surgery_") && rule[key] !== "no default setting") - .forEach(key => { - surgery[key] = rule[key]; - }); - }); - return surgery; + function long_mods(slave) { + modScore(slave); + if (slave.corsetPiercing === 0 && V.piercingScore < 3 && V.tatScore < 2) { + return; + } else if (V.modScore > 15 || (V.piercingScore > 8 && V.tatScore > 5)) { + r += `Extensive body mods.`; + } else if (V.modScore > 7) { + r += `Noticeable body mods.`; + } else { + r += `Light body mods.`; + } + r += " "; } - - function ProcessHGTastes(slave) { - let thisSurgery; - switch (V.HGTastes) { - case 1: - thisSurgery = { - surgery_lactation: 0, - surgery_cosmetic: 1, - surgery_faceShape: "cute", - surgery_lips: 10, - surgery_hips: 0, - surgery_hipsImplant: 0, - surgery_butt: 0, - surgery_accent: 0, - surgery_shoulders: 0, - surgery_shouldersImplant: 0, - surgery_boobs: 0, - surgery_holes: 0 - }; - break ; - case 2: - thisSurgery = { - surgery_lactation: 0, - surgery_cosmetic: 1, - surgery_faceShape: "cute", - surgery_lips: 60, - surgery_hips: 0, - surgery_hipsImplant: 0, - surgery_butt: 4, - surgery_accent: 0, - surgery_shoulders: 0, - surgery_shouldersImplant: 0, - surgery_boobs: 1200, - surgery_holes: 0 - }; - break; - case 3: - thisSurgery = { - surgery_lactation: 0, - surgery_cosmetic: 1, - surgery_faceShape: "cute", - surgery_lips: 95, - surgery_hips: 0, - surgery_hipsImplant: 0, - surgery_butt: 8, - surgery_accent: 0, - surgery_shoulders: 0, - surgery_shouldersImplant: 0, - surgery_boobs: 10000, - surgery_holes: 2 - }; - break; - case 4: - thisSurgery = { - surgery_lactation: 1, - surgery_cosmetic: 1, - surgery_faceShape: "cute", - surgery_lips: 10, - surgery_hips: 3, - surgery_hipsImplant: 0, - surgery_butt: 0, - surgery_accent: 0, - surgery_shoulders: 0, - surgery_shouldersImplant: 0, - surgery_boobs: 0, - surgery_holes: 0 - }; - break; - default: - thisSurgery = autoSurgerySelector( - slave, - 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 (slave.hips < -1) { - if (thisSurgery.surgery_butt > 2) - thisSurgery.surgery_butt = 2; - } else if (slave.hips < 0) { - if (thisSurgery.surgery_butt > 4) - thisSurgery.surgery_butt = 4; - } else if (slave.hips > 0) { - if (thisSurgery.surgery_butt > 8) - thisSurgery.surgery_butt = 8; - } else if (slave.hips > 1) { - true; - } else { - if (thisSurgery.surgery_butt > 6) - thisSurgery.surgery_butt = 6; + + function short_intelligence(slave) { + if (slave.fetish === "mindbroken") { + return; + } else if (slave.intelligenceImplant === 1) { + switch (slave.intelligence) { + case 3: + r += `<span class="deepskyblue">I+++(e)</span>`; + break; + case 2: + r += `<span class="deepskyblue">I++(e)</span>`; + break; + case 1: + r += `<span class="deepskyblue">I+(e)</span>`; + break; + case -1: + r += `<span class="orangered">I-(e)</span>`; + break; + case -2: + r += `<span class="orangered">I--(e)</span>`; + break; + case -3: + r += `<span class="orangered">I---(e)</span>`; + break; + default: + r += `I(e)`; + break; + } + } else { + switch (slave.intelligence) { + case 3: + r += `<span class="deepskyblue">I+++</span>`; + break; + case 2: + r += `<span class="deepskyblue">I++</span>`; + break; + case 1: + r += `<span class="deepskyblue">I+</span>`; + break; + case -1: + r += `<span class="orangered">I-</span>`; + break; + case -2: + r += `<span class="orangered">I--</span>`; + break; + case -3: + r += `<span class="orangered">I---</span>`; + break; + default: + r += `I`; + break; + } + } + r += " "; + } + + function short_sex_skills(slave) { + let _SSkills = slave.analSkill + slave.oralSkill; + r += `<span class="aquamarine">`; + if (((_SSkills + slave.whoreSkill + slave.entertainSkill) >= 400) && ((slave.vagina < 0) || (slave.vaginalSkill >= 100))) { + r += `MSS`; + } else { + _SSkills += slave.vaginalSkill; + _SSkills = Math.trunc(_SSkills); + if (_SSkills > 180) { + r += `S++`; + } else if ((_SSkills > 120) && (slave.vagina < 0)) { + r += `Sh++`; + } else if (_SSkills > 90) { + r += `S+`; + } else if (_SSkills > 30) { + r += `S`; + } else { + r += `S-`; + } + if (V.summaryStats) { + r += `[${_SSkills}] `; + } + r += " "; + if (slave.whoreSkill >= 100) { + r += `W+++`; + } else if (slave.whoreSkill > 60) { + r += `W++`; + } else if (slave.whoreSkill > 30) { + r += `W+`; + } else if (slave.whoreSkill > 10) { + r += `W`; + } + if (slave.whoreSkill > 10) { + if (V.summaryStats) { + r += `[${slave.whoreSkill}] `; + } + } + r += " "; + if (slave.entertainSkill >= 100) { + r += `E+++`; + } else if (slave.entertainSkill > 60) { + r += `E++`; + } else if (slave.entertainSkill > 30) { + r += `E+`; + } else if (slave.entertainSkill > 10) { + r += `E`; + } + if (slave.entertainSkill > 10) { + if (V.summaryStats) { + r += `[${slave.entertainSkill}] `; } } - break; } - return thisSurgery; + r += " "; } - - function CommitSurgery(slave, thisSurgery, surgeries) { - if ((slave.eyes == -1) && (thisSurgery.surgery_eyes == 1)) { - surgeries.push("surgery to correct her vision"); - slave.eyes = 1; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.eyes == 1) && (thisSurgery.surgery_eyes == -1)) { - surgeries.push("surgery to blur her vision"); - slave.eyes = -1; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.lactation == 2) && (thisSurgery.surgery_lactation == 0)) { - surgeries.push("surgery to remove her lactation implants"); - slave.lactation = 0; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if (slave.lactation != 2 && (thisSurgery.surgery_lactation == 1)) { - surgeries.push("lactation inducing implanted drugs"); - slave.lactation = 2; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.prostate == 2) && (thisSurgery.surgery_prostate == 0)) { - surgeries.push("surgery to remove her prostate implant"); - slave.prostate = 0; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if (slave.prostate == 1 && (thisSurgery.surgery_prostate == 1)) { - surgeries.push("a precum production enhancing drug implant"); - slave.prostate = 2; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.anus > 3) && (thisSurgery.surgery_cosmetic > 0)) { - surgeries.push("a restored anus"); - slave.anus = 3; - if (slave.analSkill > 10) - slave.analSkill -= 10; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.vagina > 3) && (thisSurgery.surgery_cosmetic > 0)) { - surgeries.push("a restored pussy"); - slave.vagina = 3; - if (slave.vaginalSkill > 10) - slave.vaginalSkill -= 10; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else 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); - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } 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; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } 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"; - V.cash -= V.surgeryCost; - - } else if ((slave.bald == 0 || slave.hStyle != "bald") && (thisSurgery.surgery_hair == 2)) { - surgeries.push("hair removal"); - slave.hStyle = "bald"; - slave.bald = 1; - V.cash -= V.surgeryCost; - - } else if ((slave.weight >= 10) && (thisSurgery.surgery_cosmetic > 0)) { - surgeries.push("liposuction"); - slave.weight -= 50; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.voice == 1) && (slave.voiceImplant == 0) && (thisSurgery.surgery_cosmetic > 0)) { - surgeries.push("a feminine voice"); - slave.voice += 1; - slave.voiceImplant += 1; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.waist >= -10) && (thisSurgery.surgery_cosmetic > 0)) { - surgeries.push("a narrower waist"); - slave.waist -= 20; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if (((slave.boobShape == "saggy") || (slave.boobShape == "downward-facing")) && (thisSurgery.surgery_cosmetic > 0) && (slave.breastMesh != 1)) { - surgeries.push("a breast lift"); - slave.boobShape = "normal"; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } 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"); - V.cash -= V.surgeryCost; - 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.oralSkill > 10) - slave.oralSkill -= 10; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.lips <= 95) && (slave.lips < thisSurgery.surgery_lips)) { - if (thisSurgery.surgery_lips !== "no default setting") { - surgeries.push("bigger lips"); - slave.lipsImplant += 10; - slave.lips += 10; - if (slave.oralSkill > 10) - slave.oralSkill -= 10; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; + + function short_prestige(slave) { + if (slave.prestige > 0) { + r += `<span class="green">`; + if (slave.prestige > 2) { + r += `Prest++`; + } else if (slave.prestige === 2) { + r += `Prest+`; + } else if (slave.prestige === 1) { + r += `Prest`; } - - } 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); - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.hips < 1) && (slave.hips < thisSurgery.surgery_hips) && (V.surgeryUpgrade == 1)) { - surgeries.push("wider hips"); - slave.hips++; - slave.hipsImplant++; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } 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; + r += `</span> `; + } + } + + function long_intelligence(slave) { + if (slave.fetish === "mindbroken") { + return; + } else if (slave.intelligenceImplant === 1) { + switch (slave.intelligence) { + case 3: + r += `<span class="deepskyblue">Brilliant, educated.</span>`; + break; + case 2: + r += `<span class="deepskyblue">Very smart, educated.</span>`; + break; + case 1: + r += `<span class="deepskyblue">Smart, educated.</span>`; + break; + case -1: + r += `<span class="orangered">Slow, educated.</span>`; + break; + case -2: + r += `<span class="orangered">Very slow, educated.</span>`; + break; + case -3: + r += `<span class="orangered">Moronic, educated.</span>`; + break; + default: + r += `Average intelligence, educated.`; + break; + } + } else { + switch (slave.intelligence) { + case 3: + r += `<span class="deepskyblue">Brilliant.</span>`; + break; + case 2: + r += `<span class="deepskyblue">Very smart.</span>`; + break; + case 1: + r += `<span class="deepskyblue">Smart.</span>`; + break; + case -1: + r += `<span class="orangered">Slow.</span>`; + break; + case -2: + r += `<span class="orangered">Very slow.</span>`; + break; + case -3: + r += `<span class="orangered">Moronic.</span>`; + break; + default: + r += `Average intelligence.`; + break; } - slave.faceImplant += 25-5*Math.trunc(V.PC.medicine/50)-5*V.surgeryUpgrade; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.waist >= -95) && (thisSurgery.surgery_cosmetic == 2) && (V.seeExtreme == 1)) { - surgeries.push("a narrower waist"); - slave.waist = Math.clamp(slave.waist-20,-100,100); - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.voice < 3) && (slave.voiceImplant == 0) && (thisSurgery.surgery_cosmetic == 2)) { - surgeries.push("a bimbo's voice"); - slave.voice += 1; - slave.voiceImplant += 1; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else 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; - V.cash -= V.surgeryCost; - 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; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - } else if ((slave.butt <= 3) && (slave.butt < thisSurgery.surgery_butt)) { - if (thisSurgery.surgery_butt !== "no default setting") { - surgeries.push("a bigger butt"); - slave.buttImplant = 1; - slave.butt += 1; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; + } + r += " "; + } + + function long_sex_skills(slave) { + let _SSkills = (slave.analSkill + slave.oralSkill); + r += `<span class="aquamarine">`; + if (((_SSkills + slave.whoreSkill + slave.entertainSkill) >= 400) && ((slave.vagina < 0) || (slave.vaginalSkill >= 100))) { + r += `Masterful Sex Slave. `; + } else { + _SSkills += slave.vaginalSkill; + if (_SSkills > 180) { + r += `Sex master${V.summaryStats? `[${Math.trunc(_SSkills)}]`: ''}.`; + } else if ((_SSkills > 120) && (slave.vagina < 0)) { + r += `Masterful shemale${V.summaryStats? `[${Math.trunc(_SSkills)}]`: ''}.`; + } else if (_SSkills > 90) { + r += `Sexual expert${V.summaryStats? `[${Math.trunc(_SSkills)}]`: ''}.`; + } else if (_SSkills > 30) { + r += `Sexually skilled${V.summaryStats? `[${Math.trunc(_SSkills)}]` : ''}.`; + } else { + r += `Sexually unskilled${V.summaryStats? `[${Math.trunc(_SSkills)}]` : ''}.`; } - } else if ((slave.boobs <= 600) && (slave.lactation < 2) && (slave.boobs+400 <= thisSurgery.surgery_boobs)) { - if (thisSurgery.surgery_boobs !== "no default setting") { - surgeries.push("bigger boobs"); - slave.boobsImplant += 400; - slave.boobs += 400; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; + r += " "; + if (slave.whoreSkill >= 100) { + r += `Masterful whore${V.summaryStats? `[${slave.whoreSkill}]`: ''}.`; + } else if (slave.whoreSkill >= 60) { + r += `Expert whore${V.summaryStats? `[${slave.whoreSkill}]`: ''}.`; + } else if (slave.whoreSkill >= 30) { + r += `Skilled whore${V.summaryStats? `[${slave.whoreSkill}]`: ''}.`; + } else if (slave.whoreSkill >= 10) { + r += `Basic whore${V.summaryStats? `[${slave.whoreSkill}]`: ''}.`; } - } else if ((slave.boobs <= 600) && (slave.lactation < 2) && (slave.boobs+200 <= thisSurgery.surgery_boobs)) { - if (thisSurgery.surgery_boobs !== "no default setting") { - surgeries.push("modestly bigger boobs"); - slave.boobsImplant += 200; - slave.boobs += 200; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; + r += " "; + if (slave.entertainSkill >= 100) { + r += `Masterful entertainer${V.summaryStats? `[${slave.entertainSkill}]`: ''}.`; + } else if (slave.entertainSkill >= 60) { + r += `Expert entertainer${V.summaryStats? `[${slave.entertainSkill}]`: ''}.`; + } else if (slave.entertainSkill >= 30) { + r += `Skilled entertainer${V.summaryStats? `[${slave.entertainSkill}]`: ''}.`; + } else if (slave.entertainSkill >= 10) { + r += `Basic entertainer${V.summaryStats? `[${slave.entertainSkill}]`: ''}.`; } - - } else if ((slave.butt <= 5) && (slave.butt < thisSurgery.surgery_butt)) { - if (thisSurgery.surgery_butt !== "no default setting") { - surgeries.push("a bigger butt"); - slave.buttImplant = 1; - slave.butt += 1; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; + r += " "; + } + } + + function long_prestige(slave) { + if (slave.prestige > 0) { + r += `<span class="green">`; + if (slave.prestige > 2) { + r += `Extremely prestigious.`; + } else if (slave.prestige === 2) { + r += `Very prestigious.`; + } else if (slave.prestige === 1) { + r += `Prestigious.`; } - - } else if ((slave.boobs <= 2000) && (slave.lactation < 2) && (slave.boobs+400 < thisSurgery.surgery_boobs)) { - if (thisSurgery.surgery_boobs !== "no default setting") { - surgeries.push("bigger boobs"); - slave.boobsImplant += 400; - slave.boobs += 400; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; + r += `</span> `; + } + } + + function short_fetish(slave) { + r += `<span class="lightcoral">`; + switch (slave.fetish) { + case "submissive": + if (slave.fetishStrength > 95) { + r += `Sub++`; + } else if (slave.fetishStrength > 60) { + r += `Sub+`; + } else { + r += `Sub`; + } + break; + case "cumslut": + if (slave.fetishStrength > 95) { + r += `Oral++`; + } else if (slave.fetishStrength > 60) { + r += `Oral+`; + } else { + r += `Oral`; + } + break; + case "humiliation": + if (slave.fetishStrength > 95) { + r += `Humil++`; + } else if (slave.fetishStrength > 60) { + r += `Humil+`; + } else { + r += `Humil`; + } + break; + case "buttslut": + if (slave.fetishStrength > 95) { + r += `Anal++`; + } else if (slave.fetishStrength > 60) { + r += `Anal+`; + } else { + r += `Anal`; + } + break; + case "boobs": + if (slave.fetishStrength > 95) { + r += `Boobs++`; + } else if (slave.fetishStrength > 60) { + r += `Boobs+`; + } else { + r += `Boobs`; + } + break; + case "sadist": + if (slave.fetishStrength > 95) { + r += `Sadist++`; + } else if (slave.fetishStrength > 60) { + r += `Sadist+`; + } else { + r += `Sadist`; + } + break; + case "masochist": + if (slave.fetishStrength > 95) { + r += `Pain++`; + } else if (slave.fetishStrength > 60) { + r += `Pain+`; + } else { + r += `Pain`; + } + break; + case "dom": + if (slave.fetishStrength > 95) { + r += `Dom++`; + } else if (slave.fetishStrength > 60) { + r += `Dom+`; + } else { + r += `Dom`; + } + break; + case "pregnancy": + if (slave.fetishStrength > 95) { + r += `Preg++`; + } else if (slave.fetishStrength > 60) { + r += `Preg+`; + } else { + r += `Preg`; + } + break; + default: + r += `Vanilla`; + break; + } + if (V.summaryStats) { + r += `[${slave.fetishStrength}]`; + } + r += `</span> `; + } + + function short_attraction(slave) { + if (slave.attrXY <= 5) { + r += `<span class="red">XY---${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; + } else if (slave.attrXY <= 15) { + r += `<span class="red">XY--${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; + } else if (slave.attrXY <= 35) { + r += `<span class="red">XY-${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; + } else if (slave.attrXY <= 65) { + r += `XY${V.summaryStats? `[${slave.attrXY}]`: ''}`; + } else if (slave.attrXY <= 85) { + r += `<span class="green">XY+${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; + } else if (slave.attrXY <= 95) { + r += `<span class="green">XY++${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; + } else if (slave.attrXX > 95) { + if (slave.energy <= 95) { + r += `<span class="green">Omni!</span>`; + } else { + r += `<span class="green">Omni+Nympho!!</span>`; } - - } else if ((slave.anus > 0) && (V.surgeryUpgrade == 1) && (thisSurgery.surgery_holes == 2)) { - surgeries.push("a virgin anus"); - slave.anus = 0; - if (slave.analSkill > 10) { - slave.analSkill -= 10; + } else { + r += `<span class="green">XY+++${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; + } + r += " "; + if (slave.attrXX <= 5) { + r += `<span class="red">XX---${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; + } else if (slave.attrXX <= 15) { + r += `<span class="red">XX--${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; + } else if (slave.attrXX <= 35) { + r += `<span class="red">XX-${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; + } else if (slave.attrXX <= 65) { + r += `XX${V.summaryStats? `[${slave.attrXX}]`: ''}`; + } else if (slave.attrXX <= 85) { + r += `<span class="green">XX+${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; + } else if (slave.attrXX <= 95) { + r += `<span class="green">XX++${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; + } else if (slave.attrXY <= 95) { + r += `<span class="green">XX+++${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; + } + r += " "; + if (slave.energy > 95) { + if ((slave.attrXY <= 95) || (slave.attrXX <= 95)) { + r += `<span class="green">Nympho!</span>`; } - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.vagina > 0) && (V.surgeryUpgrade == 1) && (thisSurgery.surgery_holes == 2)) { - surgeries.push("a virgin pussy"); - slave.vagina = 0; - if (slave.vaginalSkill > 10) - slave.vaginalSkill -= 10; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.hips < 2) && (slave.hips < thisSurgery.surgery_hips) && (V.surgeryUpgrade == 1)) { - surgeries.push("wider hips"); - slave.hips++; - slave.hipsImplant++; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.anus > 1) && (thisSurgery.surgery_holes == 1)) { - surgeries.push("a tighter anus"); - slave.anus = 1; - if (slave.analSkill > 10) { - slave.analSkill -= 10; + } else if (slave.energy > 80) { + r += `<span class="green">SD++${V.summaryStats? `[${slave.energy}]`: ''}</span>`; + } else if (slave.energy > 60) { + r += `<span class="green">SD+${V.summaryStats? `[${slave.energy}]`: ''}</span>`; + } else if (slave.energy > 40) { + r += `<span class="yellow">SD${V.summaryStats? `[${slave.energy}]`: ''}</span>`; + } else if (slave.energy > 20) { + r += `<span class="red">SD-${V.summaryStats? `[${slave.energy}]`: ''}</span>`; + } else { + r += `<span class="red">SD--${V.summaryStats? `[${slave.energy}]`: ''}</span>`; + } + r += " "; + } + + function short_smart_fetish(slave) { + if (slave.fetishKnown === 1) { + if (slave.clitSetting === "off") { + r += `SP-`; + } else if (((slave.fetish !== "submissive") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "submissive")) { + r += `SP:sub`; + } else if (((slave.fetish !== "cumslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "oral")) { + r += `SP:oral`; + } else if (((slave.fetish !== "humiliation") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "humiliation")) { + r += `SP:humil`; + } else if (((slave.fetish !== "buttslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "anal")) { + r += `SP:anal`; + } else if (((slave.fetish !== "boobs") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "boobs")) { + r += `SP:boobs`; + } else if (((slave.fetish !== "sadist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "sadist")) { + r += `SP:sade`; + } else if (((slave.fetish !== "masochist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "masochist")) { + r += `SP:pain`; + } else if (((slave.fetish !== "dom") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "dom")) { + r += `SP:dom`; + } else if (((slave.fetish !== "pregnancy") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "pregnancy")) { + r += `SP:preg`; + } else if (((slave.fetish !== "none") && (slave.clitSetting === "vanilla"))) { + r += `SP:vanilla`; + } else if ((slave.energy <= 95) && (slave.clitSetting === "all")) { + r += `SP:all`; + } else if ((slave.energy > 5) && (slave.clitSetting === "none")) { + r += `SP:none`; + } else if (!["women", "men", "anti-women", "anti-men"].includes(slave.clitSetting)) { + r += `SP:monitoring`; } - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.vagina > 1) && (thisSurgery.surgery_holes == 1)) { - surgeries.push("a tighter pussy"); - slave.vagina = 1; - if (slave.vaginalSkill > 10) { - slave.vaginalSkill -= 10; + } else { + switch (slave.clitSetting) { + case "off": + r += `SP-`; + break; + case "submissive": + r += `SP:sub`; + break; + case "lesbian": + r += `SP:les`; + break; + case "oral": + r += `SP:oral`; + break; + case "humiliation": + r += `SP:humil`; + break; + case "anal": + r += `SP:anal`; + break; + case "boobs": + r += `SP:boobs`; + break; + case "sadist": + r += `SP:sade`; + break; + case "masochist": + r += `SP:pain`; + break; + case "dom": + r += `SP:dom`; + break; + case "pregnancy": + r += `SP:pregnancy`; + break; + case "vanilla": + r += `SP:vanilla`; + break; + case "all": + r += `SP:all`; + break; + case "none": + r += `SP:none`; + break; } - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if ((slave.butt <= 8) && (slave.butt < thisSurgery.surgery_butt)) { - if (thisSurgery.surgery_butt !== "no default setting") { - surgeries.push("a bigger butt"); - slave.buttImplant = 1; - slave.butt += 1; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; + } + r += " "; + } + + function short_smart_attraction(slave) { + if (slave.attrKnown === 1) { + if (slave.clitSetting === "women") { + if (slave.attrXX < 95) { + r += `SP:women`; + } else { + r += `SP:monitoring`; + } + } else if (slave.clitSetting === "men") { + if (slave.attrXY < 95) { + r += `SP:men`; + } else { + r += `SP:monitoring`; + } + } else if (slave.clitSetting === "anti-women") { + if (slave.attrXX > 0) { + r += `SP:anti-women`; + } else { + r += `SP:monitoring`; + } + } else if (slave.clitSetting === "anti-men") { + if (slave.attrXY > 0) { + r += `SP:anti-men`; + } else { + r += `SP:monitoring`; + } } - - } else if ((slave.boobs <= 9000) && (slave.lactation < 2) && (slave.boobs < thisSurgery.surgery_boobs)) { - if (thisSurgery.surgery_boobs !== "no default setting") { - surgeries.push("bigger boobs"); - slave.boobsImplant += 200; - slave.boobs += 200; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; + } else { + if (slave.clitSetting === "women") { + r += `SP:women`; + } else if (slave.clitSetting === "men") { + r += `SP:men`; + } else if (slave.clitSetting === "anti-women") { + r += `SP:anti-women`; + } else if (slave.clitSetting === "anti-men") { + r += `SP:anti-men`; } - - } else if ((slave.hips < 3) && (slave.hips < thisSurgery.surgery_hips) && (V.surgeryUpgrade == 1)) { - surgeries.push("wider hips"); - slave.hips++; - slave.hipsImplant++; - V.cash -= V.surgeryCost; - if (V.PC.medicine >= 100) slave.health -= 5; - else slave.health -= 10; - - } else if (slave.bellyImplant < 0 && V.bellyImplants > 0 && thisSurgery.surgery_bellyImplant == "install" && slave.womb.length == 0 && slave.broodmother == 0) { - slave.bellyImplant = 100; - slave.preg = -2; - V.cash -= V.surgeryCost; - 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; + } + r += " "; + } + + function short_behavior_flaw(slave) { + r += `<span class="red">`; + switch (slave.behavioralFlaw) { + case "arrogant": + r += `Arrog`; + break; + case "bitchy": + r += `Bitchy`; + break; + case "odd": + r += `Odd`; + break; + case "hates men": + r += `Men-`; + break; + case "hates women": + r += `Women-`; + break; + case "gluttonous": + r += `Glut`; + break; + case "anorexic": + r += `Ano`; + break; + case "devout": + r += `Dev`; + break; + case "liberated": + r += `Lib`; + break; + default: + slave.behavioralFlaw = "none"; + break; + } + r += `</span> `; + } + + function short_sex_flaw(slave) { + switch (slave.sexualFlaw) { + case "hates oral": + r += `<span class="red">Oral-</span>`; + break; + case "hates anal": + r += `<span class="red">Anal-</span>`; + break; + case "hates penetration": + r += `<span class="red">Fuck-</span>`; + break; + case "shamefast": + r += `<span class="red">Shame</span>`; + break; + case "idealistic": + r += `<span class="red">Ideal</span>`; + break; + case "repressed": + r += `<span class="red">Repre</span>`; + break; + case "apathetic": + r += `<span class="red">Apath</span>`; + break; + case "crude": + r += `<span class="red">Crude</span>`; + break; + case "judgemental": + r += `<span class="red">Judge</span>`; + break; + case "cum addict": + r += `<span class="yellow">CumAdd</span>`; + break; + case "anal addict": + r += `<span class="yellow">AnalAdd</span>`; + break; + case "attention whore": + r += `<span class="yellow">Attention</span>`; + break; + case "breast growth": + r += `<span class="yellow">BoobObsess</span>`; + break; + case "abusive": + r += `<span class="yellow">Abusive</span>`; + break; + case "malicious": + r += `<span class="yellow">Malice</span>`; + break; + case "self hating": + r += `<span class="yellow">SelfHatr</span>`; + break; + case "neglectful": + r += `<span class="yellow">SelfNeglect</span>`; + break; + case "breeder": + r += `<span class="yellow">BreedObsess</span>`; + break; + default: + slave.sexualFlaw = "none"; + break; + } + r += " "; + } + + function short_behavior_quirk(slave) { + r += `<span class="green">`; + switch (slave.behavioralQuirk) { + case "confident": + r += `Confid`; + break; + case "cutting": + r += `Cutting`; + break; + case "funny": + r += `Funny`; + break; + case "fitness": + r += `Fit`; + break; + case "adores women": + r += `Women+`; + break; + case "adores men": + r += `Men+`; + break; + case "insecure": + r += `Insec`; + break; + case "sinful": + r += `Sinf`; + break; + case "advocate": + r += `Advoc`; + break; + default: + slave.behavioralQuirk = "none"; + break; + } + r += " "; + } + + function short_sex_quirk(slave) { + switch (slave.sexualQuirk) { + case "gagfuck queen": + r += `Gagfuck`; + break; + case "painal queen": + r += `Painal`; + break; + case "strugglefuck queen": + r += `Struggle`; + break; + case "tease": + r += `Tease`; + break; + case "romantic": + r += `Romantic`; + break; + case "perverted": + r += `Perverted`; + break; + case "caring": + r += `Caring`; + break; + case "unflinching": + r += `Unflinch`; + break; + case "size queen": + r += `SizeQ`; + break; + default: + slave.sexualQuirk = "none"; + break; + } + r += `</span> `; + } + + function long_fetish(slave) { + r += `<span class="lightcoral">`; + switch (slave.fetish) { + case "submissive": + if (slave.fetishStrength > 95) { + r += `Complete submissive${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else if (slave.fetishStrength > 60) { + r += `Submissive${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else { + r += `Submissive tendencies${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } + break; + case "cumslut": + if (slave.fetishStrength > 95) { + r += `Cumslut${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else if (slave.fetishStrength > 60) { + r += `Oral fixation${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else { + r += `Prefers oral${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } + break; + case "humiliation": + if (slave.fetishStrength > 95) { + r += `Humiliation slut${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else if (slave.fetishStrength > 60) { + r += `Exhibitionist${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else { + r += `Interest in humiliation${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } + break; + case "buttslut": + if (slave.fetishStrength > 95) { + r += `Buttslut${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else if (slave.fetishStrength > 60) { + r += `Anal fixation${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else { + r += `Prefers anal${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } + break; + case "boobs": + if (slave.fetishStrength > 95) { + r += `Boobslut${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else if (slave.fetishStrength > 60) { + r += `Breast fixation${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else { + r += `Loves boobs${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } + break; + case "sadist": + if (slave.fetishStrength > 95) { + r += `Complete sadist${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else if (slave.fetishStrength > 60) { + r += `Sadist${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else { + r += `Sadistic tendencies${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } + break; + case "masochist": + if (slave.fetishStrength > 95) { + r += `Complete masochist${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else if (slave.fetishStrength > 60) { + r += `Masochist${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else { + r += `Masochistic tendencies${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } + break; + case "dom": + if (slave.fetishStrength > 95) { + r += `Complete dom${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else if (slave.fetishStrength > 60) { + r += `Dominant${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else { + r += `Dominant tendencies${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } + break; + case "pregnancy": + if (slave.fetishStrength > 95) { + r += `Pregnancy fetish${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else if (slave.fetishStrength > 60) { + r += `Pregnancy kink${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } else { + r += `Interest in impregnation${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + } + break; + default: + r += `Sexually vanilla${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; + break; + } + r += `</span> `; + } + + function long_attraction(slave) { + if (slave.attrXY <= 5) { + r += `<span class="red">Disgusted by men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; + } else if (slave.attrXY <= 15) { + r += `<span class="red">Turned off by men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; + } else if (slave.attrXY <= 35) { + r += `<span class="red">Not attracted to men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; + } else if (slave.attrXY <= 65) { + r += `Indifferent to men${V.summaryStats? `[${slave.attrXY}]` : ''}, `; + } else if (slave.attrXY <= 85) { + r += `<span class="green">Attracted to men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; + } else if (slave.attrXY <= 95) { + r += `<span class="green">Aroused by men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; + } else if (slave.attrXX > 95) { + if (slave.energy <= 95) { + r += `<span class="green">Omnisexual!</span> `; } else { - surgeries.push("male belly implant"); - V.surgeryType = "bellyInMale"; - if (V.PC.medicine >= 100) slave.health -= 25; - else slave.health -= 50; + r += `<span class="green">Omnisexual nymphomaniac!</span> `; } - bellyIn(slave); - - } else if (slave.bellyImplant >= 0 && thisSurgery.surgery_bellyImplant == "remove") { - surgeries.push("belly implant removal"); - V.surgeryType = "bellyOut"; - if (V.PC.medicine >= 100) - slave.health -= 5; - else - slave.health -= 10; - slave.preg = 0; - slave.bellyImplant = -1; - V.cash -= V.surgeryCost; - } else if (slave.balls > 0 && slave.vasectomy === 0 && thisSurgery.surgery_vasectomy === true) { - surgeries.push("vasectomy"); - V.surgeryType = "vasectomy"; - if (V.PC.medicine >= 100) - slave.health -= 5; - else - slave.health -= 10; - slave.vasectomy = 1; - V.cash -= V.surgeryCost; - } else if (slave.balls > 0 && slave.vasectomy === 1 && thisSurgery.surgery_vasectomy === false) { - surgery.push("undo vasectomy"); - V.surgeryType = "vasectomy undo"; - if (V.PC.medicine >= 100) - slave.health -=5; - else - slave.health -= 10; - slave.vasectomy = 0; - V.cash -= V.surgeryCost; + } else { + r += `<span class="green">Passionate about men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; } - } - - function PrintResult(slave, thisSurgery, surgeries) { - let surgeriesDisplay = ""; - if (surgeries.length === 1) - surgeriesDisplay = surgeries[0]; - else { - surgeriesDisplay = surgeries.slice(0, surgeries.length - 1).join(", "); - surgeriesDisplay += ", and" + surgeries[surgeries.length - 1]; + if (slave.attrXX <= 5) { + r += `<span class="red">disgusted by women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; + } else if (slave.attrXX <= 15) { + r += `<span class="red">turned off by women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; + } else if (slave.attrXX <= 35) { + r += `<span class="red">not attracted to women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; + } else if (slave.attrXX <= 65) { + r += `indifferent to women${V.summaryStats? `[${slave.attrXX}]` : ''}. `; + } else if (slave.attrXX <= 85) { + r += `<span class="green">attracted to women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; + } else if (slave.attrXX <= 95) { + r += `<span class="green">aroused by women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; + } else if (slave.attrXY <= 95) { + r += `<span class="green">passionate about women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; } - r += `${V.assistantName === "your personal assistant" ? "Your personal assistant" : V.assistantName}, ordered to apply surgery, gives ${slave.slaveName} <span class="lime">${surgeriesDisplay}.</span>`; - } - - function bellyIn(slave) { - // less hacky version of calling surgery degradation silently - if (slave.devotion > 50) - slave.devotion += 4; - else if (slave.devotion >= -20) - slave.trust -= 5; - else { - slave.trust -= 5; - slave.devotion -= 5; + if (slave.energy > 95) { + if ((slave.attrXY <= 95) || (slave.attrXX <= 95)) { + r += `<span class="green">Nymphomaniac!</span>`; + } + } else if (slave.energy > 80) { + r += `<span class="green">Powerful sex drive${V.summaryStats? `[${slave.energy}]` : ''}.</span>`; + } else if (slave.energy > 60) { + r += `<span class="green">Good sex drive${V.summaryStats? `[${slave.energy}]` : ''}.</span>`; + } else if (slave.energy > 40) { + r += `<span class="yellow">Average sex drive${V.summaryStats? `[${slave.energy}]` : ''}.</span>`; + } else if (slave.energy > 20) { + r += `<span class="red">Poor sex drive${V.summaryStats? `[${slave.energy}]` : ''}.</span>`; + } else { + r += `<span class="red">No sex drive${V.summaryStats? `[${slave.energy}]` : ''}.</span>`; } + r += " "; } -})(); - - -/*:: sexActJS [script]*/ - -/* - times is how many times to increment the anal counts. - if left undefined it will assume it to be 1. -*/ -window.AnalVCheck = function AnalVCheck(times) { - const V = State.variables; - const slave = V.activeSlave; - let r = ``; - if (canDoAnal(slave) && slave.anus === 0) { - r += `@@.lime;This breaks in ${slave.slaveName}'s virgin ass.@@ `; - if (slave.devotion > 50 || slave.career == "a slave since birth") { - r += `Since it's her first time, you gently ease yourself into her butthole and gradually increase the intensity of your thrusts. Before long she's moaning loudly as you continue working away at her butthole. `; - if (slave.tankBaby == 2) { - r += `She thinks of losing her anal virginity to her ${WrittenMaster(slave)} a @@.hotpink;necessity.@@ She expects her asshole to be seeing a lot more attention now.`; + + function long_smart_fetish(slave) { + if (slave.fetishKnown === 1) { + if (slave.clitSetting === "off") { + r += `SP off.`; + } else if (((slave.fetish !== "submissive") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "submissive")) { + r += `SP: submissive.`; + } else if (((slave.fetish !== "cumslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "oral")) { + r += `SP: oral.`; + } else if (((slave.fetish !== "humiliation") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "humiliation")) { + r += `SP: humiliation.`; + } else if (((slave.fetish !== "buttslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "anal")) { + r += `SP: anal.`; + } else if (((slave.fetish !== "boobs") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "boobs")) { + r += `SP: breasts.`; + } else if (((slave.fetish !== "sadist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "sadist")) { + r += `SP: sadism.`; + } else if (((slave.fetish !== "masochist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "masochist")) { + r += `SP: masochism.`; + } else if (((slave.fetish !== "dom") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "dom")) { + r += `SP: dominance.`; + } else if (((slave.fetish !== "pregnancy") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "pregnancy")) { + r += `SP: pregnancy.`; + } else if ((slave.fetish !== "none") && (slave.clitSetting === "vanilla")) { + r += `SP: vanilla.`; + } else if ((slave.energy <= 95) && (slave.clitSetting === "all")) { + r += `SP: all.`; + } else if ((slave.energy > 5) && (slave.clitSetting === "none")) { + r += `SP: none.`; + } else if (!["women", "men", "anti-women", "anti-men"].includes(slave.clitSetting)) { + r += `SP: monitoring.`; } - else { - r += `She thinks of losing her anal virginity to you as a @@.hotpink;connection@@ with her beloved ${WrittenMaster(slave)}. `; - if ((slave.fetishKnown && slave.fetish == "buttslut") || (slave.energy > 95) || (slave.attrXX >= 85 && V.PC.dick === 0)) { - r += `She can't wait to be fucked in the ass by you again.`; - } - else { - r += `She looks forward to having her asshole fucked by you again.`; - } + } else { + switch (slave.clitSetting) { + case "off": + r += `SP off.`; + break; + case "submissive": + r += `SP: submissive.`; + break; + case "oral": + r += `SP: oral.`; + break; + case "humiliation": + r += `SP: humiliation.`; + break; + case "anal": + r += `SP: anal.`; + break; + case "boobs": + r += `SP: breasts.`; + break; + case "sadist": + r += `SP: sadism.`; + break; + case "masochist": + r += `SP: masochism.`; + break; + case "dom": + r += `SP: dominance.`; + break; + case "pregnancy": + r += `SP: pregnancy.`; + break; + case "vanilla": + r += `SP: vanilla.`; + break; + case "all": + r += `SP: all.`; + break; + case "none": + r += `SP: none.`; + break; } - slave.devotion += 4; - } - else if (slave.devotion > 20) { - r += `Since it's her first time, you gently ease yourself into her butthole and gradually increase the intensity of your thrusts. Her moans become louder and louder as you continue working away at her butthole. She accepts the pain and humiliation of anal sex as part of her sexual servitude, though she hopes that her next time will be less painful.`; - } - else if (slave.devotion >= -20) { - r += `You force yourself into her butthole. She sobs and cries with disgust while you continue thrusting into her ass. She @@.gold;fears@@ her next anal sex, remembering the pain of losing her anal virginity. She dreads having her ass violated by you again.`; - slave.trust -= 5; - } - else { - r += `You force yourself into her butthole. She sobs and cries with disgust while you continue thrusting into her ass. She @@.mediumorchid;hates@@ and @@.gold;fears@@ you for violating her virgin butt. She dreads having her ass fucked by you again.`; - slave.trust -= 5; - slave.devotion -= 5; - } - slave.anus = 1; - } - if (canDoAnal(slave)) { - if (V.PC.dick === 1 && canGetPregnant(slave) && slave.eggType == "human") { - r += knockMeUp(slave, 10, 1, -1, 1); - } - if (!times) { - V.analTotal += 1; - slave.analCount += 1; - } - else { - V.analTotal += times; - slave.analCount += times; } + r += " "; } - return r; -} - -/* - times is how many times to increment the vaginal counts. - if left undefined it will assume it to be 1. -*/ -window.VaginalVCheck = function VaginalVCheck(times) { - const V = State.variables; - const slave = V.activeSlave; - let r = ``; - if (canDoVaginal(slave) && slave.vagina === 0) { - r += `@@.lime;This breaks in ${slave.slaveName}'s virgin pussy.@@ `; - if (slave.devotion > 50 || slave.career == "a slave since birth") { - r += `You ease yourself into her pussy, since it's her first time, then gradually speed up your thrusts while she slowly learns to move her hips along with you. She moans loudly. `; - if (slave.tankBaby == 2) { - r += `She thinks of losing her virginity to her ${WrittenMaster(slave)} a @@.hotpink;necessity to be happy.@@ She expects her pussy to be seeing a lot more attention in the future.`; + + function long_smart_attraction(slave) { + if (slave.attrKnown === 1) { + if ((slave.attrXX < 100) && (slave.clitSetting === "women")) { + r += `SP: women.`; + } else if ((slave.attrXY < 100) && (slave.clitSetting === "men")) { + r += `SP: men.`; } - else { - r += `@@.hotpink;She enjoys losing her cherry to you.@@ `; - if ((slave.fetishKnown && slave.fetish == "pregnancy") || (slave.energy > 95) || (slave.attrXY >= 85 && V.PC.dick === 1)) { - r += `She can't wait to have her pussy fucked by you again.`; - } - else { - r += `She looks forward to having her pussy fucked by you again.`; - } + } else { + if (slave.clitSetting === "women") { + r += `SP: women.`; + } else if (slave.clitSetting === "men") { + r += `SP: men.`; } - slave.devotion += 4; - } - else if (slave.devotion > 20) { - r += `You ease yourself into her pussy, since it's her first time, then gradually speed up your thrusts while she slowly learns to move her hips along with you. She accepts losing her virginity to her owner and she looks forward to having her pussy fucked by you again.`; } - else if (slave.devotion >= -20) { - r += `You force yourself into her pussy. She sobs and cries with disgust while you continue thrusting into her fuck hole. She @@.mediumorchid;hates@@ losing her virginity this way and @@.gold;fears@@ the next time you'll conquer her. She dreads getting violated by you again.`; - slave.trust -= 5; - slave.devotion -= 5; - } - else { - r += `You force yourself into her pussy. She sobs and cries with disgust while you continue working her fuck hole. She tries to struggle, but you only pound harder. She @@.mediumorchid;hates@@ and @@.gold;fears@@ you for robbing her of her virginity. She dreads getting fucked by you again.`; - slave.trust -= 10; - slave.devotion -= 15; + r += " "; + } + + function long_behavior_flaw(slave) { + r += `<span class="red">`; + switch (slave.behavioralFlaw) { + case "arrogant": + r += `Arrogant.`; + break; + case "bitchy": + r += `Bitchy.`; + break; + case "odd": + r += `Odd.`; + break; + case "hates men": + r += `Hates men.`; + break; + case "hates women": + r += `Hates women.`; + break; + case "gluttonous": + r += `Stress eater.`; + break; + case "anorexic": + r += `Anorexic.`; + break; + case "devout": + r += `Devoutly religious.`; + break; + case "liberated": + r += `Mentally liberated.`; + break; + default: + slave.behavioralFlaw = "none"; + break; } - slave.vagina = 1; - - if (V.PC.dick === 1 && canGetPregnant(slave) && slave.eggType == "human") { - r += knockMeUp(slave, 10, 0, -1, 1); + r += `</span> `; + } + + function long_sex_flaw(slave) { + switch (slave.sexualFlaw) { + case "hates oral": + r += `<span class="red">Hates oral.</span>`; + break; + case "hates anal": + r += `<span class="red">Hates anal.</span>`; + break; + case "hates penetration": + r += `<span class="red">Hates penetration.</span>`; + break; + case "shamefast": + r += `<span class="red">Shamefast.</span>`; + break; + case "idealistic": + r += `<span class="red">Sexually idealistic.</span>`; + break; + case "repressed": + r += `<span class="red">Sexually repressed.</span>`; + break; + case "apathetic": + r += `<span class="red">Sexually apathetic.</span>`; + break; + case "crude": + r += `<span class="red">Sexually crude.</span>`; + break; + case "judgemental": + r += `<span class="red">Sexually judgemental.</span>`; + break; + case "cum addict": + r += `<span class="yellow">Cum addict.</span>`; + break; + case "anal addict": + r += `<span class="yellow">Anal addict.</span>`; + break; + case "attention whore": + r += `<span class="yellow">Attention whore.</span>`; + break; + case "breast growth": + r += `<span class="yellow">Breast obsession.</span>`; + break; + case "abusive": + r += `<span class="yellow">Sexually abusive.</span>`; + break; + case "malicious": + r += `<span class="yellow">Sexually malicious.</span>`; + break; + case "self hating": + r += `<span class="yellow">Self hatred.</span>`; + break; + case "neglectful": + r += `<span class="yellow">Self neglectful.</span>`; + break; + case "breeder": + r += `<span class="yellow">Breeding obsession.</span>`; + break; + default: + slave.sexualFlaw = "none"; + break; } - if (!times) { - V.vaginalTotal += 1; - slave.vaginalCount += 1; + r += " "; + } + + function long_behavior_quirk(slave) { + r += `<span class="green">`; + switch (slave.behavioralQuirk) { + case "confident": + r += `Confident.`; + break; + case "cutting": + r += `Cutting.`; + break; + case "funny": + r += `Funny.`; + break; + case "fitness": + r += `Fitness.`; + break; + case "adores women": + r += `Adores women.`; + break; + case "adores men": + r += `Adores men.`; + break; + case "insecure": + r += `Insecure.`; + break; + case "sinful": + r += `Sinful.`; + break; + case "advocate": + r += `Advocate.`; + break; + default: + slave.behavioralQuirk = "none"; + break; } - else { - V.vaginalTotal += times; - slave.vaginalCount += times; + r += " "; + } + + function long_sex_quirk(slave) { + switch (slave.sexualQuirk) { + case "gagfuck queen": + r += `Gagfuck queen.`; + break; + case "painal queen": + r += `Painal queen.`; + break; + case "strugglefuck queen": + r += `Strugglefuck queen.`; + break; + case "tease": + r += `Tease.`; + break; + case "romantic": + r += `Romantic.`; + break; + case "perverted": + r += `Perverted.`; + break; + case "caring": + r += `Caring.`; + break; + case "unflinching": + r += `Unflinching.`; + break; + case "size queen": + r += `Size queen.`; + break; + default: + slave.sexualQuirk = "none"; + break; } + r += `</span> `; } - return r; -} - -/* - analTimes is how many times to increment the anal counts, if there is no vagina available. - bothTimes is how many times to increment both holes counts (usually it is half of analTimes). - In both cases if left undefined it will assume it to be 1. -*/ -window.BothVCheck = function BothVCheck(analTimes, bothTimes) { - const V = State.variables; - const slave = V.activeSlave; - let r = ``; - if (canDoVaginal(slave)) { - if (slave.vagina === 0) { - if (canDoAnal(slave) && slave.anus == 0) { - r += `@@.lime;This breaks in ${slave.slaveName}'s virgin holes.@@ `; - if (slave.devotion > 50 || slave.career == "a slave since birth") { - r += `As it's her first time, you ease yourself into her pussy before gradually working your way into her ass and alternate between the two holes while she moans. `; - if (slave.tankBaby == 2) { - r += `She believes you taking her virgin holes @@.hotpink;will keep her from suffering.@@ She expects you to require her holes as tribute again soon.`; - } - else { - r += `@@.hotpink;She's so devoted she enjoys being fucked in both holes for the first time.@@ She looks forward to having her holes fucked by you again.`; - } - slave.devotion += 4; - } - else if (slave.devotion <= 20) { - r += `You force yourself into her pussy before working your way into her ass. She sobs and cries with disgust while you alternate between the two holes. She @@.mediumorchid;hates@@ losing her virginity and anal virginity in one @@.gold;brutal@@ incident. She dreads having her holes violated by you again.`; - slave.trust -= 5; - slave.devotion -= 5; - } - else { - r += `As it's her first time, you ease yourself into her pussy before gradually working your way into her ass and alternate between the two holes while she moans. She accepts being fucked in both holes for the first time. She looks forward to having her holes fucked by you again.`; - } - slave.anus = 1; - } - else { - r += `@@.lime;This breaks in ${slave.slaveName}'s virgin pussy.@@ `; - if (slave.devotion > 50 || slave.career == "a slave since birth") { - r += `As it's her first time, you ease yourself into her pussy and gradually speed up your thrusts while she slowly learns to move her hips along with you. She moans loudly. `; - if (slave.tankBaby == 2) { - r += `She thinks of losing her virginity to her ${WrittenMaster(slave)} a @@.hotpink;necessity to be happy.@@ She expects her pussy to be seeing a lot more attention in the future.`; - } - else { - r += `@@.hotpink;She enjoys losing her cherry to you.@@ She looks forward to having her pussy fucked by you again.`; + + function short_extended_family(slave) { + let handled = 0; + if (slave.mother > 0) { + let _ssj = V.slaves.findIndex(function(s) { + return s.ID === slave.mother; + }); + if (_ssj !== -1) { + r += `${SlaveFullName(V.slaves[_ssj])}'s daughter`; + if (slave.relationshipTarget === V.slaves[_ssj].ID) { + if (slave.relationship === 1) { + r += ` & friend`; + } else if (slave.relationship === 2) { + r += ` & BFF`; + } else if (slave.relationship === 3) { + r += ` & FWB`; + } else if (slave.relationship === 4) { + r += ` & lover`; + } else { + r += ` & wife`; } - slave.devotion += 4; - } - else if (slave.devotion <= 20) { - r += `You force yourself into her pussy. She sobs and cries with disgust while you continue working her fuck hole. She @@.mediumorchid;hates@@ and @@.gold;fears@@ you for taking her virginity. She dreads having her pussy violated by you again.`; - slave.trust -= 5; - slave.devotion -= 5; - } - else { - r += `As it's her first time, you ease yourself into her pussy before gradually increasing the intensity of your thrusts while she softly moans. She accepts losing her virginity to her owner and she looks forward to having her pussy fucked by you again.`; + handled = 1; } } - slave.vagina = 1; + r += " "; + } else if (slave.mother === -1) { + r += `Your daughter`; + if (slave.relationship === -3) { + r += ` & wife`; + handled = 1; + } else if (slave.relationship === -2) { + r += ` & lover`; + handled = 1; + } + r += " "; } - else if (canDoAnal(slave) && slave.anus == 0) { - r += `@@.lime;This breaks in ${slave.slaveName}'s virgin ass.@@ `; - if (slave.devotion > 50 || slave.career == "a slave since birth") { - r += `As it's her first time, you ease yourself into her butthole and gradually speed up your thrusts while she slowly learns to move her hips along with you. She moans loudly. `; - if (slave.tankBaby == 2) { - r += `She thinks of losing her anal virginity to her ${WrittenMaster(slave)} a @@.hotpink;necessity.@@ She expects her asshole to be seeing a lot more attention now.`; - } - else { - r += `She thinks of losing her anal virginity to you as a @@.hotpink;connection@@ with her beloved ${WrittenMaster(slave)}. She looks forward to having her asshole fucked by you again.` + if (slave.father > 0 && slave.father !== slave.mother) { + let _ssj = V.slaves.findIndex(function(s) { + return s.ID === slave.father; + }); + if (_ssj !== -1) { + r += `${SlaveFullName(V.slaves[_ssj])}'s daughter`; + if (slave.relationshipTarget === V.slaves[_ssj].ID && handled !== 1) { + if (slave.relationship === 1) { + r += ` & friend`; + } else if (slave.relationship === 2) { + r += ` & BFF`; + } else if (slave.relationship === 3) { + r += ` & FWB`; + } else if (slave.relationship === 4) { + r += ` & lover`; + } else { + r += ` & wife`; + } + handled = 1; } - slave.devotion += 4; - } - else if (slave.devotion > 20){ - r += `As it's her first time, you ease yourself into her butthole and gradually increase the intensity of your thrusts. She accepts the pain and humiliation of anal sex as part of her sexual servitude, though she hopes that her next time will be less painful.`; - } - else if (slave.devotion >= -20) { - r += `You force yourself into her butthole. She sobs and cries with disgust while you continue thrusting into her ass. She @@.gold;fears@@ her next anal sex, remembering the pain of losing her anal virginity. She dreads having her ass violated by you again.`; - slave.trust -= 5; } - else { - r += `You force yourself into her butthole. She sobs and cries with disgust while you continue thrusting into her ass. She @@.mediumorchid;hates@@ and @@.gold;fears@@ you for violating her virgin butt. She dreads having her ass fucked by you again.`; - slave.trust -= 5; - slave.devotion -= 5; + r += " "; + } else if (slave.father === -1 && slave.mother !== -1) { + r += `Your daughter`; + if (slave.relationship === -3) { + r += ` & wife`; + handled = 1; + } else if (slave.relationship === -2) { + r += ` & lover`; + handled = 1; } - slave.anus = 1; } - if (canDoAnal(slave)) { - if (!bothTimes) { - V.vaginalTotal += 1; - V.analTotal += 1; - slave.vaginalCount += 1; - slave.analCount += 1; + if (slave.daughters === 1) { + let _ssj = V.slaves.findIndex(function(s) { + return s.mother === slave.ID; + }); + if (_ssj !== -1) { + r += `${SlaveFullName(V.slaves[_ssj])}'s mother`; + if (slave.relationshipTarget === V.slaves[_ssj].ID) { + if (slave.relationship === 1) { + r += ` & friend`; + } else if (slave.relationship === 2) { + r += ` & BFF`; + } else if (slave.relationship === 3) { + r += ` & FWB`; + } else if (slave.relationship === 4) { + r += ` & lover`; + } else { + r += ` & wife`; + } + handled = 1; + } } - else { - V.vaginalTotal += bothTimes; - V.analTotal += bothTimes; - slave.vaginalCount += bothTimes; - slave.analCount += bothTimes; + r += " "; + _ssj = V.slaves.findIndex(function(s) { + return s.father === slave.ID; + }); + if (_ssj !== -1) { + r += `${SlaveFullName(V.slaves[_ssj])}'s father`; + if (slave.relationshipTarget === V.slaves[_ssj].ID && handled !== 1) { + if (slave.relationship === 1) { + r += ` & friend`; + } else if (slave.relationship === 2) { + r += ` & BFF`; + } else if (slave.relationship === 3) { + r += ` & FWB`; + } else if (slave.relationship === 4) { + r += ` & lover`; + } else { + r += ` & wife`; + } + handled = 1; + } } - if (V.PC.dick === 1 && canGetPregnant(slave) && slave.eggType == "human") { - r += knockMeUp(slave, 10, 2, -1, 1); + r += " "; + } else if (slave.daughters > 1) { + r += `multiple daughters `; + } + if (slave.sisters === 1) { + let _ssj = V.slaves.findIndex(function(s) { + return areSisters(s, slave) > 0; + }); + if (_ssj !== -1) { + r += `${SlaveFullName(V.slaves[_ssj])}'s sister`; + if (slave.relationshipTarget === V.slaves[_ssj].ID) { + if (slave.relationship === 1) { + r += ` & friend`; + } else if (slave.relationship === 2) { + r += ` & BFF`; + } else if (slave.relationship === 3) { + r += ` & FWB`; + } else if (slave.relationship === 4) { + r += ` & lover`; + } else { + r += ` & wife`; + } + handled = 1; + } } + r += " "; + } else if (slave.sisters > 1) { + r += `multiple sisters `; } - else { - if (!bothTimes) { - V.vaginalTotal += 1; - slave.vaginalCount += 1; + if (slave.relationship > 0 && handled !== 1) { + let _ssj = V.slaves.findIndex(function(s) { + return s.ID === slave.relationshipTarget; + }); + if (_ssj !== -1) { + r += `${SlaveFullName(V.slaves[_ssj])}'s`; + switch (slave.relationship) { + case 1: + r += ` friend`; + break; + case 2: + r += ` BFF`; + break; + case 3: + r += ` FWB`; + break; + case 4: + r += ` lover`; + break; + case 5: + r += ` wife`; + break; + } } - else { - V.vaginalTotal += bothTimes; - slave.vaginalCount += bothTimes; + } else if (slave.relationship === -3) { + r += `Your wife`; + } else if (slave.relationship === -2) { + r += `E Bonded`; + } else if (slave.relationship === -1) { + r += `E Slut`; + } + r += " "; + } + + function short_legacy_family(slave) { + if (slave.relation !== 0) { + let _ssj = V.slaves.findIndex(function(s) { + return s.ID === slave.relationTarget; + }); + if (_ssj !== -1) { + r += `${SlaveFullName(V.slaves[_ssj])}'s ${slave.relation}`; } - if (V.PC.dick == 1 && canGetPregnant(slave) && slave.eggType == "human") { - r += knockMeUp(slave, 10, 0, -1, 1); + } + if (slave.relationship > 0) { + let _ssj = V.slaves.findIndex(function(s) { + return s.ID === slave.relationshipTarget; + }); + if (_ssj !== -1) { + switch (slave.relationship) { + case 1: + if (slave.relationshipTarget !== slave.relationTarget) { + r += `${SlaveFullName(V.slaves[_ssj])}'s`; + } else { + r += ` &`; + } + r += ` friend`; + break; + case 2: + if (slave.relationshipTarget !== slave.relationTarget) { + r += `${SlaveFullName(V.slaves[_ssj])}'s`; + } else { + r += ` &`; + } + r += ` BFF`; + break; + case 3: + if (slave.relationshipTarget !== slave.relationTarget) { + r += `${SlaveFullName(V.slaves[_ssj])}'s`; + } else { + r += ` &`; + } + r += ` FWB`; + break; + case 4: + if (slave.relationshipTarget !== slave.relationTarget) { + r += `${SlaveFullName(V.slaves[_ssj])}'s`; + } else { + r += ` &`; + } + r += ` lover`; + break; + case 5: + if (slave.relationshipTarget !== slave.relationTarget) { + r += `${SlaveFullName(V.slaves[_ssj])}'s`; + } else { + r += ` &`; + } + r += ` wife`; + break; + } } + } else if (slave.relationship === -3) { + r += `Your wife`; + } else if (slave.relationship === -2) { + r += `E Bonded`; + } else if (slave.relationship === -1) { + r += `E Slut`; } } - else if (canDoAnal(slave)) { - if (slave.anus == 0) { - r += `@@.lime;This breaks in ${slave.slaveName}'s virgin ass.@@ `; - if (slave.devotion > 50 || slave.career == "a slave since birth") { - r += `As it's her first time, you ease yourself into her butthole and gradually speed up your thrusts while she slowly learns to move her hips along with you. She moans loudly. `; - if (slave.tankBaby == 2) { - r += `She thinks of losing her anal virginity to her ${WrittenMaster(slave)} a @@.hotpink;necessity.@@ She expects her asshole to be seeing a lot more attention now.`; - } - else { - r += `She thinks of losing her anal virginity to you as a @@.hotpink;connection@@ with her beloved ${WrittenMaster(slave)}. She looks forward to having her asshole fucked by you again.`; + + function short_rival(slave) { + if (slave.rivalry !== 0) { + r += ` `; + let _ssj = V.slaves.findIndex(function(s) { + return s.ID === slave.rivalryTarget; + }); + if (_ssj !== -1) { + r += `<span class="lightsalmon">`; + if (slave.rivalry <= 1) { + r += `Disl ${SlaveFullName(V.slaves[_ssj])}`; + } else if (slave.rivalry <= 2) { + r += `${SlaveFullName(V.slaves[_ssj])}'s rival`; + } else { + r += `Hates ${SlaveFullName(V.slaves[_ssj])}`; } - slave.devotion += 4; - } - else if (slave.devotion > 20) { - r += `As it's her first time, you ease yourself into her butthole and gradually increase the intensity of your thrusts. She accepts the pain and humiliation of anal sex as part of her sexual servitude, though she hopes that her next time will be less painful.`; - } - else if (slave.devotion >= -20) { - r += `You force yourself into her butthole. She sobs and cries with disgust while you continue thrusting into her ass. She @@.gold;fears@@ her next anal sex, remembering the pain of losing her anal virginity. She dreads having her ass violated by you again.`; - slave.trust -= 5; - } - else { - r += `You force yourself into her butthole. She sobs and cries with disgust while you continue thrusting into her ass. She @@.mediumorchid;hates@@ and @@.gold;fears@@ you for violating her virgin butt. She dreads having her ass fucked by you again.` - slave.trust -= 5; - slave.devotion -= 5; + r += `</span> `; } - slave.anus = 1; - } - if (!analTimes) { - V.analTotal += 1; - slave.analCount += 1; - } - else { - V.analTotal += analTimes; - slave.analCount += analTimes; - } - if (V.PC.dick === 1 && canGetPregnant(slave) && slave.eggType == "human") { - r += knockMeUp(slave, 10, 1, -1, 1); } } - return r; -} - -/* - times is how many times to increment either the Vaginal or the Anal counts, if there is no Vagina available. - If left undefined it will assume it to be 1. -*/ -window.SimpleVCheck = function SimpleVCheck(times) { - let r = ``; - if (canDoVaginal(State.variables.activeSlave)) { - r += VaginalVCheck(times); - } - else if (canDoAnal(State.variables.activeSlave)) { - r += AnalVCheck(times); - } - return r; -} - -/* - Before using this function, set $partner to the index of the partner in the $slaves array - analTimes is how many times to increment the Anal counts, if there is no Vagina available. - bothTimes is how many times to increment both holes counts (usually it is half of Anal). - In both cases if left undefined it will assume it to be 1. - This also checks for a valid Vagina/Accessory, though most code I've seen does this already, you - never know when someone might use the routine and forget to do such. -*/ -window.PartnerVCheck = function PartnerVCheck(analTimes, bothTimes) { - const V = State.variables; - const partner = V.slaves[V.partner]; - let r = ``; - if (V.partner < 0 || V.partner >= V.slaves.length) { - r += `@@.red;PartnerVCheck called with invalid partner '$partner' from passage ${passage()}.@@`; - } - else if (canDoVaginal(partner)) { - if (partner.vagina === 0) { - if (canDoAnal(partner) && partner.anus === 0) { - r += `Since it's ${partner.slaveName}'s first time, you take your time and gently ease yourself into her pussy before gradually working your way into her butthole, alternating between her holes. @@.lime;This breaks in ${partner.slaveName}'s virgin holes.@@ `; - partner.vagina = 1; - partner.anus = 1; + function long_extended_family(slave) { + let handled = 0; + if (slave.mother > 0) { + let _ssj = V.slaves.findIndex(function(s) { + return s.ID === slave.mother; + }); + if (_ssj !== -1) { + r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">daughter`; + if (slave.relationshipTarget === V.slaves[_ssj].ID) { + if (slave.relationship === 1) { + r += ` and friend`; + } else if (slave.relationship === 2) { + r += ` and best friend`; + } else if (slave.relationship === 3) { + r += ` and FWB`; + } else if (slave.relationship === 4) { + r += ` and lover`; + } else { + r += ` and wife`; + } + handled = 1; + } + r += `.</span> `; } - else { - r += `Since it's ${partner.slaveName}'s first time, you take your time and gently ease yourself into her pussy before gradually increasing the intensity of your thrusts. @@.lime;This breaks in partner.slaveName's virgin pussy.@@ `; - partner.vagina = 1; + } else if (slave.mother === -1) { + r += `Your `; + if (slave.relationship === -3) { + r += `<span class="lightgreen">daughter and wife.</span> `; + handled = 1; + } else if (slave.relationship === -2) { + r += `<span class="lightgreen">daughter and lover.</span> `; + handled = 1; + } else { + r += `<span class="lightgreen">daughter.</span> `; } } - else if (canDoAnal(partner) && partner.anus == 0) { - r += `Since it's ${partner.slaveName}'s first time, you take your time and gently ease yourself into her butthole before gradually increasing the intensity of your thrusts into her ass. @@.lime;This breaks in ${partner.slaveName}'s virgin ass.@@ `; - partner.anus = 1; + if (slave.father > 0 && slave.father !== slave.mother) { + let _ssj = V.slaves.findIndex(function(s) { + return s.ID === slave.father; + }); + if (_ssj !== -1) { + r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">daughter`; + if (slave.relationshipTarget === V.slaves[_ssj].ID) { + if (slave.relationship === 1) { + r += ` and friend`; + } else if (slave.relationship === 2) { + r += ` and best friend`; + } else if (slave.relationship === 3) { + r += ` and FWB`; + } else if (slave.relationship === 4) { + r += ` and lover`; + } else { + r += ` and wife`; + } + handled = 1; + } + r += `.</span> `; + } + } else if (slave.father === -1 && slave.father !== slave.mother) { + r += `Your `; + if (slave.relationship === -3) { + r += `<span class="lightgreen">daughter and wife.</span> `; + handled = 1; + } else if (slave.relationship === -2) { + r += `<span class="lightgreen">daughter and lover.</span> `; + handled = 1; + } else { + r += `<span class="lightgreen">daughter.</span> `; + } } - - if (canDoAnal(partner)) { - if (!bothTimes) { - V.vaginalTotal += 1; - V.analTotal += 1; - partner.vaginalCount += 1; - partner.analCount += 1; + if (slave.daughters === 1) { + let _ssj = V.slaves.findIndex(function(s) { + return s.mother === slave.ID; + }); + if (_ssj !== -1) { + r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">mother`; + if (slave.relationshipTarget === V.slaves[_ssj].ID) { + if (slave.relationship === 1) { + r += ` and friend`; + } else if (slave.relationship === 2) { + r += ` and best friend`; + } else if (slave.relationship === 3) { + r += ` and FWB`; + } else if (slave.relationship === 4) { + r += ` and lover`; + } else { + r += ` and wife`; + } + handled = 1; + } + r += `.</span> `; } - else { - V.vaginalTotal += bothTimes; - V.analTotal += bothTimes; - partner.vaginalCount += bothTimes; - partner.analCount += bothTimes; + _ssj = V.slaves.findIndex(function(s) { + return s.father === slave.ID; + }); + if (_ssj !== -1) { + r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">father`; + if (slave.relationshipTarget === V.slaves[_ssj].ID) { + if (slave.relationship === 1) { + r += ` and friend`; + } else if (slave.relationship === 2) { + r += ` and best friend`; + } else if (slave.relationship === 3) { + r += ` and FWB`; + } else if (slave.relationship === 4) { + r += ` and lover`; + } else { + r += ` and wife`; + } + handled = 1; + } + r += `.</span> `; } - if (V.PC.dick === 1 && canGetPregnant(partner) && partner.eggType == "human") { - r += knockMeUp(partner, 10, 2, -1); + } else if (slave.daughters > 1) { + if (slave.daughters > 10) { + r += `<span class="lightgreen">Has tons of daughters.</span> `; + } else if (slave.daughters > 5) { + r += `<span class="lightgreen">Has many daughters.</span> `; + } else { + r += `<span class="lightgreen">Has several daughters.</span> `; } } - else { - if (!bothTimes) { - V.vaginalTotal += 1; - partner.vaginalCount += 1; - } - else { - V.vaginalTotal += bothTimes; - partner.vaginalCount += bothTimes; + if (slave.sisters === 1) { + let _ssj = V.slaves.findIndex(function(s) { + return areSisters(s, slave) > 0; + }); + if (_ssj !== -1) { + r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">sister`; + if (slave.relationshipTarget === V.slaves[_ssj].ID) { + if (slave.relationship === 1) { + r += ` and friend`; + } else if (slave.relationship === 2) { + r += ` and best friend`; + } else if (slave.relationship === 3) { + r += ` and FWB`; + } else if (slave.relationship === 4) { + r += ` and lover`; + } else { + r += ` and wife`; + } + handled = 1; + } + r += `.</span> `; } - if (V.PC.dick === 1 && canGetPregnant(partner) && partner.eggType == "human") { - r += knockMeUp(partner, 10, 0, -1); + } else if (slave.sisters > 1) { + if (slave.sisters > 10) { + r += `<span class="lightgreen">One of many sisters.</span> `; + } else if (slave.sisters > 5) { + r += `<span class="lightgreen">Has many sisters.</span> `; + } else { + r += `<span class="lightgreen">Has several sisters.</span> `; } } - } - else if (canDoAnal(partner)) { - if (partner.anus === 0) { - r += `Since it's ${partner.slaveName}'s first time, you take your time and gently ease yourself into her butthole before gradually increasing the intensity of your thrusts into her ass. @@.lime;This breaks in ${partner.slaveName}'s virgin ass.@@ `; - partner.anus = 1; - } - if (!analTimes) { - V.analTotal += analTimes; - partner.analCount += analTimes; - } - else { - V.analTotal += 1; - partner.analCount += 1; - } - if (V.PC.dick === 1 && canGetPregnant(partner) && partner.eggType == "human") { - r += knockMeUp(partner, 10, 1, -1); + if (slave.relationship > 0 && handled !== 1) { + let _ssj = V.slaves.findIndex(function(s) { + return s.ID === slave.relationshipTarget; + }); + if (_ssj !== -1) { + r += `${SlaveFullName(V.slaves[_ssj])}'s `; + switch (slave.relationship) { + case 1: + r += `<span class="lightgreen">friend.</span> `; + break; + case 2: + r += `<span class="lightgreen">best friend.</span> `; + break; + case 3: + r += `<span class="lightgreen">FWB.</span> `; + break; + case 4: + r += `<span class="lightgreen">lover.</span> `; + break; + case 5: + r += `<span class="lightgreen">slave wife.</span> `; + break; + } + } + } else if (slave.relationship === -3) { + r += `<span class="lightgreen">Your wife.</span> `; + } else if (slave.relationship === -2) { + r += `<span class="lightgreen">Emotionally bonded to you.</span> `; + } else if (slave.relationship === -1) { + r += `<span class="lightgreen">Emotional slut.</span> `; } } - return r; -} - -/* - count is how many times to increment either the Vaginal, Anal, or Oral counts, depending on availability of slave. - If count is left undefined it will assume it to be 1. - Intended to be a simple "I want to fuck x and not have to code a bunch of logic for it". -*/ -window.SimpleSexAct = function SimpleSexAct(slave, count) { - const V = State.variables; - let fuckTarget = 0; - let fuckCount = 1; - let r = ``; - if (count) { - fuckCount = count; - } - for (var i = 0; i < fuckCount; i++) { - fuckTarget = jsRandom(1,100); - if (slave.nipples == "fuckable" && V.PC.dick === 1 && fuckTarget > 80) { - V.mammaryTotal += 1; - slave.mammaryCount += 1; + + function long_legacy_family(slave) { + if (slave.relation !== 0) { + let _ssj = V.slaves.findIndex(function(s) { + return s.ID === slave.relationTarget; + }); + if (_ssj !== -1) { + r += `${SlaveFullName(V.slaves[_ssj])}'s `; + if (slave.relationshipTarget !== slave.relationTarget) { + r += `<span class="lightgreen">${slave.relation}</span>. `; + } else { + r += `<span class="lightgreen">${slave.relation}</span> `; + } + if (slave.relationship <= 0) { + r += ` `; + } + } } - else if (canDoVaginal(slave) && slave.vagina > 0 && fuckTarget > 33) { - V.vaginalTotal += 1; - slave.vaginalCount += 1; - if (V.PC.dick === 1 && canGetPregnant(slave) && slave.eggType == "human") { - r += knockMeUp(slave, 10, 0, -1, 1); + if (slave.relationship > 0) { + let _ssj = V.slaves.findIndex(function(s) { + return s.ID === slave.relationshipTarget; + }); + if (_ssj !== -1) { + switch (slave.relationship) { + case 1: + if (slave.relationshipTarget !== slave.relationTarget) { + r += `${SlaveFullName(V.slaves[_ssj])}'s `; + } else { + r += ` and `; + } + r += `<span class="lightgreen">friend.</span> `; + break; + case 2: + if (slave.relationshipTarget !== slave.relationTarget) { + r += `${SlaveFullName(V.slaves[_ssj])}'s `; + } else { + r += ` and `; + } + r += `<span class="lightgreen">best friend.</span> `; + break; + case 3: + if (slave.relationshipTarget !== slave.relationTarget) { + r += `${SlaveFullName(V.slaves[_ssj])}'s `; + } else { + r += ` and `; + } + r += `<span class="lightgreen">FWB.</span> `; + break; + case 4: + if (slave.relationshipTarget !== slave.relationTarget) { + r += `${SlaveFullName(V.slaves[_ssj])}'s `; + } else { + r += ` and `; + } + r += `<span class="lightgreen">lover.</span> `; + break; + case 5: + if (slave.relationshipTarget !== slave.relationTarget) { + r += `${SlaveFullName(V.slaves[_ssj])}'s`; + } else { + r += ` and `; + } + r += `<span class="lightgreen">slave wife.</span> `; + break; + } } + } else if (slave.relationship === -3) { + r += `<span class="lightgreen">Your wife.</span> `; + } else if (slave.relationship === -2) { + r += `<span class="lightgreen">Emotionally bonded to you.</span> `; + } else if (slave.relationship === -1) { + r += `<span class="lightgreen">Emotional slut.</span> `; } - else if (canDoAnal(slave) && slave.anus > 0 && fuckTarget > 10) { - V.analTotal += 1; - slave.analCount += 1; - if (V.PC.dick == 1 && canGetPregnant(slave) && slave.eggType == "human") { - r += knockMeUp(slave, 10, 1, -1, 1); + } + + function long_rival(slave) { + if (slave.rivalry !== 0) { + r += ` `; + let _ssj = V.slaves.findIndex(function(s) { + return s.ID === slave.rivalryTarget; + }); + if (_ssj !== -1) { + if (slave.rivalry <= 1) { + r += `<span class="lightsalmon">Dislikes</span> ${SlaveFullName(V.slaves[_ssj])}.`; + } else if (slave.rivalry <= 2) { + r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightsalmon">rival.</span>`; + } else { + r += `<span class="lightsalmon">Hates</span> ${SlaveFullName(V.slaves[_ssj])}.`; + } } + r += " "; } - else { - V.oralTotal += 1; - slave.oralCount += 1; + } + + function long_clothes(slave) { + switch (slave.clothes) { + case "attractive lingerie": + r += `Lingerie.`; + break; + case "a succubus outfit": + r += `Succubus outfit.`; + break; + case "a string bikini": + r += `String bikini.`; + break; + case "a scalemail bikini": + r += `Scalemail bikini.`; + break; + case "a monokini": + r += `Monokini.`; + break; + case "an apron": + r += `Apron.`; + break; + case "a cybersuit": + r += `Cybersuit.`; + break; + case "cutoffs and a t-shirt": + r += `Cutoffs, t-shirt.`; + break; + case "a slutty outfit": + r += `Slutty outfit.`; + break; + case "uncomfortable straps": + r += `Leather straps.`; + break; + case "a fallen nuns habit": + r += `Slutty habit.`; + break; + case "a chattel habit": + r += `Chattel habit.`; + break; + case "a penitent nuns habit": + r += `Cilice.`; + break; + case "slutty jewelry": + r += `Bangles.`; + break; + case "attractive lingerie for a pregnant woman": + r += `Preggo lingerie.`; + break; + case "a maternity dress": + r += `Maternity dress.`; + break; + case "stretch pants and a crop-top": + r += `Stretch pants, crop-top.`; + break; + case "harem gauze": + r += `Harem outfit.`; + break; + case "a slave gown": + r += `Slave gown.`; + break; + case "a halter top dress": + r += `Halter top dress.`; + break; + case "a mini dress": + r += `Mini dress.`; + break; + case "a ball gown": + r += `Ball gown.`; + break; + case "slutty business attire": + r += `Slutty suit.`; + break; + case "nice business attire": + r += `Nice suit.`; + break; + case "a comfortable bodysuit": + r += `Bodysuit.`; + break; + case "a military uniform": + r += `Military uniform.`; + break; + case "a schutzstaffel uniform": + r += `Schutzstaffel uniform.`; + break; + case "a slutty schutzstaffel uniform": + r += `Slutty Schutzstaffel uniform.`; + break; + case "a red army uniform": + r += `Red Army uniform.`; + break; + case "a long qipao": + r += `Long Qipao.`; + break; + case "battlearmor": + r += `Battlearmor.`; + break; + case "a mounty outfit": + r += `Mounty outfit.`; + break; + case "a dirndl": + r += `Dirndl.`; + break; + case "lederhosen": + r += `Lederhosen.`; + break; + case "a biyelgee costume": + r += `Biyelgee costume.`; + break; + case "a leotard": + r += `Leotard.`; + break; + case "a bunny outfit": + r += `Bunny outfit.`; + break; + case "a slutty maid outfit": + r += `Slutty maid.`; + break; + case "a nice maid outfit": + r += `Nice maid.`; + break; + case "a slutty nurse outfit": + r += `Slutty nurse.`; + break; + case "a nice nurse outfit": + r += `Nice nurse.`; + break; + case "a schoolgirl outfit": + r += `Schoolgirl outfit.`; + break; + case "a kimono": + r += `Kimono.`; + break; + case "a hijab and abaya": + r += `Hijab and abaya.`; + break; + case "battledress": + r += `Battledress.`; + break; + case "a latex catsuit": + r += `Nice latex.`; + break; + case "restrictive latex": + r += `Bondage latex.`; + break; + case "conservative clothing": + r += `Conservative clothing.`; + break; + case "chains": + r += `Chains.`; + break; + case "a cheerleader outfit": + r += `Cheerleader.`; + break; + case "clubslut netting": + r += `Netting.`; + break; + case "shibari ropes": + r += `Shibari.`; + break; + case "Western clothing": + r += `Chaps.`; + break; + case "body oil": + r += `Body oil.`; + break; + case "a toga": + r += `Toga.`; + break; + case "a huipil": + r += `Huipil.`; + break; + case "a slutty qipao": + r += `Qipao.`; + break; + case "spats and a tank top": + r += `Spats, tank top.`; + break; + default: + r += `Naked.`; + break; } + r += " "; } - return r; -} -/* - count is how many times to increment either the Vaginal, Anal, or Oral counts, depending on availability of slave. - If count is left undefined it will assume it to be 1. - Intended to be a simple "x got fucked y times and I don't want to keep coding it". - Pregnancy chance is handled in saLongTermEffects.tw. -*/ -window.SimpleSlaveFucking = function SimpleSlaveFucking(slave, count) { - const V = State.variables; - let fuckTarget = 0; - let fuckCount = 1; - if (count) { - fuckCount = count; - } - for (var i = 0; i < fuckCount; i++) { - fuckTarget = jsRandom(1,100); - if (slave.nipples == "fuckable" && fuckTarget > 80) { - V.mammaryTotal += 1; - slave.mammaryCount += 1; - } - else if (canDoVaginal(slave) && slave.vagina > 0 && fuckTarget > 33) { - V.vaginalTotal += 1; - slave.vaginalCount += 1; - } - else if (canDoAnal(slave) && slave.anus > 0 && fuckTarget > 10) { - V.analTotal += 1; - slave.analCount += 1; - } - else { - V.oralTotal += 1; - slave.oralCount += 1; + function long_collar(slave) { + switch (slave.collar) { + case "uncomfortable leather": + r += `Leather collar.`; + break; + case "tight steel": + r += `Steel collar.`; + break; + case "preg biometrics": + r += `Pregnancy biometrics collar.`; + break; + case "cruel retirement counter": + r += `Cruel counter collar.`; + break; + case "shock punishment": + r += `Shock collar.`; + break; + case "dildo gag": + r += `Dildo gag.`; + break; + case "massive dildo gag": + r += `Throat-bulging dildo gag.`; + break; + case "neck corset": + r += `Neck corset.`; + break; + case "stylish leather": + r += `Stylish leather collar.`; + break; + case "satin choker": + r += `Satin choker.`; + break; + case "silk ribbon": + r += `Silken ribbon.`; + break; + case "heavy gold": + r += `Gold collar.`; + break; + case "bowtie": + r += `Bowtie collar.`; + break; + case "pretty jewelry": + r += `Pretty collar.`; + break; + case "nice retirement counter": + r += `Nice counter collar.`; + break; + case "leather with cowbell": + r += `Cowbell collar.`; + break; + case "ancient Egyptian": + r += `Wesekh.`; + break; + case "ball gag": + r += `Ball gag.`; + break; + case "bit gag": + r += `Bit gag.`; + break; + case "porcelain mask": + r += `Porcelain mask.`; + break; } + r += " "; } - return; -} - -/* - count is how many times to increment either the Vaginal, Anal, or Oral counts, depending on availability of slave. - If count is left undefined it will assume it to be 1. - Intended to be a simple "x got fucked y times by z and I don't want to keep coding it". -*/ -window.SimpleSlaveSlaveFucking = function SimpleSlaveSlaveFucking(subslave, domslave, count) { - const V = State.variables; - let fuckTarget = 0; - let fuckCount = 1; - let r = ``; - if (count) { - fuckCount = count; - } - for (var j = 0; j < fuckCount; j++) { - //there is a reason randomization happens inside cycle - to spread fuck around, otherwise cycle isn't even needed - fuckTarget = jsRandom(1,100); - if (subslave.nipples === "fuckable" && canPenetrate(domslave) && fuckTarget > 80) { - if (passage() === "SA serve your other slaves") { - if (subslave.ID == V.slaves[V.i].ID) { - V.slaves[V.i].mammaryCount++; - V.mammaryTotal++; - domslave.penetrativeCount++; - V.penetrativeTotal++; - } - else { - subslave.mammaryCount++; - V.mammaryTotal++; - V.slaves[V.i].penetrativeCount++; - V.penetrativeTotal++; - } - } - else { - V.mammaryTotal++; - V.penetrativeTotal++; - subslave.mammaryCount++; - domslave.penetrativeCount++; - } + + function long_belly(slave) { + switch (slave.bellyAccessory) { + case "shapewear": + r += `Shapewear.`; + break; + case "a small empathy belly": + r += `Small fake belly.`; + break; + case "a medium empathy belly": + r += `Medium fake belly.`; + break; + case "a large empathy belly": + r += `Large fake belly.`; + break; + case "a huge empathy belly": + r += `Huge fake belly.`; + break; + case "a corset": + r += `Corset.`; + break; + case "an extreme corset": + r += `Extreme corsetage.`; + break; } - else if (canDoVaginal(subslave) && subslave.vagina > 0 && canPenetrate(domslave) && fuckTarget > 33) { - if (passage() === "SA serve your other slaves") { - if (subslave.ID == V.slaves[V.i].ID) { - V.slaves[V.i].vaginalCount++; - V.vaginalTotal++; - V.penetrativeTotal++; - domslave.penetrativeCount++; - } - else { - V.slaves[V.i].penetrativeCount++; - V.penetrativeTotal++; - subslave.vaginalCount++; - V.vaginalTotal++; - } - } - else { - V.vaginalTotal++; - subslave.vaginalCount++; - V.penetrativeTotal++; - domslave.penetrativeCount++; - } - if (canImpreg(subslave, domslave)) { - r += knockMeUp(subslave, 3, 0, domslave.ID, 1); - } + r += " "; + } + + function long_legs(slave) { + if (slave.legAccessory === "short stockings") { + r += `Short stockings.`; + } else if (slave.legAccessory === "long stockings") { + r += `Long stockings.`; } - else if (canDoAnal(subslave) && subslave.anus > 0 && canPenetrate(domslave) && fuckTarget > 10) { - //i think would impregnate from anal here even without .mpreg? same in original widget too - if (canImpreg(subslave, domslave) && subslave.mpreg == 1) { - r += knockMeUp(subslave, 3, 1, domslave.ID, 1); - } - if (passage() === "SA serve your other slaves") { - if (subslave.ID == V.slaves[V.i].ID) { - V.slaves[V.i].analCount++; - V.analTotal++; - V.penetrativeTotal++; - domslave.penetrativeCount++; - } - else { - V.slaves[V.i].penetrativeCount++; - V.penetrativeTotal++; - V.analTotal++; - subslave.analCount++; - } - } - else { - V.analTotal++; - subslave.analCount++; - V.penetrativeTotal++; - domslave.penetrativeCount++; - } + r += " "; + } + + function long_shoes(slave) { + if (slave.shoes === "heels") { + r += `Heels.`; + } else if (slave.shoes === "pumps") { + r += `Pumps.`; + } else if (slave.shoes === "extreme heels") { + r += `Extreme heels.`; + } else if (slave.shoes === "boots") { + r += `Boots.`; + } else if (slave.heels === 1) { + r += `<span class="yellow">Crawling.</span>`; + } else if (slave.shoes === "flats") { + r += `Flats.`; } - else { - V.oralTotal++; - subslave.oralCount++; + r += " "; + } + + function long_vaginal_acc(slave) { + switch (slave.vaginalAccessory) { + case "chastity belt": + r += `Vaginal chastity.`; + break; + case "combined chastity": + r += `Combined chastity.`; + break; + case "anal chastity": + r += `Anal chastity.`; + break; + case "dildo": + r += `Vaginal dildo.`; + break; + case "large dildo": + r += `Large vaginal dildo.`; + break; + case "huge dildo": + r += `Huge vaginal dildo.`; + break; + case "long dildo": + r += `Long vaginal dildo.`; + break; + case "long, large dildo": + r += `Long and large vaginal dildo.`; + break; + case "long, huge dildo": + r += `Long and wide vaginal dildo.`; + break; } + r += " "; } - return r; -} - -window.SimpleVaginaFuck = function SimpleVaginaFuck(slave, count) { - if (count) { - State.variables.vaginalTotal += count; - slave.vaginalCount += count; + + function long_dick_acc(slave) { + if (slave.dickAccessory === "chastity") { + r += `Chastity cage.`; + } else if (slave.dickAccessory === "combined chastity") { + r += `Combined chastity.`; + } else if (slave.dickAccessory === "anal chastity") { + r += `Anal chastity.`; + } + r += " "; } - else { - State.variables.vaginalTotal++; - slave.vaginalCount++; + + function long_buttplug(slave) { + switch (slave.buttplug) { + case "plug": + r += `Buttplug.`; + break; + case "large plug": + r += `Large buttplug.`; + break; + case "huge plug": + r += `Huge buttplug.`; + break; + case "long plug": + r += `Long buttplug.`; + break; + case "long, large plug": + r += `Large, long buttplug.`; + break; + case "long, huge plug": + r += `Enormous buttplug.`; + break; + } + r += " "; + switch (slave.buttplugAttachment) { + case "tail": + r += `Attached tail. `; + break; + } } -} - -window.SimpleAssFuck = function SimpleAssFuck(slave, count) { - if (count) { - State.variables.analTotal += count; - slave.analCount += count; + + function rules_assistant(slave) { + if (slave.useRulesAssistant === 0) { + r += `<span class="lightgreen">RA-Exempt</span> `; + } else if (V.abbreviateRulesets === 2 && (slave.currentRules !== undefined) && (slave.currentRules.length > 0)) { + r += `Rules: ${V.defaultRules.filter(x => ruleApplied(slave, x)).map(x => x.name).join(", ") }`; + } } - else { - State.variables.analTotal++; - slave.analCount++; + + function origins(slave) { + r += `<br>`; + if (V.seeImages !== 1 || V.seeSummaryImages !== 1 || V.imageChoice === 1) { + r += ` `; + } + r += `<span class="gray">${slave.origin}</span>`; } -} + + return SlaveSummaryUncached; +})(); -/*:: PenthouseNaming [script]*/ -window.MS = function() { - const V = State.variables; - var name = ""; - if (V.masterSuiteNameCaps === "The Master Suite") - name = "Master Suite" - else - name = V.masterSuiteNameCaps; - return `<<link "${name}""Master Suite">><</link>> `} -window.HS = function() { - const V = State.variables; - var name = ""; - if (V.HGSuiteNameCaps === "The Head Girl Suite") - name = "Head Girl Suite" - else - name = V.HGSuiteNameCaps; - return `<<link "${name}""Head Girl Suite">><</link>> `} -window.SQ = function() { - const V = State.variables; - var name = ""; - if (V.servantsQuartersNameCaps === "The Servants' Quarters") - name = "Servants' Quarters" - else - name = V.servantsQuartersNameCaps; - return `<<link "${name}""Servants' Quarters">><</link>> `} -window.S = function() { - const V = State.variables; - var name = ""; - if (V.spaNameCaps === "The Spa") - name = "Spa" - else - name = V.spaNameCaps; - return `<<link "${name}""Spa">><</link>> `} -window.CI = function() { - const V = State.variables; - var name = ""; - if (V.clinicNameCaps === "The Clinic") - name = "Clinic" - else - name = V.clinicNameCaps; - return `<<link "${name}""Clinic">><</link>> `} -window.SC = function() { - const V = State.variables; - var name = ""; - if (V.schoolroomNameCaps === "The Schoolroom") - name = "Schoolroom" - else - name = V.schoolroomNameCaps; - return `<<link "${name}""Schoolroom">><</link>> `} -window.CB = function() { - const V = State.variables; - var name = ""; - if (V.cellblockNameCaps === "The Cellblock") - name = "Cellblock" - else - name = V.cellblockNameCaps; - return `<<link "${name}""Cellblock">><</link>> `} -window.I = function() { - const V = State.variables; - var name = ""; - if (V.incubatorNameCaps === "The Incubator") - name = "Incubator" - else - name = V.incubatorNameCaps; - return `<<link "${name}""Incubator">><</link>> `} -- GitLab