diff --git a/js/003-data/gameVariableData.js b/js/003-data/gameVariableData.js index 12cbec347487303d3c991fecc5293561c4b25db7..fee41a5b8c3144c5d6ad33450f27a8c314356d5c 100644 --- a/js/003-data/gameVariableData.js +++ b/js/003-data/gameVariableData.js @@ -225,6 +225,9 @@ App.Data.defaultGameStateVariables = { retirementAge: 45, customRetirementAge: 45, customMenialRetirementAge: 65, + idealAge: 18, + targetIdealAge: 18, + idealAgeAdoption: 0, sortIncubatorList: "Unsorted", AgeEffectOnTrainerPricingPC: 1, AgeEffectOnTrainerEffectivenessPC: 1, @@ -366,6 +369,7 @@ App.Data.resetOnNGPlus = { }, childProtectionAct: 1, + idealAge: 0, culturalOpenness: 0, proRefugees: 0, publicFuckdolls: 0, diff --git a/js/003-data/policiesData.js b/js/003-data/policiesData.js index f3985991e1f125432d61a92f41ecf1e9404784af..b2b82cd5f2334eb50eea68f07bc43a377c019faa 100644 --- a/js/003-data/policiesData.js +++ b/js/003-data/policiesData.js @@ -312,6 +312,61 @@ App.Data.Policies.Selection = { get hide() { return (V.extremeUnderage === 1) ? {button: 0} : {button: 1}; } // CPA is complicated. It inits to "on". Make sure button is hidden if extreme underage is OFF. If a player enables extreme underage, then we can let them control it. } ], + "policies.idealAge": [ + { + title: "Ideal Age Of Sexual Appeal", + get text() { + const el = new DocumentFragment; + if(V.idealAge === 18) { + el.append(`most consider the ideal age of sexual appeal to be the old world default of 18. You will use your influence to change the sexually ideal age to `); + } + else { + el.append(`most consider the ideal age of sexual appeal to be ${V.idealAge}. You will use your influence to change the sexually ideal age to `); + } + el.append( + App.UI.DOM.makeElement( + "div", + App.UI.DOM.makeTextBox( + V.targetIdealAge, + v => { + let minAge = V.minimumSlaveAge; + let maxAge = V.retirementAge - 1 > 60 ? 60 : V.retirementAge - 1;/* problems do occur if idealAge can be set to over 60 */ + if(V.arcologies[0].FSMaturityPreferentialist !== "unset") { + minAge = 30; + } + if(V.arcologies[0].FSYouthPreferentialist !== "unset") { + maxAge = 29; + } + V.targetIdealAge = Math.clamp(v, minAge, maxAge); + App.UI.reload(); + }, + true + ), + ["indent"] + ) + ); + return el; + }, + get activatedText() { + return `you are using your personal influence to make ${V.targetIdealAge} the most sexually appealing age. The current percieved ideal age of sexual appeal is ${V.idealAge}.`; + }, + onRepeal: function() { + if(V.arcologies[0].FSMaturityPreferentialist !== "unset") { + if(V.idealAge < 30) { + V.idealAge = 30; + } + V.targetIdealAge = 30; + } + else { + if(V.idealAge >= 30) { + V.idealAge = 29; + } + V.targetIdealAge = 18; + } + }, + get note() { return `Will cost ${cashFormat(1500)} weekly until the target age is reached; high reputation will accelerate adoption.`} + } + ], "arcologies[0].FSEgyptianRevivalistIncestPolicy": [ { title: "Incest Encouragement", @@ -746,6 +801,9 @@ App.Data.Policies.Selection = { const age = Math.clamp(v, 20, 120); V.customRetirementAge = age; V.retirementAge = age; + if (V.idealAge >= V.retirementAge) { + V.idealAge = V.retirementAge - 1; + } App.UI.reload(); }, true @@ -776,6 +834,9 @@ App.Data.Policies.Selection = { const age = Math.clamp(v, 20, 120); V.customRetirementAge = age; V.retirementAge = age; + if(V.idealAge >= V.retirementAge) { + V.idealAge = V.retirementAge - 1; + } App.UI.reload(); }, true diff --git a/src/cheats/cheatEditArcology.js b/src/cheats/cheatEditArcology.js index 9f2c6640eabfc41ce47ba93c87060d45511440b3..3fa3fdac49e45869b02236da396b9da5f41f71f0 100644 --- a/src/cheats/cheatEditArcology.js +++ b/src/cheats/cheatEditArcology.js @@ -15,6 +15,29 @@ App.UI.Cheat.arcology = function(num) { el.append(tabBar.render()); } + if(num === 0) { + if(arc.FSMaturityPreferentialist !== "unset") { + if(V.idealAge < 30) { + V.idealAge = 30; + } + if(V.targetIdealAge < 30) { + V.targetIdealAge = 30; + } + V.policies.idealAge = 1; + } + else if(arc.FSYouthPreferentialist !== "unset") { + if(V.idealAge >= 30) { + V.idealAge = 29; + } + if(V.targetIdealAge >= 30) { + V.targetIdealAge = 29; + } + if(V.targetIdealAge !== 18) { + V.policies.idealAge = 1; + } + } + } + return el; function cheat() { @@ -134,7 +157,7 @@ App.UI.Cheat.arcology = function(num) { option.addValue(capRace, race); } } - } + } } el.append(options.render()); return el; diff --git a/src/data/backwardsCompatibility/policiesBC.js b/src/data/backwardsCompatibility/policiesBC.js index af28db08ccd7df11a64bc1ea017a14a3784a9805..1cf9125656d27e98753d1d0f84fe05131618039e 100644 --- a/src/data/backwardsCompatibility/policiesBC.js +++ b/src/data/backwardsCompatibility/policiesBC.js @@ -13,13 +13,10 @@ App.Update.policies = function() { } } - if (V.policies.gumjobFetishism == null) { - V.policies.gumjobFetishism = 0; - } - - if (V.policies.gumjobFetishismSMR == null) { - V.policies.gumjobFetishismSMR = 0; - } + App.Update.setNonexistentProperties(V.policies, { + gumjobFetishism: 0, + gumjobFetishismSMR: 0 + }); // Spelling fixes: V.policies.sexualOpenness = V.policies.sexualOpenness || V.policies.sexualOpeness || 0; diff --git a/src/endWeek/economics/arcmgmt.js b/src/endWeek/economics/arcmgmt.js index a52cdb25d9fd7b8012546aeb05853d8d71c6c7bb..bee0102dc008097f693ddd45e512d1825f886dc7 100644 --- a/src/endWeek/economics/arcmgmt.js +++ b/src/endWeek/economics/arcmgmt.js @@ -1058,6 +1058,41 @@ App.EndWeek.arcManagement = function() { function policiesImpact() { const el = new DocumentFragment(); const r = []; + if(V.policies.idealAge) { + if(V.targetIdealAge !== V.idealAge) { + r.push(`You spend <span class="yellow">${cashFormat(1500)}</span> and use your personal influence to shift the percieved ideal age of sexual appeal.`); + V.idealAgeAdoption += V.rep / 100; + if(V.idealAgeAdoption > 100) { + const adoptionModifier = Math.floor(V.idealAgeAdoption / 100); + if(V.targetIdealAge > V.idealAge) { + V.idealAge = Math.clamp(Math.floor(V.idealAge + adoptionModifier),V.idealAge,V.targetIdealAge); + } else { + V.idealAge = Math.clamp(Math.floor(V.idealAge - adoptionModifier),V.idealAge,V.targetIdealAge); + } + if(adoptionModifier > 1) { + r.push(`Your peerless reptutation <span class="green">rapidly accelerates</span> the adoption of your proposed ideal age of sexual appeal, and most now consider it to be ${V.idealAge}.`); + } else { + r.push(`The percieved ideal age of sexual appeal has shifted ${V.idealAge === V.targetIdealAge ? "to" : "toward"} ${V.targetIdealAge}${V.idealAge !== V.targetIdealAge ? ", and most now consider the ideal age to be " + V.idealAge : ""}.`); + } + if(V.targetIdealAge === V.idealAge) { + r.push(`The percieved ideal age of sexual appeal has <span class="green">reached your intended target.</span>`); + } + V.idealAgeAdoption = V.idealAgeAdoption - (100 * adoptionModifier); + } + else { + if(V.idealAgeAdoption <= 0) { + r.push(`Unfortunately, your efforts <span class="red">had no effect</span> on the perceived ideal age of sexual appeal, and it remains ${V.idealAge}.`); + } + else { + r.push(`You have made <span class="yellow">partial progress</span> in shifting the perceived ideal age of sexual appeal, but for now, it remains ${V.idealAge}.`); + } + } + } else { + r.push(`Most continue to consider the ideal age of sexual appeal to be ${V.idealAge}.`); + } + } else { + r.push(`Most consider the ideal age of sexual appeal to be ${V.idealAge}.`); + } if (V.policies.retirement.menial2Citizen === 1) { slaveDemandU *= 0.8; slaveDemandT *= 0.75; diff --git a/src/events/intro/introSummary.js b/src/events/intro/introSummary.js index dcf7e99ff8802c00569c7165b78fbe19e46f266a..f72206639a9929d774233191868f72c6a26cce8c 100644 --- a/src/events/intro/introSummary.js +++ b/src/events/intro/introSummary.js @@ -10,6 +10,19 @@ App.Intro.summary = function() { V.minimumSlaveAge = variableAsNumber(V.minimumSlaveAge, 3, 18, 18); V.retirementAge = variableAsNumber(V.retirementAge, 25, 120, 45); + let minAge = V.minimumSlaveAge; + let maxAge = V.retirementAge - 1 > 60 ? 60 : V.retirementAge - 1; + let defaultAge = 18; + if(V.targetArcology.fs === "FSMaturityPreferentialist") { + minAge = 30; + defaultAge = 30; + } + else if(V.targetArcology.fs === "FSYouthPreferentialist") { + maxAge = 29; + } + V.idealAge = variableAsNumber(V.idealAge, minAge, maxAge, defaultAge); + V.targetIdealAge = V.idealAge; + V.fertilityAge = variableAsNumber(V.fertilityAge, 3, 18, 13); V.potencyAge = variableAsNumber(V.potencyAge, 3, 18, 13); V.PC.mother = Number(V.PC.mother); @@ -609,6 +622,10 @@ App.Intro.summary = function() { options.addOption("Initial retirement age will be at", "retirementAge") .addComment("May cause issues with New Game and initial slaves if set below 45.").showTextBox(); + V.idealAge = Math.clamp(V.idealAge, minAge, maxAge); + options.addOption("Initial ideal age of sexual appeal will be", "idealAge") + .addComment("Percieved beauty will decrease the farther (younger or older) a body is visually from this age.").showTextBox(); + V.fertilityAge = Math.clamp(V.fertilityAge, 3, 18); options.addOption("Girls will not be able to become pregnant if their age is under", "fertilityAge").showTextBox(); diff --git a/src/futureSocieties/fsPassage.js b/src/futureSocieties/fsPassage.js index 31e77af51fb4d8151f6d1c534f2ce13526773951..86cb4b40626ed879a404c703efbb8f560c3f2aa6 100644 --- a/src/futureSocieties/fsPassage.js +++ b/src/futureSocieties/fsPassage.js @@ -718,6 +718,15 @@ App.UI.fsPassage = function() { "Youth Preferentialism", () => { arc.FSYouthPreferentialist = 4; + if(V.idealAge >= 30) { + V.idealAge = 29; + } + if(V.targetIdealAge >= 30) { + V.targetIdealAge = 29; + } + if(V.targetIdealAge !== 18) { + V.policies.idealAge = 1; + } App.UI.reload(); } ) @@ -742,6 +751,13 @@ App.UI.fsPassage = function() { "Maturity Preferentialism", () => { arc.FSMaturityPreferentialist = 4; + if(V.idealAge < 30) { + V.idealAge = 30; + } + if(V.targetIdealAge < 30) { + V.targetIdealAge = 30; + } + V.policies.idealAge = 1; App.UI.reload(); } ) diff --git a/src/js/economyJS.js b/src/js/economyJS.js index ac2907a22aa8314a4b3446e5ea2cbeaa96685297..d23112d09e4451d7047fdb84cb1706adee01a54c 100644 --- a/src/js/economyJS.js +++ b/src/js/economyJS.js @@ -751,6 +751,9 @@ globalThis.calculateCosts = (function() { function getPolicyCosts() { let costs = 0; + if (V.policies.idealAge && (V.targetIdealAge !== V.idealAge)) { + costs += 1500; + } if (V.policies.alwaysSubsidizeGrowth === 1) { costs += policies.cost(); } diff --git a/src/js/slaveCostJS.js b/src/js/slaveCostJS.js index bb1999bf6eb4b2caf942022a87eeba2e471e1aae..d080e0bebeee1b20813dd850c3fa8a492a409a43 100644 --- a/src/js/slaveCostJS.js +++ b/src/js/slaveCostJS.js @@ -431,12 +431,12 @@ globalThis.BeautyArray = (function() { adjustBeauty("Skilled: Slave Professionalism", ((arcology.FSSlaveProfessionalism / 50) * ((slave.skill.entertainment + slave.skill.whoring + slave.skill.oral + slave.skill.anal + slave.skill.vaginal) / 100))); /* 10 */ } if (arcology.FSYouthPreferentialist !== "unset") { - if (V.retirementAge <= 60) { - adjustBeauty("Age: Youth Preferentialist", ((30 - slave.visualAge) / (30 - V.minimumSlaveAge) * ((arcology.FSYouthPreferentialist / 2) + (arcology.FSYouthPreferentialistLaw * 10)))); /* max 60 */ + if(slave.visualAge < 30) { + adjustBeauty("Age: Youth Preferentialist", Math.clamp(((arcology.FSYouthPreferentialist / 2) + (arcology.FSYouthPreferentialistLaw * 10)) - Math.round(Math.abs(slave.visualAge - V.idealAge) * 2.222),0,60)); /* max 60 */ } } else if (arcology.FSMaturityPreferentialist !== "unset") { - if (V.retirementAge.isBetween(30, 60, true)) { - adjustBeauty("Age: Maturity Preferentialist", ((30 - slave.visualAge) / (30 - V.retirementAge) * ((arcology.FSMaturityPreferentialist / 2) + (arcology.FSMaturityPreferentialistLaw * 10)))); /* max 60, problems if retirementAge is 30 or under */ + if(slave.visualAge >= 30 && slave.visualAge < 60) { + adjustBeauty("Age: Maturity Preferentialist", Math.clamp(((arcology.FSMaturityPreferentialist / 2) + (arcology.FSMaturityPreferentialistLaw * 10)) - Math.round(Math.abs(slave.visualAge - V.idealAge) * 2.222),0,60)); /* max 60 */ } } if (arcology.FSBodyPurist > 20) { @@ -500,7 +500,8 @@ globalThis.BeautyArray = (function() { adjustBeauty(`Voice Pitch`, (slave.voice)); adjustBeauty(`Skill: Entertainment (${slave.skill.entertainment})`, (slave.skill.entertainment / 10)); adjustBeauty(`Skill: Whoring (${slave.skill.whoring})`, (slave.skill.whoring / 10)); - adjustBeauty(`Age: Visual Age (${slave.visualAge})`, -(3 * slave.visualAge)); + const ageBeautyPenaltyOffset = slave.visualAge - V.idealAge === 0 ? 0 : 9; + adjustBeauty(`Age: Visual Age (${slave.visualAge})`, -((3 * Math.abs(slave.visualAge - V.idealAge)) + ageBeautyPenaltyOffset)); if (App.Data.Careers.General.entertainment.includes(slave.career)) { adjustBeauty("Career: Entertainment", (20)); } else if (V.week - slave.weekAcquired >= 20 && slave.skill.entertainment >= 100) { diff --git a/src/npc/descriptions/descriptionWidgets.js b/src/npc/descriptions/descriptionWidgets.js index 49d7996376f16bb95937030c682ecceac456bf0a..9afaef4b7424b581f3ebefa96144a163e6d38ceb 100644 --- a/src/npc/descriptions/descriptionWidgets.js +++ b/src/npc/descriptions/descriptionWidgets.js @@ -468,7 +468,25 @@ App.Desc.ageAndHealth = function(slave) { } age = slave.actualAge + 1; r += ` ${He} `; - if (slave.birthWeek >= 52 && V.seeAge) { + if(slave.actualAge === V.idealAge || (slave.actualAge === V.idealAge - 1 && slave.birthWeek >= 52 && V.seeAge)) { + if(slave.birthWeek >= 52 && V.seeAge) { + r += `is going to turn ${age} this week`; + if (V.showAgeDetail && V.seeAge !== 0 && slave.actualAge !== V.idealAge) { + r += `, and people are looking forward to ${his} birthday with great interest.`; + } else { + r += `.`; + } + } + else if(!slave.birthWeek && V.seeAge) { + r += `just turned ${num(slave.actualAge)} this week, which many citizens find especially appealing.`; + } + else if (slave.birthWeek < 4 && V.seeAge) { + r += `only turned ${num(slave.actualAge)} this month. `; + } else { + r += `is ${num(slave.actualAge)} years old${birthday}. `; + } + } + else if (slave.birthWeek >= 52 && V.seeAge) { r += `is going to turn ${age} this week,`; } else if (slave.actualAge < 3) { r += `is an infant, only `; @@ -513,21 +531,9 @@ App.Desc.ageAndHealth = function(slave) { } else if (slave.actualAge < 17) { r += `is young and fresh at ${num(slave.actualAge)}${birthday}. `; } else if (slave.actualAge < 18) { - r += `is young, fresh, and nearly 18${birthday}`; - if (V.showAgeDetail && V.seeAge !== 0) { - if (V.seeAge) { - r += ` and people are already beginning to eye ${him}`; - } - } - r += `. `; + r += `is young, fresh, and nearly 18${birthday}.`; } else if (slave.actualAge < 19) { - if (!slave.birthWeek && V.seeAge) { - r += `just turned ${num(slave.actualAge)} this week, which many citizens find especially appealing. `; - } else if (slave.birthWeek < 4 && V.seeAge) { - r += `only turned ${num(slave.actualAge)} this month. `; - } else { - r += `is ${num(slave.actualAge)} years old${birthday}. `; - } + r += `is ${num(slave.actualAge)} years old${birthday}. `; } else if (slave.actualAge < 20) { r += `is in ${his} final year as a teenager at age 19${birthday}. `; } else if (slave.actualAge < 26) { diff --git a/src/npc/descriptions/longSlave.js b/src/npc/descriptions/longSlave.js index 46a519fab8e814a16e6205867d1747ea5045f70c..a996c0e7265408bb25d351c59080969a609ac91e 100644 --- a/src/npc/descriptions/longSlave.js +++ b/src/npc/descriptions/longSlave.js @@ -293,6 +293,38 @@ App.Desc.longSlave = function(slave, {descType, market = 0, prisonCrime, noArt} r.push(`bimbo by societal trends.`); } + if(slave.visualAge === V.idealAge) { + if(slave.actualAge === V.idealAge) { + r.push(`${He} is ${slave.actualAge}, `); + } else { + r.push(`${He} appears to be ${slave.visualAge}, `); + } + if(V.idealAge === 18) { + r.push(`and many still find this age especially attractive due to old world tradition.`); + } else { + r.push(`and many in the arcology find this age especially attractive.`); + } + } else if (slave.visualAge !== slave.actualAge && slave.visualAge === V.idealAge - 1) { + r.push(`${He} appears to be ${slave.visualAge}, which is nearly the ideal, but as ${he} is actually ${slave.actualAge}, this can sometimes be cause for confusion regarding the appropriate level of enthusiasm society should have for ${him}.`); + } else if(slave.visualAge === V.idealAge - 1) { + if(slave.actualAge === V.idealAge - 1) { + r.push(`${He} is ${slave.actualAge}, `); + } else { + r.push(`${He} appears to be ${slave.visualAge}, `); + } + if(V.idealAge === 18) { + r.push(`and many are already looking forward to ${his} birthday with great anticipation due to old world tradition.`); + } else { + r.push(`and many in the arcology are already looking forward to ${his} birthday with great anticipation.`); + } + } else if(slave.actualAge === V.idealAge && slave.visualAge !== V.idealAge) { + r.push(`${He} is ${slave.actualAge}, a fact that many in the arcology find appealing `); + if(V.idealAge === 18) { + r.push(`because of old world tradition, `); + } + r.push(`but due to ${his} appearing to be ${slave.visualAge}, there is less enthusiasm for ${him} than there might otherwise be.`); + } + $(p).append(r.join(" ")); if (V.showScores !== 0) {