diff --git a/src/js/descriptionWidgets.js b/src/js/descriptionWidgets.js index a702976f1ac0da6c303a775b34d3bb6c668cdc6c..f445f1802f6615922bc78565455f48bdd2def49c 100644 --- a/src/js/descriptionWidgets.js +++ b/src/js/descriptionWidgets.js @@ -576,7 +576,62 @@ App.Desc.brand = function(slave, surface) { } = getPronouns(slave); /* eslint-enable */ if (State.variables.showBodyMods === 1) { - if (surface) { /* describes a single branded body part */ + if (surface === "extra") { // Make a sentence that describes all body parts that aren't explicitly described elsewhere in longSlave. If you brand a slave on her thumb, for instance. But why. + let extraMarks = App.Desc.extraMarks(slave, "brand"); + extraMarks = Object.keys(extraMarks); + let length = extraMarks.length; + if (length === 0) { + return r; + } else if (length === 1) { + r += `${He} also has a single unusual brand: `; + } else { + r += `${He} also has several unusual brands: `; + } + + // If L/R parts of this object match, they will be described in the same phrase. Length is used only to calculate punctuation, so we prepare to skip. + for (const bodyPart of extraMarks) { + if (bodyPart.startsWith("left ")) { + let right = "right " + bodyPart.replace("left ", ""); + if (slave.brand[bodyPart] && slave.brand[right]) { + length--; + } + } + } + let counter = 0; + for (const bodyPart of extraMarks) { + counter++; + surface = App.Desc.oppositeSides(bodyPart); + if (slave.brand[surface.center]) { // center defined, body part has no mirror. + r += `${slave.brand[surface.center]} branded into the flesh of ${his} ${surface.center}`; + } else { // Center not defined, body part has a mirror. + if (!slave.brand[surface.left] && !slave.brand[surface.right]) { + // no marks + } else if (bodyPart.startsWith("right ") && slave.brand[surface.left]) { + // we already described it on the left + } else if (slave.brand[surface.left] === slave.brand[surface.right]) { + // matching places and marks + // note that the slave.brand object won't have slave.brand["upper armS"] with an S defined, just the left and right, so we just use the left since we know they match. + r += `${slave.brand[surface.left]} branded into the flesh of both ${his} ${surface.both}`; + } else if (slave.brand[surface.left] && slave.brand[surface.right]) { + // matching places but different marks + r += `both ${slave.brand[surface.left]} branded into the flesh of ${his} ${surface.left}, and ${slave.brand[surface.right]} branded into ${his} ${surface.right}`; + } else if (slave.brand[surface.left]) { + // left + r += `${slave.brand[surface.left]} branded into the flesh of ${his} ${surface.left}`; + } else if (slave.brand[surface.right]) { + // right + r += `${slave.brand[surface.right]} branded into the flesh of ${his} ${surface.right}`; + } + } + if (counter === length) { + r += `. `; + } else if (counter === length - 1) { + r += `, and `; + } else if (counter < length) { + r += `, `; + } + } + } else if (surface) { /* describes a single branded body part */ if (surface === "belly" && setup.fakeBellies.includes(bellyAccessory) && slave.brand.belly) { r += `${His} fake belly has the same brand, ${slave.brand.belly}, as ${his} real one. `; } else { @@ -700,11 +755,16 @@ App.Desc.inscrip = function(slave) { */ App.Desc.oppositeSides = function(surface) { let parts = {}; - if (["neck", "chest", "back", "lower back", "belly", "pubic mound"].includes(surface) || surface.startsWith("left") || surface.startsWith("right")) { - parts.center = surface; - } else { + if (["ear", "cheek", "shoulder", "breast", "upper arm", "lower arm", "hand", "wrist", "testicle", "buttock", "thigh", "calf", "ankle", "foot"].includes(surface) || surface.startsWith("left ") || surface.startsWith("right ")) { // set up a left part and a right to check for a mirror brand or marking - if (surface === "feet") { + if (surface.startsWith("left ") || surface.startsWith("right ")) { + // find root word + if (surface.startsWith("left ")) { + surface = surface.replace("left ", ""); + } else if (surface.startsWith("right ")) { + surface = surface.replace("right ", ""); + } + } else if (surface === "feet") { parts.both = surface; surface = "foot"; } else if (surface === "calves") { @@ -716,6 +776,49 @@ App.Desc.oppositeSides = function(surface) { if (!parts.both) { parts.both = surface + "s"; } + } else { + parts.center = surface; } return parts; }; + +/** + * @param {string} slave + * @param {string} markType + * @returns {object} Returns an object containing marks that are not explicitly described elsewhere, so they can be placed in a single sentence. + */ +App.Desc.extraMarks = function(slave, markType) { + let extras = {}; + let slaveMarks = Object.keys(slave[markType]); + if (markType === "brand") { + for (const bodyPart of slaveMarks) { + if ([ + "left ear", "right ear", + "left cheek", "right cheek", + "lips", "neck", + "left shoulder", "right shoulder", + "left breast", "right breast", + "left upper arm", "right upper arm", + "left lower arm", "right lower arm", + "left hand", "right hand", + "left wrist", "right wrist", + "back", "lower back", + "penis", + "left testicle", "right testicle", + "pubic mound", + "belly", + "left buttock", "right buttock", + "anus", "asshole", + "left thigh", "right thigh", + "left calf", "right calf", + "left ankle", "right ankle", + "left foot", "right foot" + ].includes(bodyPart)) { + continue; + } else { + extras[bodyPart] = slave[markType][bodyPart]; + } + } + } + return extras; +}; diff --git a/src/js/generateNewSlaveJS.js b/src/js/generateNewSlaveJS.js index c781796185f1950722cdd2a2e4dba4c6dca0511f..68e8099de605f02863284984b4e4800fe9b535e3 100644 --- a/src/js/generateNewSlaveJS.js +++ b/src/js/generateNewSlaveJS.js @@ -65,6 +65,7 @@ window.GenerateNewSlave = (function() { generateSkills(); generateDisabilities(); generateGeneticQuirkTweaks(); + generateHormones(); generatePronouns(slave); slave.origRace = slave.race; slave.origEye = slave.eyeColor; @@ -1708,6 +1709,39 @@ window.GenerateNewSlave = (function() { } } } + + function generateHormones() { + // PubertyXX and PubertyXY == 1 at this point should guarantee functioning sex organs of the appropriate type + if (slave.genes === "XX") { + if (slave.pubertyXX === 1) { + if (slave.pubertyXY === 1) { + slave.hormoneBalance = 20; + } else { + slave.hormoneBalance = 60; + } + } else { + if (slave.pubertyXY === 1) { + slave.hormoneBalance = -20; + } else { + slave.hormoneBalance = 20; + } + } + } else if (slave.genes === "XY") { + if (slave.pubertyXX === 1) { + if (slave.pubertyXY === 1) { + slave.hormoneBalance = 20; + } else { + slave.hormoneBalance = 40; + } + } else { + if (slave.pubertyXY === 1) { + slave.hormoneBalance = -40; + } else { + slave.hormoneBalance = 20; + } + } + } + } return GenerateNewSlave; })(); diff --git a/src/uncategorized/longSlaveDescription.tw b/src/uncategorized/longSlaveDescription.tw index 8d377773f31064bb21990984805d1c276661855d..9ca4d6b520a06c3f9ddf131743bc4367709dbe98 100644 --- a/src/uncategorized/longSlaveDescription.tw +++ b/src/uncategorized/longSlaveDescription.tw @@ -2051,6 +2051,11 @@ $He is <</if>> <</if>> +<<if $activeSlave.fuckdoll == 0>> + /* Describe any brands that are not directly addressed elsewhere in longSlave */ + <<= App.Desc.brand($activeSlave, "extra")>> +<</if>> + <<if ($showClothing == 1) && ($saleDescription == 0)>> <<earDescription>>