diff --git a/devTools/types/FC/human.d.ts b/devTools/types/FC/human.d.ts index c804ce0d2625f775a0e2f78b667c948fbae49731..8a2776e8ea9f25048462873842ab98dd3335d937 100644 --- a/devTools/types/FC/human.d.ts +++ b/devTools/types/FC/human.d.ts @@ -405,6 +405,8 @@ declare global { * * **macromastia + gigantomastia** - Breasts never stop growing. Increased growth rate, no shrink rate. */ gigantomastia: GeneticQuirk | 3; + /** sperm is much more likely to knock someone up */ + potent: GeneticQuirk; /** is prone to having twins, shorter pregnancy recovery rate */ fertility: GeneticQuirk; /** is prone to having multiples, even shorter pregnancy recovery rate @@ -441,6 +443,9 @@ declare global { mGain: GeneticQuirk; /** constantly loses muscle mass, easier to gain muscle. mGain + mLoss - muscle gain/loss amplified, passively lose muscle unless building */ mLoss: GeneticQuirk; + /** ova will split if room is available + * only affects fetuses */ + twinning: GeneticQuirk; /** slave can only ever birth girls */ girlsOnly: GeneticQuirk; /** abnormal production of amniotic fluid @@ -482,6 +487,8 @@ declare global { fetish: Fetish; spermY: number; inbreedingCoeff?: number; + adultHeight: number; + artSeed: number; } //#endregion diff --git a/src/002-config/fc-version.js b/src/002-config/fc-version.js index 86917d4b34807cea99329f3261a336f25142af07..ccc8c2c2e2dee16ebc9920e85981302f31647bd9 100644 --- a/src/002-config/fc-version.js +++ b/src/002-config/fc-version.js @@ -2,5 +2,5 @@ App.Version = { base: "0.10.7.1", // The vanilla version the mod is based off of, this should never be changed. pmod: "4.0.0-alpha.23", commitHash: null, - release: 1187, // When getting close to 2000, please remove the check located within the onLoad() function defined at line five of src/js/eventHandlers.js. + release: 1188, // When getting close to 2000, please remove the check located within the onLoad() function defined at line five of src/js/eventHandlers.js. }; diff --git a/src/Mods/Catmod/generateCatgirl.js b/src/Mods/Catmod/generateCatgirl.js index 2bd8936d82b0b793efde344dbc5fec3d48a5d917..5724ff6500e8967a6ce6356437a18f54e3d0b9ce 100644 --- a/src/Mods/Catmod/generateCatgirl.js +++ b/src/Mods/Catmod/generateCatgirl.js @@ -41,9 +41,11 @@ globalThis.growCatgirl = function(sex, { // they're genetically engineered and very expensive, so go ahead and make their genes conform a bit better to local expectations... const arc = V.arcologies[0]; if (arc.FSStatuesqueGlorification !== "unset") { - slave.height = Math.min(slave.height + 10, 274); + slave.natural.height = Math.min(slave.natural.height + 10, 274); + slave.height = Height.forAge(slave.natural.height, slave); } else if (arc.FSPetiteAdmiration !== "unset") { - slave.height = Math.max(slave.height - 10, 85); + slave.natural.height = Math.max(slave.natural.height - 10, 85); + slave.height = Height.forAge(slave.natural.height, slave); } if (arc.FSIntellectualDependency !== "unset") { slave.intelligence = Math.max(slave.intelligence - 15, -100); diff --git a/src/art/webgl/art.js b/src/art/webgl/art.js index d1ca2f14c228623d830c03ab233c2f28a7bc0ca6..d3d801ba068f1c2592eca21eb7a5d5e401d72b27 100644 --- a/src/art/webgl/art.js +++ b/src/art/webgl/art.js @@ -9,6 +9,11 @@ App.Art.hexToRgb = function(hex) { App.Art.seed = 0; +App.Art.setSeed = function(slave, offset) { + App.Art.seed = slave.natural.artSeed + offset; + return App.Art.seed; +}; + App.Art.random = function() { App.Art.seed += 1; let x = Math.sin(App.Art.seed) * 10000; @@ -82,7 +87,7 @@ App.Art.getArtParams = function(slave) { }; App.Art.applyFigures = function(slave, scene, p) { - App.Art.seed = slave.ID; + App.Art.seed = App.Art.setSeed(slave, 0); let figures = []; switch (slave.clothes) { @@ -1133,7 +1138,7 @@ App.Art.applyFigures = function(slave, scene, p) { }; App.Art.applySurfaces = function(slave, scene, p) { - App.Art.seed = slave.ID + 1000; + App.Art.seed = App.Art.setSeed(slave, 1000); let glansFutaliciousShellLayers = []; let shaftFutaliciousShellLayers = []; @@ -1294,28 +1299,30 @@ App.Art.applySurfaces = function(slave, scene, p) { } let pubicStyle = ""; - switch (slave.pubicHStyle) { - case "hairless": - case "waxed": - case "bald": - break; - case "neat": - pubicStyle = "PubicNeat"; - break; - case "in a strip": - pubicStyle = "PubicStrip"; - break; - case "bushy": - pubicStyle = "PubicBushy"; - break; - case "very bushy": - pubicStyle = "PubicVeryBushy"; - break; - case "bushy in the front and neat in the rear": - pubicStyle = "PubicBushyFront"; - break; - default: - break; + if (slave.physicalAge >= slave.pubertyAge) { + switch (slave.pubicHStyle) { + case "hairless": + case "waxed": + case "bald": + break; + case "neat": + pubicStyle = "PubicNeat"; + break; + case "in a strip": + pubicStyle = "PubicStrip"; + break; + case "bushy": + pubicStyle = "PubicBushy"; + break; + case "very bushy": + pubicStyle = "PubicVeryBushy"; + break; + case "bushy in the front and neat in the rear": + pubicStyle = "PubicBushyFront"; + break; + default: + break; + } } if (pubicStyle !== "") { @@ -1637,7 +1644,7 @@ App.Art.applySurfaces = function(slave, scene, p) { }; App.Art.applyMaterials = function(slave, scene, p) { - App.Art.seed = slave.ID + 2000; + App.Art.seed = App.Art.setSeed(slave, 2000); let materials = []; @@ -2172,29 +2179,31 @@ App.Art.applyMaterials = function(slave, scene, p) { materials.push(["TemplateGenitalia", "Ni", Ni]); materials.push(["TemplateGenitalia", "map_Ka", "base/skin/" + skin + "Torso.jpg"]); - let pubicColor = App.Art.hexToRgb(extractColor(slave.pubicHColor)); - switch (slave.pubicHStyle) { - case "hairless": - case "waxed": - case "bald": - break; - case "neat": - materials.push(["PubicNeat", "Ka", pubicColor]); - break; - case "in a strip": - materials.push(["PubicStrip", "Ka", pubicColor]); - break; - case "bushy": - materials.push(["PubicBushy", "Ka", pubicColor]); - break; - case "very bushy": - materials.push(["PubicVeryBushy", "Ka", pubicColor]); - break; - case "bushy in the front and neat in the rear": - materials.push(["PubicBushyFront", "Ka", pubicColor]); - break; - default: - break; + if (slave.physicalAge >= slave.pubertyAge) { + const pubicColor = App.Art.hexToRgb(extractColor(slave.pubicHColor)); + switch (slave.pubicHStyle) { + case "hairless": + case "waxed": + case "bald": + break; + case "neat": + materials.push(["PubicNeat", "Ka", pubicColor]); + break; + case "in a strip": + materials.push(["PubicStrip", "Ka", pubicColor]); + break; + case "bushy": + materials.push(["PubicBushy", "Ka", pubicColor]); + break; + case "very bushy": + materials.push(["PubicVeryBushy", "Ka", pubicColor]); + break; + case "bushy in the front and neat in the rear": + materials.push(["PubicBushyFront", "Ka", pubicColor]); + break; + default: + break; + } } switch (slave.vaginaLube) { @@ -2596,7 +2605,7 @@ App.Art.getAnimState = function(slave, scene, p, morphs, isAnimTick) { }; App.Art.applyMorphs = function(slave, scene, p, isAnimating) { - App.Art.seed = slave.ID + 3000; + App.Art.seed = App.Art.setSeed(slave, 3000); let morphs = []; diff --git a/src/data/backwardsCompatibility/backwardsCompatibility.js b/src/data/backwardsCompatibility/backwardsCompatibility.js index 5a46884413b8b20276015fceefefbe42d95e5b48..033ec6041b41ae7f5d3da5637140dd411ab52abd 100644 --- a/src/data/backwardsCompatibility/backwardsCompatibility.js +++ b/src/data/backwardsCompatibility/backwardsCompatibility.js @@ -1546,6 +1546,16 @@ App.Update.slaveRecords = function(node) { if (child.spermY === undefined) { child.spermY = normalRandInt(50, 5); } + if (!child.natural) { + child.natural = new App.Entity.GeneticState(); + if (child.geneticQuirks.dwarfism === 2 && child.geneticQuirks.gigantism !== 2) { + child.natural.height = Height.randomAdult(child, {limitMult: [-4, -1], spread: 0.15}); + } else if (child.geneticQuirks.gigantism === 2) { + child.natural.height = Height.randomAdult(child, {limitMult: [3, 10], spread: 0.15}); + } else { + child.natural.height = Height.randomAdult(child); + } + } App.Facilities.Nursery.InfantDatatypeCleanup(child); child.inbreedingCoeff = ibc.coeff(child); } else { @@ -2391,8 +2401,6 @@ App.Update.oldVersions = function(node) { } } - WombInit(newPC); - V.PC = clone(newPC); if (typeof V.PC.name === "undefined") { @@ -2445,6 +2453,22 @@ App.Update.oldVersions = function(node) { V.PC.skill.combat = 10; } } + if (!V.PC.natural) { + V.PC.natural = new App.Entity.GeneticState(); + if (V.PC.physicalAge >= 20) { + V.PC.natural.height = V.PC.height - V.PC.heightImplant * 10; + } else { + // find and set a reasonable natural height for this immature player + if (V.PC.geneticQuirks.dwarfism === 2 && V.PC.geneticQuirks.gigantism !== 2) { + V.PC.natural.height = Height.randomAdult(V.PC, {limitMult: [-4, -1], spread: 0.15}); + } else if (V.PC.geneticQuirks.gigantism === 2) { + V.PC.natural.height = Height.randomAdult(V.PC, {limitMult: [3, 10], spread: 0.15}); + } else { + V.PC.natural.height = Height.randomAdult(V.PC); + } + } + } + WombInit(V.PC); if (V.releaseID < 1185) { if (V.nurseryNannies > 0) { diff --git a/src/data/backwardsCompatibility/updateSlaveObject.js b/src/data/backwardsCompatibility/updateSlaveObject.js index 56448a7cdaff6b1903353af712062a70682d37b8..862d8e041712ea59dac07705fdf4f22ab720c037 100644 --- a/src/data/backwardsCompatibility/updateSlaveObject.js +++ b/src/data/backwardsCompatibility/updateSlaveObject.js @@ -1437,4 +1437,21 @@ App.Update.Slave = function(slave, genepool = false) { slave.skill.combat = 70; } } + + if (!slave.natural) { + slave.natural = new App.Entity.GeneticState(); + slave.natural.artSeed = slave.ID; // used to use the ID as the seed; copy it on old slaves so they don't suddenly change appearance + if (slave.physicalAge >= 20) { + slave.natural.height = slave.height - slave.heightImplant * 10; + } else { + // find and set a reasonable natural height for this immature slave + if (slave.geneticQuirks.dwarfism === 2 && slave.geneticQuirks.gigantism !== 2) { + slave.natural.height = Height.randomAdult(slave, {limitMult: [-4, -1], spread: 0.15}); + } else if (slave.geneticQuirks.gigantism === 2) { + slave.natural.height = Height.randomAdult(slave, {limitMult: [3, 10], spread: 0.15}); + } else { + slave.natural.height = Height.randomAdult(slave); + } + } + } }; diff --git a/src/endWeek/nextWeek/nextWeek.js b/src/endWeek/nextWeek/nextWeek.js index f4d433d5478147dc3868e7261e0fe92a1724c891..7fee81272282a2bff1ebe5a4877e67cda1f66707 100644 --- a/src/endWeek/nextWeek/nextWeek.js +++ b/src/endWeek/nextWeek/nextWeek.js @@ -39,7 +39,7 @@ App.EndWeek.nextWeek = function() { V.PC.visualAge++; V.PC.ovaryAge += either(0.8, 0.9, 0.9, 1.0, 1.0, 1.0, 1.1); } - if (V.PC.physicalAge <= 18 && V.loliGrow > 0) { + if (V.PC.physicalAge <= 20 && V.loliGrow > 0) { App.EndWeek.Shared.physicalDevelopment(V.PC, true); } agePCEffects(); diff --git a/src/endWeek/player/prDrugs.js b/src/endWeek/player/prDrugs.js index 7385a8de254f83be27803563bd2f424f539750e4..eb3188b48b8b8672994018e1b371b9ac2765f5f5 100644 --- a/src/endWeek/player/prDrugs.js +++ b/src/endWeek/player/prDrugs.js @@ -879,9 +879,9 @@ App.EndWeek.Player.drugs = function(PC = V.PC) { // evaluate against expected height, with neoteny comparing against expected height for 12 year olds... let heightDiff; if (PC.geneticQuirks.neoteny === 2 && PC.physicalAge > 12) { - heightDiff = (PC.height - PC.heightImplant * 10) / Height.mean(PC.nationality, PC.race, PC.genes, 12); + heightDiff = (PC.height - PC.heightImplant * 10) / Height.forAge(PC.natural.height, 12, PC.genes); } else { - heightDiff = (PC.height - PC.heightImplant * 10) / Height.mean(PC); + heightDiff = (PC.height - PC.heightImplant * 10) / Height.forAge(PC.natural.height, PC); } // if you are taller than the expected height the growth is reduced, if shorter accelerated proportionally to the distance from the expected height heightDiff = 1 - heightDiff; diff --git a/src/endWeek/reports/incubatorReport.js b/src/endWeek/reports/incubatorReport.js index ac5dc09d1fc551356cea0e6c5c5451797cc7f6b7..a3f138fee6a7cd656f86d76022ac9c5339471aaa 100644 --- a/src/endWeek/reports/incubatorReport.js +++ b/src/endWeek/reports/incubatorReport.js @@ -156,23 +156,23 @@ App.EndWeek.incubatorReport = function() { r = []; if (V.incubator.upgrade.growthStims === 1 && V.incubator.setting.growthStims !== 0) { - let heightLimit = Math.clamp((Height.mean(tank) * 1.25), 0, 274); - let heightLimitAge = Height.mean(tank); + let heightLimit = Math.clamp((Height.forAge(tank.natural.height, tank) * 1.25), 0, 274); + let heightLimitAge = Height.forAge(tank.natural.height, tank); if (tank.geneticQuirks.dwarfism === 2 && tank.geneticQuirks.gigantism !== 2) { - heightLimit = Math.clamp((Height.mean(tank) * 0.95), 0, 160); + heightLimit = Math.clamp((Height.forAge(tank.natural.height, tank) * 0.95), 0, 160); } else if (tank.geneticQuirks.gigantism === 2 && tank.geneticQuirks.dwarfism !== 2) { - heightLimit = Math.clamp((Height.mean(tank) * 1.75), 0, 274); + heightLimit = Math.clamp((Height.forAge(tank.natural.height, tank) * 1.75), 0, 274); } if (tank.geneMods.NCS === 1) { /* NCS should block physical growth beyond that of a toddler, but some players might like * a little more or less. So using V.minimumSlaveAge or 8, whichever is lesser. */ const limitAge = Math.min(8, V.minimumSlaveAge); - /* Generate new average height for slave of age limitAge */ - heightLimitAge = Height.mean(tank.nationality, tank.race, tank.genes, limitAge); - heightLimit = heightLimitAge; /* TODO: Add some variation, right now all NCS slaves will be the exact same height */ + /* scale height to age 8 */ + heightLimitAge = Height.forAge(tank.natural.height, limitAge); + heightLimit = heightLimitAge; } else if (tank.geneticQuirks.neoteny === 2 && tank.physicalAge > 12) { - /* Generate new average height for slave of age 12 */ - heightLimitAge = Height.mean(tank.nationality, tank.race, tank.genes, 12); + /* scale height to age 12 */ + heightLimitAge = Height.forAge(tank.natural.height, 12); heightLimit = Math.clamp((heightLimitAge * 1.25), 0, 274); } if (tank.height >= heightLimit) { diff --git a/src/endWeek/saDrugs.js b/src/endWeek/saDrugs.js index c03bba400e049622c79ae92511f68bb56005c652..13c74177ab9f3151ec12e3eedbd5d05e743ebe5c 100644 --- a/src/endWeek/saDrugs.js +++ b/src/endWeek/saDrugs.js @@ -930,9 +930,9 @@ App.SlaveAssignment.drugs = function saDrugs(slave) { // evaluate against slave expected height, with neoteny slaves comparing against expected height for 12 year olds... let heightDiff; if (slave.geneticQuirks.neoteny === 2 && slave.physicalAge > 12) { - heightDiff = (slave.height - slave.heightImplant * 10) / Height.mean(slave.nationality, slave.race, slave.genes, 12); + heightDiff = (slave.height - slave.heightImplant * 10) / Height.forAge(slave.natural.height, 12, slave.genes); } else { - heightDiff = (slave.height - slave.heightImplant * 10) / Height.mean(slave); + heightDiff = (slave.height - slave.heightImplant * 10) / Height.forAge(slave.natural.height, slave); } // if ${he} is taller than the expected height the growth is reduced, if shorter accelerated proportionally to the distance from the expected height heightDiff = 1 - heightDiff; diff --git a/src/endWeek/shared/physicalDevelopment.js b/src/endWeek/shared/physicalDevelopment.js index 6b7e98562c4d8c389e9b934b090f55923bc91a94..3765d58dfe0aa2c4b1a09ef33d9f7d7a69b97db0 100644 --- a/src/endWeek/shared/physicalDevelopment.js +++ b/src/endWeek/shared/physicalDevelopment.js @@ -5,7 +5,6 @@ App.EndWeek.Shared.physicalDevelopment = function(actor, player = false) { const rearQuirkDivider = rearQuirk === 0 ? 1 : rearQuirk; const dickMod = (actor.geneticQuirks.wellHung === 2 ? 2 : 1); let physicalAgeSwap; - const tallerPC = (player && actor.height >= Height.mean(actor) + 5 && actor.bodySwap === 0); if (actor.geneticQuirks.progeria === 2) { // since progeria increases .physicalAge, we need to work around it. @@ -15,1557 +14,109 @@ App.EndWeek.Shared.physicalDevelopment = function(actor, player = false) { physicalAgeSwap = actor.physicalAge; } if (actor.geneMods.NCS !== 1) { - /* NCS completely blocks all natural physical growth: no height increases. It also blocks all hormonal secondary sexual * characteristics. So, on the female side: no boobs, no butt, no hips, and no labia. And on the male side: no dick, no clit, no balls, no scrotum, no shoulders. */ + /* NCS completely blocks all natural physical growth: no height increases. It also blocks all hormonal secondary sexual + * characteristics. So, on the female side: no boobs, no butt, no hips, and no labia. And on the male side: no dick, no clit, no balls, no scrotum, no shoulders. */ /* so this is a big old NO-OP to skip the physical development. */ - if (actor.geneticQuirks.androgyny === 2) { /* takes a mix of both to create a very androgynous slave */ - if (actor.geneticQuirks.dwarfism === 2 && actor.geneticQuirks.gigantism !== 2) { - increaseHeightDwarf(actor); - } else if (actor.geneticQuirks.gigantism === 2) { - increaseHeightGiant(actor); - } else if (actor.geneticQuirks.neoteny === 2) { - increaseHeightNeoteny(actor); - } else { - increaseHeightXX(actor); - } - if (actor.geneticQuirks.neoteny !== 2) { - if (actor.boobs - actor.boobsImplant <= 300) { - increaseBoobsXX(actor); - } - if (actor.dick.isBetween(0, 3) || actor.geneticQuirks.wellHung === 2) { - increaseDick(actor); - } - if (actor.balls.isBetween(0, 3)) { - increaseBalls(actor); - } - if (actor.vagina > 0 && actor.ovaries > 0 && physicalAgeSwap > actor.pubertyAgeXX) { - increaseWetness(actor); - } - if (actor.waist < 10) { - increaseWaistXY(actor); - } - if (actor.hips - actor.hipsImplant < 0) { - increaseHipsXX(actor); - } - if (actor.butt - actor.buttImplant < 3) { - increaseButtXX(actor); - } - } - increasePregAdaptationXX(actor); - } else if (actor.genes === "XX") { /* loli becoming a woman */ - if (actor.geneticQuirks.dwarfism === 2 && actor.geneticQuirks.gigantism !== 2) { - increaseHeightDwarf(actor); - } else if (actor.geneticQuirks.gigantism === 2) { - increaseHeightGiant(actor); - } else if (actor.geneticQuirks.neoteny === 2) { - increaseHeightNeoteny(actor); - } else { - increaseHeightXX(actor); - } - if (physicalAgeSwap === 13 || (physicalAgeSwap > 13 && (actor.hormoneBalance >= 100 || actor.hormoneBalance <= -100))) { - increaseFaceXX(actor); - if (actor.voice > 1) { - increaseVoiceXX(actor); - } - } - if (actor.geneticQuirks.neoteny !== 2) { - increaseBoobsXX(actor); - if (actor.clit > 0) { - increaseClit(actor); - } - if (actor.vagina > 0 && actor.ovaries > 0 && physicalAgeSwap > actor.pubertyAgeXX) { - increaseWetness(actor); - } - increaseWaistXX(actor); - increaseHipsXX(actor); - increaseButtXX(actor); - } - increasePregAdaptationXX(actor); - } else { - /* shota becoming a man */ - if (actor.geneticQuirks.dwarfism === 2 && actor.geneticQuirks.gigantism !== 2) { - increaseHeightDwarf(actor); - } else if (actor.geneticQuirks.gigantism === 2) { - increaseHeightGiant(actor); - } else if (actor.geneticQuirks.neoteny === 2) { - increaseHeightNeoteny(actor); - } else { - increaseHeightXY(actor); - } - if (physicalAgeSwap === 13 || (physicalAgeSwap > 13 && (actor.hormoneBalance >= 100 || actor.hormoneBalance <= -100))) { - increaseFaceXY(actor); - if (actor.voice > 1) { - increaseVoiceXY(actor); - } - } - if (actor.geneticQuirks.neoteny !== 2) { - increaseBoobsXY(actor); - if (actor.dick > 0) { - increaseDick(actor); - } - if (actor.balls > 0) { - increaseBalls(actor); - } - increaseWaistXY(actor); - increaseHipsXY(actor); - increaseButtXY(actor); - } - increasePregAdaptationXY(actor); - } - } - - /** - * @param {FC.HumanState} actor - */ - function increaseHeightXX(actor) { - if (actor.hormoneBalance >= 200) { - if (physicalAgeSwap === 3) { - if (actor.height <= 91) { - actor.height += jsEither([8, 8, 9, 9]); - } else if (actor.height <= 101) { - actor.height += 5; - } - } else if (physicalAgeSwap === 4) { - if (actor.height <= 101) { - actor.height += jsEither([6, 6, 7, 7]); - } else if (actor.height <= 109) { - actor.height += 4; - } - } else if (physicalAgeSwap === 5) { - if (actor.height <= 109) { - actor.height += jsEither([6, 6, 7, 7]); - } else if (actor.height <= 116) { - actor.height += 4; - } - } else if (physicalAgeSwap === 6) { - if (actor.height <= 116) { - actor.height += jsEither([5, 5, 6, 6]); - } else if (actor.height <= 124) { - actor.height += 3; - } - } else if (physicalAgeSwap === 7) { - if (actor.height <= 124) { - actor.height += jsEither([7, 7, 8, 8]); - } else if (actor.height <= 131) { - actor.height += 3; - } - } else if (physicalAgeSwap === 8) { - if (actor.height <= 131) { - actor.height += jsEither([5, 5, 6, 6]); - } else if (actor.height <= 137) { - actor.height += 3; - } - } else if (physicalAgeSwap === 9) { - if (actor.height <= 137) { - actor.height += jsEither([4, 4, 5, 5]); - } else if (actor.height <= 144) { - actor.height += 3; - } - } else if (physicalAgeSwap === 10) { - if (actor.height <= 144) { - actor.height += jsEither([6, 6, 7, 7]); - } else if (actor.height <= 156) { - actor.height += 3; - } - } else if (physicalAgeSwap === 11) { - if (actor.height <= 156) { - actor.height += jsEither([5, 5, 6, 6]); - } else if (actor.height <= 163) { - actor.height += 3; - } - } else if (physicalAgeSwap === 12) { - if (actor.height <= 163) { - actor.height += jsEither([6, 6, 7, 7]); - } else if (actor.height <= 168) { - actor.height += 3; - } - } else if (physicalAgeSwap === 13) { - if (actor.height <= 168) { - actor.height += jsEither([5, 5, 6, 6]); - } else if (actor.height <= 171) { - actor.height += 3; - } - } else if (physicalAgeSwap === 14) { - if (actor.height <= 171) { - actor.height += jsEither([4, 4, 5, 5]); - } else if (actor.height <= 173) { - actor.height += 3; - } - } else if (physicalAgeSwap === 15) { - if (actor.height <= 174) { - actor.height += jsEither([0, 0, 1, 1]); - } - } else if (physicalAgeSwap === 16) { - if (actor.height <= 174) { - actor.height += jsEither([0, 0, 1, 1]); - } - } else if (physicalAgeSwap === 17) { - if (actor.height <= 174) { - actor.height += jsEither([0, 0, 1, 1]); - } - } else if (physicalAgeSwap === 18) { - if (actor.height <= 174) { - actor.height += jsEither([0, 0, 1, 1]); - } - } - } else if (actor.hormoneBalance >= 100) { - if (physicalAgeSwap === 3) { - if (actor.height <= 91) { - actor.height += jsEither([8, 8, 9, 9, 9]); - } else if (actor.height <= 101) { - actor.height += 5; - } - } else if (physicalAgeSwap === 4) { - if (actor.height <= 101) { - actor.height += jsEither([6, 6, 7, 7, 7]); - } else if (actor.height <= 109) { - actor.height += 4; - } - } else if (physicalAgeSwap === 5) { - if (actor.height <= 109) { - actor.height += jsEither([6, 6, 7, 7, 7]); - } else if (actor.height <= 116) { - actor.height += 4; - } - } else if (physicalAgeSwap === 6) { - if (actor.height <= 116) { - actor.height += jsEither([5, 5, 6, 6, 6]); - } else if (actor.height <= 124) { - actor.height += 3; - } - } else if (physicalAgeSwap === 7) { - if (actor.height <= 124) { - actor.height += jsEither([7, 7, 8, 8, 8]); - } else if (actor.height <= 131) { - actor.height += 3; - } - } else if (physicalAgeSwap === 8) { - if (actor.height <= 131) { - actor.height += jsEither([5, 5, 6, 6, 6]); - } else if (actor.height <= 137) { - actor.height += 3; - } - } else if (physicalAgeSwap === 9) { - if (actor.height <= 137) { - actor.height += jsEither([4, 4, 5, 5, 5]); - } else if (actor.height <= 144) { - actor.height += 3; - } - } else if (physicalAgeSwap === 10) { - if (actor.height <= 144) { - actor.height += jsEither([6, 6, 7, 7, 7]); - } else if (actor.height <= 156) { - actor.height += 3; - } - } else if (physicalAgeSwap === 11) { - if (actor.height <= 156) { - actor.height += jsEither([5, 5, 6, 6, 6]); - } else if (actor.height <= 163) { - actor.height += 3; - } - } else if (physicalAgeSwap === 12) { - if (actor.height <= 163) { - actor.height += jsEither([6, 6, 7, 7, 7]); - } else if (actor.height <= 168) { - actor.height += 3; - } - } else if (physicalAgeSwap === 13) { - if (actor.height <= 168) { - actor.height += jsEither([5, 5, 6, 6, 6]); - } else if (actor.height <= 171) { - actor.height += 3; - } - } else if (physicalAgeSwap === 14) { - if (actor.height <= 171) { - actor.height += jsEither([4, 4, 5, 5, 5]); - } else if (actor.height <= 173) { - actor.height += 3; - } - } else if (physicalAgeSwap === 15) { - if (actor.height <= 174) { - actor.height += jsEither([0, 0, 1, 1, 1]); - } - } else if (physicalAgeSwap === 16) { - if (actor.height <= 174) { - actor.height += jsEither([0, 0, 1, 1, 1]); - } - } else if (physicalAgeSwap === 17) { - if (actor.height <= 174) { - actor.height += jsEither([0, 0, 1, 1, 1]); - } - } else if (physicalAgeSwap === 18) { - if (actor.height <= 174) { - actor.height += jsEither([0, 0, 1, 1, 1]); - } - } - } else if (actor.hormoneBalance <= -200) { - if (physicalAgeSwap === 3) { - if (actor.height <= 91) { - actor.height += jsEither([9, 9, 9, 10, 10]); - } else if (actor.height <= 101) { - actor.height += 5; - } - } else if (physicalAgeSwap === 4) { - if (actor.height <= 101) { - actor.height += jsEither([7, 7, 7, 8, 8]); - } else if (actor.height <= 109) { - actor.height += 4; - } - } else if (physicalAgeSwap === 5) { - if (actor.height <= 109) { - actor.height += jsEither([7, 7, 7, 8, 8]); - } else if (actor.height <= 116) { - actor.height += 4; - } - } else if (physicalAgeSwap === 6) { - if (actor.height <= 116) { - actor.height += jsEither([6, 6, 6, 7, 7]); - } else if (actor.height <= 124) { - actor.height += 3; - } - } else if (physicalAgeSwap === 7) { - if (actor.height <= 124) { - actor.height += jsEither([8, 8, 8, 9, 9]); - } else if (actor.height <= 131) { - actor.height += 3; - } - } else if (physicalAgeSwap === 8) { - if (actor.height <= 131) { - actor.height += jsEither([6, 6, 6, 7, 7]); - } else if (actor.height <= 137) { - actor.height += 3; - } - } else if (physicalAgeSwap === 9) { - if (actor.height <= 137) { - actor.height += jsEither([5, 5, 5, 6, 6]); - } else if (actor.height <= 144) { - actor.height += 3; - } - } else if (physicalAgeSwap === 10) { - if (actor.height <= 144) { - actor.height += jsEither([7, 7, 7, 8, 8]); - } else if (actor.height <= 156) { - actor.height += 3; - } - } else if (physicalAgeSwap === 11) { - if (actor.height <= 156) { - actor.height += jsEither([6, 6, 6, 7, 7]); - } else if (actor.height <= 163) { - actor.height += 3; - } - } else if (physicalAgeSwap === 12) { - if (actor.height <= 163) { - actor.height += jsEither([7, 7, 7, 8, 8]); - } else if (actor.height <= 168) { - actor.height += 3; - } - } else if (physicalAgeSwap === 13) { - if (actor.height <= 168) { - actor.height += jsEither([6, 6, 6, 7, 7]); - } else if (actor.height <= 171) { - actor.height += 3; - } - } else if (physicalAgeSwap === 14) { - if (actor.height <= 171) { - actor.height += jsEither([5, 5, 5, 6, 6]); - } else if (actor.height <= 173) { - actor.height += 3; - } - } else if (physicalAgeSwap === 15) { - if (actor.height <= 174) { - actor.height += jsEither([1, 1, 1, 2, 2]); - } - } else if (physicalAgeSwap === 16) { - if (actor.height <= 174) { - actor.height += jsEither([1, 1, 1, 2, 2]); - } - } else if (physicalAgeSwap === 17) { - if (actor.height <= 174) { - actor.height += jsEither([1, 1, 1, 2, 2]); - } - } else if (physicalAgeSwap === 18) { - if (actor.height <= 174) { - actor.height += jsEither([1, 1, 1, 2, 2]); - } - } - } else if (actor.hormoneBalance <= -100) { - if (physicalAgeSwap === 3) { - if (actor.height <= 91) { - actor.height += jsEither([8, 9, 9, 10, 10]); - } else if (actor.height <= 101) { - actor.height += 5; - } - } else if (physicalAgeSwap === 4) { - if (actor.height <= 101) { - actor.height += jsEither([6, 7, 7, 8, 8]); - } else if (actor.height <= 109) { - actor.height += 4; - } - } else if (physicalAgeSwap === 5) { - if (actor.height <= 109) { - actor.height += jsEither([6, 7, 7, 8, 8]); - } else if (actor.height <= 116) { - actor.height += 4; - } - } else if (physicalAgeSwap === 6) { - if (actor.height <= 116) { - actor.height += jsEither([5, 6, 6, 7, 7]); - } else if (actor.height <= 124) { - actor.height += 3; - } - } else if (physicalAgeSwap === 7) { - if (actor.height <= 124) { - actor.height += jsEither([7, 8, 8, 9, 9]); - } else if (actor.height <= 131) { - actor.height += 3; - } - } else if (physicalAgeSwap === 8) { - if (actor.height <= 131) { - actor.height += jsEither([5, 6, 6, 7, 7]); - } else if (actor.height <= 137) { - actor.height += 3; - } - } else if (physicalAgeSwap === 9) { - if (actor.height <= 137) { - actor.height += jsEither([4, 5, 5, 6, 6]); - } else if (actor.height <= 144) { - actor.height += 3; - } - } else if (physicalAgeSwap === 10) { - if (actor.height <= 144) { - actor.height += jsEither([6, 7, 7, 8, 8]); - } else if (actor.height <= 156) { - actor.height += 3; - } - } else if (physicalAgeSwap === 11) { - if (actor.height <= 156) { - actor.height += jsEither([5, 6, 6, 7, 7]); - } else if (actor.height <= 163) { - actor.height += 3; - } - } else if (physicalAgeSwap === 12) { - if (actor.height <= 163) { - actor.height += jsEither([6, 7, 7, 8, 8]); - } else if (actor.height <= 168) { - actor.height += 3; - } - } else if (physicalAgeSwap === 13) { - if (actor.height <= 168) { - actor.height += jsEither([5, 6, 6, 7, 7]); - } else if (actor.height <= 171) { - actor.height += 3; - } - } else if (physicalAgeSwap === 14) { - if (actor.height <= 171) { - actor.height += jsEither([4, 5, 5, 6, 6]); - } else if (actor.height <= 173) { - actor.height += 3; - } - } else if (physicalAgeSwap === 15) { - if (actor.height <= 174) { - actor.height += jsEither([0, 1, 1, 2, 2]); - } - } else if (physicalAgeSwap === 16) { - if (actor.height <= 174) { - actor.height += jsEither([0, 1, 1, 2, 2]); - } - } else if (physicalAgeSwap === 17) { - if (actor.height <= 174) { - actor.height += jsEither([0, 1, 1, 2, 2]); - } - } else if (physicalAgeSwap === 18) { - if (actor.height <= 174) { - actor.height += jsEither([0, 1, 1, 2, 2]); - } - } + if (actor.geneticQuirks.neoteny === 2) { + // special case for neoteny (genetic target height does not take it into account) + increaseHeightNeoteny(actor); } else { - if (physicalAgeSwap === 3) { - if (actor.height <= 91) { - actor.height += jsEither([8, 8, 9, 9, 9, 10]); - } else if (actor.height <= 101) { - actor.height += 5; - } - } else if (physicalAgeSwap === 4) { - if (actor.height <= 101) { - actor.height += jsEither([6, 6, 7, 7, 8, 8]); - } else if (actor.height <= 109) { - actor.height += 4; - } - } else if (physicalAgeSwap === 5) { - if (actor.height <= 109) { - actor.height += jsEither([6, 6, 7, 7, 7, 8]); - } else if (actor.height <= 116) { - actor.height += 4; - } - } else if (physicalAgeSwap === 6) { - if (actor.height <= 116) { - actor.height += jsEither([5, 5, 6, 6, 6, 7]); - } else if (actor.height <= 124) { - actor.height += 3; - } - } else if (physicalAgeSwap === 7) { - if (actor.height <= 124) { - actor.height += jsEither([7, 7, 8, 8, 8, 9]); - } else if (actor.height <= 131) { - actor.height += 3; - } - } else if (physicalAgeSwap === 8) { - if (actor.height <= 131) { - actor.height += jsEither([5, 5, 6, 6, 6, 7]); - } else if (actor.height <= 137) { - actor.height += 3; - } - } else if (physicalAgeSwap === 9) { - if (actor.height <= 137) { - actor.height += jsEither([4, 4, 5, 5, 5, 6]); - } else if (actor.height <= 144) { - actor.height += 3; - } - } else if (physicalAgeSwap === 10) { - if (actor.height <= 144) { - actor.height += jsEither([6, 6, 7, 7, 7, 8]); - } else if (actor.height <= 156) { - actor.height += 3; - } - } else if (physicalAgeSwap === 11) { - if (actor.height <= 156) { - actor.height += jsEither([5, 5, 6, 6, 6, 7]); - } else if (actor.height <= 163) { - actor.height += 3; - } - } else if (physicalAgeSwap === 12) { - if (actor.height <= 163) { - actor.height += jsEither([6, 6, 7, 7, 7, 8]); - } else if (actor.height <= 168) { - actor.height += 3; - } - } else if (physicalAgeSwap === 13) { - if (actor.height <= 168) { - actor.height += jsEither([5, 5, 6, 6, 6, 7]); - } else if (actor.height <= 171) { - actor.height += 3; - } - } else if (physicalAgeSwap === 14) { - if (actor.height <= 171) { - actor.height += jsEither([4, 4, 5, 5, 5, 6]); - } else if (actor.height <= 173) { - actor.height += 3; - } - } else if (physicalAgeSwap === 15) { - if (actor.height <= 174) { - actor.height += jsEither([0, 0, 1, 1, 1, 2]); - } - } else if (physicalAgeSwap === 16) { - if (actor.height <= 174) { - actor.height += jsEither([0, 0, 1, 1, 1, 2]); - } - } else if (physicalAgeSwap === 17) { - if (actor.height <= 174) { - actor.height += jsEither([0, 0, 1, 1, 1, 2]); - } - } else if (physicalAgeSwap === 18) { - if (actor.height <= 174) { - actor.height += jsEither([0, 0, 1, 1, 1, 2]); - } - } + // giant/dwarf/sex/race/etc is already taken into account by the target height. just need to take one step towards it. + increaseHeight(actor); } - // experiment - Let's see if this keeps players on average above average height or if it makes them too tall in the long run. - if (tallerPC) { - actor.height += random(0, 3); - } - } - - /** - * @param {FC.HumanState} actor - */ - function increaseHeightXY(actor) { - if (actor.hormoneBalance >= 200) { - if (physicalAgeSwap === 3) { - if (actor.height <= 93) { - actor.height += jsEither([9, 9, 10, 10]); - } else if (actor.height <= 103) { - actor.height += 6; - } - } else if (physicalAgeSwap === 4) { - if (actor.height <= 103) { - actor.height += jsEither([7, 7, 8, 8]); - } else if (actor.height <= 110) { - actor.height += 5; - } - } else if (physicalAgeSwap === 5) { - if (actor.height <= 110) { - actor.height += jsEither([6, 6, 7, 7]); - } else if (actor.height <= 117) { - actor.height += 4; - } - } else if (physicalAgeSwap === 6) { - if (actor.height <= 117) { - actor.height += jsEither([6, 6, 7, 7]); - } else if (actor.height <= 124) { - actor.height += 4; - } - } else if (physicalAgeSwap === 7) { - if (actor.height <= 124) { - actor.height += jsEither([6, 6, 7, 7]); - } else if (actor.height <= 131) { - actor.height += 4; - } - } else if (physicalAgeSwap === 8) { - if (actor.height <= 131) { - actor.height += jsEither([5, 5, 6, 6]); - } else if (actor.height <= 137) { - actor.height += 3; - } - } else if (physicalAgeSwap === 9) { - if (actor.height <= 137) { - actor.height += jsEither([4, 4, 5, 5]); - } else if (actor.height <= 144) { - actor.height += 3; - } - } else if (physicalAgeSwap === 10) { - if (actor.height <= 144) { - actor.height += jsEither([5, 5, 6, 6]); - } else if (actor.height <= 150) { - actor.height += 3; - } - } else if (physicalAgeSwap === 11) { - if (actor.height <= 150) { - actor.height += jsEither([5, 5, 6, 6]); - } else if (actor.height <= 156) { - actor.height += 3; - } - } else if (physicalAgeSwap === 12) { - if (actor.height <= 156) { - actor.height += jsEither([5, 5, 6, 6]); - } else if (actor.height <= 162) { - actor.height += 3; - } - } else if (physicalAgeSwap === 13) { - if (actor.height <= 162) { - actor.height += jsEither([7, 7, 8, 8]); - } else if (actor.height <= 170) { - actor.height += 5; - } - } else if (physicalAgeSwap === 14) { - if (actor.height <= 170) { - actor.height += jsEither([6, 6, 7, 7]); - } else if (actor.height <= 177) { - actor.height += 4; - } - } else if (physicalAgeSwap === 15) { - if (actor.height <= 177) { - actor.height += jsEither([6, 6, 7, 7]); - } else if (actor.height <= 184) { - actor.height += 4; - } - } else if (physicalAgeSwap === 16) { - if (actor.height <= 184) { - actor.height += jsEither([2, 2, 3, 3]); - } - } else if (physicalAgeSwap === 17) { - if (actor.height <= 185) { - actor.height += jsEither([1, 1, 2, 2]); - } - } else if (physicalAgeSwap === 18) { - if (actor.height <= 186) { - actor.height += jsEither([0, 0, 1, 1]); - } - } - } else if (actor.hormoneBalance >= 100) { - if (physicalAgeSwap === 3) { - if (actor.height <= 93) { - actor.height += jsEither([9, 9, 9, 10, 10]); - } else if (actor.height <= 103) { - actor.height += 6; - } - } else if (physicalAgeSwap === 4) { - if (actor.height <= 103) { - actor.height += jsEither([7, 7, 8, 8, 8]); - } else if (actor.height <= 110) { - actor.height += 5; - } - } else if (physicalAgeSwap === 5) { - if (actor.height <= 110) { - actor.height += jsEither([6, 6, 7, 7, 7]); - } else if (actor.height <= 117) { - actor.height += 4; - } - } else if (physicalAgeSwap === 6) { - if (actor.height <= 117) { - actor.height += jsEither([6, 6, 7, 7, 7]); - } else if (actor.height <= 124) { - actor.height += 4; - } - } else if (physicalAgeSwap === 7) { - if (actor.height <= 124) { - actor.height += jsEither([6, 6, 7, 7, 7]); - } else if (actor.height <= 131) { - actor.height += 4; - } - } else if (physicalAgeSwap === 8) { - if (actor.height <= 131) { - actor.height += jsEither([5, 5, 6, 6, 6]); - } else if (actor.height <= 137) { - actor.height += 3; - } - } else if (physicalAgeSwap === 9) { - if (actor.height <= 137) { - actor.height += jsEither([4, 4, 5, 5, 5]); - } else if (actor.height <= 144) { - actor.height += 3; - } - } else if (physicalAgeSwap === 10) { - if (actor.height <= 144) { - actor.height += jsEither([5, 5, 6, 6, 6]); - } else if (actor.height <= 150) { - actor.height += 3; - } - } else if (physicalAgeSwap === 11) { - if (actor.height <= 150) { - actor.height += jsEither([5, 5, 6, 6, 6]); - } else if (actor.height <= 156) { - actor.height += 3; - } - } else if (physicalAgeSwap === 12) { - if (actor.height <= 156) { - actor.height += jsEither([5, 5, 6, 6, 6]); - } else if (actor.height <= 162) { - actor.height += 3; - } - } else if (physicalAgeSwap === 13) { - if (actor.height <= 162) { - actor.height += jsEither([7, 7, 8, 8, 8]); - } else if (actor.height <= 170) { - actor.height += 5; - } - } else if (physicalAgeSwap === 14) { - if (actor.height <= 170) { - actor.height += jsEither([6, 6, 7, 7, 7]); - } else if (actor.height <= 177) { - actor.height += 4; - } - } else if (physicalAgeSwap === 15) { - if (actor.height <= 177) { - actor.height += jsEither([6, 6, 7, 7, 7]); - } else if (actor.height <= 184) { - actor.height += 4; - } - } else if (physicalAgeSwap === 16) { - if (actor.height <= 184) { - actor.height += jsEither([2, 2, 3, 3, 3]); - } - } else if (physicalAgeSwap === 17) { - if (actor.height <= 185) { - actor.height += jsEither([1, 1, 2, 2, 2]); - } - } else if (physicalAgeSwap === 18) { - if (actor.height <= 186) { - actor.height += jsEither([0, 0, 1, 1, 1]); - } - } - } else if (actor.hormoneBalance <= -200) { - if (physicalAgeSwap === 3) { - if (actor.height <= 93) { - actor.height += jsEither([10, 10, 11, 11]); - } else if (actor.height <= 103) { - actor.height += 6; - } - } else if (physicalAgeSwap === 4) { - if (actor.height <= 103) { - actor.height += jsEither([8, 8, 9, 9]); - } else if (actor.height <= 110) { - actor.height += 5; - } - } else if (physicalAgeSwap === 5) { - if (actor.height <= 110) { - actor.height += jsEither([7, 7, 8, 8]); - } else if (actor.height <= 117) { - actor.height += 4; - } - } else if (physicalAgeSwap === 6) { - if (actor.height <= 117) { - actor.height += jsEither([7, 7, 8, 8]); - } else if (actor.height <= 124) { - actor.height += 4; - } - } else if (physicalAgeSwap === 7) { - if (actor.height <= 124) { - actor.height += jsEither([7, 7, 8, 8]); - } else if (actor.height <= 131) { - actor.height += 4; - } - } else if (physicalAgeSwap === 8) { - if (actor.height <= 131) { - actor.height += jsEither([6, 6, 7, 7]); - } else if (actor.height <= 137) { - actor.height += 3; - } - } else if (physicalAgeSwap === 9) { - if (actor.height <= 137) { - actor.height += jsEither([5, 5, 6, 6]); - } else if (actor.height <= 144) { - actor.height += 3; - } - } else if (physicalAgeSwap === 10) { - if (actor.height <= 144) { - actor.height += jsEither([6, 6, 7, 7]); - } else if (actor.height <= 150) { - actor.height += 3; - } - } else if (physicalAgeSwap === 11) { - if (actor.height <= 150) { - actor.height += jsEither([6, 6, 7, 7]); - } else if (actor.height <= 156) { - actor.height += 3; - } - } else if (physicalAgeSwap === 12) { - if (actor.height <= 156) { - actor.height += jsEither([6, 6, 7, 7]); - } else if (actor.height <= 162) { - actor.height += 3; - } - } else if (physicalAgeSwap === 13) { - if (actor.height <= 162) { - actor.height += jsEither([8, 8, 9, 9]); - } else if (actor.height <= 170) { - actor.height += 5; - } - } else if (physicalAgeSwap === 14) { - if (actor.height <= 170) { - actor.height += jsEither([7, 7, 8, 8]); - } else if (actor.height <= 177) { - actor.height += 4; - } - } else if (physicalAgeSwap === 15) { - if (actor.height <= 177) { - actor.height += jsEither([7, 7, 8, 8]); - } else if (actor.height <= 184) { - actor.height += 4; - } - } else if (physicalAgeSwap === 16) { - if (actor.height <= 184) { - actor.height += jsEither([3, 3, 4, 4]); - } - } else if (physicalAgeSwap === 17) { - if (actor.height <= 185) { - actor.height += jsEither([2, 2, 3, 3]); - } - } else if (physicalAgeSwap === 18) { - if (actor.height <= 186) { - actor.height += jsEither([1, 1, 2, 2]); - } - } - } else if (actor.hormoneBalance <= -100) { - if (physicalAgeSwap === 3) { - if (actor.height <= 93) { - actor.height += jsEither([10, 10, 10, 11, 11]); - } else if (actor.height <= 103) { - actor.height += 6; - } - } else if (physicalAgeSwap === 4) { - if (actor.height <= 103) { - actor.height += jsEither([8, 8, 8, 9, 9]); - } else if (actor.height <= 110) { - actor.height += 5; - } - } else if (physicalAgeSwap === 5) { - if (actor.height <= 110) { - actor.height += jsEither([7, 7, 7, 8, 8]); - } else if (actor.height <= 117) { - actor.height += 4; - } - } else if (physicalAgeSwap === 6) { - if (actor.height <= 117) { - actor.height += jsEither([7, 7, 7, 8, 8]); - } else if (actor.height <= 124) { - actor.height += 4; - } - } else if (physicalAgeSwap === 7) { - if (actor.height <= 124) { - actor.height += jsEither([7, 7, 7, 8, 8]); - } else if (actor.height <= 131) { - actor.height += 4; - } - } else if (physicalAgeSwap === 8) { - if (actor.height <= 131) { - actor.height += jsEither([6, 6, 6, 7, 7]); - } else if (actor.height <= 137) { - actor.height += 3; - } - } else if (physicalAgeSwap === 9) { - if (actor.height <= 137) { - actor.height += jsEither([5, 5, 5, 6, 6]); - } else if (actor.height <= 144) { - actor.height += 3; - } - } else if (physicalAgeSwap === 10) { - if (actor.height <= 144) { - actor.height += jsEither([6, 6, 6, 7, 7]); - } else if (actor.height <= 150) { - actor.height += 3; - } - } else if (physicalAgeSwap === 11) { - if (actor.height <= 150) { - actor.height += jsEither([6, 6, 6, 7, 7]); - } else if (actor.height <= 156) { - actor.height += 3; - } - } else if (physicalAgeSwap === 12) { - if (actor.height <= 156) { - actor.height += jsEither([6, 6, 6, 7, 7]); - } else if (actor.height <= 162) { - actor.height += 3; - } - } else if (physicalAgeSwap === 13) { - if (actor.height <= 162) { - actor.height += jsEither([8, 8, 8, 9, 9]); - } else if (actor.height <= 170) { - actor.height += 5; - } - } else if (physicalAgeSwap === 14) { - if (actor.height <= 170) { - actor.height += jsEither([7, 7, 7, 8, 8]); - } else if (actor.height <= 177) { - actor.height += 4; - } - } else if (physicalAgeSwap === 15) { - if (actor.height <= 177) { - actor.height += jsEither([7, 7, 7, 8, 8]); - } else if (actor.height <= 184) { - actor.height += 4; - } - } else if (physicalAgeSwap === 16) { - if (actor.height <= 184) { - actor.height += jsEither([3, 3, 3, 4, 4]); - } - } else if (physicalAgeSwap === 17) { - if (actor.height <= 185) { - actor.height += jsEither([2, 2, 2, 3, 3]); - } - } else if (physicalAgeSwap === 18) { - if (actor.height <= 186) { - actor.height += jsEither([1, 1, 1, 2, 2]); - } - } - } else { - if (physicalAgeSwap === 3) { - if (actor.height <= 93) { - actor.height += jsEither([9, 9, 10, 10, 10, 11]); - } else if (actor.height <= 103) { - actor.height += 6; - } - } else if (physicalAgeSwap === 4) { - if (actor.height <= 103) { - actor.height += jsEither([7, 7, 8, 8, 9, 9]); - } else if (actor.height <= 110) { - actor.height += 5; - } - } else if (physicalAgeSwap === 5) { - if (actor.height <= 110) { - actor.height += jsEither([6, 6, 7, 7, 8, 8]); - } else if (actor.height <= 117) { - actor.height += 4; - } - } else if (physicalAgeSwap === 6) { - if (actor.height <= 117) { - actor.height += jsEither([6, 6, 7, 7, 8, 8]); - } else if (actor.height <= 124) { - actor.height += 4; - } - } else if (physicalAgeSwap === 7) { - if (actor.height <= 124) { - actor.height += jsEither([6, 6, 7, 7, 8, 8]); - } else if (actor.height <= 131) { - actor.height += 4; - } - } else if (physicalAgeSwap === 8) { - if (actor.height <= 131) { - actor.height += jsEither([5, 5, 6, 6, 7, 7]); - } else if (actor.height <= 137) { - actor.height += 3; - } - } else if (physicalAgeSwap === 9) { - if (actor.height <= 137) { - actor.height += jsEither([4, 4, 5, 5, 5, 6]); - } else if (actor.height <= 144) { - actor.height += 3; - } - } else if (physicalAgeSwap === 10) { - if (actor.height <= 144) { - actor.height += jsEither([5, 5, 6, 6, 7, 7]); - } else if (actor.height <= 150) { - actor.height += 3; - } - } else if (physicalAgeSwap === 11) { - if (actor.height <= 150) { - actor.height += jsEither([5, 5, 6, 6, 6, 7]); - } else if (actor.height <= 156) { - actor.height += 3; - } - } else if (physicalAgeSwap === 12) { - if (actor.height <= 156) { - actor.height += jsEither([5, 5, 6, 6, 7, 7]); - } else if (actor.height <= 162) { - actor.height += 3; - } - } else if (physicalAgeSwap === 13) { - if (actor.height <= 162) { - actor.height += jsEither([7, 7, 8, 8, 9, 9]); - } else if (actor.height <= 170) { - actor.height += 5; - } - } else if (physicalAgeSwap === 14) { - if (actor.height <= 170) { - actor.height += jsEither([6, 6, 7, 7, 8, 8]); - } else if (actor.height <= 177) { - actor.height += 4; + // physical development EXCEPT for height stops at 18; height keeps going until 20. + if (physicalAgeSwap <= 18) { + if (actor.geneticQuirks.androgyny === 2) { /* takes a mix of both to create a very androgynous slave */ + if (actor.geneticQuirks.neoteny !== 2) { + if (actor.boobs - actor.boobsImplant <= 300) { + increaseBoobsXX(actor); + } + if (actor.dick.isBetween(0, 3) || actor.geneticQuirks.wellHung === 2) { + increaseDick(actor); + } + if (actor.balls.isBetween(0, 3)) { + increaseBalls(actor); + } + if (actor.vagina > 0 && actor.ovaries > 0 && physicalAgeSwap > actor.pubertyAgeXX) { + increaseWetness(actor); + } + if (actor.waist < 10) { + increaseWaistXY(actor); + } + if (actor.hips - actor.hipsImplant < 0) { + increaseHipsXX(actor); + } + if (actor.butt - actor.buttImplant < 3) { + increaseButtXX(actor); + } } - } else if (physicalAgeSwap === 15) { - if (actor.height <= 177) { - actor.height += jsEither([6, 6, 7, 7, 8, 8]); - } else if (actor.height <= 184) { - actor.height += 4; + increasePregAdaptationXX(actor); + } else if (actor.genes === "XX") { /* loli becoming a woman */ + if (physicalAgeSwap === 13 || (physicalAgeSwap > 13 && (actor.hormoneBalance >= 100 || actor.hormoneBalance <= -100))) { + increaseFaceXX(actor); + if (actor.voice > 1) { + increaseVoiceXX(actor); + } } - } else if (physicalAgeSwap === 16) { - if (actor.height <= 184) { - actor.height += jsEither([2, 2, 3, 3, 4, 4]); + if (actor.geneticQuirks.neoteny !== 2) { + increaseBoobsXX(actor); + if (actor.clit > 0) { + increaseClit(actor); + } + if (actor.vagina > 0 && actor.ovaries > 0 && physicalAgeSwap > actor.pubertyAgeXX) { + increaseWetness(actor); + } + increaseWaistXX(actor); + increaseHipsXX(actor); + increaseButtXX(actor); } - } else if (physicalAgeSwap === 17) { - if (actor.height <= 185) { - actor.height += jsEither([1, 1, 2, 2, 3, 3]); + increasePregAdaptationXX(actor); + } else { /* shota becoming a man */ + if (physicalAgeSwap === 13 || (physicalAgeSwap > 13 && (actor.hormoneBalance >= 100 || actor.hormoneBalance <= -100))) { + increaseFaceXY(actor); + if (actor.voice > 1) { + increaseVoiceXY(actor); + } } - } else if (physicalAgeSwap === 18) { - if (actor.height <= 186) { - actor.height += jsEither([0, 0, 1, 1, 2, 2]); + if (actor.geneticQuirks.neoteny !== 2) { + increaseBoobsXY(actor); + if (actor.dick > 0) { + increaseDick(actor); + } + if (actor.balls > 0) { + increaseBalls(actor); + } + increaseWaistXY(actor); + increaseHipsXY(actor); + increaseButtXY(actor); } + increasePregAdaptationXY(actor); } } - // experiment - Let's see if this keeps players on average above average height or if it makes them too tall in the long run. - if (tallerPC) { - actor.height += random(0, 3); - } } /** * @param {FC.HumanState} actor */ - function increaseHeightDwarf(actor) { - if (actor.hormoneBalance >= 200) { - if (physicalAgeSwap === 3) { - if (actor.height <= 80) { - actor.height += jsEither([1, 1, 2, 2]); - } else if (actor.height <= 84) { - actor.height += 1; - } - } else if (physicalAgeSwap === 4) { - if (actor.height <= 84) { - actor.height += jsEither([4, 4, 5, 5]); - } else if (actor.height <= 90) { - actor.height += 2; - } - } else if (physicalAgeSwap === 5) { - if (actor.height <= 90) { - actor.height += jsEither([8, 8, 9, 9]); - } else if (actor.height <= 100) { - actor.height += 5; - } - } else if (physicalAgeSwap === 6) { - if (actor.height <= 100) { - actor.height += jsEither([3, 3, 4, 4]); - } else if (actor.height <= 105) { - actor.height += 2; - } - } else if (physicalAgeSwap === 7) { - if (actor.height <= 105) { - actor.height += jsEither([2, 2, 3, 3]); - } else if (actor.height <= 109) { - actor.height += 1; - } - } else if (physicalAgeSwap === 8) { - if (actor.height <= 109) { - actor.height += jsEither([3, 3, 4, 4]); - } else if (actor.height <= 114) { - actor.height += 1; - } - } else if (physicalAgeSwap === 9) { - if (actor.height <= 114) { - actor.height += jsEither([2, 2, 3, 3]); - } else if (actor.height <= 118) { - actor.height += 1; - } - } else if (physicalAgeSwap === 10) { - if (actor.height <= 118) { - actor.height += jsEither([2, 2, 3, 3]); - } else if (actor.height <= 122) { - actor.height += 1; - } - } else if (physicalAgeSwap === 11) { - if (actor.height <= 122) { - actor.height += jsEither([3, 3, 4, 4]); - } else if (actor.height <= 127) { - actor.height += 2; - } - } else if (physicalAgeSwap === 12) { - if (actor.height <= 127) { - actor.height += jsEither([3, 3, 4, 4]); - } else if (actor.height <= 132) { - actor.height += 2; - } - } else if (physicalAgeSwap === 13) { - if (actor.height <= 132) { - actor.height += jsEither([1, 1, 2, 2]); - } else if (actor.height <= 135) { - actor.height += 1; - } - } else if (physicalAgeSwap === 14) { - if (actor.height <= 135) { - actor.height += jsEither([1, 1, 2, 2]); - } else if (actor.height <= 138) { - actor.height += 1; - } - } else if (physicalAgeSwap === 15) { - if (actor.height <= 138) { - actor.height += jsEither([1, 1, 2, 2]); - } else if (actor.height <= 141) { - actor.height += 1; - } - } else if (physicalAgeSwap === 16) { - if (actor.height <= 143) { - actor.height += jsEither([0, 0, 1, 1]); - } - } else if (physicalAgeSwap === 17) { - if (actor.height <= 143) { - actor.height += jsEither([0, 0, 1, 1]); - } - } else if (physicalAgeSwap === 18) { - if (actor.height <= 143) { - actor.height += jsEither([0, 0, 1, 1]); - } - } - } else if (actor.hormoneBalance >= 100) { - if (physicalAgeSwap === 3) { - if (actor.height <= 80) { - actor.height += jsEither([1, 1, 2, 2, 2]); - } else if (actor.height <= 84) { - actor.height += 1; - } - } else if (physicalAgeSwap === 4) { - if (actor.height <= 84) { - actor.height += jsEither([4, 4, 5, 5, 5]); - } else if (actor.height <= 90) { - actor.height += 2; - } - } else if (physicalAgeSwap === 5) { - if (actor.height <= 90) { - actor.height += jsEither([8, 8, 9, 9, 9]); - } else if (actor.height <= 100) { - actor.height += 5; - } - } else if (physicalAgeSwap === 6) { - if (actor.height <= 100) { - actor.height += jsEither([3, 3, 4, 4, 4]); - } else if (actor.height <= 105) { - actor.height += 2; - } - } else if (physicalAgeSwap === 7) { - if (actor.height <= 105) { - actor.height += jsEither([2, 2, 3, 3, 3]); - } else if (actor.height <= 109) { - actor.height += 1; - } - } else if (physicalAgeSwap === 8) { - if (actor.height <= 109) { - actor.height += jsEither([3, 3, 4, 4, 4]); - } else if (actor.height <= 114) { - actor.height += 1; - } - } else if (physicalAgeSwap === 9) { - if (actor.height <= 114) { - actor.height += jsEither([2, 2, 3, 3, 3]); - } else if (actor.height <= 118) { - actor.height += 1; - } - } else if (physicalAgeSwap === 10) { - if (actor.height <= 118) { - actor.height += jsEither([2, 2, 3, 3, 3]); - } else if (actor.height <= 122) { - actor.height += 1; - } - } else if (physicalAgeSwap === 11) { - if (actor.height <= 122) { - actor.height += jsEither([3, 3, 4, 4, 4]); - } else if (actor.height <= 127) { - actor.height += 2; - } - } else if (physicalAgeSwap === 12) { - if (actor.height <= 127) { - actor.height += jsEither([3, 3, 4, 4, 4]); - } else if (actor.height <= 132) { - actor.height += 2; - } - } else if (physicalAgeSwap === 13) { - if (actor.height <= 132) { - actor.height += jsEither([1, 1, 2, 2, 2]); - } else if (actor.height <= 135) { - actor.height += 1; - } - } else if (physicalAgeSwap === 14) { - if (actor.height <= 135) { - actor.height += jsEither([1, 1, 2, 2, 2]); - } else if (actor.height <= 138) { - actor.height += 1; - } - } else if (physicalAgeSwap === 15) { - if (actor.height <= 138) { - actor.height += jsEither([1, 1, 2, 2, 2]); - } else if (actor.height <= 141) { - actor.height += 1; - } - } else if (physicalAgeSwap === 16) { - if (actor.height <= 143) { - actor.height += jsEither([0, 0, 1, 1, 1]); - } - } else if (physicalAgeSwap === 17) { - if (actor.height <= 143) { - actor.height += jsEither([0, 0, 1, 1, 1]); - } - } else if (physicalAgeSwap === 18) { - if (actor.height <= 143) { - actor.height += jsEither([0, 0, 1, 1, 1]); - } - } - } else if (actor.hormoneBalance <= -200) { - if (physicalAgeSwap === 3) { - if (actor.height <= 80) { - actor.height += jsEither([2, 2, 3, 3]); - } else if (actor.height <= 84) { - actor.height += 1; - } - } else if (physicalAgeSwap === 4) { - if (actor.height <= 84) { - actor.height += jsEither([5, 5, 6, 6]); - } else if (actor.height <= 90) { - actor.height += 2; - } - } else if (physicalAgeSwap === 5) { - if (actor.height <= 90) { - actor.height += jsEither([9, 9, 10, 10]); - } else if (actor.height <= 100) { - actor.height += 5; - } - } else if (physicalAgeSwap === 6) { - if (actor.height <= 100) { - actor.height += jsEither([4, 4, 5, 5]); - } else if (actor.height <= 105) { - actor.height += 2; - } - } else if (physicalAgeSwap === 7) { - if (actor.height <= 105) { - actor.height += jsEither([3, 3, 4, 4]); - } else if (actor.height <= 109) { - actor.height += 1; - } - } else if (physicalAgeSwap === 8) { - if (actor.height <= 109) { - actor.height += jsEither([4, 4, 5, 5]); - } else if (actor.height <= 114) { - actor.height += 1; - } - } else if (physicalAgeSwap === 9) { - if (actor.height <= 114) { - actor.height += jsEither([3, 3, 4, 4]); - } else if (actor.height <= 118) { - actor.height += 1; - } - } else if (physicalAgeSwap === 10) { - if (actor.height <= 118) { - actor.height += jsEither([3, 3, 4, 4]); - } else if (actor.height <= 122) { - actor.height += 1; - } - } else if (physicalAgeSwap === 11) { - if (actor.height <= 122) { - actor.height += jsEither([4, 4, 5, 5]); - } else if (actor.height <= 127) { - actor.height += 2; - } - } else if (physicalAgeSwap === 12) { - if (actor.height <= 127) { - actor.height += jsEither([4, 4, 5, 5]); - } else if (actor.height <= 132) { - actor.height += 2; - } - } else if (physicalAgeSwap === 13) { - if (actor.height <= 132) { - actor.height += jsEither([2, 2, 3, 3]); - } else if (actor.height <= 135) { - actor.height += 1; - } - } else if (physicalAgeSwap === 14) { - if (actor.height <= 135) { - actor.height += jsEither([2, 2, 3, 3]); - } else if (actor.height <= 138) { - actor.height += 1; - } - } else if (physicalAgeSwap === 15) { - if (actor.height <= 138) { - actor.height += jsEither([2, 2, 3, 3]); - } else if (actor.height <= 141) { - actor.height += 1; - } - } else if (physicalAgeSwap === 16) { - if (actor.height <= 143) { - actor.height += jsEither([1, 1, 2, 2]); - } - } else if (physicalAgeSwap === 17) { - if (actor.height <= 143) { - actor.height += jsEither([1, 1, 2, 2]); - } - } else if (physicalAgeSwap === 18) { - if (actor.height <= 143) { - actor.height += jsEither([1, 1, 2, 2]); - } - } - } else if (actor.hormoneBalance <= -100) { - if (physicalAgeSwap === 3) { - if (actor.height <= 80) { - actor.height += jsEither([2, 2, 2, 3, 3]); - } else if (actor.height <= 84) { - actor.height += 1; - } - } else if (physicalAgeSwap === 4) { - if (actor.height <= 84) { - actor.height += jsEither([5, 5, 5, 6, 6]); - } else if (actor.height <= 90) { - actor.height += 2; - } - } else if (physicalAgeSwap === 5) { - if (actor.height <= 90) { - actor.height += jsEither([9, 9, 9, 10, 10]); - } else if (actor.height <= 100) { - actor.height += 5; - } - } else if (physicalAgeSwap === 6) { - if (actor.height <= 100) { - actor.height += jsEither([4, 4, 4, 5, 5]); - } else if (actor.height <= 105) { - actor.height += 2; - } - } else if (physicalAgeSwap === 7) { - if (actor.height <= 105) { - actor.height += jsEither([3, 3, 3, 4, 4]); - } else if (actor.height <= 109) { - actor.height += 1; - } - } else if (physicalAgeSwap === 8) { - if (actor.height <= 109) { - actor.height += jsEither([4, 4, 4, 5, 5]); - } else if (actor.height <= 114) { - actor.height += 1; - } - } else if (physicalAgeSwap === 9) { - if (actor.height <= 114) { - actor.height += jsEither([3, 3, 3, 4, 4]); - } else if (actor.height <= 118) { - actor.height += 1; - } - } else if (physicalAgeSwap === 10) { - if (actor.height <= 118) { - actor.height += jsEither([3, 3, 3, 4, 4]); - } else if (actor.height <= 122) { - actor.height += 1; - } - } else if (physicalAgeSwap === 11) { - if (actor.height <= 122) { - actor.height += jsEither([4, 4, 4, 5, 5]); - } else if (actor.height <= 127) { - actor.height += 2; - } - } else if (physicalAgeSwap === 12) { - if (actor.height <= 127) { - actor.height += jsEither([4, 4, 4, 5, 5]); - } else if (actor.height <= 132) { - actor.height += 2; - } - } else if (physicalAgeSwap === 13) { - if (actor.height <= 132) { - actor.height += jsEither([2, 2, 2, 3, 3]); - } else if (actor.height <= 135) { - actor.height += 1; - } - } else if (physicalAgeSwap === 14) { - if (actor.height <= 135) { - actor.height += jsEither([2, 2, 2, 3, 3]); - } else if (actor.height <= 138) { - actor.height += 1; - } - } else if (physicalAgeSwap === 15) { - if (actor.height <= 138) { - actor.height += jsEither([2, 2, 2, 3, 3]); - } else if (actor.height <= 141) { - actor.height += 1; - } - } else if (physicalAgeSwap === 16) { - if (actor.height <= 143) { - actor.height += jsEither([1, 1, 1, 2, 2]); - } - } else if (physicalAgeSwap === 17) { - if (actor.height <= 143) { - actor.height += jsEither([1, 1, 1, 2, 2]); - } - } else if (physicalAgeSwap === 18) { - if (actor.height <= 143) { - actor.height += jsEither([1, 1, 1, 2, 2]); - } - } - } else { - if (physicalAgeSwap === 3) { - if (actor.height <= 80) { - actor.height += jsEither([1, 1, 2, 2, 3, 3]); - } else if (actor.height <= 84) { - actor.height += 1; - } - } else if (physicalAgeSwap === 4) { - if (actor.height <= 84) { - actor.height += jsEither([4, 4, 5, 5, 6, 6]); - } else if (actor.height <= 90) { - actor.height += 2; - } - } else if (physicalAgeSwap === 5) { - if (actor.height <= 90) { - actor.height += jsEither([8, 8, 9, 9, 10, 10]); - } else if (actor.height <= 100) { - actor.height += 5; - } - } else if (physicalAgeSwap === 6) { - if (actor.height <= 100) { - actor.height += jsEither([3, 3, 4, 4, 5, 5]); - } else if (actor.height <= 105) { - actor.height += 2; - } - } else if (physicalAgeSwap === 7) { - if (actor.height <= 105) { - actor.height += jsEither([2, 2, 3, 3, 4, 4]); - } else if (actor.height <= 109) { - actor.height += 1; - } - } else if (physicalAgeSwap === 8) { - if (actor.height <= 109) { - actor.height += jsEither([3, 3, 4, 4, 5, 5]); - } else if (actor.height <= 114) { - actor.height += 1; - } - } else if (physicalAgeSwap === 9) { - if (actor.height <= 114) { - actor.height += jsEither([2, 2, 3, 3, 4, 4]); - } else if (actor.height <= 118) { - actor.height += 1; - } - } else if (physicalAgeSwap === 10) { - if (actor.height <= 118) { - actor.height += jsEither([2, 2, 3, 3, 4, 4]); - } else if (actor.height <= 122) { - actor.height += 1; - } - } else if (physicalAgeSwap === 11) { - if (actor.height <= 122) { - actor.height += jsEither([3, 3, 4, 4, 5, 5]); - } else if (actor.height <= 127) { - actor.height += 2; - } - } else if (physicalAgeSwap === 12) { - if (actor.height <= 127) { - actor.height += jsEither([3, 3, 4, 4, 5, 5]); - } else if (actor.height <= 132) { - actor.height += 2; - } - } else if (physicalAgeSwap === 13) { - if (actor.height <= 132) { - actor.height += jsEither([1, 1, 2, 2, 3, 3]); - } else if (actor.height <= 135) { - actor.height += 1; - } - } else if (physicalAgeSwap === 14) { - if (actor.height <= 135) { - actor.height += jsEither([1, 1, 2, 2, 3, 3]); - } else if (actor.height <= 138) { - actor.height += 1; - } - } else if (physicalAgeSwap === 15) { - if (actor.height <= 138) { - actor.height += jsEither([1, 1, 2, 2, 3, 3]); - } else if (actor.height <= 141) { - actor.height += 1; - } - } else if (physicalAgeSwap === 16) { - if (actor.height <= 143) { - actor.height += jsEither([0, 0, 1, 1, 2, 2]); - } - } else if (physicalAgeSwap === 17) { - if (actor.height <= 143) { - actor.height += jsEither([0, 0, 1, 1, 2, 2]); - } - } else if (physicalAgeSwap === 18) { - if (actor.height <= 143) { - actor.height += jsEither([0, 0, 1, 1, 2, 2]); - } - } + function increaseHeight(actor) { + const unalteredHeight = actor.height - actor.heightImplant * 10; + const lastYearsTarget = Height.forAge(actor.natural.height, physicalAgeSwap - 1, actor.genes); + const thisYearsTarget = Height.forAge(actor.natural.height, physicalAgeSwap, actor.genes); + // by default, grow by the difference in natural height targets, +1/-2 cm + // slightly undershooting on average is intentional, since we can't shrink but we CAN have growth spurts + let thisYearsGrowth = thisYearsTarget - lastYearsTarget + jsRandom(-2, 1); + // if we're way ahead of target or way behind target, adjust towards it a bit harder + // if the player doesn't interfere, this mechanism should always end up within 2cm of the target at age 20, with slightly "spurty" growth + const deltaFromTarget = thisYearsTarget - (unalteredHeight + thisYearsGrowth); + const yearsLeft = Math.min(5, 21 - physicalAgeSwap); + if (deltaFromTarget >= yearsLeft) { + thisYearsGrowth = Math.max(0, thisYearsGrowth) + 2; + } else if (deltaFromTarget <= -yearsLeft) { + thisYearsGrowth = Math.min(0, thisYearsGrowth) - 2; } - } - - /** - * @param {FC.HumanState} actor - */ - function increaseHeightGiant(actor) { - if (actor.hormoneBalance >= 200) { - if (physicalAgeSwap < 16) { - if (actor.height <= 270) { - actor.height += random(5, 12); - } - } else { - if (actor.height <= 270) { - actor.height += random(3, 7); - } - } - } else if (actor.hormoneBalance >= 100) { - if (physicalAgeSwap < 16) { - if (actor.height <= 270) { - actor.height += random(7, 15); - } - } else { - if (actor.height <= 270) { - actor.height += random(5, 7); - } - } - } else if (actor.hormoneBalance <= -200) { - if (physicalAgeSwap < 16) { - if (actor.height <= 270) { - actor.height += random(10, 25); - } - } else { - if (actor.height <= 270) { - actor.height += random(7, 13); - } - } - } else if (actor.hormoneBalance <= -100) { - if (physicalAgeSwap < 16) { - if (actor.height <= 270) { - actor.height += random(7, 22); - } - } else { - if (actor.height <= 270) { - actor.height += random(7, 12); - } - } - } else { - if (physicalAgeSwap < 16) { - if (actor.height <= 270) { - actor.height += random(7, 20); - } - } else { - if (actor.height <= 270) { - actor.height += random(5, 10); - } - } + // never shrink + if (thisYearsGrowth > 0) { + actor.height += Math.round(thisYearsGrowth); } } diff --git a/src/events/intro/acquisition.js b/src/events/intro/acquisition.js index e20aa203f71b6c69157b56b34907ed404a2a001a..f8718ee8367229eec565273633a4e38b2d5eddc4 100644 --- a/src/events/intro/acquisition.js +++ b/src/events/intro/acquisition.js @@ -1001,6 +1001,7 @@ App.Intro.acquisition = function() { slave.geneticQuirks.dwarfism = 2; } } + slave.natural.height = slave.height; } slave.skill.oral = random(35, 65); slave.skill.anal = random(15, 35); @@ -1033,6 +1034,7 @@ App.Intro.acquisition = function() { slave.geneticQuirks.gigantism = 2; } } + slave.natural.height = slave.height; } slave.skill.oral = random(15, 35); slave.skill.anal = random(15, 35); diff --git a/src/events/intro/introSummary.js b/src/events/intro/introSummary.js index b4e33818e101639220a3e459711d8ad3cf9e8f9d..5baa94df043d8b12de14a8b660184dff5644ad0a 100644 --- a/src/events/intro/introSummary.js +++ b/src/events/intro/introSummary.js @@ -5,6 +5,7 @@ App.Intro.summary = function() { V.FSCreditCount = variableAsNumber(V.FSCreditCount, 4, 7, 5); V.PC.actualAge = variableAsNumber(V.PC.actualAge, 10, 80, 35); V.PC.height = variableAsNumber(V.PC.height, 85, 305, 185); + V.PC.natural.height = variableAsNumber(V.PC.natural.height, 85, 305, 185); V.PC.boobs = variableAsNumber(V.PC.boobs, 100, 50000, 200); V.PC.pubertyAgeXX = variableAsNumber(V.PC.pubertyAgeXX, 8, 13, 13); V.PC.pubertyAgeXY = variableAsNumber(V.PC.pubertyAgeXY, 8, 13, 13); diff --git a/src/events/intro/pcAppearance.js b/src/events/intro/pcAppearance.js index 0c6f83bed7ad2ac10079dee0cbdff70de3918998..82a7f7df9c1f3b9ec89fddcf5f957f9919196d6c 100644 --- a/src/events/intro/pcAppearance.js +++ b/src/events/intro/pcAppearance.js @@ -18,19 +18,44 @@ App.UI.Player.appearance = function(options, summary = false) { options.addOption("You are genetically", "genes", V.PC) .addValue("XY").addValue("XX"); - options.addOption(`You are`, "height", V.PC).showTextBox({unit: "cm"}) - .addRange(145, 150, "<", "Petite") - .addRange(155, 160, "<", "Short") - .addRange(165, 170, "<", "Average") - .addRange(180, 185, "<", "Tall") - .addRange(190, 185, ">=", "Very tall") - .addComment(`Average height for a ${V.PC.physicalAge} year old is ${heightToEitherUnit(Height.mean(V.PC))}`); + if (V.PC.physicalAge >= 20) { + options.addOption(`You are`, "height", V.PC.natural).showTextBox({unit: "cm"}) + .addRange(145, 150, "<", "Petite") + .addRange(155, 160, "<", "Short") + .addRange(165, 170, "<", "Average") + .addRange(180, 185, "<", "Tall") + .addRange(190, 185, ">=", "Very tall") + .addComment(`Average height is ${heightToEitherUnit(Height.mean(V.PC))}`) + .addCallback(() => V.PC.height = V.PC.natural.height); + } else { + options.addOption(`When full-grown, you will be`, "height", V.PC.natural).showTextBox({unit: "cm"}) + .addRange(145, 150, "<", "Petite") + .addRange(155, 160, "<", "Short") + .addRange(165, 170, "<", "Average") + .addRange(180, 185, "<", "Tall") + .addRange(190, 185, ">=", "Very tall"); + } option = options.addCustomOption() .addButton( "Make average", () => resyncSlaveHeight(V.PC), "" ); + if (V.PC.physicalAge < 20) { + options.addOption(`But right now, you are`, "height", V.PC).showTextBox({unit: "cm"}) + .addRange(Height.forAge(145, V.PC), Height.forAge(150, V.PC), "<", "Petite for your age") + .addRange(Height.forAge(155, V.PC), Height.forAge(160, V.PC), "<", "Short for your age") + .addRange(Height.forAge(165, V.PC), Height.forAge(170, V.PC), "<", "Average for your age") + .addRange(Height.forAge(180, V.PC), Height.forAge(185, V.PC), "<", "Tall for your age") + .addRange(Height.forAge(190, V.PC), Height.forAge(185, V.PC), ">=", "Very tall for your age") + .addComment(`Average height for a ${V.PC.physicalAge} year old is ${heightToEitherUnit(Height.mean(V.PC))}`); + option = options.addCustomOption() + .addButton( + "Scale for age from adult height", + () => V.PC.height = Height.forAge(V.PC.natural.height, V.PC), + "" + ); + } options.addOption("Your skin tone is", "skin", V.PC).showTextBox() .addValueList(makeAList(V.PC.race === "catgirl" ? App.Medicine.Modification.catgirlNaturalSkins : App.Medicine.Modification.naturalSkins)); @@ -299,7 +324,7 @@ App.UI.Player.syncAgeBasedParameters = function() { V.PC.physicalAge = V.PC.actualAge; V.PC.visualAge = V.PC.actualAge; V.PC.ovaryAge = V.PC.actualAge; - V.PC.height = Height.random(V.PC, {limitMult: [1, 2]}); + V.PC.height = Height.forAge(V.PC.natural.height, V.PC); if (V.PC.genes === "XY") { if (V.PC.physicalAge <= 13) { V.PC.hips = -2; diff --git a/src/events/nonRandom/pAidResult.js b/src/events/nonRandom/pAidResult.js index 7882f1e68ce43da45bc76975ffed1ae716fe9df0..b845aa3e6354a187ea14b8a770fa61a0a624ba12 100644 --- a/src/events/nonRandom/pAidResult.js +++ b/src/events/nonRandom/pAidResult.js @@ -249,7 +249,8 @@ App.Events.pAidResult = class pAidResult extends App.Events.BaseEvent { slave = GenerateNewSlave("XX", { disableDisability: 1, ageOverridesPedoMode: 1, minAge: 18, maxAge: 18 }); - slave.height = Height.random(slave, {skew: 1, limitMult: [0, 2]}); + slave.natural.height = Height.randomAdult(slave, {skew: 1, limitMult: [0.5, 2.5]}); + slave.height = Height.forAge(slave.natural.height, slave); slave.origin = "$He was a volleyball player you enslaved when you evacuated $him from a broken down bus."; slave.career = "a student athlete"; generateSalonModifications(slave); diff --git a/src/events/reRecruit/orphanFemboy.js b/src/events/reRecruit/orphanFemboy.js index 3224281851eb8294fcc23ad08a4f17acf4d60143..c7c8ca064a44c8e8aa2217b112a0e338f2b4f764 100644 --- a/src/events/reRecruit/orphanFemboy.js +++ b/src/events/reRecruit/orphanFemboy.js @@ -73,7 +73,8 @@ App.Events.recOrphanFemboy = class recOrphanFemboy extends App.Events.BaseEvent slave.scrotum = slave.balls; slave.pubicHStyle = "waxed"; slave.underArmHStyle = "waxed"; - slave.height = random(140, 170); + slave.natural.height = random(140, 170); + slave.height = Height.forAge(slave.natural.height, slave); slave.hips = random(-1, 0); slave.butt = 1; slave.anus = 1; diff --git a/src/events/reRecruit/racerDgChaser.js b/src/events/reRecruit/racerDgChaser.js index 06347da66a3ad7dc638aee4b96d741a3612ec738..ab40f18f094331484412fb201a8db1d9b8acadb0 100644 --- a/src/events/reRecruit/racerDgChaser.js +++ b/src/events/reRecruit/racerDgChaser.js @@ -74,7 +74,8 @@ App.Events.recRacerDgChaser = class recRacerDgChaser extends App.Events.BaseEven slave.dick = random(4, 5); slave.balls = random(3, 4); slave.scrotum = slave.balls; - slave.height = Height.forAge(random(180, 200), slave); + slave.natural.height = random(180, 200); + slave.height = Height.forAge(slave.natural.height, slave); slave.weight = 0; slave.muscles = 50; slave.intelligence = random(-50, 50); diff --git a/src/events/reRecruit/racerLoser.js b/src/events/reRecruit/racerLoser.js index dd73371cc025768fe3fad3550d8b152bd2088462..59e9a315772d5990822e467f8257387439b58ea5 100644 --- a/src/events/reRecruit/racerLoser.js +++ b/src/events/reRecruit/racerLoser.js @@ -85,7 +85,8 @@ App.Events.recRacerLoser = class recRacerLoser extends App.Events.BaseEvent { WombImpregnate(slave, slave.pregType, slave.pregSource, 0); slave.pubicHStyle = "waxed"; slave.underArmHStyle = "waxed"; - slave.height = Height.forAge(random(180, 200), slave); + slave.natural.height = random(180, 200); + slave.height = Height.forAge(slave.natural.height, slave); slave.hips = -1; slave.butt = 0; slave.anus = 0; diff --git a/src/events/reRecruit/racerWinner.js b/src/events/reRecruit/racerWinner.js index 7f6fce10e2d4e6554fa7265042981ef848ff8529..911dadacc49bd697ca57da1e3dae8661d196231c 100644 --- a/src/events/reRecruit/racerWinner.js +++ b/src/events/reRecruit/racerWinner.js @@ -84,7 +84,8 @@ App.Events.recRacerWinner = class recRacerWinner extends App.Events.BaseEvent { slave.preg = -1; slave.pubicHStyle = "waxed"; slave.underArmHStyle = "waxed"; - slave.height = Height.forAge(random(180, 200), slave); + slave.natural.height = random(180, 200); + slave.height = Height.forAge(slave.natural.height, slave); slave.shoulders = random(-1, 1); slave.hips = -1; slave.butt = 0; diff --git a/src/events/reRecruit/starvingArtist.js b/src/events/reRecruit/starvingArtist.js index 4b62ba3121aa7b07f70b12953d96bc938feace7c..372a873f9ed6f09bbb570fd43e890d52c6a047d5 100644 --- a/src/events/reRecruit/starvingArtist.js +++ b/src/events/reRecruit/starvingArtist.js @@ -59,7 +59,8 @@ App.Events.recStarvingArtist = class recStarvingArtist extends App.Events.BaseEv slave.origin = "$He offered $himself to you for enslavement out of devotion to $his artistic 'craft'."; slave.boobs = random(4, 6) * 50; slave.weight = -20; - slave.height = Height.forAge(random(160, 200), slave); + slave.natural.height = random(160, 200); + slave.height = Height.forAge(slave.natural.height, slave); slave.face = random(15, 100); slave.butt = random(1, 2); slave.lips = 0; diff --git a/src/events/recETS/recetsIncestBrotherBrother.js b/src/events/recETS/recetsIncestBrotherBrother.js index f32c9036ae9b21ea231589f0d2062833c2d5e8a7..3744891a0881ad67a3ce65f364077e351cbb1fcc 100644 --- a/src/events/recETS/recetsIncestBrotherBrother.js +++ b/src/events/recETS/recetsIncestBrotherBrother.js @@ -37,7 +37,6 @@ App.Events.recetsIncestBrotherBrother = class recetsIncestBrotherBrother extends brother1.relationship = 3; const brother2 = generateRelatedSlave(brother1, "younger brother"); - brother2.height += random(-5, 5); brother2.pubicHStyle = "shaved"; brother2.dick += 2; brother2.balls += 2; diff --git a/src/events/recETS/recetsIncestTwinBrother.js b/src/events/recETS/recetsIncestTwinBrother.js index 8ab785f01258588c744138c8b8ef81215b3bfdfa..c7f204555c0cbd59da0fe394edb8462c9e904f42 100644 --- a/src/events/recETS/recetsIncestTwinBrother.js +++ b/src/events/recETS/recetsIncestTwinBrother.js @@ -37,7 +37,6 @@ App.Events.recetsIncestTwinBrother = class recetsIncestTwinBrother extends App.E brother1.relationship = 3; const brother2 = generateRelatedSlave(brother1, "twin"); - brother2.height += random(-5, 5); brother2.energy = Math.max(brother2.energy, 40); brother2.attrXY = Math.max(brother2.attrXY, 70); if (brother2.behavioralFlaw === "hates men") { diff --git a/src/events/recETS/recetsIncestTwinSister.js b/src/events/recETS/recetsIncestTwinSister.js index 091551daba1c0aa53aff34f6db38158740bd63df..8ee9b5161889c50dd933b4682e5ab9210895b54b 100644 --- a/src/events/recETS/recetsIncestTwinSister.js +++ b/src/events/recETS/recetsIncestTwinSister.js @@ -39,7 +39,6 @@ App.Events.recetsIncestTwinSister = class recetsIncestTwinSister extends App.Eve const sis2 = generateRelatedSlave(sis1, "twin"); sis2.slaveName = sis2.birthName; - sis2.height += random(-5, 5); sis2.energy = Math.max(sis2.energy, 40); sis2.attrXX = Math.max(sis2.attrXX, 70); if (sis2.behavioralFlaw === "hates women") { diff --git a/src/events/recETS/recetsIncestTwinsMixed.js b/src/events/recETS/recetsIncestTwinsMixed.js index b8f46f391e77f63a4c5b6854ae8a61af278e4013..6bcb38c8bae197ce47d8ff93ba1bca10b396b7ae 100644 --- a/src/events/recETS/recetsIncestTwinsMixed.js +++ b/src/events/recETS/recetsIncestTwinsMixed.js @@ -40,7 +40,6 @@ App.Events.recetsIncestTwinsMixed = class recetsIncestTwinsMixed extends App.Eve sis.relationship = 3; const bro = generateRelatedSlave(sis, "twin", true); - bro.height += random(-5, 5); bro.vagina = -1; bro.dick = 2; bro.foreskin = 2; diff --git a/src/events/recFS/recfsPetiteAdmiration.js b/src/events/recFS/recfsPetiteAdmiration.js index c016347525bcdf4ff3badbea79524b455ee4740e..5d7e091ed0c7b3fc874eddb4261f8f59252d7e32 100644 --- a/src/events/recFS/recfsPetiteAdmiration.js +++ b/src/events/recFS/recfsPetiteAdmiration.js @@ -11,15 +11,16 @@ App.Events.recFSPetiteAdmiration = class recFSPetiteAdmiration extends App.Event const slave = GenerateNewSlave(null, {minAge: 13, maxAge: 22, disableDisability: 1}); generateSalonModifications(slave); slave.origin = "$He offered $himself for voluntary enslavement to avoid being singled out by ruthless slavers."; - if (slave.height >= Height.forAge(150, slave)) { - slave.height = Height.random(slave, {limitMult: [-2, 0]}); - if (slave.height >= Height.forAge(150, slave)) { - slave.height = Height.random(slave, {limitMult: [-3, -1]}); - if (slave.height >= Height.forAge(150, slave)) { - slave.height = Height.forAge(random(90, 130), slave); + if (slave.natural.height >= 150) { + slave.natural.height = Height.randomAdult(slave, {limitMult: [-2, 0]}); + if (slave.natural.height >= 150) { + slave.natural.height = Height.randomAdult(slave, {limitMult: [-3, -1]}); + if (slave.natural.height >= 150) { + slave.natural.height = random(90, 130); slave.geneticQuirks.dwarfism = 2; } } + slave.height = Height.forAge(slave.natural.height, slave); } setHealth(slave, jsRandom(20, 40), undefined, undefined, 0, 0); slave.face = Math.clamp(slave.face+80, -100, 100); diff --git a/src/events/recFS/recfsPetiteAdmirationTwo.js b/src/events/recFS/recfsPetiteAdmirationTwo.js index 4f1bf7ca5f1b82ed6de92bec910e359724b97b21..294e55743373d75de419f2f9d983a8cb55f171e7 100644 --- a/src/events/recFS/recfsPetiteAdmirationTwo.js +++ b/src/events/recFS/recfsPetiteAdmirationTwo.js @@ -20,7 +20,8 @@ App.Events.recFSPetiteAdmirationTwo = class recFSPetiteAdmirationTwo extends App slave.career = "a porn star"; generateSalonModifications(slave); slave.origin = "$He offered $himself to you for enslavement because $he felt your arcology would be a nice place to retire to."; - slave.height = random(90, 100); + slave.natural.height = random(90, 100); + slave.height = slave.natural.height; slave.geneticQuirks.dwarfism = 2; slave.boobsImplant += random(4, 6)*200; slave.boobs += slave.boobsImplant; diff --git a/src/events/recFS/recfsSlimnessEnthusiast.js b/src/events/recFS/recfsSlimnessEnthusiast.js index 64dd26301cde6c9690bacb209ee0b893e2f0c46a..c0a04697fd137ec2c6e9ed2ac641fe61ece3f7c1 100644 --- a/src/events/recFS/recfsSlimnessEnthusiast.js +++ b/src/events/recFS/recfsSlimnessEnthusiast.js @@ -22,7 +22,8 @@ App.Events.recFSSlimnessEnthusiast = class recFSSlimnessEnthusiast extends App.E slave.origin = "$He offered $himself to you for enslavement because $he felt your arcology was the best place for a $woman of $his appearance."; slave.boobs = random(4, 6)*50; slave.weight = -20; - slave.height = random(160, 200); + slave.natural.height = random(160, 200); + slave.height = slave.natural.height; slave.face = random(15, 100); slave.butt = random(1, 2); slave.lips = 0; diff --git a/src/events/recFS/recfsSlimnessEnthusiastTwo.js b/src/events/recFS/recfsSlimnessEnthusiastTwo.js index 069960a74a3c6b3161e1a9becf47878c717950da..b8660fa09b4136981c7458db1661ad014680c565 100644 --- a/src/events/recFS/recfsSlimnessEnthusiastTwo.js +++ b/src/events/recFS/recfsSlimnessEnthusiastTwo.js @@ -13,7 +13,8 @@ App.Events.recFSSlimnessEnthusiastTwo = class recFSSlimnessEnthusiastTwo extends slave.origin = "$He offered $himself to you for enslavement to escape having plastic surgery foisted on $him."; slave.boobs = random(4, 6)*50; slave.weight = -20; - slave.height = random(160, 200); + slave.natural.height = random(160, 200); + slave.height = slave.natural.height; slave.face = random(15, 100); slave.butt = random(1, 2); slave.lips = 0; diff --git a/src/events/recFS/recfsStatuesqueGlorification.js b/src/events/recFS/recfsStatuesqueGlorification.js index a8701cd3b7b499207e9c4cdb148589c803017a85..9e22ea676caa876e6e0547bf9a5cd610d6abb3bd 100644 --- a/src/events/recFS/recfsStatuesqueGlorification.js +++ b/src/events/recFS/recfsStatuesqueGlorification.js @@ -18,7 +18,8 @@ App.Events.recFSStatuesqueGlorification = class recFSStatuesqueGlorification ext const slave = GenerateNewSlave(null, {disableDisability: 1}); generateSalonModifications(slave); slave.origin = "$He offered $himself for voluntary enslavement to avoid being singled out by ruthless slavers."; - slave.height = Height.forAge(random(200, 264), slave); + slave.natural.height = random(200, 264); + slave.height = Height.forAge(slave.natural.height, slave); setHealth(slave, jsRandom(20, 40), undefined, undefined, 0, 0); slave.geneticQuirks.gigantism = 2; slave.devotion = random(15, 20); diff --git a/src/events/recFS/recfsStatuesqueGlorificationTwo.js b/src/events/recFS/recfsStatuesqueGlorificationTwo.js index 7ba3ebf7ab06a76a9aae4573ac6d916ec1635587..dfd7bcefebbdd31d290b0cde529092d8a6d5afcb 100644 --- a/src/events/recFS/recfsStatuesqueGlorificationTwo.js +++ b/src/events/recFS/recfsStatuesqueGlorificationTwo.js @@ -10,7 +10,8 @@ App.Events.recFSStatuesqueGlorificationTwo = class recFSStatuesqueGlorificationT let r = []; const slave = GenerateNewSlave(null, {disableDisability: 1}); slave.origin = "$He offered $himself for voluntary enslavement knowing $he would only fit in with your help."; - slave.height = 165; + slave.natural.height = 165; + slave.height = Height.forAge(slave.natural.height, slave); setHealth(slave, jsRandom(20, 40), undefined, undefined, 0, 0); slave.shoes = "extreme heels"; slave.devotion = random(30, 45); diff --git a/src/events/scheduled/assholeKnight.js b/src/events/scheduled/assholeKnight.js index 98014450cd255ce3def4a3e0de6e0eeefd78d4ce..77123c11534d50412c50298f47abb69514402b0d 100644 --- a/src/events/scheduled/assholeKnight.js +++ b/src/events/scheduled/assholeKnight.js @@ -23,7 +23,8 @@ App.Events.SEAssholeKnight = class SEAssholeKnight extends App.Events.BaseEvent assholeKnight.behavioralQuirk = "none"; assholeKnight.trust = random(-30, -20); assholeKnight.butt = random(0, 1); - assholeKnight.height = random(175, 195); + assholeKnight.natural.height = random(175, 195); + assholeKnight.height = assholeKnight.natural.height; assholeKnight.fetish = "sadist"; assholeKnight.fetishStrength = 80; assholeKnight.preg = 0; diff --git a/src/events/scheduled/seCustomSlaveDelivery.js b/src/events/scheduled/seCustomSlaveDelivery.js index 3fc0fa58f9759c7f164ee6f7592142c0b6488932..6fce1c98df4fb76f06b4edd8b87279b10dfae3f7 100644 --- a/src/events/scheduled/seCustomSlaveDelivery.js +++ b/src/events/scheduled/seCustomSlaveDelivery.js @@ -193,16 +193,17 @@ App.Events.SEcustomSlaveDelivery = class SEcustomSlaveDelivery extends App.Event /* I have no clue what I'm doing here */ if (V.customSlave.heightMod === "greatly below average") { - delivery.height = Height.random(delivery, {skew: -5, spread: 0.15, limitMult: [-5, -2]}); + delivery.natural.height = Height.randomAdult(delivery, {skew: -5, spread: 0.15, limitMult: [-5, -2]}); } else if (V.customSlave.heightMod === "below average") { - delivery.height = Height.random(delivery, {skew: -1, limitMult: [-2, 0]}); + delivery.natural.height = Height.randomAdult(delivery, {skew: -1, limitMult: [-2, 0]}); } else if (V.customSlave.heightMod === "normal") { - delivery.height = Height.random(delivery, {limitMult: [-1, 1]}); + delivery.natural.height = Height.randomAdult(delivery, {limitMult: [-1, 1]}); } else if (V.customSlave.heightMod === "above average") { - delivery.height = Height.random(delivery, {skew: 1, limitMult: [0, 2]}); + delivery.natural.height = Height.randomAdult(delivery, {skew: 1, limitMult: [0, 2]}); } else { - delivery.height = Height.random(delivery, {skew: 5, spread: 0.15, limitMult: [2, 5]}); + delivery.natural.height = Height.randomAdult(delivery, {skew: 5, spread: 0.15, limitMult: [2, 5]}); } + delivery.height = Height.forAge(delivery.natural.height, delivery); if (V.customSlave.intelligence === 3) { delivery.intelligence = random(96, 100); diff --git a/src/events/scheduled/seRecruiterSuccess.js b/src/events/scheduled/seRecruiterSuccess.js index 68e7acbdab755d1592829856f8816e08a77d3daa..3855c82e52d666c3c86367128e173aeeedbc81f8 100644 --- a/src/events/scheduled/seRecruiterSuccess.js +++ b/src/events/scheduled/seRecruiterSuccess.js @@ -141,7 +141,8 @@ App.Events.SERecruiterSuccess = class SERecruiterSuccess extends App.Events.Base slave.intelligence = Intelligence.random({limitIntelligence: [40, 100]}); } if (V.policies.SMR.eugenics.heightSMR === 1) { - slave.height = Height.mean(slave) + random(15, 30); + slave.natural.height = Height.mean(slave.nationality, slave.race, slave.genes, 20) + random(15, 30); + slave.height = Height.forAge(slave.natural.height, slave); } if (V.policies.SMR.eugenics.faceSMR === 1) { slave.face = random(40, 100); diff --git a/src/facilities/nursery/utils/nurseryUtils.js b/src/facilities/nursery/utils/nurseryUtils.js index 914c006e347d7d037271d8193429749f809e9660..7240d517b2f56b2e21aa0bdfd110963ff4121a18 100644 --- a/src/facilities/nursery/utils/nurseryUtils.js +++ b/src/facilities/nursery/utils/nurseryUtils.js @@ -200,7 +200,6 @@ App.Facilities.Nursery.infantToChild = function infantToChild(child) { setHealth(child, jsRandom(80, 100), 0, 0, 0, 0); child.hears = 0; child.heels = 0; - child.height = jsRandom(85, 105); child.hips = 0; child.hormoneBalance = 0; child.hormones = 0; @@ -354,6 +353,7 @@ App.Facilities.Nursery.infantToChild = function infantToChild(child) { child.wombImplant = "none"; resetEyeColor(child, "both"); generatePronouns(child); + child.height = Height.forAge(child.natural.height, child); return child; }; diff --git a/src/facilities/surgery/analyzePregnancy.js b/src/facilities/surgery/analyzePregnancy.js index d8ca35ebedbe1f7a3ccf56111499bbd30ac3d809..5f25ca40354f5d78474c2a69712cb0d818013704 100644 --- a/src/facilities/surgery/analyzePregnancy.js +++ b/src/facilities/surgery/analyzePregnancy.js @@ -62,6 +62,10 @@ globalThis.analyzePregnancies = function(mother, cheat) { if (cheat) { option.showTextBox(); } + option = options.addOption(`Expected adult height: ${heightToEitherUnit(genes.adultHeight)}`, "adultHeight", genes); + if (cheat) { + option.showTextBox(); + } option = options.addOption(`Eye Color: ${capFirstChar(genes.eyeColor)}`, "eyeColor", genes); if (cheat) { option.showTextBox().pulldown(); diff --git a/src/interaction/siCustom.js b/src/interaction/siCustom.js index 71418245b010b8bf09fbaea3c431c9c2a7e1e8ad..1afa30bea50fd602432d1e18c9abcf301a67edab 100644 --- a/src/interaction/siCustom.js +++ b/src/interaction/siCustom.js @@ -16,7 +16,8 @@ App.UI.SlaveInteract.custom = function(slave, refresh) { App.UI.DOM.appendNewElement("h3", el, `Art`); el.append( customSlaveImage(), - customHairImage() + customHairImage(), + artSeed() ); App.UI.DOM.appendNewElement("h3", el, `Names`); @@ -674,6 +675,30 @@ App.UI.SlaveInteract.custom = function(slave, refresh) { return el; } + function artSeed() { + const frag = new DocumentFragment(); + if (V.imageChoice === 4) { // webGL only right now + App.UI.DOM.appendNewElement("p", frag, `WebGL rendering uses a "seed value" to make small changes to the appearance of your slaves. If you're dissatisfied with this slave's appearance and correcting ${his} physical parameters doesn't seem to help, you can try replacing the seed value. Slaves with identical seeds will look identical; the game carefully preserves this value for clones and identical twins, but if you change it here it becomes your responsibility.`); + + const setArtSeed = (/** @type {number} */ num) => { + slave.natural.artSeed = num; + refresh(); + App.Events.refreshEventArt(slave); + }; + const button = App.UI.DOM.makeElement("button", "Randomize"); + button.onclick = () => setArtSeed(jsRandom(0, 10 ** 14)); + const textbox = App.UI.DOM.makeTextBox(slave.natural.artSeed, (num) => setArtSeed(num), true); + textbox.style.maxWidth = "12em"; + textbox.style.minWidth = "12em"; + App.UI.DOM.appendNewElement("p", frag, App.UI.DOM.combineNodes( + "Art seed: ", + textbox, + button + )); + } + return frag; + } + function customSlaveImage() { let el = document.createElement('p'); el.append(`Assign ${him} a custom image: `); diff --git a/src/js/SlaveState.js b/src/js/SlaveState.js index 5224aead3fbdf748b80116a71209de4b6709e2c3..65f660557e4a406a180bdd7bf0147d16c040667c 100644 --- a/src/js/SlaveState.js +++ b/src/js/SlaveState.js @@ -601,6 +601,16 @@ App.Entity.EyeState = class EyeState { } }; +/** Genetic "natural targets" for this individual when full grown, without influence from drugs, surgery, etc */ +App.Entity.GeneticState = class GeneticState { + constructor() { + // TODO: move origHColor, origSkin, origRace here, as hColor, skin, race? + this.height = 170; // new - almost done. need to rewrite physical development for both player and slave. + // this.boobs = 500; // TODO: for pregmodder + this.artSeed = jsRandom(0, 10 ** 14); + } +}; + App.Entity.SlaveState = class SlaveState { constructor() { /** Slave's current name */ @@ -618,6 +628,8 @@ App.Entity.SlaveState = class SlaveState { this.genes = "XX"; /** @type {number} */ this.pronoun = App.Data.Pronouns.Kind.female; + /** slave's natural genetic properties */ + this.natural = new App.Entity.GeneticState(); /** game week slave was acquired. * * _0: Obtained prior to game start / at game start_ */ diff --git a/src/js/utilsSlave.js b/src/js/utilsSlave.js index 9c0c46f67e867a423c5075296437431aeb5f795a..200b1f3d13f84a55ab074b297f69fb5c4dd2acdf 100644 --- a/src/js/utilsSlave.js +++ b/src/js/utilsSlave.js @@ -637,6 +637,27 @@ globalThis.Height = (function() { return applyAge(result, age, genes); } + /** + * @param {{nationality: string, race: FC.Race, genes: string, physicalAge: number, birthWeek: number}} slave + * @param {Partial<heightConfig>} [conf] + * @returns {number} + */ + function _randomAdultHeight(slave, conf) { + const mean = _meanHeight({ + nationality: slave.nationality, + race: slave.race, + genes: slave.genes, + physicalAge: 20, + birthWeek: 0 + }); + if (conf) { + const localConfig = Object.assign({}, defaultConfig); + Object.assign(localConfig, conf); + return heightGenerator(localConfig, mean); + } + return heightGenerator(defaultConfig, mean); + } + /** * @param {{nationality: string, race: FC.Race, genes: string, physicalAge: number, birthWeek: number}} slave * @param {Partial<heightConfig>} [conf] @@ -670,6 +691,7 @@ globalThis.Height = (function() { return { mean: _meanHeight, random: _randomHeight, + randomAdult: _randomAdultHeight, forAge: _forAge, config: _config, }; @@ -959,7 +981,8 @@ globalThis.randomCareer = function(slave) { * @param {FC.HumanState} slave */ globalThis.resyncSlaveHeight = function(slave) { - slave.height = Height.random(slave); + slave.natural.height = Height.randomAdult(slave); + slave.height = Height.forAge(slave.natural.height, slave); }; /** @@ -2843,7 +2866,7 @@ globalThis.ageSlave = function(slave, forceDevelopment = false) { if (slave.broodmother === 1) { slave.ovaryAge += 0.2; } - if (slave.physicalAge <= 18 && (forceDevelopment || V.loliGrow > 0)) { + if (slave.physicalAge <= 20 && (forceDevelopment || V.loliGrow > 0)) { App.EndWeek.Shared.physicalDevelopment(slave); } }; diff --git a/src/js/wombJS.js b/src/js/wombJS.js index 00b724f1be45b9a491221b746190508743bfe8eb..b73dbee7883f63c9b65f608ba032b154b296d996 100644 --- a/src/js/wombJS.js +++ b/src/js/wombJS.js @@ -101,6 +101,13 @@ globalThis.WombInit = function(actor) { {ID: null, mother: f.genetics.mother, father: f.genetics.father} ); } + if (!jsDef(f.genetics.artSeed)) { + // probably could detect and fix clones/twins here too, but I'm not bothering + f.genetics.artSeed = jsRandom(0, 10 ** 14); + } + if (!jsDef(f.genetics.adultHeight)) { + f.genetics.adultHeight = Height.randomAdult({nationality: f.genetics.nationality, race: f.genetics.race, genes: f.genetics.gender, physicalAge: 20, birthWeek: 0}); + } }); }; @@ -197,6 +204,7 @@ globalThis.WombImpregnateClone = function(actor, fCount, mother, age) { tf.genetics.faceShape = motherOriginal.faceShape; tf.genetics.geneticQuirks = clone(mother.geneticQuirks); tf.genetics.skin = motherOriginal.skin; + tf.genetics.artSeed = mother.natural.artSeed; try { if (actor.womb.length === 0) { diff --git a/src/markets/specificMarkets/eliteSlave.js b/src/markets/specificMarkets/eliteSlave.js index 6aa670ec4e332abd00629a579a06f49410bfb0ce..8e5a2e99f015c4e5cbd8431ad69071cf9c676012 100644 --- a/src/markets/specificMarkets/eliteSlave.js +++ b/src/markets/specificMarkets/eliteSlave.js @@ -37,10 +37,11 @@ App.Markets["Elite Slave"] = function() { slave.devotion = random(60, 100); if (!heightPass(slave)) { if (V.arcologies[0].FSPetiteAdmiration > 20) { - slave.height = Height.random(slave, {limitMult: [-4, -2]}); + slave.natural.height = Height.randomAdult(slave, {limitMult: [-4, -2]}); } else if (V.arcologies[0].FSStatuesqueGlorification > 20) { - slave.height = Height.random(slave, {limitMult: [3, 5]}); + slave.natural.height = Height.randomAdult(slave, {limitMult: [3, 5]}); } + slave.height = Height.forAge(slave.natural.height, slave); } if (V.arcologies[0].FSPaternalist > 20) { setHealth(slave, 100, 0, 0, 0, 0); diff --git a/src/markets/specificMarkets/prestigiousSlave.js b/src/markets/specificMarkets/prestigiousSlave.js index a14e42781f7810397d086df809c5ef616ba9f524..550f2ffc5854c1f2c8d579865dd10c26783e692a 100644 --- a/src/markets/specificMarkets/prestigiousSlave.js +++ b/src/markets/specificMarkets/prestigiousSlave.js @@ -823,7 +823,8 @@ App.Markets["Prestigious Slave"] = function() { slave.prestigeDesc = "$He was once a rising old world politician, but was forced to flee from the increasingly dangerous politics common in a stressed world, and was subsequently enslaved."; slave.career = "a politician"; slave.muscles = random(10, 50); - slave.height = random(160, 200); + slave.natural.height = random(160, 200); + slave.height = slave.natural.height; slave.face = Math.clamp(slave.face + 20, -100, 100); slave.faceImplant += 20; slave.faceShape = "masculine"; diff --git a/src/npc/children/ChildState.js b/src/npc/children/ChildState.js index 67143dd75b9c2b2d8cf92c1a158e5a48068cc606..27388ac6e51c66ecf6dae71c516f1f358999d83a 100644 --- a/src/npc/children/ChildState.js +++ b/src/npc/children/ChildState.js @@ -19,6 +19,8 @@ App.Facilities.Nursery.ChildState = class ChildState { this.genes = "XX"; /** @type {number} */ this.pronoun = App.Data.Pronouns.Kind.female; + /** slave's natural genetic properties */ + this.natural = new App.Entity.GeneticState(); /** Game week slave was acquired. * * _0: Obtained prior to game start / at game start_ */ diff --git a/src/npc/databases/cheatmodeDatabase.js b/src/npc/databases/cheatmodeDatabase.js index 919e7945e8a89d1bed3f022b79ac50c43de58777..60baa3766077f2b116ee705b27c84e124dc35c69 100644 --- a/src/npc/databases/cheatmodeDatabase.js +++ b/src/npc/databases/cheatmodeDatabase.js @@ -23,6 +23,7 @@ App.Intro.cheatModeSlaves = function() { setHealth(cheatSlave, 50); cheatSlave.devotion = 100; cheatSlave.nationality = "Stateless"; + cheatSlave.natural.height = 175; cheatSlave.height = 175; cheatSlave.race = "white"; cheatSlave.eye.origColor = "green"; @@ -92,6 +93,7 @@ App.Intro.cheatModeSlaves = function() { cheatSlave.devotion = 100; cheatSlave.nationality = "Stateless"; cheatSlave.muscles = 20; + cheatSlave.natural.height = 190; cheatSlave.height = 190; cheatSlave.race = "black"; cheatSlave.origHColor = "black"; @@ -161,6 +163,7 @@ App.Intro.cheatModeSlaves = function() { setHealth(cheatSlave, 10); cheatSlave.devotion = 60; cheatSlave.nationality = "Stateless"; + cheatSlave.natural.height = 175; cheatSlave.height = 175; cheatSlave.race = "black"; cheatSlave.pubicHColor = "black"; @@ -227,6 +230,7 @@ App.Intro.cheatModeSlaves = function() { cheatSlave.devotion = 60; cheatSlave.nationality = "Stateless"; cheatSlave.muscles = 50; + cheatSlave.natural.height = 190; cheatSlave.height = 190; cheatSlave.race = "black"; cheatSlave.origHColor = "black"; @@ -299,6 +303,7 @@ App.Intro.cheatModeSlaves = function() { cheatSlave.devotion = 30; cheatSlave.nationality = "Stateless"; cheatSlave.muscles = 50; + cheatSlave.natural.height = 175; cheatSlave.height = 175; cheatSlave.race = "white"; cheatSlave.eye.origColor = "green"; @@ -359,6 +364,7 @@ App.Intro.cheatModeSlaves = function() { cheatSlave.devotion = 60; cheatSlave.nationality = "Stateless"; cheatSlave.muscles = 50; + cheatSlave.natural.height = 190; cheatSlave.height = 190; cheatSlave.race = "black"; cheatSlave.origHColor = "black"; diff --git a/src/npc/generate/generateGenetics.js b/src/npc/generate/generateGenetics.js index 23cfcc48ee84e04852ca241c906600af580bfbbe..1a0a13c3deb543042bb233d49b9529b204adc229 100644 --- a/src/npc/generate/generateGenetics.js +++ b/src/npc/generate/generateGenetics.js @@ -49,7 +49,9 @@ globalThis.generateGenetics = (function() { cloneID: 0, geneticQuirks: {}, fetish: "none", - spermY: 50 + spermY: 50, + adultHeight: 170, + artSeed: jsRandom(0, 10 ** 14) }; if (actor1.ID > 0) { mother = V.genePool.find(s => s.ID === actor1.ID); @@ -109,10 +111,40 @@ globalThis.generateGenetics = (function() { genes.behavioralFlaw = setBehavioralFlaw(father, mother); genes.fetish = setFetish(father, mother); genes.spermY = setSpermY(father, mother); + genes.adultHeight = setAdultHeight(father, mother, genes.gender, genes.race, genes.nationality, genes.geneticQuirks); return genes; } + /** set expected adult height for the fetus + * @param {FC.Zeroable<FC.HumanState>} father + * @param {FC.HumanState} mother + * @param {string} gender + * @param {FC.Race} race + * @param {string} nationality + * @param {Partial<FC.GeneticQuirks>} quirks + * @returns {number} + */ + function setAdultHeight(father, mother, gender, race, nationality, quirks) { + const randomPart = Height.random({nationality, race, genes: gender, physicalAge: 20, birthWeek: 0}); + if ((quirks.dwarfism === 2) !== (mother.geneticQuirks.dwarfism === 2) || + (quirks.gigantism === 2) !== (mother.geneticQuirks.gigantism === 2) || + father && ((quirks.dwarfism === 2) !== (father.geneticQuirks.dwarfism === 2)) || + father && ((quirks.gigantism === 2) !== (father.geneticQuirks.gigantism === 2))) { + // we have a height quirk change compared to one of our parents. better to just start over with a completely random target height. + return randomPart; + } + // global average: men are 7% taller than women. natural heights contain this bias. + const genderScalingFactor = 1.07; + // heritance ratio for height in humans is currently estimated at 79% (Yengo, L., Vedantam, S., Marouli, E., et al. "A saturated map of common genetic variants associated with human height." Nature 610, 704–712 (2022)) + const heritanceRatio = 0.79; + // assemble! + const motherPart = mother.natural.height * (gender === "XX" ? 1.0 : genderScalingFactor); + const fatherPart = father ? father.natural.height * (gender === "XY" ? 1.0 : (1 / genderScalingFactor)) : motherPart; + const inheritedPart = (motherPart + fatherPart) * 0.5; + return Math.round((heritanceRatio * inheritedPart) + ((1 - heritanceRatio) * randomPart)); + } + // get spermY value of the parent that's donating the Y chromosome function getSpermY(father, mother) { let sourceSpermY = 50; // default if no inherited Y chromosome (should be impossible, but the Adam Principle is optional, so it can happen) @@ -1088,6 +1120,7 @@ globalThis.generateGenetics = (function() { * @returns {App.Entity.SlaveState|App.Facilities.Nursery.InfantState} */ globalThis.generateChild = function(mother, ovum, incubator = false) { + /** @type {FC.FetusGenetics} */ let genes = ovum.genetics; // TODO: maybe just argument this? We'll see. let child; @@ -1129,6 +1162,7 @@ globalThis.generateChild = function(mother, ovum, incubator = false) { child.skin = getGeneticSkinColor(child); child.hColor = getGeneticHairColor(child); child.spermY = genes.spermY; + child.natural.height = genes.adultHeight; child.pubicHColor = child.hColor; child.underArmHColor = child.hColor; child.eyebrowHColor = child.hColor; @@ -1219,6 +1253,7 @@ globalThis.generateChild = function(mother, ovum, incubator = false) { child.tailColor = child.hColor; } child.spermY = genes.spermY; + child.natural.height = genes.adultHeight; resetEyeColor(child, "both"); child.pubicHColor = child.hColor; child.underArmHColor = child.hColor; diff --git a/src/npc/generate/generateLeadershipSlave.js b/src/npc/generate/generateLeadershipSlave.js index 4862b4c8e606e6cac00c10e7cd500c840fcaa3f5..0f395edb91ab4d2af8cba9d71e6bea106e2b267f 100644 --- a/src/npc/generate/generateLeadershipSlave.js +++ b/src/npc/generate/generateLeadershipSlave.js @@ -66,7 +66,8 @@ globalThis.generateLeadershipSlave = function(input, location) { slave.devotion = jsRandom(51, 85); slave.trust = jsRandom(51, 85); slave.muscles = jsRandom(30, 70); - slave.height = Height.random(slave, {skew: 3, spread: .2, limitMult: [1, 4]}); + slave.natural.height = Height.randomAdult(slave, {skew: 3, spread: .2, limitMult: [1, 4]}); + slave.height = Height.forAge(slave.natural.height, slave); slave.weight = jsRandom(-10, 10); slave.teeth = either("normal", "pointy"); slave.skill.combat = 70; @@ -164,7 +165,8 @@ globalThis.generateLeadershipSlave = function(input, location) { slave.muscles = jsRandom(41, 70); slave.sexualQuirk = "caring"; slave.weight = jsRandom(0, 30); - slave.height = Height.random(slave, {skew: 3, spread: .2, limitMult: [1, 4]}); + slave.natural.height = Height.randomAdult(slave, {skew: 3, spread: .2, limitMult: [1, 4]}); + slave.height = Height.forAge(slave.natural.height, slave); applyMaleGenitalia({dick: jsRandom(3, 5), balls: jsRandom(4, 9), prostate: either(1, 1, 1, 2)}); slave.career = either(App.Data.Careers.Leader.farmer); break; diff --git a/src/npc/generate/generateMarketSlave.js b/src/npc/generate/generateMarketSlave.js index 22843621dcdc6816f9a3d9b8d657607f998f8f56..84f4c115e5ea52c54588a46a8cd3f53bef0abc5f 100644 --- a/src/npc/generate/generateMarketSlave.js +++ b/src/npc/generate/generateMarketSlave.js @@ -112,7 +112,8 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1 r += `The corporation specifically targets incredibly tall slaves. `; maxMult = 5; // do not limit tallness } - slave.height = Height.random(slave, {skew: V.corp.SpecHeight - 3, limitMult: [minMult, maxMult]}); + slave.natural.height = Height.randomAdult(slave, {skew: V.corp.SpecHeight - 3, limitMult: [minMult, maxMult]}); + slave.height = Height.forAge(slave.natural.height, slave); } if (V.corp.SpecVirgin === 1) { r += `The corporation ensures its slaves are virgins. `; @@ -865,27 +866,29 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1 } if (neighbor.FSPetiteAdmiration > 20) { r += `They tend to be short, some far more than others. `; - if (slave.height >= Height.forAge(160, slave)) { - slave.height = Height.random(slave, {limitMult: [-2, 0]}); - if (slave.height >= Height.forAge(160, slave)) { - slave.height = Height.random(slave, {limitMult: [-3, -1]}); - if (slave.height >= Height.forAge(160, slave)) { - slave.height = Height.forAge(jsRandom(90, 130), slave); + if (slave.natural.height >= 160) { + slave.natural.height = Height.random(slave, {limitMult: [-2, 0]}); + if (slave.natural.height >= 160) { + slave.natural.height = Height.random(slave, {limitMult: [-3, -1]}); + if (slave.natural.height >= 160) { + slave.natural.height = jsRandom(90, 130); slave.geneticQuirks.dwarfism = 2; } } + slave.height = Height.forAge(slave.natural.height, slave); } } else if (neighbor.FSStatuesqueGlorification > 20) { r += `They tend to be tall, if not unbelievably so. `; - if (slave.height < Height.forAge(170, slave)) { - slave.height = Height.random(slave, {limitMult: [0, 2]}); - if (slave.height < Height.forAge(170, slave)) { - slave.height = Height.random(slave, {limitMult: [1, 3]}); - if (slave.height < Height.forAge(170, slave)) { - slave.height = Height.forAge(jsRandom(200, 264), slave); + if (slave.natural.height < 170) { + slave.natural.height = Height.random(slave, {limitMult: [0, 2]}); + if (slave.natural.height < 170) { + slave.natural.height = Height.random(slave, {limitMult: [1, 3]}); + if (slave.natural.height < 170) { + slave.natural.height = jsRandom(200, 264); slave.geneticQuirks.gigantism = 2; } } + slave.height = Height.forAge(slave.natural.height, slave); } } if (neighbor.FSSlimnessEnthusiast > 20) { @@ -1599,7 +1602,7 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1 } else { setHealth(slave, jsRandom(-50, 100), Math.max(normalRandInt(0, 4), 0), Math.max(normalRandInt(10, 4), 0), Math.max(normalRandInt(0, 0.5), 0), jsRandom(10, 20)); } - slave.height = jsRandom(160, 210); + slave.height = Math.max(jsRandom(160, 210), slave.natural.height); slave.butt = jsRandom(4, 10); if (V.GRI.schoolUpgrade === 2) { slave.boobs = 200 * jsRandom(15, 30); @@ -2227,15 +2230,16 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1 setHealth(slave, jsRandom(60, 80), 0, Math.max(normalRandInt(0, 2), 0), 0, jsRandom(5, 20)); const minHeight = jsRandom(170, 180); if (V.HA.schoolUpgrade === 2) { - slave.height = Math.clamp(Height.random(slave, { + slave.natural.height = Math.clamp(Height.random(slave, { limitMult: [2, 15], spread: 0.1 }), minHeight, 274); slave.muscles = jsRandom(40, 80); } else { - slave.height = Math.clamp(Height.random(slave, {limitMult: [1, 4]}), minHeight, 274); + slave.natural.height = Math.clamp(Height.random(slave, {limitMult: [1, 4]}), minHeight, 274); slave.muscles = jsRandom(20, 40); } + slave.height = slave.natural.height; if (V.HA.schoolUpgrade === 3) { slave.weight = jsEither([10, 20, 20, 30, 30, 40, 40, 50]); slave.waist = jsRandom(-10, 40); diff --git a/src/npc/generate/generateNewSlaveJS.js b/src/npc/generate/generateNewSlaveJS.js index 771360302c3b98d907ea80a006f9073c03eb3f18..da75bca2f209edc8d3f0c424f8025d3f229bef62 100644 --- a/src/npc/generate/generateNewSlaveJS.js +++ b/src/npc/generate/generateNewSlaveJS.js @@ -167,12 +167,13 @@ globalThis.GenerateNewSlave = (function() { function generateXXBodyProportions() { if (slave.geneticQuirks.dwarfism === 2 && slave.geneticQuirks.gigantism !== 2) { - slave.height = Height.random(slave, {limitMult: [-4, -1], spread: 0.15}); + slave.natural.height = Height.randomAdult(slave, {limitMult: [-4, -1], spread: 0.15}); } else if (slave.geneticQuirks.gigantism === 2) { - slave.height = Height.random(slave, {limitMult: [3, 10], spread: 0.15}); + slave.natural.height = Height.randomAdult(slave, {limitMult: [3, 10], spread: 0.15}); } else { - slave.height = Height.random(slave); + slave.natural.height = Height.randomAdult(slave); } + slave.height = Height.forAge(slave.natural.height, slave); if (slave.height >= Height.mean(slave) * 170 / 162.5) { slave.hips = jsEither([-1, 0, 0, 1, 1, 2, 2]); slave.shoulders = jsEither([-1, -1, 0, 0, 0, 1]); @@ -200,12 +201,13 @@ globalThis.GenerateNewSlave = (function() { function generateXYBodyProportions() { if (slave.geneticQuirks.dwarfism === 2 && slave.geneticQuirks.gigantism !== 2) { - slave.height = Height.random(slave, {limitMult: [-4, -1], spread: 0.15}); + slave.natural.height = Height.randomAdult(slave, {limitMult: [-4, -1], spread: 0.15}); } else if (slave.geneticQuirks.gigantism === 2) { - slave.height = Height.random(slave, {limitMult: [3, 10], spread: 0.15}); + slave.natural.height = Height.randomAdult(slave, {limitMult: [3, 10], spread: 0.15}); } else { - slave.height = Height.random(slave); + slave.natural.height = Height.randomAdult(slave); } + slave.height = Height.forAge(slave.natural.height, slave); if (slave.physicalAge <= 13) { if (slave.height > Height.mean(slave) * 170 / 172.5) { slave.hips = jsEither([-2, -1, -1, 0, 1]); diff --git a/src/npc/generate/generateRelatedSlave.js b/src/npc/generate/generateRelatedSlave.js index 9d9dd98adf8b36bd1322f6c37f06b1c293c1989b..95fc244f2afdb0b548cfc2c6518feb610c8724c9 100644 --- a/src/npc/generate/generateRelatedSlave.js +++ b/src/npc/generate/generateRelatedSlave.js @@ -260,6 +260,12 @@ globalThis.generateRelatedSlave = (function() { if (slave.butt > 1) { slave.butt += random(-1, 1); } + // fuzz height + const heightAdjust = random(-5, Math.min(maxHeight(slave) - slave.height, 5)); + slave.natural.height += heightAdjust; + slave.height += heightAdjust; + // reset art seed + slave.natural.artSeed = jsRandom(0, 10 ** 14); } /** @@ -290,7 +296,7 @@ globalThis.generateRelatedSlave = (function() { } // reset height - slave.height = Height.random(slave); + slave.height = Height.forAge(slave.natural.height, slave); // reset puberty status generatePuberty(slave); diff --git a/src/npc/generate/heroCreator.js b/src/npc/generate/heroCreator.js index 8ebe65004b82ad359a02823b5714ce7a977c845b..b742630504754e62afd042dd5095b81cadc6539b 100644 --- a/src/npc/generate/heroCreator.js +++ b/src/npc/generate/heroCreator.js @@ -100,10 +100,10 @@ App.Utils.getHeroSlave = function(heroSlave) { repairLimbs(newSlave); generatePuberty(newSlave); newSlave.weekAcquired = V.week; - if (!newSlave.pubicHColor) { + if (!heroSlave.pubicHColor) { newSlave.pubicHColor = newSlave.hColor; } - if (!newSlave.underArmHColor) { + if (!heroSlave.underArmHColor) { newSlave.underArmHColor = newSlave.hColor; } if (newSlave.override_Race !== 1) { @@ -127,6 +127,13 @@ App.Utils.getHeroSlave = function(heroSlave) { if (newSlave.override_Skin !== 1) { newSlave.skin = getGeneticSkinColor(newSlave); } + if (!heroSlave.natural?.height) { + // assumes adult - child hero slaves MUST specify natural height separately! + newSlave.natural.height = newSlave.height - newSlave.heightImplant * 10; + } + if (!heroSlave.natural?.artSeed) { + newSlave.natural.artSeed = jsRandom(0, 10 ** 14); + } setHealth(newSlave, newSlave.health.condition, 0, 0, 0, newSlave.health.tired); SetBellySize(newSlave); diff --git a/src/npc/generate/lawCompliance.js b/src/npc/generate/lawCompliance.js index d67ff08d971afaff42bc95806a0fd2ab942f9863..050138c0eab13b9324cbafdd6e0d582f3bc4272a 100644 --- a/src/npc/generate/lawCompliance.js +++ b/src/npc/generate/lawCompliance.js @@ -320,14 +320,16 @@ App.Desc.lawCompliance = function(slave, market = 0) { function FSPetiteAdmirationSMR() { if (!heightPass(slave)) { - slave.height = Height.random(slave, {skew: -1, limitMult: [-5, -2]}); + slave.natural.height = Height.randomAdult(slave, {skew: -1, limitMult: [-5, -2]}); + slave.height = Height.forAge(slave.natural.height, slave); } return `${His} height was meticulously taken before being allowed into the markets.`; } function FSStatuesqueGlorificationSMR() { if (!heightPass(slave)) { - slave.height = Height.random(slave, {skew: 1, limitMult: [2, 5]}); + slave.natural.height = Height.randomAdult(slave, {skew: 1, limitMult: [2, 5]}); + slave.height = Height.forAge(slave.natural.height, slave); } return `${His} height, as well as ${his} potential for growth, were meticulously taken before being allowed into the markets.`; } @@ -672,10 +674,11 @@ App.Desc.lawCompliance = function(slave, market = 0) { } function heightAdvancedSMRup() { - slave.height = Height.random(slave, { + slave.natural.height = Height.randomAdult(slave, { skew: V.policies.SMR.height.advancedSMR, limitMult: [0, 5 * V.policies.SMR.height.advancedSMR] }); + slave.height = Height.forAge(slave.natural.height, slave); let t = [`While ${he} was in the slave pens, ${he} saw that slaves on the shorter end of the height curve were immediately designated as menials and Fuckdolls.`]; if (slave.physicalAge < 16) { t.push(`${He} is <span class="gold">terrified</span> that if ${he} doesn't keep growing, ${he}'ll be reassigned on the spot without a second thought.`); @@ -688,10 +691,11 @@ App.Desc.lawCompliance = function(slave, market = 0) { } function heightAdvancedSMRdown() { - slave.height = Height.random(slave, { + slave.natural.height = Height.randomAdult(slave, { skew: V.policies.SMR.height.advancedSMR, limitMult: [0, 5 * V.policies.SMR.height.advancedSMR] }); + slave.height = Height.forAge(slave.natural.height, slave); let t = [`While ${he} was in the slave pens, ${he} saw that slaves on the taller end of the height curve were immediately designated as menials and Fuckdolls.`]; if (slave.physicalAge < 16) { t.push(`${He} is <span class="gold">terrified</span> that if ${he} goes through a growth spurt, ${he}'ll be reassigned on the spot without a second thought.`); diff --git a/src/npc/infants/InfantState.js b/src/npc/infants/InfantState.js index 1d74fcd36deeed36191af52fb613bd3c6de9f8a3..b0c36f76a85116b76606a57b4ffa1c64435708c5 100644 --- a/src/npc/infants/InfantState.js +++ b/src/npc/infants/InfantState.js @@ -13,6 +13,8 @@ App.Facilities.Nursery.InfantState = class InfantState { /** @type {FC.GenderGenes} */ this.genes = "XX"; this.pronoun = App.Data.Pronouns.Kind.female; + /** slave's natural genetic properties */ + this.natural = new App.Entity.GeneticState(); /** game week child was acquired. * * _0: Obtained prior to game start / at game start_ */ diff --git a/src/npc/startingGirls/startingGirls.js b/src/npc/startingGirls/startingGirls.js index 00d1aa92736a01108b049182270906d8249987a5..42021b2aa1b38967a555faab80c98bb226a43792 100644 --- a/src/npc/startingGirls/startingGirls.js +++ b/src/npc/startingGirls/startingGirls.js @@ -66,6 +66,7 @@ App.StartingGirls.cleanup = function(slave) { slave.indenture = Math.clamp(slave.indenture, 26, 208) || 26; } + slave.natural.height = Math.clamp(slave.natural.height, 85, 274) || 140; slave.height = Math.clamp(slave.height, 85, 274) || 140; slave.boobs = Math.clamp(Math.trunc(slave.boobs / 50) * 50, 0, 50000) || 200; slave.hLength = Math.clamp(slave.hLength, 0, 500) || 40; @@ -714,13 +715,13 @@ App.StartingGirls.physical = function(slave, cheat = false) { .showTextBox().pulldown(); } - options.addOption(`Height: ${heightToEitherUnit(slave.height)}`, "height", slave).showTextBox({unit: "cm"}) + options.addOption(`Natural Adult Height: ${heightToEitherUnit(slave.natural.height)}`, "height", slave.natural).showTextBox({unit: "cm"}) .addRange(145, 150, "<", "Petite") .addRange(155, 160, "<", "Short") .addRange(165, 170, "<", "Average") .addRange(180, 185, "<", "Tall") .addRange(190, 185, ">=", "Very tall"); - option = options.addCustomOption(`Average height for a ${slave.physicalAge} year old is ${heightToEitherUnit(Height.mean(slave))}`) + option = options.addCustomOption(`Average natural adult height is ${heightToEitherUnit(Height.mean(slave.nationality, slave.race, slave.genes, 20))}`) .addButton( "Make average", () => resyncSlaveHeight(slave), @@ -729,17 +730,29 @@ App.StartingGirls.physical = function(slave, cheat = false) { if (cheat || slave.geneticQuirks.dwarfism === 2) { option.addButton( "Make dwarf", - () => slave.height = Height.random(slave, {limitMult: [-4, -1], spread: 0.15}), + () => slave.natural.height = Height.random(slave, {limitMult: [-4, -1], spread: 0.15}), "" ); } if (cheat || slave.geneticQuirks.gigantism === 2) { option.addButton( "Make giant", - () => slave.height = Height.random(slave, {limitMult: [3, 10], spread: 0.15}), + () => slave.natural.height = Height.random(slave, {limitMult: [3, 10], spread: 0.15}), "" ); } + options.addOption(`Current Height: ${heightToEitherUnit(slave.height)}`, "height", slave).showTextBox({unit: "cm"}) + .addRange(Height.forAge(145, slave), Height.forAge(150, slave), "<", `Petite for age`) + .addRange(Height.forAge(155, slave), Height.forAge(160, slave), "<", "Short for age") + .addRange(Height.forAge(165, slave), Height.forAge(170, slave), "<", "Average for age") + .addRange(Height.forAge(180, slave), Height.forAge(185, slave), "<", "Tall for age") + .addRange(Height.forAge(190, slave), Height.forAge(185, slave), ">=", "Very tall for age"); + options.addCustomOption(`Average height for a ${slave.physicalAge} year old is ${heightToEitherUnit(Height.mean(slave))}`) + .addButton( + "Scale for age from adult height", + () => slave.height = Height.forAge(slave.natural.height, slave), + "" + ); if (cheat) { options.addOption("Height implant", "heightImplant", slave) @@ -1714,7 +1727,7 @@ App.StartingGirls.profile = function(slave, cheat = false) { options.addOption("Age", "actualAge", slave).showTextBox() .customButton("Resync characteristics to age", () => resyncSlaveToAge(slave), "") - .customButton("Resync only height to age", () => slave.height = Height.random(slave), "") + .customButton("Resync only height to age", () => resyncSlaveHeight(slave), "") .addComment("It is recommended to resync if you change age significantly"); if (cheat) { options.addOption("Physical age", "physicalAge", slave).showTextBox(); @@ -1821,6 +1834,11 @@ App.StartingGirls.profile = function(slave, cheat = false) { options.addOption("Description", "desc", slave.custom).showTextBox({large: true}) .addComment("Use complete, capitalized and punctuated sentences."); options.addOption("Label", "label", slave.custom).showTextBox().addComment("Use a short phrase"); + if (V.imageChoice === 4) { + options.addOption("Art Seed", "artSeed", slave.natural).showTextBox({large: true}) + .customButton("Randomize", () => slave.natural.artSeed = jsRandom(0, 10 ** 14), "") + .addComment(`The WebGL Art Renderer uses the art seed to set minor face and body parameters. You can change it if you don't like this slave's appearance.`); + } el.append(options.render()); return el; diff --git a/src/npc/startingGirls/startingGirlsPassage.js b/src/npc/startingGirls/startingGirlsPassage.js index 91e4def4d8c6904fa16ff483c875f26090b81da9..dbdacc91f568f7bc8a957fb3f03962f3c7838cf6 100644 --- a/src/npc/startingGirls/startingGirlsPassage.js +++ b/src/npc/startingGirls/startingGirlsPassage.js @@ -120,7 +120,8 @@ App.StartingGirls.passage = function() { V.activeSlave.face = 55; V.activeSlave.muscles = 20; V.activeSlave.weight = -20; - V.activeSlave.height = Height.forAge(190, V.activeSlave); + V.activeSlave.natural.height = 190; + V.activeSlave.height = Height.forAge(V.activeSlave.natural.height, V.activeSlave); }, [], "Starting Girls" diff --git a/src/npc/surgery/bodySwap/bodySwap.js b/src/npc/surgery/bodySwap/bodySwap.js index 5c6cdb2c71a87055bf9fdd14ed79048dfbb30469..a14253a4510200b1abd031c42a917888560f8df1 100644 --- a/src/npc/surgery/bodySwap/bodySwap.js +++ b/src/npc/surgery/bodySwap/bodySwap.js @@ -7,6 +7,7 @@ globalThis.bodySwap = function(soul, body, fromGenepool) { WombInit(body); // Just to be sure. soul.genes = body.genes; + soul.natural = body.natural; soul.physicalAge = body.physicalAge; soul.visualAge = body.visualAge; soul.ageImplant = body.ageImplant; diff --git a/src/player/js/PlayerState.js b/src/player/js/PlayerState.js index ef4f1d8c425ce80ddde5fa79ca3b525179e04f02..01dbb6fea5ca80b496375e75a92eeb1666dce4b7 100644 --- a/src/player/js/PlayerState.js +++ b/src/player/js/PlayerState.js @@ -258,6 +258,8 @@ App.Entity.PlayerState = class PlayerState { this.refreshmentType = 0; /** @type {number} */ this.pronoun = App.Data.Pronouns.Kind.male; + /** player's natural genetic properties */ + this.natural = new App.Entity.GeneticState(); /** * * career prior to becoming owner * * (22+) (14+) (10+)