diff --git a/src/endWeek/saRelationships.js b/src/endWeek/saRelationships.js index 4f5b92ae7c5d273f2c5a67bc36d713eb5e35ede6..8de75ab26cd11e393585092c951cbbd1f9ec3411 100644 --- a/src/endWeek/saRelationships.js +++ b/src/endWeek/saRelationships.js @@ -1177,34 +1177,120 @@ App.SlaveAssignment.relationships = (function() { * */ function familyFeelings(slave) { + /** @param {Map<string, Array<App.Entity.SlaveState>>} map + * @param {App.Entity.SlaveState} relative */ + function addToRelativeMap(map, relative) { + const term = relativeTerm(slave, relative); + if (!map.has(term)) { + map.set(term, [relative]); + } else { + map.get(term).push(relative); + } + } + + /** @param {Map<string, Array<App.Entity.SlaveState>>} map + * @returns {Array<string>} */ + function relativeMapToGroupArray(map) { + let groups = []; + for (const [type, people] of map) { + if (people.length > 1) { + groups.push(`${his} ${type}s ${arrayToSentence(people.map(s => s.slaveName))}`); + } else { + groups.push(`${his} ${type} ${people[0].slaveName}`); + } + } + return groups; + } + + /** @param {Map<string, Array<App.Entity.SlaveState>>} map + * @returns {App.Entity.SlaveState} */ + function singleRelativeInMap(map) { + if (map.size !== 1) { + return null; + } + /** @type {App.Entity.SlaveState[]} */ + const slavesOfType = map.values().next().value; + if (slavesOfType.length !== 1) { + return null; + } + return slavesOfType[0]; + } + if (slave.trust <= 95) { - let relatives = V.slaves.filter((s) => areRelated(slave, s)); // Is it possible to move this into the loop? - for (const relative of relatives) { - const {he2, him2} = getPronouns(relative).appendSuffix("2"); - if (slave.trust < -20) { + let relatives = V.slaves.filter((s) => areRelated(slave, s)); + if (slave.trust < -20) { + /** @type {Array<App.Entity.SlaveState>} */ + const worriedAboutChildren = []; + /** @type {Map<string, Array<App.Entity.SlaveState>>} */ + const worriedAboutRelatives = new Map(); + for (const relative of relatives) { if (slave.rivalryTarget !== relative.ID) { if (isParentP(relative, slave)) { - r.push(`${slave.slaveName} is <span class="trust dec">agonizingly aware</span> that ${his} child ${relative.slaveName} is also your slave and might suffer if either of them angers you, and <span class="devotion inc">does ${his} best</span> to protect ${him2}.`); + worriedAboutChildren.push(relative); slave.trust -= 2; slave.devotion += 6; } else { - r.push(`${slave.slaveName} is <span class="trust dec">painfully conscious</span> that ${his} ${relativeTerm(slave, relative)} ${relative.slaveName} is also your slave and might suffer if either of them displeases you, and <span class="devotion inc">tries to obey</span> as best ${he} can.`); + addToRelativeMap(worriedAboutRelatives, relative); slave.trust -= 1; slave.devotion += 3; } } - } else { - r.push(`${slave.slaveName} knows that ${his} ${relativeTerm(slave, relative)} ${relative.slaveName}`); + } + if (worriedAboutChildren.length > 1) { + r.push(`${slave.slaveName} is <span class="trust dec">agonizingly aware</span> that ${his} children ${arrayToSentence(worriedAboutChildren.map(s => s.slaveName))} are also your slaves and might suffer if any of them angers you, and <span class="devotion inc">does ${his} best</span> to protect them.`); + } else if (worriedAboutChildren.length > 0) { + const {him2} = getPronouns(worriedAboutChildren[0]).appendSuffix("2"); + r.push(`${slave.slaveName} is <span class="trust dec">agonizingly aware</span> that ${his} child ${worriedAboutChildren[0].slaveName} is also your slave and might suffer if either of them angers you, and <span class="devotion inc">does ${his} best</span> to protect ${him2}.`); + } + let singleRelative = singleRelativeInMap(worriedAboutRelatives); + if (singleRelative) { + r.push(`${slave.slaveName} is <span class="trust dec">painfully conscious</span> that ${his} ${relativeTerm(slave, singleRelative)} ${singleRelative.slaveName} is also your slave and might suffer if either of them displeases you, and <span class="devotion inc">tries to obey</span> as best ${he} can.`); + } else if (worriedAboutRelatives.size > 0) { + const groups = relativeMapToGroupArray(worriedAboutRelatives); + r.push(`${slave.slaveName} is <span class="trust dec">painfully conscious</span> that ${arrayToSentence(groups)} are also your slaves and might suffer if any of them displeases you, and <span class="devotion inc">tries to obey</span> as best ${he} can.`); + } + } else { + /** @type {Map<string, Array<App.Entity.SlaveState>>} */ + const devotedRelatives = new Map(); + /** @type {Map<string, Array<App.Entity.SlaveState>>} */ + const obedientRelatives = new Map(); + /** @type {Map<string, Array<App.Entity.SlaveState>>} */ + const hatefulRelatives = new Map(); + for (const relative of relatives) { if (relative.devotion > 50) { - r.push(`loves being your sex slave, and is <span class="devotion inc">happy</span> for ${him2}.`); + addToRelativeMap(devotedRelatives, relative); slave.devotion += 4; } else if (relative.devotion > 20 || relative.trust < -20) { - r.push(`is an obedient sex slave, and hopes ${he2}'ll avoid punishment.`); + addToRelativeMap(obedientRelatives, relative); } else { - r.push(`hates being a sex slave, and is <span class="trust dec">afraid</span> for ${him2}.`); + addToRelativeMap(hatefulRelatives, relative); slave.trust -= 1; } } + let singleRelative = singleRelativeInMap(devotedRelatives); + if (singleRelative) { + const {him2} = getPronouns(singleRelative).appendSuffix('2'); + r.push(`${slave.slaveName} knows that ${his} ${relativeTerm(slave, singleRelative)} ${singleRelative.slaveName} loves being your sex slave, and is <span class="devotion inc">happy</span> for ${him2}.`); + } else if (devotedRelatives.size > 0) { + const groups = relativeMapToGroupArray(devotedRelatives); + r.push(`${slave.slaveName} knows that ${arrayToSentence(groups)} all love being your sex slaves, and is <span class="devotion inc">happy</span> for them.`); + } + singleRelative = singleRelativeInMap(obedientRelatives); + if (singleRelative) { + const {he2} = getPronouns(singleRelative).appendSuffix('2'); + r.push(`${slave.slaveName} knows that ${his} ${relativeTerm(slave, singleRelative)} ${singleRelative.slaveName} is an obedient sex slave, and hopes ${he2}'ll avoid punishment.`); + } else if (obedientRelatives.size > 0) { + const groups = relativeMapToGroupArray(obedientRelatives); + r.push(`${slave.slaveName} knows that ${arrayToSentence(groups)} are obedient sex slaves, and hopes they'll avoid punishment.`); + } + singleRelative = singleRelativeInMap(hatefulRelatives); + if (singleRelative) { + const {him2} = getPronouns(singleRelative).appendSuffix('2'); + r.push(`${slave.slaveName} knows that ${his} ${relativeTerm(slave, singleRelative)} ${singleRelative.slaveName} hates being a sex slave, and is <span class="trust dec">afraid</span> for ${him2}.`); + } else if (hatefulRelatives.size > 0) { + const groups = relativeMapToGroupArray(hatefulRelatives); + r.push(`${slave.slaveName} knows that ${arrayToSentence(groups)} all hate being sex slaves, and is <span class="trust dec">afraid</span> for them.`); + } } } }