diff --git a/src/js/utilsFC.js b/src/js/utilsFC.js index 3f0b2ea0c45f2219e313b57b5cc1b3913b992612..6953e0af1df7cfa84488f7827ed525c0dfe3c0dd 100644 --- a/src/js/utilsFC.js +++ b/src/js/utilsFC.js @@ -2097,6 +2097,14 @@ globalThis.pronounReplacer = function(slavetext) { } return slavetext; }; +/** + * Converts an array of strings into a sentence parted by commas. + * @param {Array} array ["apple", "bannana", "carrot"] + * @returns {string} "apple, bannana and carrot" + */ +globalThis.arrayToSentence = function(array) { + return array.reduce((res, ch, i, arr) => res + (i === arr.length - 1 ? ' and ' : ', ') + ch); +}; globalThis.convertCareer = function(slave) { let job = slave.career; diff --git a/src/npc/descriptions/describeBrands.js b/src/npc/descriptions/describeBrands.js index 19250234f7101169ef52da0a0ba3eb7bc09ab00b..d9226091bc6d376b970de8f9ba1ff08106f8936f 100644 --- a/src/npc/descriptions/describeBrands.js +++ b/src/npc/descriptions/describeBrands.js @@ -5,111 +5,62 @@ App.Desc.brand = function(slave, surface) { "use strict"; let r = ``; - const bellyAccessory = slave.bellyAccessory; - /* eslint-disable no-unused-vars*/ const { - he, him, his, hers, himself, boy, He, His + his, He, His } = getPronouns(slave); - /* eslint-enable */ if (V.showBodyMods === 1) { 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) { + const array = []; + for (const bodyPart of Object.keys(App.Desc.extraMarks(slave, "brand"))) { + const description = desc(bodyPart); + if (description) { + array.push(description); + } + } + if (array.length === 0) { return r; - } else if (length === 1) { + } else if (array.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 += `, `; - } - } + r += `${arrayToSentence(array)}. `; } else if (surface) { /* describes a single branded body part */ - if (surface === "belly" && setup.fakeBellies.includes(bellyAccessory) && slave.brand.belly) { + if (surface === "belly" && setup.fakeBellies.includes(slave.bellyAccessory) && slave.brand.belly) { r += `${His} fake belly has the same brand, ${slave.brand.belly}, as ${his} real one. `; } else { - surface = App.Desc.oppositeSides(surface); - if (slave.brand[surface.center]) { // center defined, body part has no mirror. - r += `${He} has ${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 (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 += `${He} has ${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 += `${He} has 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 += `${He} has ${slave.brand[surface.left]} branded into the flesh of ${his} ${surface.left}. `; - } else if (slave.brand[surface.right]) { - // right - r += `${He} has ${slave.brand[surface.right]} branded into the flesh of ${his} ${surface.right}. `; - } - } - } - } else { /* describes all branded body parts */ - for (let [key, value] of Object.entries(slave.brand)) { - if (r === ``) { - r += `${He} has `; - } - if (key === "belly" && setup.fakeBellies.includes(bellyAccessory) && slave.brand.belly) { - r += `${value} branded on both ${his} real belly and ${his} fake one, `; - } else { - r += `${value} branded into the flesh of ${his} ${key}, `; - } - } - if (r !== ``) { - r += `marking ${him} as yours. `; - } else { - r += `${His} body is unmarked by brands. `; + r += `${He} has ${desc(surface)}. `; } } } return r; + + function desc(part) { + const surface = App.Desc.oppositeSides(part); + const centerBrand = slave.brand[surface.center] ? pronounsForSlaveProp(slave, slave.brand[surface.center]) : undefined; + const leftBrand = slave.brand[surface.left] ? pronounsForSlaveProp(slave, slave.brand[surface.left]) : undefined; + const rightBrand = slave.brand[surface.right] ? pronounsForSlaveProp(slave, slave.brand[surface.right]) : undefined; + if (centerBrand) { // center defined, body part has no mirror. + return `${centerBrand} branded into the flesh of ${his} ${surface.center}`; + } else { // Center not defined, body part has a mirror. + if (!leftBrand && !rightBrand) { + return; // no marks + } else if (part.startsWith("right ") && leftBrand) { + return; // we already described it on the left + } else if (leftBrand === rightBrand) { + // 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. + return `${leftBrand} branded into the flesh of both ${his} ${surface.both}`; + } else if (leftBrand && rightBrand) { + // matching places but different marks + return `both ${leftBrand} branded into the flesh of ${his} ${surface.left}, and ${rightBrand} branded into ${his} ${surface.right}`; + } else if (leftBrand) { + // left + return `${leftBrand} branded into the flesh of ${his} ${surface.left}`; + } else if (rightBrand) { + // right + return `${rightBrand} branded into the flesh of ${his} ${surface.right}`; + } + } + } };