diff --git a/src/data/backwardsCompatibility/datatypeCleanup.js b/src/data/backwardsCompatibility/datatypeCleanup.js index 6c747999a1efdcf08bf950f35cb13c77f66a18a0..dc90d89df371cd6010074b6819cac478d0874617 100644 --- a/src/data/backwardsCompatibility/datatypeCleanup.js +++ b/src/data/backwardsCompatibility/datatypeCleanup.js @@ -2073,10 +2073,13 @@ App.Entity.Utils.RARuleDatatypeCleanup = function() { return ruleCleanup; - /** @param {FC.RA.Rule} rule */ + /** + * @param {FC.RA.Rule} rule + * @returns {FC.RA.Rule} + */ function ruleCleanup(rule) { // ensure rule has all required properties - let newRule = App.RA.ruleDeepAssign(emptyDefaultRule(), rule); + let newRule = App.RA.ruleDeepAssign(emptyDefaultRule(), rule, {}, ""); cleanupConditions(newRule.condition); cleanupSetters(newRule.set); return newRule; diff --git a/src/js/DefaultRules.js b/src/js/DefaultRules.js index ea6789ee623f4e3b2650696473c34e7abfd50534..4cb6389756cfd5a2feb4633a40df5db1fd2312a0 100644 --- a/src/js/DefaultRules.js +++ b/src/js/DefaultRules.js @@ -9,7 +9,7 @@ globalThis.DefaultRules = function(slave) { } const slaveReadOnly = createReadonlyProxy(slave); - const {rule, ruleIds} = runWithReadonlyProxy(() => ProcessSlaveRules(slaveReadOnly)); + const {rule, ruleIds, sourceRecord} = runWithReadonlyProxy(() => ProcessSlaveRules(slaveReadOnly)); slave.currentRules = ruleIds; if (ruleIds.length === 0) { return ""; // no rules apply @@ -85,19 +85,23 @@ globalThis.DefaultRules = function(slave) { /** * @param {App.Entity.SlaveState} slave - * @returns {{ruleIds: string[], rule: FC.RA.RuleSetters}}} + * @returns {{ruleIds: string[], rule: FC.RA.RuleSetters, sourceRecord: object}} */ function ProcessSlaveRules(slave) { // merge all rules applying on a slave into one big rule /** @type {FC.RA.Rule[]} */ const rules = V.defaultRules.filter((rule) => ruleAppliesP(rule, slave)); const ruleIds = []; + /** + * @type {Array<[FC.RA.RuleSetters, string]>} + */ const assignments = []; for (const rule of rules) { ruleIds.push(rule.ID); - assignments.push(ProcessAssignments(slave, Object.assign({}, rule.set))); + assignments.push([ProcessAssignments(slave, Object.assign({}, rule.set)), rule.name]); } - return {ruleIds, rule: mergeRules(assignments)}; + const [combinedRule, sourceRecord] = mergeRules(assignments); + return {ruleIds, rule: combinedRule, sourceRecord}; } /** @@ -191,16 +195,16 @@ globalThis.DefaultRules = function(slave) { if (slave.clothes !== rule.clothes) { slave.clothes = rule.clothes; slave.choosesOwnClothes = 0; - r += `<br>${slave.slaveName} is now wearing ${slave.clothes}.`; + message(`${slave.slaveName} is now wearing ${slave.clothes}.`, sourceRecord.clothes); } } if ((rule.choosesOwnClothes !== undefined) && (rule.choosesOwnClothes !== null)) { if (slave.choosesOwnClothes !== rule.choosesOwnClothes) { slave.choosesOwnClothes = rule.choosesOwnClothes; if (slave.choosesOwnClothes) { - r += `<br>${slave.slaveName} is now allowed to choose ${his} own clothes.`; + message(`${slave.slaveName} is now allowed to choose ${his} own clothes.`, sourceRecord.choosesOwnClothes); } else { - r += `<br>${slave.slaveName} is now forbidden from choosing ${his} own clothes.`; + message(`${slave.slaveName} is now forbidden from choosing ${his} own clothes.`, sourceRecord.choosesOwnClothes); } } } @@ -214,21 +218,21 @@ globalThis.DefaultRules = function(slave) { // apply collar to slave if ((rule.collar !== undefined) && (rule.collar !== null)) { if (slave.collar !== rule.collar) { - r += "<br>"; + let m = ""; if (rule.collar === "preg biometrics" && slave.preg <= -1 && slave.ovaries === 0 && slave.mpreg === 0) { slave.collar = "none"; - r += `${slave.slaveName} cannot utilize preg biometrics. `; + m = `${slave.slaveName} cannot utilize preg biometrics. `; } else { slave.collar = rule.collar; } if (slave.collar === "none") { - r += `${slave.slaveName} has been given no collar.`; + message(`${m}${slave.slaveName} has been given no collar.`, sourceRecord.collar); } else if (slave.collar === "pretty jewelry") { - r += `${slave.slaveName} has been given ${slave.collar}.`; + message(`${m}${slave.slaveName} has been given ${slave.collar}.`, sourceRecord.collar); } else if ((["bell collar", "bowtie", "neck corset", "neck tie"].includes(slave.collar))) { - r += `${slave.slaveName} has been given a ${slave.collar}.`; + message(`${m}${slave.slaveName} has been given a ${slave.collar}.`, sourceRecord.collar); } else { - r += `${slave.slaveName} has been given a ${slave.collar} collar.`; + message(`${m}${slave.slaveName} has been given a ${slave.collar} collar.`, sourceRecord.collar); } } } @@ -242,12 +246,11 @@ globalThis.DefaultRules = function(slave) { // apply faceAccessory to slave if ((rule.faceAccessory !== undefined) && (rule.faceAccessory !== null)) { if (slave.faceAccessory !== rule.faceAccessory) { - r += "<br>"; slave.faceAccessory = rule.faceAccessory; if (slave.faceAccessory === "none") { - r += `${slave.slaveName} has had their mask removed.`; + message(`${slave.slaveName} has had their mask removed.`, sourceRecord.faceAccessory); } else { - r += `${slave.slaveName} has been given a ${slave.faceAccessory}.`; + message(`${slave.slaveName} has been given a ${slave.faceAccessory}.`, sourceRecord.faceAccessory); } } } @@ -261,17 +264,17 @@ globalThis.DefaultRules = function(slave) { // apply mouthAccessory to slave if ((rule.mouthAccessory !== undefined) && (rule.mouthAccessory !== null)) { if (slave.mouthAccessory !== rule.mouthAccessory) { - r += "<br>"; + let m = ""; if (rule.mouthAccessory === "massive dildo gag" && slave.skill.oral <= 50) { slave.mouthAccessory = "none"; - r += `${slave.slaveName} lacks the oral skill to successfully keep the massive dildo gag in ${his} throat. `; + m = `${slave.slaveName} lacks the oral skill to successfully keep the massive dildo gag in ${his} throat. `; } else { slave.mouthAccessory = rule.mouthAccessory; } if (slave.mouthAccessory === "none") { - r += `${slave.slaveName} has been given no gag.`; + message(`${m}}${slave.slaveName} has been given no gag.`, sourceRecord.mouthAccessory); } else { - r += `${slave.slaveName} has been given a ${slave.mouthAccessory}.`; + message(`${m}}${slave.slaveName} has been given a ${slave.mouthAccessory}.`, sourceRecord.mouthAccessory); } } } @@ -290,12 +293,12 @@ globalThis.DefaultRules = function(slave) { if (slave.eyewear !== "corrective glasses") { slave.eyewear = "corrective glasses"; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName} has been given corrective glasses.`; + message(`${slave.slaveName} has been given corrective glasses.`, sourceRecord.eyewear); } } else { if (slave.eyewear !== "none") { slave.eyewear = "none"; - r += `<br>${slave.slaveName}'s eyewear has been removed.`; + message(`${slave.slaveName}'s eyewear has been removed.`, sourceRecord.eyewear); } } break; @@ -305,12 +308,12 @@ globalThis.DefaultRules = function(slave) { if (slave.eyewear !== "corrective contacts") { slave.eyewear = "corrective contacts"; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName} has been given corrective contacts.`; + message(`${slave.slaveName} has been given corrective contacts.`, sourceRecord.eyewear); } } else { if (slave.eyewear !== "none") { slave.eyewear = "none"; - r += `<br>${slave.slaveName}'s eyewear has been removed.`; + message(`${slave.slaveName}'s eyewear has been removed.`, sourceRecord.eyewear); } } break; @@ -320,12 +323,12 @@ globalThis.DefaultRules = function(slave) { if (slave.eyewear !== "blurring glasses") { slave.eyewear = "blurring glasses"; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName} has been given blurring glasses.`; + message(`${slave.slaveName} has been given blurring glasses.`, sourceRecord.eyewear); } } else { if (slave.eyewear !== "none") { slave.eyewear = "none"; - r += `<br>${slave.slaveName}'s eyewear has been removed.`; + message(`${slave.slaveName}'s eyewear has been removed.`, sourceRecord.eyewear); } } break; @@ -335,12 +338,12 @@ globalThis.DefaultRules = function(slave) { if (slave.eyewear !== "blurring contacts") { slave.eyewear = "blurring contacts"; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName} has been given blurring contacts.`; + message(`${slave.slaveName} has been given blurring contacts.`, sourceRecord.eyewear); } } else { if (slave.eyewear !== "none") { slave.eyewear = "none"; - r += `<br>${slave.slaveName}'s eyewear has been removed.`; + message(`${slave.slaveName}'s eyewear has been removed.`, sourceRecord.eyewear); } } break; @@ -350,13 +353,13 @@ globalThis.DefaultRules = function(slave) { if (slave.eyewear !== "corrective glasses") { slave.eyewear = "corrective glasses"; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName} has been given corrective glasses.`; + message(`${slave.slaveName} has been given corrective glasses.`, sourceRecord.eyewear); } } else { if (slave.eyewear !== "glasses") { slave.eyewear = "glasses"; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName} has been given decorative glasses.`; + message(`${slave.slaveName} has been given decorative glasses.`, sourceRecord.eyewear); } } break; @@ -364,7 +367,7 @@ globalThis.DefaultRules = function(slave) { default: if (slave.eyewear !== "none") { slave.eyewear = "none"; - r += `<br>${slave.slaveName}'s eyewear has been removed.`; + message(`${slave.slaveName}'s eyewear has been removed.`, sourceRecord.eyewear); } break; } @@ -384,12 +387,12 @@ globalThis.DefaultRules = function(slave) { if (slave.earwear !== "hearing aids") { slave.earwear = "hearing aids"; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName} has been given hearing aids.`; + message(`${slave.slaveName} has been given hearing aids.`, sourceRecord.earwear); } } else { if (slave.earwear !== "none") { slave.earwear = "none"; - r += `<br>${slave.slaveName}'s earwear has been removed.`; + message(`${slave.slaveName}'s earwear has been removed.`, sourceRecord.earwear); } } break; @@ -399,12 +402,12 @@ globalThis.DefaultRules = function(slave) { if (slave.earwear !== "muffling ear plugs") { slave.earwear = "muffling ear plugs"; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName} has been given muffling ear plugs.`; + message(`${slave.slaveName} has been given muffling ear plugs.`, sourceRecord.earwear); } } else { if (slave.earwear !== "none") { slave.earwear = "none"; - r += `<br>${slave.slaveName}'s earwear has been removed.`; + message(`${slave.slaveName}'s earwear has been removed.`, sourceRecord.earwear); } } break; @@ -414,12 +417,12 @@ globalThis.DefaultRules = function(slave) { if (slave.earwear !== "deafening ear plugs") { slave.earwear = "deafening ear plugs"; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName} has been given deafening ear plugs.`; + message(`${slave.slaveName} has been given deafening ear plugs.`, sourceRecord.earwear); } } else { if (slave.earwear !== "none") { slave.earwear = "none"; - r += `<br>${slave.slaveName}'s earwear has been removed.`; + message(`${slave.slaveName}'s earwear has been removed.`, sourceRecord.earwear); } } break; @@ -427,7 +430,7 @@ globalThis.DefaultRules = function(slave) { default: if (slave.earwear !== "none") { slave.earwear = "none"; - r += `<br>${slave.slaveName}'s earwear has been removed.`; + message(`${slave.slaveName}'s earwear has been removed.`, sourceRecord.earwear); } break; } @@ -461,50 +464,50 @@ globalThis.DefaultRules = function(slave) { slave.vaginalAccessory = rule.virginAccessory; switch (slave.vaginalAccessory) { case "huge dildo": - r += `<br>${slave.slaveName} is a virgin and has been given a `; + const m = `${slave.slaveName} is a virgin and has been given a`; if (slave.vagina >= 2) { - r += `massive dildo to permanently gape ${his} cunt.`; + message(`${m} massive dildo to permanently gape ${his} cunt.`, sourceRecord.virginAccessory); } else { - r += `large dildo for ${his} pussy, since it must be stretched before it can accommodate a huge one.`; + message(`${m} large dildo for ${his} pussy, since it must be stretched before it can accommodate a huge one.`, sourceRecord.virginAccessory); slave.vaginalAccessory = "large dildo"; } break; case "long dildo": if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length dildo for ${his} pussy.`; + message(`Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length dildo for ${his} pussy.`, sourceRecord.virginAccessory); slave.vaginalAccessory = "dildo"; } break; case "long, large dildo": if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length large dildo for ${his} pussy.`; + message(`Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length large dildo for ${his} pussy.`, sourceRecord.virginAccessory); slave.vaginalAccessory = "large dildo"; } break; case "long, huge dildo": if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length huge dildo for ${his} pussy.`; + message(`Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length huge dildo for ${his} pussy.`, sourceRecord.virginAccessory); slave.vaginalAccessory = "huge dildo"; } else { - r += `<br>${slave.slaveName} is a virgin and has been given a `; + const m = `${slave.slaveName} is a virgin and has been given a`; if (slave.vagina >= 2) { - r += `massive and oversized dildo to permanently gape ${his} cunt.`; + message(`${m} massive and oversized dildo to permanently gape ${his} cunt.`, sourceRecord.virginAccessory); } else { - r += `long, large dildo for ${his} pussy, since it must be stretched before it can accommodate a huge one.`; + message(`${m} long, large dildo for ${his} pussy, since it must be stretched before it can accommodate a huge one.`, sourceRecord.virginAccessory); slave.vaginalAccessory = "long, large dildo"; } } break; case "none": - r += `<br>${slave.slaveName} is a virgin and has been instructed not to use a vaginal accessory.`; + message(`${slave.slaveName} is a virgin and has been instructed not to use a vaginal accessory.`, sourceRecord.virginAccessory); break; default: - r += `<br>${slave.slaveName} is a virgin and has been given a ${slave.vaginalAccessory} for ${his} pussy.`; + message(`${slave.slaveName} is a virgin and has been given a ${slave.vaginalAccessory} for ${his} pussy.`, sourceRecord.virginAccessory); break; } } @@ -522,50 +525,50 @@ globalThis.DefaultRules = function(slave) { slave.vaginalAccessory = rule.aVirginAccessory; switch (slave.vaginalAccessory) { case "huge dildo": - r += `<br>${slave.slaveName} is a virgin and has been given a `; + const m = `${slave.slaveName} is a virgin and has been given a`; if (slave.vagina >= 2) { - r += `massive dildo to permanently gape ${his} cunt.`; + message(`${m} massive dildo to permanently gape ${his} cunt.`, sourceRecord.aVirginAccessory); } else { - r += `large dildo for ${his} pussy, since it must be stretched before it can accommodate a huge one.`; + message(`${m} large dildo for ${his} pussy, since it must be stretched before it can accommodate a huge one.`, sourceRecord.aVirginAccessory); slave.vaginalAccessory = "large dildo"; } break; case "long dildo": if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length dildo for ${his} pussy.`; + message(`Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length dildo for ${his} pussy.`, sourceRecord.aVirginAccessory); slave.vaginalAccessory = "dildo"; } break; case "long, large dildo": if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length large dildo for ${his} pussy.`; + message(`Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length large dildo for ${his} pussy.`, sourceRecord.aVirginAccessory); slave.vaginalAccessory = "large dildo"; } break; case "long, huge dildo": if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length huge dildo for ${his} pussy.`; + message(`Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so the virgin ${slave.slaveName} has been given a standard length huge dildo for ${his} pussy.`, sourceRecord.aVirginAccessory); slave.vaginalAccessory = "huge dildo"; } else { - r += `<br>${slave.slaveName} is a virgin and has been given a `; + const m = `${slave.slaveName} is a virgin and has been given a`; if (slave.vagina >= 2) { - r += `massive and oversized dildo to permanently gape ${his} cunt.`; + message(`${m} massive and oversized dildo to permanently gape ${his} cunt.`, sourceRecord.aVirginAccessory); } else { - r += `long, large dildo for ${his} pussy, since it must be stretched before it can accommodate a huge one.`; + message(`${m} long, large dildo for ${his} pussy, since it must be stretched before it can accommodate a huge one.`, sourceRecord.aVirginAccessory); slave.vaginalAccessory = "long, large dildo"; } } break; case "none": - r += `<br>${slave.slaveName} is a virgin and has been instructed not to use a vaginal accessory.`; + message(`${slave.slaveName} is a virgin and has been instructed not to use a vaginal accessory.`, sourceRecord.aVirginAccessory); break; default: - r += `<br>${slave.slaveName} is a virgin and has been given a ${slave.vaginalAccessory} for ${his} pussy.`; + message(`${slave.slaveName} is a virgin and has been given a ${slave.vaginalAccessory} for ${his} pussy.`, sourceRecord.aVirginAccessory); break; } } @@ -583,49 +586,49 @@ globalThis.DefaultRules = function(slave) { slave.vaginalAccessory = rule.vaginalAccessory; switch (slave.vaginalAccessory) { case "huge dildo": - r += `<br>${slave.slaveName} has been given a `; + const m = `${slave.slaveName} has been given a`; if (slave.vagina >= 2) { - r += `massive dildo to permanently gape ${his} cunt.`; + message(`${m} massive dildo to permanently gape ${his} cunt.`, sourceRecord.vaginalAccessory); } else { - r += `large dildo for ${his} pussy, since it must be stretched before it can accommodate a huge one.`; + message(`${m} large dildo for ${his} pussy, since it must be stretched before it can accommodate a huge one.`, sourceRecord.vaginalAccessory); slave.vaginalAccessory = "large dildo"; } break; case "long dildo": if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so ${slave.slaveName} has been given a standard length dildo for ${his} pussy.`; + message(`Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so ${slave.slaveName} has been given a standard length dildo for ${his} pussy.`, sourceRecord.vaginalAccessory); slave.vaginalAccessory = "dildo"; } break; case "long, large dildo": if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so ${slave.slaveName} has been given a standard length large dildo for ${his} pussy.`; + message(`Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so ${slave.slaveName} has been given a standard length large dildo for ${his} pussy.`, sourceRecord.vaginalAccessory); slave.vaginalAccessory = "large dildo"; } break; case "long, huge dildo": if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") { - r += `<br>Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so ${slave.slaveName} has been given a standard length huge dildo for ${his} pussy.`; + message(`Breeding regulations forbid the use of cervix penetrating dildos on marked slaves, so ${slave.slaveName} has been given a standard length huge dildo for ${his} pussy.`, sourceRecord.vaginalAccessory); slave.vaginalAccessory = "huge dildo"; } else { - r += `<br>${slave.slaveName} has been given a `; + const m = `${slave.slaveName} has been given a`; if (slave.vagina >= 2) { - r += `massive and oversized dildo to permanently gape ${his} cunt.`; + message(`${m} massive and oversized dildo to permanently gape ${his} cunt.`, sourceRecord.vaginalAccessory); } else { - r += `long, large dildo for ${his} pussy, since it must be stretched before it can accommodate a huge one.`; + message(`${m} long, large dildo for ${his} pussy, since it must be stretched before it can accommodate a huge one.`, sourceRecord.vaginalAccessory); slave.vaginalAccessory = "long, large dildo"; } } break; case "none": - r += `<br>${slave.slaveName} has been instructed not to use a vaginal accessory.`; + message(`${slave.slaveName} has been instructed not to use a vaginal accessory.`, sourceRecord.vaginalAccessory); break; default: - r += `<br>${slave.slaveName} has been given a ${slave.vaginalAccessory} for ${his} pussy.`; + message(`${slave.slaveName} has been given a ${slave.vaginalAccessory} for ${his} pussy.`, sourceRecord.vaginalAccessory); break; } } @@ -646,29 +649,29 @@ globalThis.DefaultRules = function(slave) { if (slave.vaginalAccessory !== "none") { switch (slave.vaginalAttachment) { case "none": - r += `<br>${slave.slaveName} has been instructed not to use an attachment for ${his} dildo.`; + message(`${slave.slaveName} has been instructed not to use an attachment for ${his} dildo.`, sourceRecord.vaginalAttachment); break; case "vibrator": - r += `<br>${slave.slaveName}'s dildo has been replaced with a vibrating model.`; + message(`${slave.slaveName}'s dildo has been replaced with a vibrating model.`, sourceRecord.vaginalAttachment); break; case "smart vibrator": - r += `<br>${slave.slaveName}'s dildo has been replaced with a smart vibrating model.`; + message(`${slave.slaveName}'s dildo has been replaced with a smart vibrating model.`, sourceRecord.vaginalAttachment); break; default: - r += `<br>${slave.slaveName} has been given a ${slave.vaginalAttachment}.`; + message(`${slave.slaveName} has been given a ${slave.vaginalAttachment}.`, sourceRecord.vaginalAttachment); break; } } else { switch (slave.vaginalAttachment) { case "none": - r += `<br>${slave.slaveName} has been instructed not to use any vaginal accessories.`; + message(`${slave.slaveName} has been instructed not to use any vaginal accessories.`, sourceRecord.vaginalAttachment); break; default: - r += `<br>${slave.slaveName} has been given a ${slave.vaginalAttachment}.`; + message(`${slave.slaveName} has been given a ${slave.vaginalAttachment}.`, sourceRecord.vaginalAttachment); break; } } @@ -688,9 +691,9 @@ globalThis.DefaultRules = function(slave) { if (slave.dickAccessory !== rule.aVirginDickAccessory) { slave.dickAccessory = rule.aVirginDickAccessory; if (slave.dickAccessory === "none") { - r += `<br>${slave.slaveName} is a virgin and has been instructed not to wear a dick accessory.`; + message(`${slave.slaveName} is a virgin and has been instructed not to wear a dick accessory.`, sourceRecord.aVirginDickAccessory); } else { - r += `<br>${slave.slaveName} is a virgin and has been given a ${slave.dickAccessory} accessory for ${his} cock.`; + message(`${slave.slaveName} is a virgin and has been given a ${slave.dickAccessory} accessory for ${his} cock.`, sourceRecord.aVirginDickAccessory); } } } @@ -699,9 +702,9 @@ globalThis.DefaultRules = function(slave) { if (slave.dickAccessory !== rule.dickAccessory) { slave.dickAccessory = rule.dickAccessory; if (slave.dickAccessory === "none") { - r += `<br>${slave.slaveName} has been instructed not to wear a dick accessory.`; + message(`${slave.slaveName} has been instructed not to wear a dick accessory.`, sourceRecord.aVirginDickAccessory); } else { - r += `<br>${slave.slaveName} has been given a ${slave.dickAccessory} accessory for ${his} cock.`; + message(`${slave.slaveName} has been given a ${slave.dickAccessory} accessory for ${his} cock.`, sourceRecord.aVirginDickAccessory); } } } @@ -720,9 +723,9 @@ globalThis.DefaultRules = function(slave) { if (slave.chastityVagina !== rule.chastityVagina) { slave.chastityVagina = rule.chastityVagina; if (rule.chastityVagina === 1) { - r += `<br>${slave.slaveName} has been given a chastity belt to wear.`; + message(`${slave.slaveName} has been given a chastity belt to wear.`, sourceRecord.chastityVagina); } else { - r += `<br>${slave.slaveName}'s vaginal chastity has been removed.`; + message(`${slave.slaveName}'s vaginal chastity has been removed.`, sourceRecord.chastityVagina); } } } @@ -732,9 +735,9 @@ globalThis.DefaultRules = function(slave) { if (slave.chastityPenis !== rule.chastityPenis) { slave.chastityPenis = rule.chastityPenis; if (rule.chastityPenis === 1) { - r += `<br>${slave.slaveName} has been given a chastity cage to wear.`; + message(`${slave.slaveName} has been given a chastity cage to wear.`, sourceRecord.chastityPenis); } else { - r += `<br>${slave.slaveName}'s chastity cage has been removed.`; + message(`${slave.slaveName}'s chastity cage has been removed.`, sourceRecord.chastityPenis); } } } @@ -743,9 +746,9 @@ globalThis.DefaultRules = function(slave) { if (slave.chastityAnus !== rule.chastityAnus) { slave.chastityAnus = rule.chastityAnus; if (rule.chastityAnus === 1) { - r += `<br>${slave.slaveName} has been given anal chastity to wear.`; + message(`${slave.slaveName} has been given anal chastity to wear.`, sourceRecord.chastityAnus); } else { - r += `<br>${slave.slaveName}'s anal chastity has been removed.`; + message(`${slave.slaveName}'s anal chastity has been removed.`, sourceRecord.chastityAnus); } } } @@ -761,7 +764,7 @@ globalThis.DefaultRules = function(slave) { if (slave.shoes !== rule.shoes) { if (hasAnyLegs(slave)) { slave.shoes = rule.shoes; - r += `<br>${slave.slaveName}'s shoes have been set to ${slave.shoes}.`; + message(`${slave.slaveName}'s shoes have been set to ${slave.shoes}.`, sourceRecord.shoes); } } } @@ -776,14 +779,14 @@ globalThis.DefaultRules = function(slave) { if ((rule.bellyAccessory !== undefined) && (rule.bellyAccessory !== null)) { if (slave.bellyAccessory !== rule.bellyAccessory) { if ((slave.belly >= 1500 || slave.weight >= 130) && App.Data.misc.fakeBellies.includes(rule.bellyAccessory)) { - r += `<br>${slave.slaveName}'s natural belly is too big to properly wear an empathy belly.`; + message(`${slave.slaveName}'s natural belly is too big to properly wear an empathy belly.`, sourceRecord.bellyAccessory); slave.bellyAccessory = "none"; } else { slave.bellyAccessory = rule.bellyAccessory; if (slave.bellyAccessory === "none") { - r += `<br>${slave.slaveName} has been instructed not to wear a torso accessory.`; + message(`${slave.slaveName} has been instructed not to wear a torso accessory.`, sourceRecord.bellyAccessory); } else { - r += `<br>${slave.slaveName} has been given ${slave.bellyAccessory} to wear.`; + message(`${slave.slaveName} has been given ${slave.bellyAccessory} to wear.`, sourceRecord.bellyAccessory); } } } @@ -797,7 +800,7 @@ globalThis.DefaultRules = function(slave) { function ProcessArmAccessory(slave, rule) { if (rule.armAccessory !== undefined && rule.armAccessory !== null && hasAnyArms(slave) && slave.armAccessory !== rule.armAccessory) { slave.armAccessory = rule.armAccessory; - r += `<br>${slave.slaveName}'s arm accessory was set to ${rule.armAccessory}.`; + message(`${slave.slaveName}'s arm accessory was set to ${rule.armAccessory}.`, sourceRecord.armAccessory); } } @@ -808,7 +811,7 @@ globalThis.DefaultRules = function(slave) { function ProcessLegAccessory(slave, rule) { if (rule.legAccessory !== undefined && rule.legAccessory !== null && hasAnyLegs(slave) && slave.legAccessory !== rule.legAccessory) { slave.legAccessory = rule.legAccessory; - r += `<br>${slave.slaveName}'s leg accessory was set to ${rule.legAccessory}.`; + message(`${slave.slaveName}'s leg accessory was set to ${rule.legAccessory}.`, sourceRecord.legAccessory); } } @@ -839,50 +842,50 @@ globalThis.DefaultRules = function(slave) { slave.buttplug = rule.aVirginButtplug; switch (slave.buttplug) { case "huge plug": - r += `<br>${slave.slaveName} is an anal virgin and has been given a `; + const m = `${slave.slaveName} is an anal virgin and has been given a`; if (slave.anus >= 2) { - r += `massive plug to permanently gape ${his} asshole.`; + message(`${m} massive plug to permanently gape ${his} asshole.`, sourceRecord.aVirginButtplug); } else { slave.buttplug = "large plug"; - r += `large buttplug for ${his} asshole, since it must be stretched before it can accommodate a huge one.`; + message(`${m} large buttplug for ${his} asshole, since it must be stretched before it can accommodate a huge one.`, sourceRecord.aVirginButtplug); } break; case "long plug": if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") { - r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so the anal virgin ${slave.slaveName} has been given a standard length plug for ${his} anus.`; + message(`Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so the anal virgin ${slave.slaveName} has been given a standard length plug for ${his} anus.`, sourceRecord.aVirginButtplug); slave.buttplug = "plug"; } break; case "long, large plug": if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") { - r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so the anal virgin ${slave.slaveName} has been given a standard length large plug for ${his} anus.`; + message(`Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so the anal virgin ${slave.slaveName} has been given a standard length large plug for ${his} anus.`, sourceRecord.aVirginButtplug); slave.buttplug = "large plug"; } break; case "long, huge plug": if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") { - r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so the anal virgin ${slave.slaveName} has been given a standard length huge plug for ${his} anus.`; + message(`Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so the anal virgin ${slave.slaveName} has been given a standard length huge plug for ${his} anus.`, sourceRecord.aVirginButtplug); slave.buttplug = "huge plug"; } else { - r += `<br>${slave.slaveName} is an anal virgin and has been given a `; + const m = `${slave.slaveName} is an anal virgin and has been given a`; if (slave.anus >= 2) { - r += `massive and oversized plug to permanently gape ${his} asshole.`; + message(`${m} massive and oversized plug to permanently gape ${his} asshole.`, sourceRecord.aVirginButtplug); } else { - r += `long, large buttplug for ${his} asshole, since it must be stretched before it can accommodate a huge one.`; + message(`${m} long, large buttplug for ${his} asshole, since it must be stretched before it can accommodate a huge one.`, sourceRecord.aVirginButtplug); slave.buttplug = "long, large plug"; } } break; case "none": - r += `<br>${slave.slaveName} is an anal virgin and has been instructed not to use an anal accessory.`; + message(`${slave.slaveName} is an anal virgin and has been instructed not to use an anal accessory.`, sourceRecord.aVirginButtplug); break; default: - r += `<br>${slave.slaveName} is an anal virgin and has been given a ${slave.buttplug} for ${his} asshole.`; + message(`${slave.slaveName} is an anal virgin and has been given a ${slave.buttplug} for ${his} asshole.`, sourceRecord.aVirginButtplug); break; } } @@ -900,50 +903,50 @@ globalThis.DefaultRules = function(slave) { slave.buttplug = rule.buttplug; switch (slave.buttplug) { case "huge plug": - r += `<br>${slave.slaveName} has been given a `; + const m = `${slave.slaveName} has been given a`; if (slave.anus >= 2) { - r += `massive plug to permanently gape ${his} asshole.`; + message(`${m} massive plug to permanently gape ${his} asshole.`, sourceRecord.buttplug); } else { slave.buttplug = "large plug"; - r += `large buttplug for ${his} asshole, since it must be stretched before it can accommodate a huge one.`; + message(`${m} large buttplug for ${his} asshole, since it must be stretched before it can accommodate a huge one.`, sourceRecord.buttplug); } break; case "long plug": if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") { - r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so ${slave.slaveName} has been given a standard length plug for ${his} anus.`; + message(`Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so ${slave.slaveName} has been given a standard length plug for ${his} anus.`, sourceRecord.buttplug); slave.buttplug = "plug"; } break; case "long, large plug": if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") { - r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so ${slave.slaveName} has been given a standard length large plug for ${his} anus.`; + message(`Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so ${slave.slaveName} has been given a standard length large plug for ${his} anus.`, sourceRecord.buttplug); slave.buttplug = "large plug"; } break; case "long, huge plug": if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") { - r += `<br>Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so ${slave.slaveName} has been given a standard length huge plug for ${his} anus.`; + message(`Breeding regulations forbid the use of anal plugs that can damage a growing fetus on marked slaves, so ${slave.slaveName} has been given a standard length huge plug for ${his} anus.`, sourceRecord.buttplug); slave.buttplug = "huge plug"; } else { - r += `<br>${slave.slaveName} has been given a `; + const m = `${slave.slaveName} has been given a`; if (slave.anus >= 2) { - r += `massive and oversized plug to permanently gape ${his} asshole.`; + message(`${m} massive and oversized plug to permanently gape ${his} asshole.`, sourceRecord.buttplug); } else { - r += `long, large buttplug for ${his} asshole, since it must be stretched before it can accommodate a huge one.`; + message(`${m} long, large buttplug for ${his} asshole, since it must be stretched before it can accommodate a huge one.`, sourceRecord.buttplug); slave.buttplug = "long, large plug"; } } break; case "none": - r += `<br>${slave.slaveName} has been instructed not to use an anal accessory.`; + message(`${slave.slaveName} has been instructed not to use an anal accessory.`, sourceRecord.buttplug); break; default: - r += `<br>${slave.slaveName} has been given a ${slave.buttplug} for ${his} asshole.`; + message(`${slave.slaveName} has been given a ${slave.buttplug} for ${his} asshole.`, sourceRecord.buttplug); break; } } @@ -965,11 +968,11 @@ globalThis.DefaultRules = function(slave) { slave.buttplugAttachment = rule.buttplugAttachment; switch (slave.buttplugAttachment) { case "none": - r += `<br>${slave.slaveName} has been instructed not to use an attachment for ${his} anal accessory.`; + message(`${slave.slaveName} has been instructed not to use an attachment for ${his} anal accessory.`, sourceRecord.buttplugAttachment); break; default: - r += `<br>${slave.slaveName} has been given a ${slave.buttplugAttachment} to attach to ${his} buttplug.`; + message(`${slave.slaveName} has been given a ${slave.buttplugAttachment} to attach to ${his} buttplug.`, sourceRecord.buttplugAttachment); break; } } @@ -984,30 +987,29 @@ globalThis.DefaultRules = function(slave) { // Here is belly implant size control, it's used in Surgery Degradation passage to set up devotion and trust changes. // silent calls to surgery degradation have been replaced with a js function, which is less hacky if ((rule.bellyImplantVol !== undefined) && slave.bellyImplant >= 0 && rule.bellyImplantVol >= 0) { - r += "<br>"; if (slave.health.condition > -10) { let diff = rule.bellyImplantVol - slave.bellyImplant; if (diff >= 5000 && slave.bellyPain === 0 && slave.health.condition > 50) { - r += `${slave.slaveName}'s belly is way too small, so ${he} has been directed to have intensive belly implant filling procedures throughout this week.`; + message(`${slave.slaveName}'s belly is way too small, so ${he} has been directed to have intensive belly implant filling procedures throughout this week.`, sourceRecord.bellyImplantVol); slave.bellyImplant += 1000; slave.bellyPain += 2; BellySurgery(slave, diff); } else if (diff >= 500 && slave.bellyPain < 2) { - r += `${slave.slaveName}'s belly has not reached the desired size, so ${he} has been directed to have belly implant filling procedures throughout this week.`; + message(`${slave.slaveName}'s belly has not reached the desired size, so ${he} has been directed to have belly implant filling procedures throughout this week.`, sourceRecord.bellyImplantVol); slave.bellyImplant += 500; slave.bellyPain += 1; BellySurgery(slave, diff); } else if (diff <= -5000) { - r += `${slave.slaveName}'s belly is way too big, so ${he} has been directed to have intensive belly implant draining procedures throughout this week.`; + message(`${slave.slaveName}'s belly is way too big, so ${he} has been directed to have intensive belly implant draining procedures throughout this week.`, sourceRecord.bellyImplantVol); slave.bellyImplant -= 1000; BellySurgery(slave, diff); } else if (diff <= -500) { - r += `${slave.slaveName}'s belly is too big, so ${he} has been directed to have belly implant draining procedures throughout this week.`; + message(`${slave.slaveName}'s belly is too big, so ${he} has been directed to have belly implant draining procedures throughout this week.`, sourceRecord.bellyImplantVol); slave.bellyImplant -= 500; BellySurgery(slave, diff); } } else { - r += `${slave.slaveName} is not healthy enough to safely adjust ${his} belly implant.`; + message(`${slave.slaveName} is not healthy enough to safely adjust ${his} belly implant.`, sourceRecord.bellyImplantVol); } } } @@ -1065,10 +1067,10 @@ globalThis.DefaultRules = function(slave) { function ProcessContraceptives(slave, rule) { if ((rule.preg !== undefined) && (rule.preg !== null)) { if (rule.preg === true && slave.preg === 0 && slave.pubertyXX === 1) { - r += `<br>${slave.slaveName} is being given contraceptives.`; + message(`${slave.slaveName} is being given contraceptives.`, sourceRecord.preg); slave.preg = -1; } else if (slave.preg === -1 && rule.preg === false) { - r += `<br>${slave.slaveName} is no longer being put on contraceptives.`; + message(`${slave.slaveName} is no longer being put on contraceptives.`, sourceRecord.preg); slave.preg = 0; } } @@ -1103,34 +1105,34 @@ globalThis.DefaultRules = function(slave) { for (const ar of rule.abortion) { if (ar === "all") { if (slave.preg < 4 || (slave.fetish === "mindbroken" || slave.fuckdoll !== 0)) { - r += `<br>${slave.slaveName}'s pregnancy has been terminated.`; + message(`${slave.slaveName}'s pregnancy has been terminated.`, sourceRecord.abortion); } else { - r += `<br>${slave.slaveName}'s pregnancy has been terminated; `; + const m = `${slave.slaveName}'s pregnancy has been terminated;`; if (slave.sexualFlaw === "breeder") { - r += `it broke ${his} mind.`; + message(`${m} it broke ${his} mind.`, sourceRecord.abortion); applyMindbroken(slave); } else if (slave.devotion < -50) { - r += `${he} did not handle it well.`; + message(`${m} ${he} did not handle it well.`, sourceRecord.abortion); slave.trust -= 10; slave.devotion -= 25; } else if (slave.devotion < -20) { - r += `${he} did not handle it well.`; + message(`${m} ${he} did not handle it well.`, sourceRecord.abortion); slave.trust -= 10; slave.devotion -= 10; } else if (slave.fetish === "pregnancy") { - r += `${he} did not handle it well.`; + message(`${m} ${he} did not handle it well.`, sourceRecord.abortion); let fetishModifier = slave.fetishStrength / 2; slave.devotion -= fetishModifier; slave.trust -= fetishModifier; } else if (slave.devotion <= 20) { - r += `${he} did not handle it well.`; + message(`${m} ${he} did not handle it well.`, sourceRecord.abortion); slave.trust -= 10; slave.devotion -= 5; } else if (slave.devotion <= 50) { - r += `${he} did not handle it well.`; + message(`${m} ${he} did not handle it well.`, sourceRecord.abortion); slave.trust -= 10; } else { - r += "it had little mental effect."; + message(`${m} it had little mental effect.`, sourceRecord.abortion); } } @@ -1147,16 +1149,16 @@ globalThis.DefaultRules = function(slave) { actX(slave, "abortions"); } else if (ar === "male") { if (conditionalTermination(slave, fetus => fetus.genetics.gender === "XY")) { - r += `<br>${slave.slaveName}'s male fetuses have been terminated.`; + message(`${slave.slaveName}'s male fetuses have been terminated.`, sourceRecord.abortion); } } else if (ar === "female") { if (conditionalTermination(slave, fetus => fetus.genetics.gender === "XX")) { - r += `<br>${slave.slaveName}'s female fetuses have been terminated.`; + message(`${slave.slaveName}'s female fetuses have been terminated.`, sourceRecord.abortion); } } else if (ar.startsWith("race:")) { // ar is the race name in the notation "race:<lowercase_race_name>" const race = ar.substr("race:".length); if (conditionalTermination(slave, fetus => fetus.genetics.race === race)) { - r += `<br>${slave.slaveName}'s ${race} fetuses have been terminated.`; + message(`${slave.slaveName}'s ${race} fetuses have been terminated.`, sourceRecord.abortion); } } SetBellySize(slave); @@ -1174,7 +1176,7 @@ globalThis.DefaultRules = function(slave) { return; } if ((slave.drugs === "super fertility drugs" || slave.drugs === "fertility drugs") && isFertile(slave)) { - r += `<br>${slave.slaveName} is on ${slave.drugs} and will not be considered for drug enhancement until that regime is complete.`; + message(`${slave.slaveName} is on ${slave.drugs} and will not be considered for drug enhancement until that regime is complete.`); ProcessOtherDrugs(slave, rule); return; } else if ( @@ -1257,10 +1259,11 @@ globalThis.DefaultRules = function(slave) { * @param {App.Entity.SlaveState} slave * @param {FC.SizableBodyPart} asset * @param {FC.RA.ExpressiveNumericTarget} target - * @param {{drug: FC.Drug, weight: number}[]} priorities + * @param {{drug: FC.Drug, weight: number, source:string}[]} priorities * @param {number} step + * @param {string} source */ - function drugs(slave, asset, target, priorities, step) { + function drugs(slave, asset, target, priorities, step, source) { if (target === null || (growDrugs[asset] === null && shrinkDrugs[asset] === null)) { return; } @@ -1271,71 +1274,71 @@ globalThis.DefaultRules = function(slave) { if (V.debugMode) { console.log(asset + " expression for '" + slave.slaveName + "' resolves to " + newVal.toString()); } - return drugsImpl(slave, asset, {cond: target.cond, val: newVal}, priorities, step); + drugsImpl(slave, asset, {cond: target.cond, val: newVal}, priorities, step, source); + } else { + drugsImpl(slave, asset, {cond: target.cond, val: target.val}, priorities, step, source); } - - return drugsImpl(slave, asset, {cond: target.cond, val: target.val}, priorities, step); } /** * @param {App.Entity.SlaveState} slave * @param {FC.SizableBodyPart} asset * @param {FC.RA.NumericTarget} target - * @param {{drug: FC.Drug, weight: number}[]} priorities + * @param {{drug: FC.Drug, weight: number, source:string}[]} priorities * @param {number} step + * @param {string} source */ - function drugsImpl(slave, asset, target, priorities, step) { + function drugsImpl(slave, asset, target, priorities, step, source) { const flesh = App.Medicine.fleshSize(slave, asset); if (growDrugs[asset] !== null && App.RA.shallGrow(flesh, target, step) && App.Medicine.maxAssetSize(asset) > slave[asset]) { priorities.push({ - drug: growDrugs[asset], - weight: 1.0 - (flesh / target.val) + drug: growDrugs[asset], weight: 1.0 - (flesh / target.val), source }); } else if (shrinkDrugs[asset] !== null && App.RA.shallShrink(flesh, target, step)) { priorities.push({ - drug: shrinkDrugs[asset], - weight: flesh / target.val - 1.0 + drug: shrinkDrugs[asset], weight: flesh / target.val - 1.0, source }); } } - /** @type {{drug: FC.Drug, weight: number}[]} */ + /** @type {{drug: FC.Drug, weight: number, source:string}[]} */ let priorities = []; - drugs(slave, "boobs", rule.growth.boobs, priorities, 200); - drugs(slave, "butt", rule.growth.butt, priorities, 1); - drugs(slave, "lips", rule.growth.lips, priorities, 1); - drugs(slave, "dick", rule.growth.dick, priorities, 1); - drugs(slave, "balls", rule.growth.balls, priorities, 1); + drugs(slave, "boobs", rule.growth.boobs, priorities, 200, sourceRecord.growth.boobs); + drugs(slave, "butt", rule.growth.butt, priorities, 1, sourceRecord.growth.butt); + drugs(slave, "lips", rule.growth.lips, priorities, 1, sourceRecord.growth.lips); + drugs(slave, "dick", rule.growth.dick, priorities, 1, sourceRecord.growth.dick); + drugs(slave, "balls", rule.growth.balls, priorities, 1, sourceRecord.growth.balls); if (priorities.length > 0) { const action = priorities.reduce((acc, cur) => (acc.weight > cur.weight) ? acc : cur); if (slave.drugs !== action.drug) { slave.drugs = action.drug; - r += `<br>${slave.slaveName} has been put on ${slave.drugs}, since `; + let m = `${slave.slaveName} has been put on ${slave.drugs}, since `; if (action.drug.startsWith("intensive")) { - r += `${he}'s healthy enough to take them, and `; + m += `${he}'s healthy enough to take them, and `; } if (priorities.length > 1) { - r += `that part of ${his} body is `; + m += `that part of ${his} body is `; if (!isNaN(action.weight)) { - r += `${Math.trunc(action.weight * 100)}% `; + m += `${Math.trunc(action.weight * 100)}% `; } if (action.weight < 1) { - r += "below "; + m += "below "; } else { - r += "above "; + m += "above "; } - r += "the targeted size."; + m += "the targeted size."; } else { - r += `that is the only part of ${his} body that does not meet the targeted size.`; + m += `that is the only part of ${his} body that does not meet the targeted size.`; } + message(m, action.source); } } else if (slave.drugs !== rule.drug) { if (growthDrugs.has(slave.drugs)) { - r += `<br>${slave.slaveName}'s body has met all relevant growth targets, so ${his} pharmaceutical regime has been ended.`; + message(`${slave.slaveName}'s body has met all relevant growth targets, so ${his} pharmaceutical regime has been ended.`, sourceRecord.drug); if (rule.drug === null) { slave.drugs = "no drugs"; - r += `<br>${slave.slaveName} has been defaulted to ${slave.drugs}`; + message(`${slave.slaveName} has been defaulted to ${slave.drugs}`, sourceRecord.drug); } } ProcessOtherDrugs(slave, rule); @@ -1520,10 +1523,10 @@ globalThis.DefaultRules = function(slave) { } if (flag) { slave.drugs = rule.drug; - r += `<br>${slave.slaveName} has been put on ${slave.drugs}.`; + message(`${slave.slaveName} has been put on ${slave.drugs}.`, sourceRecord.drug); } else if (slave.drugs !== "no drugs") { slave.drugs = "no drugs"; - r += `<br>${slave.slaveName} cannot benefit from ${his} assigned drug and has been defaulted to ${slave.drugs}`; + message(`${slave.slaveName} cannot benefit from ${his} assigned drug and has been defaulted to ${slave.drugs}`, sourceRecord.drug); } } } @@ -1536,12 +1539,12 @@ globalThis.DefaultRules = function(slave) { if ((rule.inflationType !== undefined) && (rule.inflationType !== null)) { if (slave.inflationType !== rule.inflationType) { if ((slave.inflationType === "curative" && slave.health.condition > 90) || (slave.inflationType === "tightener" && slave.anus <= 1 && slave.vagina <= 1)) { - r += `<br>${slave.slaveName} cannot benefit from ${his} assigned enema and has been defaulted to none.`; + message(`${slave.slaveName} cannot benefit from ${his} assigned enema and has been defaulted to none.`, sourceRecord.inflationType); deflate(slave); } else if ((rule.inflationType === "curative" && slave.health.condition > 90) || (rule.inflationType === "tightener" && slave.anus <= 1 && slave.vagina <= 1)) { // empty block } else { - r += `<br>${slave.slaveName}'s current enema regimen has been set to ${rule.inflationType}.`; + message(`${slave.slaveName}'s current enema regimen has been set to ${rule.inflationType}.`, sourceRecord.inflationType); slave.inflation = 1; slave.inflationType = rule.inflationType; slave.inflationMethod = 2; @@ -1551,11 +1554,11 @@ globalThis.DefaultRules = function(slave) { } } if (slave.inflationType !== "none" && slave.inflation > 1 && slave.health.condition < -50) { - r += `<br>${slave.slaveName}'s current enema regimen risks death, so it has been reduced to a less threatening level.`; + message(`${slave.slaveName}'s current enema regimen risks death, so it has been reduced to a less threatening level.`, sourceRecord.inflationType); slave.inflation = 1; SetBellySize(slave); } else if (slave.inflation > 1 && (slave.bellyPreg >= 1500 || slave.bellyImplant >= 1500)) { - r += `<br>${slave.slaveName}'s current enema is too much for ${his} body, so it has been reduced.`; + message(`${slave.slaveName}'s current enema is too much for ${his} body, so it has been reduced.`, sourceRecord.inflationType); slave.inflation = 1; SetBellySize(slave); } else if (slave.inflationType === "none") { @@ -1574,15 +1577,15 @@ globalThis.DefaultRules = function(slave) { if (rule.pitRules === 0) { if (App.Entity.facilities.pit.isHosted(slave)) { removeJob(slave, Job.PIT, true); - r += `<br>${slave.slaveName} has been removed from the pit.`; + message(`${slave.slaveName} has been removed from the pit.`, sourceRecord.pitRules); } } else { if (App.Entity.facilities.pit.job().checkRequirements(slave).length !== 0) { removeJob(slave, Job.PIT, true); - r += `<br>${slave.slaveName} is not eligible to fight.`; + message(`${slave.slaveName} is not eligible to fight.`, sourceRecord.pitRules); } else if (!App.Entity.facilities.pit.isHosted(slave)) { assignJob(slave, Job.PIT); - r += `<br>${slave.slaveName} has been automatically assigned to fight in the pit.`; + message(`${slave.slaveName} has been automatically assigned to fight in the pit.`, sourceRecord.pitRules); } } } @@ -1607,17 +1610,17 @@ globalThis.DefaultRules = function(slave) { if (((slave.weight > 95) || ((slave.weight > 30) && (slave.hips < 2)))) { if (slave.diet !== "restricted") { slave.diet = "restricted"; - r += `<br>${slave.slaveName} is unreasonably fat so ${his} diet has been set to restricted.`; + message(`${slave.slaveName} is unreasonably fat so ${his} diet has been set to restricted.`, sourceRecord.diet); dietPills(slave); } } else if (((slave.weight < -95) || ((slave.weight < -30) && (slave.hips > -2)))) { if (slave.diet !== "fattening") { slave.diet = "fattening"; - r += `<br>${slave.slaveName} is unreasonably skinny so ${his} diet has been set to fattening.`; + message(`${slave.slaveName} is unreasonably skinny so ${his} diet has been set to fattening.`, sourceRecord.diet); dietPills(slave); } } else if (["restricted", "fattening"].includes(slave.diet)) { - r += `<br>${slave.slaveName} is at an acceptable weight, so ${his} diet has been normalized.`; + message(`${slave.slaveName} is at an acceptable weight, so ${his} diet has been normalized.`, sourceRecord.diet); slave.diet = "healthy"; dietPills(slave); muscleRule(slave, rule); @@ -1628,17 +1631,17 @@ globalThis.DefaultRules = function(slave) { if (slave.weight > rule.weight.max) { if (slave.diet !== "restricted") { slave.diet = "restricted"; - r += `<br>${slave.slaveName} is too fat so ${his} diet has been set to restricted.`; + message(`${slave.slaveName} is too fat so ${his} diet has been set to restricted.`, sourceRecord.weight.max); dietPills(slave); } } else if (slave.weight < rule.weight.min) { if (slave.diet !== "fattening") { slave.diet = "fattening"; - r += `<br>${slave.slaveName} is too skinny so ${his} diet has been set to fattening.`; + message(`${slave.slaveName} is too skinny so ${his} diet has been set to fattening.`, sourceRecord.weight.min); dietPills(slave); } } else if (["restricted", "fattening"].includes(slave.diet)) { - r += `<br>${slave.slaveName} is at the target weight, so ${his} diet has been normalized.`; + message(`${slave.slaveName} is at the target weight, so ${his} diet has been normalized.`, [sourceRecord.weight.max, sourceRecord.weight.min]); slave.diet = "healthy"; dietPills(slave); muscleRule(slave, rule); @@ -1652,15 +1655,15 @@ globalThis.DefaultRules = function(slave) { if (!isAmputee(slave) && App.RA.shallShrink(slave.muscles, rule.muscles, 8)) { if (slave.diet !== "slimming") { slave.diet = "slimming"; - r += `<br>${slave.slaveName} has been put on a slimming exercise regime.`; + message(`${slave.slaveName} has been put on a slimming exercise regime.`, sourceRecord.muscles); } } else if (!isAmputee(slave) && App.RA.shallGrow(slave.muscles, rule.muscles, 2)) { if (slave.diet !== "muscle building") { slave.diet = "muscle building"; - r += `<br>${slave.slaveName} has been put on a muscle building exercise regime.`; + message(`${slave.slaveName} has been put on a muscle building exercise regime.`, sourceRecord.muscles); } } else if (!isAmputee(slave) && ["slimming", "muscle building"].includes(slave.diet)) { - r += `<br>${slave.slaveName} is at the target musculature, so ${his} diet has been normalized.`; + message(`${slave.slaveName} is at the target musculature, so ${his} diet has been normalized.`, sourceRecord.muscles); dietRule(slave, rule); } else { dietRule(slave, rule); @@ -1670,56 +1673,56 @@ globalThis.DefaultRules = function(slave) { function dietRule(slave, rule) { if (rule.diet === "healthy" && slave.diet !== "healthy") { slave.diet = "healthy"; - r += `<br>${slave.slaveName} has been assigned to a healthy diet.`; + message(`${slave.slaveName} has been assigned to a healthy diet.`, sourceRecord.diet); } else if ((slave.boobs >= 1600) && (slave.muscles > 5) && (slave.diet === "muscle building") && ((rule.muscles === null) || (rule.muscles.val < 5))) { slave.diet = "healthy"; - r += `<br>${slave.slaveName} has huge boobs, but ${he} already has the back muscles to bear them, so ${he}'s been assigned to stop working out so hard.`; + message(`${slave.slaveName} has huge boobs, but ${he} already has the back muscles to bear them, so ${he}'s been assigned to stop working out so hard.`, sourceRecord.diet); } else if ((rule.dietGrowthSupport === 1) && ((slave.drugs === "breast injections") || (slave.drugs === "butt injections")) && (slave.weight <= 95)) { if (slave.diet !== "fattening") { slave.diet = "fattening"; - r += `<br>${slave.slaveName} is on drugs designed to expand major body parts, so ${he}'s been put on a fattening diet to provide ${his} body as much fuel for growth as possible.`; + message(`${slave.slaveName} is on drugs designed to expand major body parts, so ${he}'s been put on a fattening diet to provide ${his} body as much fuel for growth as possible.`, sourceRecord.diet); } } else if (rule.diet === "XX") { if (slave.diet !== "XX") { slave.diet = "XX"; - r += `<br>${slave.slaveName} has been put on a diet that favors feminine development.`; + message(`${slave.slaveName} has been put on a diet that favors feminine development.`, sourceRecord.diet); } } else if (rule.diet === "XY") { if (slave.diet !== "XY") { slave.diet = "XY"; - r += `<br>${slave.slaveName} has been put on a diet that favors masculine development.`; + message(`${slave.slaveName} has been put on a diet that favors masculine development.`, sourceRecord.diet); } } else if (rule.diet === "XXY") { if (slave.balls > 0 && (slave.ovaries === 1 || slave.mpreg === 1)) { if (slave.diet !== "XXY") { slave.diet = "XXY"; - r += `<br>${slave.slaveName} has been put on a diet that enhances a herm's unique sexuality.`; + message(`${slave.slaveName} has been put on a diet that enhances a herm's unique sexuality.`, sourceRecord.diet); } } else { if (slave.diet !== "healthy") { slave.diet = "healthy"; - r += `<br>${slave.slaveName} has been put on a standard diet since ${he} is not a hermaphrodite.`; + message(`${slave.slaveName} has been put on a standard diet since ${he} is not a hermaphrodite.`, sourceRecord.diet); } } } else if (V.dietCleanse === 1 && (rule.diet === "cleansing")) { if (slave.diet !== "cleansing") { slave.diet = "cleansing"; - r += `<br>${slave.slaveName} has been put on a diet of cleansers.`; + message(`${slave.slaveName} has been put on a diet of cleansers.`, sourceRecord.diet); } } else if (rule.diet === "fertility") { if ((isFertile(slave) && slave.preg === 0) || (slave.geneticQuirks.superfetation === 2 && canGetPregnant(slave) && V.geneticMappingUpgrade !== 0)) { if (slave.diet !== "fertility") { slave.diet = "fertility"; - r += `<br>${slave.slaveName} has been put on a diet to enhance fertility.`; + message(`${slave.slaveName} has been put on a diet to enhance fertility.`, sourceRecord.diet); } } else { if (slave.diet !== "healthy") { slave.diet = "healthy"; if (slave.pregKnown === 0 && slave.preg > 0) { - r += `<br>${slave.slaveName} has been put on a standard diet since tests reveal ${he} has become pregnant.`; + message(`${slave.slaveName} has been put on a standard diet since tests reveal ${he} has become pregnant.`, sourceRecord.diet); slave.pregKnown = 1; } else { - r += `<br>${slave.slaveName} has been put on a standard diet since ${he} is currently unable to become pregnant.`; + message(`${slave.slaveName} has been put on a standard diet since ${he} is currently unable to become pregnant.`, sourceRecord.diet); } } } @@ -1727,18 +1730,18 @@ globalThis.DefaultRules = function(slave) { if (slave.balls > 0) { if (slave.diet !== "cum production") { slave.diet = "cum production"; - r += `<br>${slave.slaveName} has been put on a diet to promote cum production.`; + message(`${slave.slaveName} has been put on a diet to promote cum production.`, sourceRecord.diet); } } else { if (slave.diet !== "healthy") { slave.diet = "healthy"; - r += `<br>${slave.slaveName} has been put on a standard diet since ${he} is no longer able to produce cum.`; + message(`${slave.slaveName} has been put on a standard diet since ${he} is no longer able to produce cum.`, sourceRecord.diet); } } } else { if (slave.diet !== "healthy") { slave.diet = "healthy"; - r += `<br>${slave.slaveName} has been put on a standard diet.`; + message(`${slave.slaveName} has been put on a standard diet.`, sourceRecord.diet); } } } @@ -1756,10 +1759,10 @@ globalThis.DefaultRules = function(slave) { function dietPills(slave) { if (slave.drugs === "appetite suppressors" && slave.diet !== "restricted") { slave.drugs = "no drugs"; - r += `<br>${slave.slaveName} no longer needs to lose weight, so ${he}'s no longer being given appetite suppressors.`; + message(`${slave.slaveName} no longer needs to lose weight, so ${he}'s no longer being given appetite suppressors.`, [sourceRecord.diet, sourceRecord.weight.max, sourceRecord.weight.min]); } else if (slave.diet === "restricted" && V.arcologies[0].FSSlimnessEnthusiastResearch === 1 && slave.drugs === "no drugs") { slave.drugs = "appetite suppressors"; - r += `<br>${slave.slaveName} needs to lose weight, so ${he} will be given weight loss pills.`; + message(`${slave.slaveName} needs to lose weight, so ${he} will be given weight loss pills.`, [sourceRecord.diet, sourceRecord.weight.max, sourceRecord.weight.min]); } } } @@ -1774,15 +1777,15 @@ globalThis.DefaultRules = function(slave) { if (rule.curatives === 2) { if (slave.health.condition > 100) { if (slave.curatives !== 1) { - r += `<br>${slave.slaveName} has been put on preventatives, since curatives cannot improve ${his} health further.`; + message(`${slave.slaveName} has been put on preventatives, since curatives cannot improve ${his} health further.`, sourceRecord.curatives); slave.curatives = 1; } } else { - r += `<br>${slave.slaveName} has been put on curatives.`; + message(`${slave.slaveName} has been put on curatives.`, sourceRecord.curatives); slave.curatives = rule.curatives; } } else { - r += `<br>${slave.slaveName} has been ${rule.curatives > 0 ? "put on preventatives" : "taken off health drugs"}`; + message(`${slave.slaveName} has been ${rule.curatives > 0 ? "put on preventatives" : "taken off health drugs"}`, sourceRecord.curatives); slave.curatives = rule.curatives; } } @@ -1796,7 +1799,7 @@ globalThis.DefaultRules = function(slave) { function ProcessAphrodisiacs(slave, rule) { if ((rule.aphrodisiacs !== undefined) && (rule.aphrodisiacs !== null)) { if (slave.aphrodisiacs !== rule.aphrodisiacs) { - r += `<br>${slave.slaveName} has been ${rule.aphrodisiacs > 0 ? "put on the proper" : "taken off"} aphrodisiacs.`; + message(`${slave.slaveName} has been ${rule.aphrodisiacs > 0 ? "put on the proper" : "taken off"} aphrodisiacs.`, sourceRecord.aphrodisiacs); slave.aphrodisiacs = rule.aphrodisiacs; } } @@ -1806,13 +1809,14 @@ globalThis.DefaultRules = function(slave) { * @param {FC.SlaveState} slave * @param {number} hormones * @param {string} slaveClass + * @param {string} source */ - function applyHormones(slave, hormones, slaveClass) { + function applyHormones(slave, hormones, slaveClass, source) { if (!_.isNil(hormones)) { const newHormones = slave.indentureRestrictions >= 2 ? Math.clamp(hormones, -1, 1) : hormones; if (slave.hormones !== newHormones) { slave.hormones = newHormones; - r += `<br>${slave.slaveName} is ${slaveClass}, so ${he} has been put on the appropriate hormonal regime.`; + message(`${slave.slaveName} is ${slaveClass}, so ${he} has been put on the appropriate hormonal regime.`, source); } } } @@ -1824,9 +1828,9 @@ globalThis.DefaultRules = function(slave) { function ProcessPenisHormones(slave, rule) { if (slave.dick > 0) { if (slave.balls === 0) { - applyHormones(slave, rule.gelding, "a gelding"); + applyHormones(slave, rule.gelding, "a gelding", sourceRecord.gelding); } else if (slave.balls > 0) { - applyHormones(slave, rule.XY, "a shemale"); + applyHormones(slave, rule.XY, "a shemale", sourceRecord.XY); } } } @@ -1837,7 +1841,7 @@ globalThis.DefaultRules = function(slave) { */ function ProcessFemaleHormones(slave, rule) { if ((slave.vagina > -1) && (slave.dick === 0)) { - applyHormones(slave, rule.XX, "a female"); + applyHormones(slave, rule.XX, "a female", sourceRecord.XX); } } @@ -1849,25 +1853,25 @@ globalThis.DefaultRules = function(slave) { if (slave.pregKnown === 1 && rule.pregSpeed !== null && (slave.breedingMark !== 1 || V.propOutcome === 0 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset") && slave.indentureRestrictions < 1 && slave.broodmother === 0) { if (rule.pregSpeed === "slow" && slave.preg < slave.pregData.normalBirth) { slave.pregControl = "slow gestation"; - r += `<br>${slave.slaveName} is pregnant, so ${he} has been put on the gestation slowing agents.`; + message(`${slave.slaveName} is pregnant, so ${he} has been put on the gestation slowing agents.`, sourceRecord.pregSpeed); } else if (rule.pregSpeed === "fast" && slave.preg < slave.pregData.normalBirth && slave.health.condition > -50) { slave.pregControl = "speed up"; - r += `<br>${slave.slaveName} is pregnant, so ${he} has been put on rapid gestation agents. CAUTION! Can be dangerous. Clinic supervision is recommended.`; + message(`${slave.slaveName} is pregnant, so ${he} has been put on rapid gestation agents. CAUTION! Can be dangerous. Clinic supervision is recommended.`, sourceRecord.pregSpeed); } else if (rule.pregSpeed === "suppress" && slave.preg >= slave.pregData.minLiveBirth && slave.health.condition > -50) { slave.pregControl = "labor suppressors"; - r += `<br>${slave.slaveName} is ready to birth, so ${he} has been put on labor suppressing agents.`; + message(`${slave.slaveName} is ready to birth, so ${he} has been put on labor suppressing agents.`, sourceRecord.pregSpeed); } else if (rule.pregSpeed === "stimulate" && slave.preg > slave.pregData.normalBirth - 2 && slave.preg > slave.pregData.minLiveBirth && slave.health.condition > -50) { induce(slave); - r += `<br>${slave.slaveName} is ready to birth, so ${his} labor has been stimulated.`; + message(`${slave.slaveName} is ready to birth, so ${his} labor has been stimulated.`, sourceRecord.pregSpeed); } else if (rule.pregSpeed === "fast" && slave.pregControl === "speed up" && slave.health.condition <= -50) { slave.pregControl = "none"; - r += `<br>${slave.slaveName} is on rapid gestation agents and dangerously unhealthy, so ${his} agent regimen has been stopped.`; + message(`${slave.slaveName} is on rapid gestation agents and dangerously unhealthy, so ${his} agent regimen has been stopped.`, sourceRecord.pregSpeed); } else if (rule.pregSpeed === "suppress" && slave.pregControl === "labor suppressors" && slave.health.condition <= -50) { slave.pregControl = "none"; - r += `<br>${slave.slaveName} is on labor suppression agents and unhealthy, so ${his} agent regimen has been stopped.`; + message(`${slave.slaveName} is on labor suppression agents and unhealthy, so ${his} agent regimen has been stopped.`, sourceRecord.pregSpeed); } else if (rule.pregSpeed === "none" && slave.pregControl !== "none") { slave.pregControl = "none"; - r += `<br>${slave.slaveName}'s pregnancy control regimen has been stopped.`; + message(`${slave.slaveName}'s pregnancy control regimen has been stopped.`, sourceRecord.pregSpeed); } } } @@ -1880,26 +1884,26 @@ globalThis.DefaultRules = function(slave) { if (rule.livingRules !== undefined && rule.livingRules !== null && slave.rules.living !== rule.livingRules) { if (App.Data.misc.facilityCareers.includes(slave.assignment)) { // Handled in Rules tab of SI now. - // r += `<br>${slave.slaveName}'s living standards are controlled by ${his} assignment.`; + // message(`${slave.slaveName}'s living standards are controlled by ${his} assignment.`); } else if (((slave.assignment === Job.HEADGIRL) && (V.HGSuite === 1)) || ((slave.assignment === Job.BODYGUARD) && (V.dojo > 1))) { - // r += `<br>${slave.slaveName} has a private room.`; + // message(`${slave.slaveName} has a private room.`); } else if (slave.fetish === "mindbroken") { if (slave.rules.living !== "spare") { slave.rules.living = "spare"; - r += `<br>Since ${slave.slaveName} is mindbroken, ${his} living standard has been set to spare.`; + message(`Since ${slave.slaveName} is mindbroken, ${his} living standard has been set to spare.`, sourceRecord.livingRules); } } else { if (rule.livingRules === "luxurious") { if (canMoveToRoom(slave)) { slave.rules.living = rule.livingRules; - r += `<br>${slave.slaveName}'s living standard has been set to ${rule.livingRules}.`; + message(`${slave.slaveName}'s living standard has been set to ${rule.livingRules}.`, sourceRecord.livingRules); } else { slave.rules.living = "normal"; - r += `<br>${slave.slaveName}'s living standard has been set to normal, since there is no room for ${him} to occupy.`; + message(`${slave.slaveName}'s living standard has been set to normal, since there is no room for ${him} to occupy.`, sourceRecord.livingRules); } } else { slave.rules.living = rule.livingRules; - r += `<br>${slave.slaveName}'s living standard has been set to ${rule.livingRules}.`; + message(`${slave.slaveName}'s living standard has been set to ${rule.livingRules}.`, sourceRecord.livingRules); } } penthouseCensus(); @@ -1917,7 +1921,7 @@ globalThis.DefaultRules = function(slave) { // These assignments enforce "restrictive", do not let RA attempt to change it. } else { slave.rules.rest = rule.restRules; - r += `<br>${slave.slaveName}'s resting time has been set to ${rule.restRules}.`; + message(`${slave.slaveName}'s resting time has been set to ${rule.restRules}.`, sourceRecord.restRules); } } } @@ -1932,27 +1936,27 @@ globalThis.DefaultRules = function(slave) { if (slave.fetish === "mindbroken") { if (slave.rules.speech !== "restrictive") { slave.rules.speech = "restrictive"; - r += `<br>Since ${slave.slaveName} is mindbroken, ${his} speech rules have been set to restrictive.`; + message(`Since ${slave.slaveName} is mindbroken, ${his} speech rules have been set to restrictive.`, sourceRecord.speechRules); } } else if (slave.accent === 4) { if ((rule.speechRules === "accent elimination" || rule.speechRules === "permissive") && slave.rules.speech !== "language lessons") { slave.rules.speech = "language lessons"; - r += `<br>Since ${slave.slaveName} does not know how to talk, ${his} speech rules have been set to language learning.`; + message(`Since ${slave.slaveName} does not know how to talk, ${his} speech rules have been set to language learning.`, sourceRecord.speechRules); } else if (slave.rules.speech !== "language lessons" && slave.rules.speech !== "restrictive") { slave.rules.speech = "restrictive"; - r += `<br>Since ${slave.slaveName} does not know how to talk, ${his} speech rules have been set to restrictive.`; + message(`Since ${slave.slaveName} does not know how to talk, ${his} speech rules have been set to restrictive.`, sourceRecord.speechRules); } } else if (rule.speechRules === "accent elimination") { if (slave.accent > 0) { slave.rules.speech = "accent elimination"; - r += `<br>${slave.slaveName}'s speech rules have been set to ${rule.speechRules}.`; + message(`${slave.slaveName}'s speech rules have been set to ${rule.speechRules}.`, sourceRecord.speechRules); } else { slave.rules.speech = "restrictive"; - r += `<br>Since ${slave.slaveName} has no accent, ${his} speech rules have been set to restrictive.`; + message(`Since ${slave.slaveName} has no accent, ${his} speech rules have been set to restrictive.`, sourceRecord.speechRules); } } else if (slave.rules.speech !== rule.speechRules) { slave.rules.speech = rule.speechRules; - r += `<br>${slave.slaveName}'s speech rules have been set to ${rule.speechRules}.`; + message(`${slave.slaveName}'s speech rules have been set to ${rule.speechRules}.`, sourceRecord.speechRules); } } } @@ -1966,7 +1970,7 @@ globalThis.DefaultRules = function(slave) { if ((rule.relationshipRules !== undefined) && (rule.relationshipRules !== null)) { if (slave.rules.relationship !== rule.relationshipRules) { slave.rules.relationship = rule.relationshipRules; - r += `<br>${slave.slaveName}'s relationship rules have been set to ${rule.relationshipRules}.`; + message(`${slave.slaveName}'s relationship rules have been set to ${rule.relationshipRules}.`, sourceRecord.relationshipRules); } } } @@ -1985,21 +1989,24 @@ globalThis.DefaultRules = function(slave) { 'slaves', 'master', ]; - if ((rule.releaseRules !== undefined) && (rule.releaseRules !== null) && processReleaseProp(releaseProperties)) { - r += `<br>${slave.slaveName}'s release rules have been set to: ${App.Utils.releaseSummaryLong(slave)}.`; + if ((rule.releaseRules !== undefined) && (rule.releaseRules !== null)) { + const source = processReleaseProp(releaseProperties); + if (source !== "") { + message(`${slave.slaveName}'s release rules have been set to: ${App.Utils.releaseSummaryLong(slave)}.`, source); + } } function processReleaseProp(releaseProperties) { - let changed = false; + let source = ""; for (const property of releaseProperties) { if (rule.releaseRules[property] !== undefined && rule.releaseRules[property] !== null) { if (slave.rules.release[property] !== rule.releaseRules[property]) { slave.rules.release[property] = rule.releaseRules[property]; - changed = true; + source = sourceRecord.releaseRules[property]; } } } - return changed; + return source; } } @@ -2012,7 +2019,7 @@ globalThis.DefaultRules = function(slave) { if (slave.rules.lactation !== rule.lactationRules) { if ((rule.lactationRules === "induce" && slave.lactation === 0) || (rule.lactationRules === "maintain" && slave.lactation === 1) || (rule.lactationRules === "none")) { slave.rules.lactation = rule.lactationRules; - r += `<br>${slave.slaveName}'s lactation rules have been set to ${rule.lactationRules}.`; + message(`${slave.slaveName}'s lactation rules have been set to ${rule.lactationRules}.`, sourceRecord.lactationRules); } } } @@ -2026,7 +2033,7 @@ globalThis.DefaultRules = function(slave) { if ((rule.mobilityRules !== undefined) && (rule.mobilityRules !== null)) { if (slave.rules.mobility !== rule.mobilityRules) { slave.rules.mobility = rule.mobilityRules; - r += `<br>${slave.slaveName}'s usage of mobility aids has been set to ${rule.mobilityRules}.`; + message(`${slave.slaveName}'s usage of mobility aids has been set to ${rule.mobilityRules}.`, sourceRecord.mobilityRules); } } } @@ -2039,7 +2046,7 @@ globalThis.DefaultRules = function(slave) { if ((rule.standardPunishment !== undefined) && (rule.standardPunishment !== null)) { if (slave.rules.punishment !== rule.standardPunishment) { slave.rules.punishment = rule.standardPunishment; - r += `<br>${slave.slaveName}'s typical punishment has been updated to ${rule.standardPunishment}.`; + message(`${slave.slaveName}'s typical punishment has been updated to ${rule.standardPunishment}.`, sourceRecord.standardPunishment); } } } @@ -2052,7 +2059,7 @@ globalThis.DefaultRules = function(slave) { if ((rule.standardReward !== undefined) && (rule.standardReward !== null)) { if (slave.rules.reward !== rule.standardReward) { slave.rules.reward = rule.standardReward; - r += `<br>${slave.slaveName}'s typical reward has been updated to ${rule.standardReward}.`; + message(`${slave.slaveName}'s typical reward has been updated to ${rule.standardReward}.`, sourceRecord.standardReward); } } } @@ -2066,30 +2073,30 @@ globalThis.DefaultRules = function(slave) { if (rule.toyHole === "pussy") { if (slave.vagina > 0 && canDoVaginal(slave)) { slave.toyHole = rule.toyHole; - r += `<br>${slave.slaveName} has been instructed to use ${his} ${rule.toyHole} to please you.`; + message(`${slave.slaveName} has been instructed to use ${his} ${rule.toyHole} to please you.`, sourceRecord.toyHole); } else if (slave.toyHole !== "all her holes") { slave.toyHole = "all her holes"; - r += `<br>${slave.slaveName}'s hole preference has defaulted to all ${his} holes.`; + message(`${slave.slaveName}'s hole preference has defaulted to all ${his} holes.`, sourceRecord.toyHole); } } else if (rule.toyHole === "ass") { if (slave.anus > 0 && canDoAnal(slave)) { slave.toyHole = rule.toyHole; - r += `<br>${slave.slaveName} has been instructed to use ${his} ${rule.toyHole} to please you.`; + message(`${slave.slaveName} has been instructed to use ${his} ${rule.toyHole} to please you.`, sourceRecord.toyHole); } else if (slave.toyHole !== "all her holes") { slave.toyHole = "all her holes"; - r += `<br>${slave.slaveName}'s hole preference has defaulted to all ${his} holes.`; + message(`${slave.slaveName}'s hole preference has defaulted to all ${his} holes.`, sourceRecord.toyHole); } } else if (rule.toyHole === "dick") { if (slave.dick > 0 && canPenetrate(slave)) { slave.toyHole = rule.toyHole; - r += `<br>${slave.slaveName} has been instructed to use ${his} ${rule.toyHole} to please you.`; + message(`${slave.slaveName} has been instructed to use ${his} ${rule.toyHole} to please you.`, sourceRecord.toyHole); } else if (slave.toyHole !== "all her holes") { slave.toyHole = "all her holes"; - r += `<br>${slave.slaveName}'s hole preference has defaulted to all ${his} holes.`; + message(`${slave.slaveName}'s hole preference has defaulted to all ${his} holes.`, sourceRecord.toyHole); } } else { slave.toyHole = rule.toyHole; - r += `<br>${slave.slaveName} has been instructed to use ${his} ${rule.toyHole} to please you.`; + message(`${slave.slaveName} has been instructed to use ${his} ${rule.toyHole} to please you.`, sourceRecord.toyHole); } } } @@ -2103,12 +2110,12 @@ globalThis.DefaultRules = function(slave) { if (slave.dietCum !== rule.dietCum) { slave.dietCum = rule.dietCum; if (slave.dietCum === 2) { - r += `<br>${slave.slaveName} has been put on a diet based on cum.`; + message(`${slave.slaveName} has been put on a diet based on cum.`, sourceRecord.dietCum); slave.dietMilk = 0; } else if (slave.dietCum === 1) { - r += `<br>${slave.slaveName} has had cum added to ${his} diet.`; + message(`${slave.slaveName} has had cum added to ${his} diet.`, sourceRecord.dietCum); } else { - r += `<br>${slave.slaveName} has had cum removed from ${his} diet.`; + message(`${slave.slaveName} has had cum removed from ${his} diet.`, sourceRecord.dietCum); } } } @@ -2123,12 +2130,12 @@ globalThis.DefaultRules = function(slave) { if (slave.dietMilk !== rule.dietMilk) { slave.dietMilk = rule.dietMilk; if (slave.dietMilk === 2) { - r += `<br>${slave.slaveName} has been put on a diet based on human milk.`; + message(`${slave.slaveName} has been put on a diet based on human milk.`, sourceRecord.dietMilk); slave.dietCum = 0; } else if (slave.dietMilk === 1) { - r += `<br>${slave.slaveName} has had human milk added to ${his} diet.`; + message(`${slave.slaveName} has had human milk added to ${his} diet.`, sourceRecord.dietMilk); } else { - r += `<br>${slave.slaveName} has had human milk removed from ${his} diet.`; + message(`${slave.slaveName} has had human milk removed from ${his} diet.`, sourceRecord.dietMilk); } } } @@ -2143,9 +2150,9 @@ globalThis.DefaultRules = function(slave) { if (slave.onDiet !== rule.onDiet) { slave.onDiet = rule.onDiet; if (slave.onDiet === 1) { - r += `<br>${slave.slaveName} is not permitted to eat the solid slave food.`; + message(`${slave.slaveName} is not permitted to eat the solid slave food.`, sourceRecord.onDiet); } else { - r += `<br>${slave.slaveName} is permitted to eat the solid slave food.`; + message(`${slave.slaveName} is permitted to eat the solid slave food.`, sourceRecord.onDiet); } } } @@ -2161,36 +2168,36 @@ globalThis.DefaultRules = function(slave) { if (slave.teeth === "crooked") { slave.teeth = "straightening braces"; cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - r += `<br>${slave.slaveName} has been given braces for ${his} crooked teeth.`; + message(`${slave.slaveName} has been given braces for ${his} crooked teeth.`, sourceRecord.teeth); } else if (slave.teeth === "gapped") { slave.teeth = "straightening braces"; cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - r += `<br>${slave.slaveName} has been given braces to close the gap in ${his} teeth.`; + message(`${slave.slaveName} has been given braces to close the gap in ${his} teeth.`, sourceRecord.teeth); } else if (slave.teeth === "normal") { slave.teeth = "cosmetic braces"; cashX(forceNeg(V.modCost), "slaveSurgery", slave); - r += `<br>${slave.slaveName} has been given cosmetic braces.`; + message(`${slave.slaveName} has been given cosmetic braces.`, sourceRecord.teeth); } } else if (rule.teeth === "straighten") { if (slave.teeth === "crooked") { slave.teeth = "straightening braces"; cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - r += `<br>${slave.slaveName} has been given braces for ${his} crooked teeth.`; + message(`${slave.slaveName} has been given braces for ${his} crooked teeth.`, sourceRecord.teeth); } else if (slave.teeth === "gapped") { slave.teeth = "straightening braces"; cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); - r += `<br>${slave.slaveName} has been given braces to close the gap in ${his} teeth.`; + message(`${slave.slaveName} has been given braces to close the gap in ${his} teeth.`, sourceRecord.teeth); } else if (slave.teeth === "cosmetic braces") { slave.teeth = "normal"; - r += `<br>${slave.slaveName} has had ${his} braces removed, since ${his} teeth are straight.`; + message(`${slave.slaveName} has had ${his} braces removed, since ${his} teeth are straight.`, sourceRecord.teeth); } } else if (rule.teeth === "none") { if (slave.teeth === "straightening braces") { slave.teeth = "crooked"; - r += `<br>${slave.slaveName} has had ${his} braces removed.`; + message(`${slave.slaveName} has had ${his} braces removed.`, sourceRecord.teeth); } else if (slave.teeth === "cosmetic braces") { slave.teeth = "normal"; - r += `<br>${slave.slaveName} has had ${his} braces removed.`; + message(`${slave.slaveName} has had ${his} braces removed.`, sourceRecord.teeth); } } } @@ -2268,7 +2275,7 @@ globalThis.DefaultRules = function(slave) { } } const lens = toSentence(lensDesc); - r += `<br>${slave.slaveName} has been given ${hasBothEyes(slave) ? `contact lenses` : `a contact lens`} with ${lens}.`; + message(`${slave.slaveName} has been given ${hasBothEyes(slave) ? `contact lenses` : `a contact lens`} with ${lens}.`, [sourceRecord.iris, sourceRecord.pupil, sourceRecord.sclera]); } } @@ -2283,7 +2290,7 @@ globalThis.DefaultRules = function(slave) { if (slave.makeup !== rule.makeup) { slave.makeup = rule.makeup; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName} has been assigned the standard makeup.`; + message(`${slave.slaveName} has been assigned the standard makeup.`, sourceRecord.makeup); } } @@ -2292,7 +2299,7 @@ globalThis.DefaultRules = function(slave) { if (slave.nails !== rule.nails) { slave.nails = rule.nails; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName} has been assigned the standard nails.`; + message(`${slave.slaveName} has been assigned the standard nails.`, sourceRecord.nails); } } } @@ -2302,7 +2309,7 @@ globalThis.DefaultRules = function(slave) { if (slave.hColor !== rule.hColor) { slave.hColor = rule.hColor; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s hair has been dyed ${rule.hColor}.`; + message(`${slave.slaveName}'s hair has been dyed ${rule.hColor}.`, sourceRecord.hColor); } } } @@ -2312,7 +2319,7 @@ globalThis.DefaultRules = function(slave) { if (slave.hornColor !== rule.hornColor) { slave.hornColor = rule.hornColor; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s horns has been dyed ${rule.hornColor}.`; + message(`${slave.slaveName}'s horns has been dyed ${rule.hornColor}.`, sourceRecord.hornColor); } } } @@ -2324,20 +2331,20 @@ globalThis.DefaultRules = function(slave) { cashX(forceNeg(V.modCost), "slaveMod", slave); if (rule.hStyle === "shaved") { slave.hLength = 0; - r += `<br>${slave.slaveName}'s hair has been shaved.`; + message(`${slave.slaveName}'s hair has been shaved.`, sourceRecord.hStyle); } else { - r += `<br>${slave.slaveName}'s hair has been restyled`; + let m = `${slave.slaveName}'s hair has been restyled`; // Cut hair if needed for (const style of App.Medicine.Modification.hairStyles.Cut) { if (style.value === rule.hStyle) { if (slave.hLength > style.hLength) { slave.hLength = style.hLength; - r += ` and shortened`; + m += ` and shortened`; } break; } } - r += `.`; + message(`${m}.`, sourceRecord.hStyle); } } } @@ -2348,10 +2355,10 @@ globalThis.DefaultRules = function(slave) { if (slave.hLength !== rule.hLength) { if (slave.hLength > rule.hLength) { cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s hair has been cut; it `; + message(`${slave.slaveName}'s hair has been cut; it `, sourceRecord.hLength); } else { cashX(forceNeg(V.modCost * Math.trunc((rule.hLength - slave.hLength) / 10)), "slaveMod", slave); - r += `<br>${slave.slaveName} has been given extensions; ${his} hair `; + message(`${slave.slaveName} has been given extensions; ${his} hair `, sourceRecord.hLength); } r += `is now ${lengthToEitherUnit(rule.hLength)} long.`; slave.hLength = rule.hLength; @@ -2362,10 +2369,10 @@ globalThis.DefaultRules = function(slave) { if (rule.haircuts !== undefined && (rule.haircuts !== null)) { if (slave.bald !== 1) { if (rule.haircuts === 1 && slave.haircuts !== 1) { - r += `<br>${slave.slaveName}'s hair will now be maintained at ${lengthToEitherUnit(slave.hLength)} long.`; + message(`${slave.slaveName}'s hair will now be maintained at ${lengthToEitherUnit(slave.hLength)} long.`, sourceRecord.haircuts); slave.haircuts = 1; } else if (rule.haircuts === 0 && slave.haircuts !== 0) { - r += `<br>${slave.slaveName}'s hair length will no longer be maintained.`; + message(`${slave.slaveName}'s hair length will no longer be maintained.`, sourceRecord.haircuts); slave.haircuts = 0; } } @@ -2376,7 +2383,7 @@ globalThis.DefaultRules = function(slave) { if (slave.eyebrowHColor !== rule.eyebrowHColor) { slave.eyebrowHColor = rule.eyebrowHColor; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s eyebrow hair, if present, has been dyed ${rule.eyebrowHColor}.`; + message(`${slave.slaveName}'s eyebrow hair, if present, has been dyed ${rule.eyebrowHColor}.`, sourceRecord.eyebrowHColor); } } } @@ -2386,7 +2393,7 @@ globalThis.DefaultRules = function(slave) { if (slave.eyebrowHStyle !== rule.eyebrowHStyle) { slave.eyebrowHStyle = rule.eyebrowHStyle; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s eyebrow hair has been restyled; they are now ${rule.eyebrowHStyle}.`; + message(`${slave.slaveName}'s eyebrow hair has been restyled; they are now ${rule.eyebrowHStyle}.`, sourceRecord.eyebrowHStyle); } } } @@ -2396,7 +2403,7 @@ globalThis.DefaultRules = function(slave) { if (slave.eyebrowFullness !== rule.eyebrowFullness) { slave.eyebrowFullness = rule.eyebrowFullness; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s eyebrow hair thickness has been adjusted; they are now ${rule.eyebrowFullness}.`; + message(`${slave.slaveName}'s eyebrow hair thickness has been adjusted; they are now ${rule.eyebrowFullness}.`, sourceRecord.eyebrowFullness); } } } @@ -2406,7 +2413,7 @@ globalThis.DefaultRules = function(slave) { if (slave.pubicHColor !== rule.pubicHColor) { slave.pubicHColor = rule.pubicHColor; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s pubic hair, if present, has been dyed ${rule.pubicHColor}.`; + message(`${slave.slaveName}'s pubic hair, if present, has been dyed ${rule.pubicHColor}.`, sourceRecord.pubicHColor); } } } @@ -2416,7 +2423,7 @@ globalThis.DefaultRules = function(slave) { if (slave.pubicHStyle !== rule.pubicHStyle) { slave.pubicHStyle = rule.pubicHStyle; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s pubic hair has been restyled; it is now ${rule.pubicHStyle}.`; + message(`${slave.slaveName}'s pubic hair has been restyled; it is now ${rule.pubicHStyle}.`, sourceRecord.pubicHStyle); } } } @@ -2426,7 +2433,7 @@ globalThis.DefaultRules = function(slave) { if (slave.underArmHColor !== rule.underArmHColor) { slave.underArmHColor = rule.underArmHColor; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s underarm hair, if present, has been dyed ${rule.underArmHColor}.`; + message(`${slave.slaveName}'s underarm hair, if present, has been dyed ${rule.underArmHColor}.`, sourceRecord.underArmHColor); } } } @@ -2436,7 +2443,7 @@ globalThis.DefaultRules = function(slave) { if (slave.underArmHStyle !== rule.underArmHStyle) { slave.underArmHStyle = rule.underArmHStyle; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s underarm hair has been restyled; it is now ${rule.underArmHStyle}.`; + message(`${slave.slaveName}'s underarm hair has been restyled; it is now ${rule.underArmHStyle}.`, sourceRecord.underArmHStyle); } } } @@ -2446,7 +2453,7 @@ globalThis.DefaultRules = function(slave) { if (slave.eyebrowHColor !== rule.eyebrowHColor) { slave.eyebrowHColor = rule.eyebrowHColor; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s eyebrow hair, if present, has been dyed ${rule.eyebrowHColor}.`; + message(`${slave.slaveName}'s eyebrow hair, if present, has been dyed ${rule.eyebrowHColor}.`, sourceRecord.eyebrowHColor); } } } @@ -2456,7 +2463,7 @@ globalThis.DefaultRules = function(slave) { if (slave.eyebrowHStyle !== rule.eyebrowHStyle) { slave.eyebrowHStyle = rule.eyebrowHStyle; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s eyebrow hair has been restyled; it is now ${rule.eyebrowHStyle}.`; + message(`${slave.slaveName}'s eyebrow hair has been restyled; it is now ${rule.eyebrowHStyle}.`, sourceRecord.eyebrowHStyle); } } } @@ -2466,19 +2473,19 @@ globalThis.DefaultRules = function(slave) { if (slave.eyebrowFullness !== rule.eyebrowFullness) { slave.eyebrowFullness = rule.eyebrowFullness; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s eyebrow hair has been reshaped; it is now ${rule.eyebrowFullness}.`; + message(`${slave.slaveName}'s eyebrow hair has been reshaped; it is now ${rule.eyebrowFullness}.`, sourceRecord.eyebrowFullness); } } } if (rule.markings !== undefined && (rule.markings !== null)) { if (slave.markings === "beauty mark" && (rule.markings === "remove beauty marks" || rule.markings === "remove both")) { - r += `<br>${slave.slaveName}'s beauty mark has been removed.`; + message(`${slave.slaveName}'s beauty mark has been removed.`, sourceRecord.markings); slave.markings = "none"; cashX(forceNeg(V.modCost), "slaveMod", slave); } if (slave.markings === "birthmark" && (rule.markings === "remove birthmarks" || rule.markings === "remove both")) { - r += `<br>${slave.slaveName}'s birthmark has been bleached away.`; + message(`${slave.slaveName}'s birthmark has been bleached away.`, sourceRecord.markings); cashX(forceNeg(V.modCost), "slaveMod", slave); slave.markings = "none"; } @@ -2488,11 +2495,11 @@ globalThis.DefaultRules = function(slave) { if (rule.skinColor === "natural") { if (slave.skin !== slave.origSkin) { slave.skin = slave.origSkin; - r += `<br>${slave.slaveName}'s skin color has been returned to ${slave.origSkin}.`; + message(`${slave.slaveName}'s skin color has been returned to ${slave.origSkin}.`, sourceRecord.skinColor); } } else { slave.skin = rule.skinColor; - r += `<br>${slave.slaveName}'s skin color has been set to ${rule.skinColor}.`; + message(`${slave.slaveName}'s skin color has been set to ${rule.skinColor}.`, sourceRecord.skinColor); } } } @@ -2506,13 +2513,13 @@ globalThis.DefaultRules = function(slave) { if (slave.piercing.nipple.weight !== rule.piercing.nipple.weight) { if (rule.piercing.nipple.weight === 0) { slave.piercing.nipple.weight = 0; - r += `<br>${slave.slaveName}'s nipple piercings have been removed.`; + message(`${slave.slaveName}'s nipple piercings have been removed.`, sourceRecord.piercing.nipple.weight); } else if (slave.nipples !== "fuckable") { slave.piercing.nipple.weight = rule.piercing.nipple.weight; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s nipples have been pierced.`; + message(`${slave.slaveName}'s nipples have been pierced.`, sourceRecord.piercing.nipple.weight); } else { - r += `<br>${slave.slaveName}'s nipples are inverted and cannot be pierced.`; + message(`${slave.slaveName}'s nipples are inverted and cannot be pierced.`, sourceRecord.piercing.nipple.weight); } } } @@ -2521,11 +2528,11 @@ globalThis.DefaultRules = function(slave) { if (slave.piercing.areola.weight !== rule.piercing.areola.weight) { if (rule.piercing.areola.weight === 0) { slave.piercing.areola.weight = 0; - r += `<br>${slave.slaveName}'s areolae piercings have been removed.`; + message(`${slave.slaveName}'s areolae piercings have been removed.`, sourceRecord.piercing.areola.weight); } else { slave.piercing.areola.weight = rule.piercing.areola.weight; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s areolae have been given stud piercings.`; + message(`${slave.slaveName}'s areolae have been given stud piercings.`, sourceRecord.piercing.areola.weight); } } } @@ -2536,17 +2543,17 @@ globalThis.DefaultRules = function(slave) { slave.piercing.genitals.weight = 0; slave.piercing.genitals.smart = false; if (slave.dick > 0) { - r += `<br>${slave.slaveName}'s frenulum piercing has been removed.`; + message(`${slave.slaveName}'s frenulum piercing has been removed.`, sourceRecord.piercing.genitals.weight); } else { - r += `<br>${slave.slaveName}'s clit piercing has been removed.`; + message(`${slave.slaveName}'s clit piercing has been removed.`, sourceRecord.piercing.genitals.weight); } } else if ((slave.vagina !== -1) || (slave.dick !== 0)) { slave.piercing.genitals.weight = rule.piercing.genitals.weight; cashX(forceNeg(V.SPcost), "slaveMod", slave); if (slave.dick > 0) { - r += `<br>${slave.slaveName}'s frenulum has been pierced.`; + message(`${slave.slaveName}'s frenulum has been pierced.`, sourceRecord.piercing.genitals.weight); } else { - r += `<br>${slave.slaveName}'s clit has been pierced.`; + message(`${slave.slaveName}'s clit has been pierced.`, sourceRecord.piercing.genitals.weight); } } } @@ -2557,11 +2564,11 @@ globalThis.DefaultRules = function(slave) { if (slave.piercing.vagina.weight !== rule.piercing.vagina.weight) { if (rule.piercing.vagina.weight === 0) { slave.piercing.vagina.weight = 0; - r += `<br>${slave.slaveName}'s labia piercings have been removed.`; + message(`${slave.slaveName}'s labia piercings have been removed.`, sourceRecord.piercing.vagina.weight); } else { slave.piercing.vagina.weight = rule.piercing.vagina.weight; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s pussylips have been pierced.`; + message(`${slave.slaveName}'s pussylips have been pierced.`, sourceRecord.piercing.vagina.weight); } } } @@ -2572,11 +2579,11 @@ globalThis.DefaultRules = function(slave) { if (slave.piercing.dick.weight !== rule.piercing.dick.weight) { if (rule.piercing.dick.weight === 0) { slave.piercing.dick.weight = 0; - r += `<br>${slave.slaveName}'s shaft piercings have been removed.`; + message(`${slave.slaveName}'s shaft piercings have been removed.`, sourceRecord.piercing.dick.weight); } else { slave.piercing.dick.weight = rule.piercing.dick.weight; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s shaft has been pierced.`; + message(`${slave.slaveName}'s shaft has been pierced.`, sourceRecord.piercing.dick.weight); } } } @@ -2587,12 +2594,12 @@ globalThis.DefaultRules = function(slave) { if (rule.piercing.genitals.smart === false) { slave.piercing.genitals.smart = false; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s ${slave.dick > 0 ? "frenulum" : "clit"} piercing's smart vibe capability has been removed.`; + message(`${slave.slaveName}'s ${slave.dick > 0 ? "frenulum" : "clit"} piercing's smart vibe capability has been removed.`, sourceRecord.piercing.genitals.smart); } else if (slave.piercing.genitals.weight) { slave.piercing.genitals.smart = true; cashX(forceNeg(V.SPcost), "slaveMod", slave); slave.clitSetting = "all"; - r += `<br>${slave.slaveName}'s ${slave.dick > 0 ? "frenulum" : "clit"} piercing has been upgraded with smart vibe functionality.`; + message(`${slave.slaveName}'s ${slave.dick > 0 ? "frenulum" : "clit"} piercing has been upgraded with smart vibe functionality.`, sourceRecord.piercing.genitals.smart); } } } @@ -2601,11 +2608,11 @@ globalThis.DefaultRules = function(slave) { if (slave.piercing.anus.weight !== rule.piercing.anus.weight) { if (rule.piercing.anus.weight === 0) { slave.piercing.anus.weight = 0; - r += `<br>${slave.slaveName}'s asshole piercings have been removed.`; + message(`${slave.slaveName}'s asshole piercings have been removed.`, sourceRecord.piercing.anus.weight); } else { slave.piercing.anus.weight = rule.piercing.anus.weight; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s asshole has been pierced.`; + message(`${slave.slaveName}'s asshole has been pierced.`, sourceRecord.piercing.anus.weight); } } } @@ -2614,11 +2621,11 @@ globalThis.DefaultRules = function(slave) { if (slave.piercing.lips.weight !== rule.piercing.lips.weight) { if (rule.piercing.lips.weight === 0) { slave.piercing.lips.weight = 0; - r += `<br>${slave.slaveName}'s lip piercings have been removed.`; + message(`${slave.slaveName}'s lip piercings have been removed.`, sourceRecord.piercing.lips.weight); } else { slave.piercing.lips.weight = rule.piercing.lips.weight; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s lips have been pierced.`; + message(`${slave.slaveName}'s lips have been pierced.`, sourceRecord.piercing.lips.weight); } } } @@ -2627,11 +2634,11 @@ globalThis.DefaultRules = function(slave) { if (slave.piercing.tongue.weight !== rule.piercing.tongue.weight) { if (rule.piercing.tongue.weight === 0) { slave.piercing.tongue.weight = 0; - r += `<br>${slave.slaveName}'s tongue piercings have been removed.`; + message(`${slave.slaveName}'s tongue piercings have been removed.`, sourceRecord.piercing.tongue.weight); } else { slave.piercing.tongue.weight = rule.piercing.tongue.weight; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s tongue has been pierced.`; + message(`${slave.slaveName}'s tongue has been pierced.`, sourceRecord.piercing.tongue.weight); } } } @@ -2640,11 +2647,11 @@ globalThis.DefaultRules = function(slave) { if (slave.piercing.ear.weight !== rule.piercing.ear.weight) { if (rule.piercing.ear.weight === 0) { slave.piercing.ear.weight = 0; - r += `<br>${slave.slaveName}'s ear piercings have been removed.`; + message(`${slave.slaveName}'s ear piercings have been removed.`, sourceRecord.piercing.ear.weight); } else { slave.piercing.ear.weight = rule.piercing.ear.weight; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s ears have been pierced.`; + message(`${slave.slaveName}'s ears have been pierced.`, sourceRecord.piercing.ear.weight); } } } @@ -2653,11 +2660,11 @@ globalThis.DefaultRules = function(slave) { if (slave.piercing.nose.weight !== rule.piercing.nose.weight) { if (rule.piercing.nose.weight === 0) { slave.piercing.nose.weight = 0; - r += `<br>${slave.slaveName}'s nose piercing has been removed.`; + message(`${slave.slaveName}'s nose piercing has been removed.`, sourceRecord.piercing.nose.weight); } else { slave.piercing.nose.weight = rule.piercing.nose.weight; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s nose has been pierced.`; + message(`${slave.slaveName}'s nose has been pierced.`, sourceRecord.piercing.nose.weight); } } } @@ -2666,11 +2673,11 @@ globalThis.DefaultRules = function(slave) { if (slave.piercing.eyebrow.weight !== rule.piercing.eyebrow.weight) { if (rule.piercing.eyebrow.weight === 0) { slave.piercing.eyebrow.weight = 0; - r += `<br>${slave.slaveName}'s eyebrow piercings have been removed.`; + message(`${slave.slaveName}'s eyebrow piercings have been removed.`, sourceRecord.piercing.eyebrow.weight); } else { slave.piercing.eyebrow.weight = rule.piercing.eyebrow.weight; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s eyebrows have been pierced.`; + message(`${slave.slaveName}'s eyebrows have been pierced.`, sourceRecord.piercing.eyebrow.weight); } } } @@ -2679,11 +2686,11 @@ globalThis.DefaultRules = function(slave) { if (slave.piercing.navel.weight !== rule.piercing.navel.weight) { if (rule.piercing.navel.weight === 0) { slave.piercing.navel.weight = 0; - r += `<br>${slave.slaveName}'s navel piercing have been removed.`; + message(`${slave.slaveName}'s navel piercing have been removed.`, sourceRecord.piercing.navel.weight); } else { slave.piercing.navel.weight = rule.piercing.navel.weight; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s navel has been pierced.`; + message(`${slave.slaveName}'s navel has been pierced.`, sourceRecord.piercing.navel.weight); } } } @@ -2692,11 +2699,11 @@ globalThis.DefaultRules = function(slave) { if (slave.piercing.corset.weight !== rule.piercing.corset.weight) { if (rule.piercing.corset.weight === 0) { slave.piercing.corset.weight = 0; - r += `<br>${slave.slaveName}'s corset piercings have been removed.`; + message(`${slave.slaveName}'s corset piercings have been removed.`, sourceRecord.piercing.corset.weight); } else { slave.piercing.corset.weight = rule.piercing.corset.weight; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName} has been given a set of corset piercings.`; + message(`${slave.slaveName} has been given a set of corset piercings.`, sourceRecord.piercing.corset.weight); } } } @@ -2706,9 +2713,9 @@ globalThis.DefaultRules = function(slave) { if (rule.piercing[p].desc !== undefined && (rule.piercing[p].desc !== null)) { if (slave.piercing[p].desc !== rule.piercing[p].desc) { if (rule.piercing[p].desc === "") { - r += `<br>${slave.slaveName}'s ${p} piercings will use the default design.`; + message(`${slave.slaveName}'s ${p} piercings will use the default design.`, sourceRecord.piercing[p].desc); } else { - r += `<br>${slave.slaveName}'s ${p} piercings have been updated to a different design.`; + message(`${slave.slaveName}'s ${p} piercings have been updated to a different design.`, sourceRecord.piercing[p].desc); } slave.piercing[p].desc = rule.piercing[p].desc; } @@ -2735,7 +2742,7 @@ globalThis.DefaultRules = function(slave) { // Set the smart thingy to the correct fetish if (slave.clitSetting !== fetish) { slave.clitSetting = fetish; - r += `<br>${slave.slaveName}'s ${smartThing} has been set to ${slave.clitSetting}.`; + message(`${slave.slaveName}'s ${smartThing} has been set to ${slave.clitSetting}.`, sourceRecord.clitSetting); } // We haven't reached full fetish yet, don't allow changing to something else return; @@ -2744,13 +2751,13 @@ globalThis.DefaultRules = function(slave) { if (rule.clitSettingEnergy !== undefined && (rule.clitSettingEnergy !== null)) { if (slave.energy < rule.clitSettingEnergy) { if (slave.clitSetting !== "all") { - r += `<br>${slave.slaveName}'s ${smartThing} has been set to enhance libido.`; + message(`${slave.slaveName}'s ${smartThing} has been set to enhance libido.`, sourceRecord.clitSettingEnergy); } slave.clitSetting = "all"; return; } else if (slave.energy >= rule.clitSettingEnergy + 10 && rule.clitSettingEnergy <= 90) { if (slave.clitSetting !== "none") { - r += `<br>${slave.slaveName}'s ${smartThing} has been set to suppress libido.`; + message(`${slave.slaveName}'s ${smartThing} has been set to suppress libido.`, sourceRecord.clitSettingEnergy); } slave.clitSetting = "none"; return; @@ -2759,13 +2766,13 @@ globalThis.DefaultRules = function(slave) { if (rule.clitSettingXY !== undefined && (rule.clitSettingXY !== null)) { if (slave.attrXY < rule.clitSettingXY) { if (slave.clitSetting !== "men") { - r += `<br>${slave.slaveName}'s ${smartThing} has been set to encourage attraction to men.`; + message(`${slave.slaveName}'s ${smartThing} has been set to encourage attraction to men.`, sourceRecord.clitSettingXY); } slave.clitSetting = "men"; return; } else if (slave.attrXY >= rule.clitSettingXY + 10 && rule.clitSettingXY <= 90) { if (slave.clitSetting !== "anti-men") { - r += `<br>${slave.slaveName}'s ${smartThing} has been set to discourage attraction to men.`; + message(`${slave.slaveName}'s ${smartThing} has been set to discourage attraction to men.`, sourceRecord.clitSettingXY); } slave.clitSetting = "anti-men"; return; @@ -2774,13 +2781,13 @@ globalThis.DefaultRules = function(slave) { if (rule.clitSettingXX !== undefined && (rule.clitSettingXX !== null)) { if (slave.attrXX < rule.clitSettingXX) { if (slave.clitSetting !== "women") { - r += `<br>${slave.slaveName}'s ${smartThing} has been set to encourage attraction to women.`; + message(`${slave.slaveName}'s ${smartThing} has been set to encourage attraction to women.`, sourceRecord.clitSettingXX); } slave.clitSetting = "women"; return; } else if (slave.attrXX >= rule.clitSettingXX + 10 && rule.clitSettingXX <= 90) { if (slave.clitSetting !== "anti-women") { - r += `<br>${slave.slaveName}'s ${smartThing} has been set to discourage attraction to women.`; + message(`${slave.slaveName}'s ${smartThing} has been set to discourage attraction to women.`, sourceRecord.clitSettingXX); } slave.clitSetting = "anti-women"; return; @@ -2798,7 +2805,7 @@ globalThis.DefaultRules = function(slave) { if (slave.boobsTat !== rule.boobsTat) { slave.boobsTat = rule.boobsTat; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s chest has been tattooed.`; + message(`${slave.slaveName}'s chest has been tattooed.`, sourceRecord.boobsTat); } } @@ -2806,7 +2813,7 @@ globalThis.DefaultRules = function(slave) { if (slave.buttTat !== rule.buttTat) { slave.buttTat = rule.buttTat; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s butt has been tattooed.`; + message(`${slave.slaveName}'s butt has been tattooed.`, sourceRecord.buttTat); } } @@ -2814,7 +2821,7 @@ globalThis.DefaultRules = function(slave) { if (slave.vaginaTat !== rule.vaginaTat) { slave.vaginaTat = rule.vaginaTat; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s abdomen has been tattooed.`; + message(`${slave.slaveName}'s abdomen has been tattooed.`, sourceRecord.vaginaTat); } } @@ -2823,7 +2830,7 @@ globalThis.DefaultRules = function(slave) { if (slave.dickTat !== rule.dickTat) { slave.dickTat = rule.dickTat; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s dick has been tattooed.`; + message(`${slave.slaveName}'s dick has been tattooed.`, sourceRecord.dickTat); } } } @@ -2832,7 +2839,7 @@ globalThis.DefaultRules = function(slave) { if (slave.lipsTat !== rule.lipsTat) { slave.lipsTat = rule.lipsTat; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s face has been tattooed.`; + message(`${slave.slaveName}'s face has been tattooed.`, sourceRecord.lipsTat); } } @@ -2840,7 +2847,7 @@ globalThis.DefaultRules = function(slave) { if (slave.anusTat !== rule.anusTat) { slave.anusTat = rule.anusTat; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s asshole has been modded.`; + message(`${slave.slaveName}'s asshole has been modded.`, sourceRecord.anusTat); } } @@ -2848,7 +2855,7 @@ globalThis.DefaultRules = function(slave) { if (slave.backTat !== rule.backTat) { slave.backTat = rule.backTat; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s back has been tattooed.`; + message(`${slave.slaveName}'s back has been tattooed.`, sourceRecord.backTat); } } @@ -2856,21 +2863,21 @@ globalThis.DefaultRules = function(slave) { if (slave.shouldersTat !== rule.shouldersTat) { slave.shouldersTat = rule.shouldersTat; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s shoulders have been tattooed.`; + message(`${slave.slaveName}'s shoulders have been tattooed.`, sourceRecord.shouldersTat); } } if (rule.armsTat !== undefined && (rule.armsTat !== null)) { - if (slave.armsTat !== rule.armsTat) { + if (hasAnyArms(slave) && slave.armsTat !== rule.armsTat) { slave.armsTat = rule.armsTat; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s `; + let m = `${slave.slaveName}'s `; if (hasBothArms(slave)) { - r += `arms have`; + m += `arms have`; } else { - r += `arm has`; + m += `arm has`; } - r += ` been tattooed.`; + message(`${m} been tattooed.`, sourceRecord.armsTat); } } @@ -2878,7 +2885,7 @@ globalThis.DefaultRules = function(slave) { if (slave.legsTat !== rule.legsTat) { slave.legsTat = rule.legsTat; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s legs have been tattooed.`; + message(`${slave.slaveName}'s legs have been tattooed.`, sourceRecord.legsTat); } } @@ -2886,21 +2893,21 @@ globalThis.DefaultRules = function(slave) { if (slave.stampTat !== rule.stampTat) { slave.stampTat = rule.stampTat; cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s lower back has been tattooed.`; + message(`${slave.slaveName}'s lower back has been tattooed.`, sourceRecord.stampTat); } } if (rule.birthsTat !== undefined && (rule.birthsTat !== null)) { if (rule.birthsTat === "remove") { if (slave.birthsTat > 0) { cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s birth tallies have been removed.`; + message(`${slave.slaveName}'s birth tallies have been removed.`, sourceRecord.birthsTat); } else if (slave.birthsTat > -1) { - r += `<br>${slave.slaveName} will no longer be tattooed with each birth.`; + message(`${slave.slaveName} will no longer be tattooed with each birth.`, sourceRecord.birthsTat); } slave.birthsTat = -1; } else if (rule.birthsTat === "tally") { if (slave.birthsTat < 0) { - r += `<br>${slave.slaveName} will be tattooed with each birth.`; + message(`${slave.slaveName} will be tattooed with each birth.`, sourceRecord.birthsTat); slave.birthsTat = 0; } } @@ -2909,14 +2916,14 @@ globalThis.DefaultRules = function(slave) { if (rule.abortionTat === "remove") { if (slave.abortionTat > 0) { cashX(forceNeg(V.modCost), "slaveMod", slave); - r += `<br>${slave.slaveName}'s abortion tallies have been removed.`; + message(`${slave.slaveName}'s abortion tallies have been removed.`, sourceRecord.abortionTat); } else if (slave.abortionTat > -1) { - r += `<br>${slave.slaveName} will no longer be tattooed with each abortion and miscarriage.`; + message(`${slave.slaveName} will no longer be tattooed with each abortion and miscarriage.`, sourceRecord.abortionTat); } slave.abortionTat = -1; } else if (rule.abortionTat === "tally") { if (slave.abortionTat < 0) { - r += `<br>${slave.slaveName} will be tattooed with each abortion and miscarriage.`; + message(`${slave.slaveName} will be tattooed with each abortion and miscarriage.`, sourceRecord.abortionTat); slave.abortionTat = 0; } } @@ -3040,18 +3047,18 @@ globalThis.DefaultRules = function(slave) { // Apply brands: if (["left", "right", "anywhere"].includes(brandPlace)) { healthDamage(slave, 10); - r += `<br>${slave.slaveName} has been branded on the `; + let m = `${slave.slaveName} has been branded on the `; if (brandPlace === "left") { App.Medicine.Modification.addBrand(slave, left, rule.brandDesign); - r += `${left}`; + m += `${left}`; } else if (brandPlace === "right") { App.Medicine.Modification.addBrand(slave, right, rule.brandDesign); - r += `${right}`; + m += `${right}`; } else if (brandPlace === "anywhere") { App.Medicine.Modification.addBrand(slave, rule.brandTarget, rule.brandDesign); - r += `${rule.brandTarget}`; + m += `${rule.brandTarget}`; } - r += `, with <span class="trust dec">fear</span>${slave.devotion < 18 ? `, <span class="devotion dec">regard,</span>` : ``} and <span class="health dec">health</span> consequences.`; + message(`${m}, with <span class="trust dec">fear</span>${slave.devotion < 18 ? `, <span class="devotion dec">regard,</span>` : ``} and <span class="health dec">health</span> consequences.`, sourceRecord.brandDesign); if (slave.devotion < 18) { slave.devotion -= 5; } @@ -3060,7 +3067,7 @@ globalThis.DefaultRules = function(slave) { App.Medicine.Modification.addBrand(slave, left, rule.brandDesign); App.Medicine.Modification.addBrand(slave, right, rule.brandDesign); healthDamage(slave, 20); - r += `<br>${slave.slaveName} has been branded on both ${rule.brandTarget}, with <span class="trust dec">fear</span>${slave.devotion < 18 ? `, <span class="devotion dec">regard,</span>` : ``} and <span class="health dec">health</span> consequences.`; + message(`${slave.slaveName} has been branded on both ${rule.brandTarget}, with <span class="trust dec">fear</span>${slave.devotion < 18 ? `, <span class="devotion dec">regard,</span>` : ``} and <span class="health dec">health</span> consequences.`, sourceRecord.brandDesign); if (slave.devotion < 18) { slave.devotion -= 10; } @@ -3086,7 +3093,7 @@ globalThis.DefaultRules = function(slave) { if (slave.porn.feed === 0) { slave.porn.spending = 0; } - r += `<br>Highlights of ${slave.slaveName}'s sex life ${yesno} being released.`; + message(`Highlights of ${slave.slaveName}'s sex life ${yesno} being released.`, sourceRecord.pornFeed); } /** @param {App.Entity.SlaveState} slave @@ -3097,7 +3104,7 @@ globalThis.DefaultRules = function(slave) { if (slave.porn.prestige < 3) { if (slave.porn.spending !== rule.pornFameSpending) { slave.porn.spending = rule.pornFameSpending; - r += `<br>${slave.slaveName}'s porn publicity has been corrected.`; + message(`${slave.slaveName}'s porn publicity has been corrected.`, sourceRecord.pornFameSpending); } } } @@ -3109,15 +3116,15 @@ globalThis.DefaultRules = function(slave) { */ function ProcessLabel(slave, rule) { // mass removal of old tags, variant from '*' mask. - if (rule.removeLabel !== null && rule.removeLabel !== '' && rule.removeLabel === '*') { + if (rule.removeLabel !== null && rule.removeLabel === '*') { slave.custom.label = slave.custom.label.replace(/(?:\[.+\])+/, ""); - r += `<br>All of ${slave.slaveName}'s tags have been removed.`; + message(`All of ${slave.slaveName}'s tags have been removed.`, sourceRecord.removeLabel); } // mass removal of old tags, variant from GUI switch. if (rule.labelTagsClear === true) { slave.custom.label = slave.custom.label.replace(/(?:\[.+\])+/, ""); - r += `<br>All of ${slave.slaveName}'s tags have been removed.`; + message(`All of ${slave.slaveName}'s tags have been removed.`, sourceRecord.removeLabel); } // removing tags selected for removal. @@ -3130,7 +3137,7 @@ globalThis.DefaultRules = function(slave) { for (i in tags) { if (tags[i] !== null && tags[i] !== '' && slave.custom.label.includes(`[${tags[i]}]`)) { slave.custom.label = slave.custom.label.replace(`[${tags[i]}]`, ""); - r += `<br>${slave.slaveName}'s tag [${tags[i]}] is removed.`; + message(`${slave.slaveName}'s tag [${tags[i]}] is removed.`, sourceRecord.removeLabel); } } @@ -3143,7 +3150,7 @@ globalThis.DefaultRules = function(slave) { for (i in tags) { if (tags[i] != null && tags[i] !== '' && !slave.custom.label.includes(`[${tags[i]}]`)) { slave.custom.label = `${slave.custom.label}[${tags[i]}]`; - r += `<br>${slave.slaveName} has been tagged as ${tags[i]}`; + message(`${slave.slaveName} has been tagged as ${tags[i]}`, sourceRecord.label); } } } @@ -3153,8 +3160,26 @@ globalThis.DefaultRules = function(slave) { slave.pronoun = rule.pronoun; } } + + /** + * @param {string} text + * @param {string|string[]} [origin] + */ + function message(text, origin = null) { + r += "<br>"; + if (origin) { + if (_.isArray(origin)) { + origin = removeDuplicates(origin); + } + r += `[${origin}] `; + } else { + r += "[Default] "; + } + r += text; + } }; + /** * @param {App.Entity.SlaveState} slave */ diff --git a/src/js/rulesAssistant.js b/src/js/rulesAssistant.js index c247619be5f65642ac3fad48be8fef87ac24ab7f..418306d23c7d3c34f6bd07c918b3e0b5309e05e1 100644 --- a/src/js/rulesAssistant.js +++ b/src/js/rulesAssistant.js @@ -65,20 +65,21 @@ globalThis.rulesDemandContraceptives = function(slave, rules) { }; /** - * @param {FC.RA.RuleSetters[]} rules - * @returns {FC.RA.RuleSetters} + * @param {Array<[FC.RA.RuleSetters, string]>} rules + * @returns {[FC.RA.RuleSetters,object]} */ globalThis.mergeRules = function(rules) { if (rules.length === 0) { - return emptyDefaultRule().set; + return [App.RA.newRule.setters(), {}]; } - const combinedRule = emptyDefaultRule().set; + const combinedRule = App.RA.newRule.setters(); + const sourceRecord = {}; rules.forEach(rule => { - App.RA.ruleDeepAssign(combinedRule, rule); + App.RA.ruleDeepAssign(combinedRule, rule[0], sourceRecord, rule[1]); }); - return combinedRule; + return [combinedRule, sourceRecord]; }; /** @@ -406,7 +407,16 @@ App.RA.shallShrink = function(current, target, step = 1) { (current === target.val && target.cond === '<')); }; -App.RA.ruleDeepAssign = function deepAssign(target, source) { +/** + * @template {object} T + * @param {object} target Rule or rule part + * @param {T} source Rule or rule part, describes the same part as target + * @param {object} sourceRecord record what was overwritten. Overwrites are located the same as in target, marked with + * sourceName. Describes the same rule(part) as target. + * @param {string} sourceName Name for the source object. + * @returns {T} + */ +App.RA.ruleDeepAssign = function deepAssign(target, source, sourceRecord, sourceName) { function isObject(o) { return (o !== undefined && o !== null && typeof o === 'object' && !Array.isArray(o)); } @@ -419,13 +429,18 @@ App.RA.ruleDeepAssign = function deepAssign(target, source) { if (!target.hasOwnProperty(key) || target[key] === null) { target[key] = {}; } - deepAssign(target[key], source[key]); + if (!sourceRecord.hasOwnProperty(key)) { + sourceRecord[key] = {}; + } + deepAssign(target[key], source[key], sourceRecord[key], sourceName); } else if (key === "label" || key === "removeLabel") { if (source[key] != null) { if (target[key] != null) { target[key] += "|" + source[key]; + sourceRecord[key] += "+" + sourceName; } else { target[key] = source[key]; + sourceRecord[key] = sourceName; } } } else { @@ -439,6 +454,9 @@ App.RA.ruleDeepAssign = function deepAssign(target, source) { (key !== "autoBrand" && source[key] !== null)); if (overrides) { target[key] = source[key]; + if (source[key] !== null) { + sourceRecord[key] = sourceName; + } } } }