diff --git a/devTools/minify/README.md b/devTools/minify/README.md index 79dee7f67b3c98b8d1fe611a8a81f562415096f2..d1544d4026118b9197b02799fc279a12378b95b0 100644 --- a/devTools/minify/README.md +++ b/devTools/minify/README.md @@ -38,6 +38,12 @@ yay -Syu minify pkg install minify ``` +### Alpine Linux +Enable the [https://wiki.alpinelinux.org/wiki/Enable_Community_Repository](community repo) and run +``` +apk add minify +``` + ### MacOS Using Homebrew: @@ -66,11 +72,12 @@ Pull the image: docker pull tdewolff/minify ``` +> The `ENTRYPOINT` of the container is the `minify` command + and run the image, for example in interactive mode: -``` -docker run -i tdewolff/minify -echo "(function(){ if (a == false) { return 0; } else { return 1; } })();" | minify --type js +```bash +docker run -i --entrypoint "" tdewolff/minify sh -c 'echo "(function(){ if (a == false) { return 0; } else { return 1; } })();" | minify --type js' ``` which will output diff --git a/devTools/minify/minify_darwin_amd64 b/devTools/minify/minify_darwin_amd64 index 3d7867ddf8c6256cab6735ef723dcc226aaff8e0..9493dd5d13eec83e639df82e2bb70860f4489c6a 100755 Binary files a/devTools/minify/minify_darwin_amd64 and b/devTools/minify/minify_darwin_amd64 differ diff --git a/devTools/minify/minify_linux_amd64 b/devTools/minify/minify_linux_amd64 index c5bd2be54251b96ca241f2831df07b7767731694..417be68018bdfdfac2ec2917fdfcb513076a81d8 100755 Binary files a/devTools/minify/minify_linux_amd64 and b/devTools/minify/minify_linux_amd64 differ diff --git a/devTools/minify/minify_win_amd64.exe b/devTools/minify/minify_win_amd64.exe index c478435ac99942f89aa492c3c14e5ddb1f71ef98..606bf006036f38751bebaec597db5e0890545e4f 100755 Binary files a/devTools/minify/minify_win_amd64.exe and b/devTools/minify/minify_win_amd64.exe differ diff --git a/devTools/types/FC/RA.d.ts b/devTools/types/FC/RA.d.ts index 4552816cf06dc92914abb6a88d289ca20914f201..973663067ed47fe75d524273851e4d140286bc45 100644 --- a/devTools/types/FC/RA.d.ts +++ b/devTools/types/FC/RA.d.ts @@ -138,7 +138,7 @@ declare namespace FC { standardReward: Rules.Reward; weight: NumericRange; diet: string; - dietCum: number; + dietCum: 0 | 1 | 2; dietMilk: FC.dietMilkType; onDiet: number; muscles: NumericTarget; diff --git a/js/rulesAssistant/conditionEvaluation.js b/js/rulesAssistant/conditionEvaluation.js index e3c50573c7529e77a4f7cab7d70c471bd788ca74..4f269468d9e716b9e86fe4461f404590762d6caf 100644 --- a/js/rulesAssistant/conditionEvaluation.js +++ b/js/rulesAssistant/conditionEvaluation.js @@ -671,6 +671,11 @@ App.RA.Activation.populateGetters = function() { "'pregnancy', 'none' (AKA vanilla)", val: c => c.slave.fetish }); + gm.addString("teeth", { + name: "Teeth", + description: "One of 'normal', 'crooked', 'gapped', 'straightening braces', 'cosmetic braces', 'removable', 'pointy', 'fangs', 'fang', 'baby', 'mixed'", + val: c => c.slave.teeth + }); gm.addString("title", { name: "Title", description: "Slave title (class) without adjectives (slavegirl, MILF, bimbo, shemale, herm, etc.). ", diff --git a/src/Mods/SpecialForce/SpecialForceFS.js b/src/Mods/SpecialForce/SpecialForceFS.js index 5835b1237d253f5045b4c86b3bb113b7ecc1543b..9253971efcd9a609cadc3afaebe99d16faf00afe 100644 --- a/src/Mods/SpecialForce/SpecialForceFS.js +++ b/src/Mods/SpecialForce/SpecialForceFS.js @@ -419,7 +419,7 @@ App.Mods.SF.fsIntegration = (function() { break; case 'Roman_Revivalism': dec = `Roman Revivalism: a vision of a new Rome.`; - gift = `The Colonel has been bestowed with an unmistakable and peerless. badge of office - a mastercrafted SPATHI sword, forged from nigh-unbreakable metals, made extremely sharp with the help of a machine that she also now owns, and equipped with an inbuilt communications array, holographic display projector, recharging port, and fingerprint scanner that delivers electric shocks to anyone other than The Colonel when wielded. It comes with an immaculate sheath, and a complementary gold-wrought laurel wreath and fine linen toga, further enabling her to command the legions of the Firebase with absolute authority and authenticity within the Roman tradition.`; + gift = `The Colonel has been bestowed with an unmistakable and peerless badge of office - a mastercrafted SPATHI sword, forged from nigh-unbreakable metals, made extremely sharp with the help of a machine that she also now owns, and equipped with an inbuilt communications array, holographic display projector, recharging port, and fingerprint scanner that delivers electric shocks to anyone other than The Colonel when wielded. It comes with an immaculate sheath, and a complementary gold-wrought laurel wreath and fine linen toga, further enabling her to command the legions of the Firebase with absolute authority and authenticity within the Roman tradition.`; foods = `You spare no expense to supply your troops with increasingly rare boar and deer meat, distinctive of Roman cuisine.`; media = `Soldiers also enjoy fresh fruits while watching gladiator games, public speakings of famous orators or the history of Ancient Rome on wall-screen TV.`; slaves = `All of the slaves serving here are from outside of your arcology, captured during the many military expeditions staged from the Firebase.`; @@ -810,7 +810,7 @@ App.Mods.SF.fsIntegration = (function() { r += `Finally fed up with your constant intrusions into her territory and crew, The Colonel riles up her people for a full takeover against your arcology. The promises of plunder and dominion over some of the wealthiest tenants in the entire Free City (and their world-class slaves), including you, are all that's needed to get things started.`; r += `<br>At midnight, the lights are the first thing The Colonel's forces disable, as they still have the excellent night vision equipment you purchased for them. Some of your citizens panic almost immediately at the sudden blackout; this is very reminiscent of the Daughters of Liberty attack that still haunts many of their memories. Her army vanguard strikes fast and hard throughout, cutting through your security units and drones with an ease that stinks of months of careful planning and study. Most disturbingly, your penthouse's communications networks are all but destroyed, and your PA has been unreachable, seemingly hacked by some obscure technology you figure only The Colonel's contacts and few others could provide.`; r += `<br>Outside, her many aircraft swarm the local airspace to patrol the arcology outskirts, conduct recon scans of the upper levels, or monitor your now-secured penthouse, while shooting down any other fleeing VTOL's. You will not be escaping by air. No one will. No escaping by land either: Swarms of her drones are tasing fleeing noncombatants by the hundreds for detainment, as the remainder of her army seizes control of vital arcology infrastructure. After just a few days, the entire arcology falls under her direct control, all dissidents, criminals, and rebels hopelessly outgunned by her lavishly equipped and experienced warriors.`; - r += `<br>You are trapped inside your Penthouse by the detachment of infantry guarding its exits in order to keep you in, probably with the goal of starving you out until you surrender yourself. With your communications down as well. your penthouse might as well be an island. You only salvation comes in the form of your neighboring arcologies and their respective mercenary contingents. They are intervening on your behalf out of paranoia; Free Cities are extremely wary of military power buildups near their borders, and they absolutely will not tolerate a full scale military coup within its borders. Fighting men and women from all over the City are seen battling in the streets of your arcology in a brutal blitzkrieg that your own tenants and mercenaries quickly join in on, pushing The Colonel's forces back gradually with sheer numbers. Eventually they are forced back into the Firebase proper, where they are sealed inside by using explosives to collapse part of the arcology atop them, rendering the Firebase itself totally defunct. Only a few small groups manage to scatter and flee this holding action, and your intelligence networks suspects that The Colonel herself was among one of them.`; + r += `<br>You are trapped inside your Penthouse by the detachment of infantry guarding its exits in order to keep you in, probably with the goal of starving you out until you surrender yourself. With your communications down as well, your penthouse might as well be an island. You only salvation comes in the form of your neighboring arcologies and their respective mercenary contingents. They are intervening on your behalf out of paranoia; Free Cities are extremely wary of military power buildups near their borders, and they absolutely will not tolerate a full scale military coup within its borders. Fighting men and women from all over the City are seen battling in the streets of your arcology in a brutal blitzkrieg that your own tenants and mercenaries quickly join in on, pushing The Colonel's forces back gradually with sheer numbers. Eventually they are forced back into the Firebase proper, where they are sealed inside by using explosives to collapse part of the arcology atop them, rendering the Firebase itself totally defunct. Only a few small groups manage to scatter and flee this holding action, and your intelligence networks suspects that The Colonel herself was among one of them.`; r += `With the help of some unlikely intervention, you've won this little war. Your arcology is once more yours, but your people will never forget the traumatic week they spent under the heel of the army that you convinced them to allow, or the fact that it took an entire coalition of outsiders to save them.`; break; case "jaded": 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/endWeek/saRelationships.js b/src/endWeek/saRelationships.js index 252c5c85f3964836da9dc60b8e2616891a3b5d29..72cc36b7bab3fd6a871d3926fa9f600e6866e879 100644 --- a/src/endWeek/saRelationships.js +++ b/src/endWeek/saRelationships.js @@ -1288,7 +1288,7 @@ App.SlaveAssignment.relationships = function saRelationships(slave) { r.push(`${slave.slaveName} knows that ${his} ${relativeTerm(slave, singleRelative)} ${singleRelative.slaveName} loves being your sex slave, and is <span class="devotion inc">happy</span> for ${him2}.`); } else if (devotedRelatives.size > 0) { const groups = relativeMapToGroupArray(devotedRelatives); - r.push(`${slave.slaveName} knows that ${toSentence(groups)} all love being your sex slaves, and is <span class="devotion inc">happy</span> for them.`); + r.push(`${slave.slaveName} knows that ${toSentence(groups)} ${devotedRelatives.size === 2 ? `both` : `all`} love being your sex slaves, and is <span class="devotion inc">happy</span> for them.`); } if (relativeMapTotalSize(devotedRelatives) > overwhelmed) { r.push(`${He} has so many relatives that love being your slaves that ${he} is sometimes overwhelmed with joy and <span class="devotion dec">neglects ${his} duties.</span>`); @@ -1310,7 +1310,7 @@ App.SlaveAssignment.relationships = function saRelationships(slave) { r.push(`${slave.slaveName} knows that ${his} ${relativeTerm(slave, singleRelative)} ${singleRelative.slaveName} hates being a sex slave, and is <span class="trust dec">afraid</span> for ${him2}.`); } else if (hatefulRelatives.size > 0) { const groups = relativeMapToGroupArray(hatefulRelatives); - r.push(`${slave.slaveName} knows that ${toSentence(groups)} all hate being sex slaves, and is <span class="trust dec">afraid</span> for them.`); + r.push(`${slave.slaveName} knows that ${toSentence(groups)} ${hatefulRelatives.size === 2 ? `both` : `all`} hate being sex slaves, and is <span class="trust dec">afraid</span> for them.`); } if (relativeMapTotalSize(hatefulRelatives) > overwhelmed) { r.push(`${He} has so many relatives that hate being your sex slaves that ${he} is overwhelmed with fear and <span class="trust inc">just has to trust you to take care of them.</span>`); diff --git a/src/events/scheduled/seFCNNstation.js b/src/events/scheduled/seFCNNstation.js index 8f87cfd72c76afcb23ee9cca054a6cac212e4b34..8a80674f28fa36779bd74b162f7ecd81236f4e8f 100644 --- a/src/events/scheduled/seFCNNstation.js +++ b/src/events/scheduled/seFCNNstation.js @@ -16,7 +16,7 @@ App.Events.SEFcnnStation = class SEFcnnStation extends App.Events.BaseEvent { const cost = 100000; const {girlP} = getPronouns(V.PC).appendSuffix("P"); - App.Events.addParagraph(node, [`One of the first groups to take advantage of the Free Cities' nearly nonexistent regulations for media and communications was the Free Cities News Network. As one of the few stations covering news within the Free Cities, and the only one doing so without any form of censorship, FCNN quickly became one the most popular news networks in the world. Presently, however, the network's future looks grim. Its reluctance on portraying explicitly pornographic content has lead to plummeting audience figures, especially in comparison to the upstart 8HGG Inc. media empire. In addition, governments within and outside the Free Cities have become increasingly restrictive towards the press, to the point that many FCNN branches have been effectively silenced.`]); + App.Events.addParagraph(node, [`One of the first groups to take advantage of the Free Cities' nearly nonexistent regulations for media and communications was the Free Cities News Network. As one of the few stations covering news within the Free Cities, and the only one doing so without any form of censorship, FCNN quickly became one of the most popular news networks in the world. Presently, however, the network's future looks grim. Its reluctance on portraying explicitly pornographic content has led to plummeting audience figures, especially in comparison to the upstart 8HGG Inc. media empire. In addition, governments within and outside the Free Cities have become increasingly restrictive towards the press, to the point that many FCNN branches have been effectively silenced.`]); App.Events.addParagraph(node, [`This is the situation when you receive a personal video call from the network's beleaguered president. The former FCNN headquarters has been outright destroyed for reporting on its host nation's human rights abuses, and they're hoping to relocate to ${V.arcologies[0].name}. "We are, of course, in dire financial straits," the president nervously explains, "So we'll need a small subsidy to establish our new headquarters. Probably, oh, let's say... <span class="yellowgreen">${cashFormat(cost)}</span> or so?" He flinches while forcing a grin.`]); diff --git a/src/events/scheduled/seFCTVinstall.js b/src/events/scheduled/seFCTVinstall.js index e3986a75f43f1f5342775e95bbb4247a977c43a0..e7952257769cead67ee73703f7a2d9bc6d060353 100644 --- a/src/events/scheduled/seFCTVinstall.js +++ b/src/events/scheduled/seFCTVinstall.js @@ -9,7 +9,7 @@ App.Events.SEFctvInstall = class SEFctvInstall extends App.Events.BaseEvent { execute(node) { V.encyclopedia = "FCTV"; V.FCTV.receiver = 0; - App.Events.addParagraph(node, [`You've been sitting in your office into the early afternoon going over bothersome lease documents that need your approval. When you take a break to look out the window, ${V.assistant.name} speaks up. "${properTitle()}, you have received an approval welcome packet from 8HGG Inc. in regards to Free Cities TV. It seems that they've determined that ${V.arcologies[0].name} is now sufficiently developed enough to warrant a FCTV-Citizen connection. All the details and contracts necessary are included in the packet. From there, a receiver will need to be built onto ${V.arcologies[0].name} in order to access FCTV."`]); + App.Events.addParagraph(node, [`You've been sitting in your office into the early afternoon, going over bothersome lease documents that need your approval. When you take a break to look out the window, ${V.assistant.name} speaks up. "${properTitle()}, you have received an approval welcome packet from 8HGG Inc. in regards to Free Cities TV. It seems that they've determined that ${V.arcologies[0].name} is now sufficiently developed enough to warrant an FCTV-Citizen connection. All the details and contracts necessary are included in the packet. From there, a receiver will need to be built onto ${V.arcologies[0].name} in order to access FCTV."`]); App.Events.addParagraph(node, [`You browse the guide: home shopping networks, random dramas, how-to shows and a myriad of other things. Of more interest are some of the programs showing glimpses into foreign arcologies and how they are using the service to help mold society.`]); diff --git a/src/js/DefaultRules.js b/src/js/DefaultRules.js index 73c08b7a4727cfe8974467c90f3ad4387bf408a7..4cb6389756cfd5a2feb4633a40df5db1fd2312a0 100644 --- a/src/js/DefaultRules.js +++ b/src/js/DefaultRules.js @@ -1,129 +1,107 @@ -// this code applies RA rules onto slaves -globalThis.DefaultRules = (function() { - "use strict"; - - const assignedTypes = { - "auto": {success: "has been automatically assigned", unable: "could not be assigned"}, - "allowed": {success: "is allowed", unable: "could not be allowed"}, - }; - const getAssignmentDescription = function({rule, slave, assignmentResult, append = null}) { - const assignment = rule.setAssignment === Job.CHOICE - ? { - descriptionType: "allowed", - work: `select ${pronouns.his} own assignments` - } : { - descriptionType: "auto", - work: App.Utils.jobForAssignment(rule.setAssignment).assignment - }; - - const assignedTypeInfo = assignedTypes[assignment.descriptionType]; - const hasBeenAssigned = assignedTypeInfo[assignmentResult]; - return `<br>${slave.slaveName} ${hasBeenAssigned} to ${assignment.work}${append || ''}.`; - }; +/** + * this code applies RA rules onto slaves + * @param {App.Entity.SlaveState} slave + * @returns {string} + */ +globalThis.DefaultRules = function(slave) { + if (slave.useRulesAssistant === 0) { + return ""; // exempted + } - /** @type {string} */ - let r; - let pronouns; - let he; - let him; - let his; + const slaveReadOnly = createReadonlyProxy(slave); + const {rule, ruleIds, sourceRecord} = runWithReadonlyProxy(() => ProcessSlaveRules(slaveReadOnly)); + slave.currentRules = ruleIds; + if (ruleIds.length === 0) { + return ""; // no rules apply + } - /** - * @param {App.Entity.SlaveState} slave - * @returns {string} - */ - function DefaultRules(slave) { - if (slave.useRulesAssistant === 0) { - return r; - } // exempted - r = ""; - ({he, him, his} = pronouns = getPronouns(slave)); - const slaveReadOnly = createReadonlyProxy(slave); - const {rule, ruleIds} = runWithReadonlyProxy(() => ProcessSlaveRules(slaveReadOnly)); - slave.currentRules = ruleIds; - if (ruleIds.length === 0) { - return r; - } // no rules apply - - AssignJobToSlave(slave, rule); - if (slave.fuckdoll === 0) { - ProcessClothing(slave, rule); - ProcessCollar(slave, rule); - ProcessMask(slave, rule); - ProcessGag(slave, rule); - ProcessEyewear(slave, rule); - ProcessEarwear(slave, rule); - ProcessDildos(slave, rule); - ProcessDickAccessories(slave, rule); - ProcessAnalAccessories(slave, rule); - ProcessChastity(slave, rule); - ProcessShoes(slave, rule); - ProcessBellyAccessories(slave, rule); - ProcessArmAccessory(slave, rule); - ProcessLegAccessory(slave, rule); - } - ProcessPit(slave, rule); - ProcessBellyImplant(slave, rule); - if (isFertile(slave) || slave.pregWeek < 0) { - ProcessContraceptives(slave, rule); - } - if (slave.preg > 0 && slave.pregKnown === 1 && slave.broodmother === 0) { - ProcessAbortions(slave, rule); - } - ProcessDrugs(slave, rule); - ProcessEnema(slave, rule); - ProcessDiet(slave, rule); - ProcessCuratives(slave, rule); - ProcessAphrodisiacs(slave, rule); - ProcessPenisHormones(slave, rule); - ProcessFemaleHormones(slave, rule); - ProcessPregnancyDrugs(slave, rule); - if (slave.fuckdoll === 0) { - ProcessLivingStandard(slave, rule); - ProcessRest(slave, rule); - ProcessSpeech(slave, rule); - ProcessRelationship(slave, rule); - ProcessRelease(slave, rule); - ProcessLactation(slave, rule); - if (!canWalk(slave) && canMove(slave)) { - ProcessMobility(slave, rule); - } - ProcessPunishment(slave, rule); - ProcessReward(slave, rule); - } - ProcessToyHole(slave, rule); - ProcessDietCum(slave, rule); - ProcessDietMilk(slave, rule); - if (V.arcologies[0].FSHedonisticDecadenceResearch === 1) { - ProcessSolidFood(slave, rule); - } - ProcessTeeth(slave, rule); - ProcessStyle(slave, rule); - ProcessPiercings(slave, rule); - ProcessSmartPiercings(slave, rule); - ProcessTattoos(slave, rule); - ProcessPornFeedEnabled(slave, rule); - ProcessPorn(slave, rule); - ProcessLabel(slave, rule); - ProcessOther(slave, rule); - return r; + let r = ""; + const pronouns = getPronouns(slave); + const {he, him, his} = pronouns; + + AssignJobToSlave(slave, rule); + if (slave.fuckdoll === 0) { + ProcessClothing(slave, rule); + ProcessCollar(slave, rule); + ProcessMask(slave, rule); + ProcessGag(slave, rule); + ProcessEyewear(slave, rule); + ProcessEarwear(slave, rule); + ProcessDildos(slave, rule); + ProcessDickAccessories(slave, rule); + ProcessAnalAccessories(slave, rule); + ProcessChastity(slave, rule); + ProcessShoes(slave, rule); + ProcessBellyAccessories(slave, rule); + ProcessArmAccessory(slave, rule); + ProcessLegAccessory(slave, rule); + } + ProcessPit(slave, rule); + ProcessBellyImplant(slave, rule); + if (isFertile(slave) || slave.pregWeek < 0) { + ProcessContraceptives(slave, rule); + } + if (slave.preg > 0 && slave.pregKnown === 1 && slave.broodmother === 0) { + ProcessAbortions(slave, rule); + } + ProcessDrugs(slave, rule); + ProcessEnema(slave, rule); + ProcessDiet(slave, rule); + ProcessCuratives(slave, rule); + ProcessAphrodisiacs(slave, rule); + ProcessPenisHormones(slave, rule); + ProcessFemaleHormones(slave, rule); + ProcessPregnancyDrugs(slave, rule); + if (slave.fuckdoll === 0) { + ProcessLivingStandard(slave, rule); + ProcessRest(slave, rule); + ProcessSpeech(slave, rule); + ProcessRelationship(slave, rule); + ProcessRelease(slave, rule); + ProcessLactation(slave, rule); + if (!canWalk(slave) && canMove(slave)) { + ProcessMobility(slave, rule); + } + ProcessPunishment(slave, rule); + ProcessReward(slave, rule); + } + ProcessToyHole(slave, rule); + ProcessDietCum(slave, rule); + ProcessDietMilk(slave, rule); + if (V.arcologies[0].FSHedonisticDecadenceResearch === 1) { + ProcessSolidFood(slave, rule); } + ProcessTeeth(slave, rule); + ProcessStyle(slave, rule); + ProcessPiercings(slave, rule); + ProcessSmartPiercings(slave, rule); + ProcessTattoos(slave, rule); + ProcessPornFeedEnabled(slave, rule); + ProcessPorn(slave, rule); + ProcessLabel(slave, rule); + ProcessOther(slave, rule); + return r; + /** * @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}; } /** @@ -132,8 +110,9 @@ globalThis.DefaultRules = (function() { * @returns {FC.RA.RuleSetters} */ function ProcessAssignments(slave, rule) { - // Before merging rules, we process assignments for each rule separately so we can remove slaves from facilities when they no longer qualify, even if the final "winning" rule assigns them elsewhere - // We also ignore inapplicable assignments for the current slave, so we only merge assignments that are valid + // Before merging rules, we process assignments for each rule separately, so we can remove slaves from + // facilities when they no longer qualify, even if the final "winning" rule assigns them elsewhere. + // We also ignore inapplicable assignments for the current slave, so we only merge assignments that are valid. if (rule.setAssignment === null) { delete rule.setAssignment; return rule; @@ -160,8 +139,7 @@ globalThis.DefaultRules = (function() { removeAssignment(); } else if (!job.facility.hasFreeSpace && slave.assignment !== rule.setAssignment) { r += getAssignmentDescription({ - rule, slave, assignmentResult: "unable", - append: " because it was full" + rule, slave, assignmentResult: "unable", append: " because it was full" }); removeAssignment(); } @@ -184,6 +162,29 @@ globalThis.DefaultRules = (function() { } } + /** + * @param {object} params + * @param {FC.RA.RuleSetters} params.rule + * @param {App.Entity.SlaveState} params.slave + * @param {"success"|"unable"} params.assignmentResult + * @param {string} [params.append] + * @returns {string} + */ + function getAssignmentDescription({rule, slave, assignmentResult, append = null}) { + const assignment = rule.setAssignment === Job.CHOICE ? { + work: `select ${pronouns.his} own assignments`, + success: "is allowed", + unable: "could not be allowed" + } : { + work: App.Utils.jobForAssignment(rule.setAssignment).assignment, + success: "has been automatically assigned", + unable: "could not be assigned" + }; + + const hasBeenAssigned = assignment[assignmentResult]; + return `<br>${slave.slaveName} ${hasBeenAssigned} to ${assignment.work}${append || ''}.`; + } + /** * @param {App.Entity.SlaveState} slave * @param {FC.RA.RuleSetters} rule @@ -194,16 +195,16 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -217,21 +218,21 @@ globalThis.DefaultRules = (function() { // 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); } } } @@ -245,12 +246,11 @@ globalThis.DefaultRules = (function() { // 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); } } } @@ -264,17 +264,17 @@ globalThis.DefaultRules = (function() { // 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); } } } @@ -293,12 +293,12 @@ globalThis.DefaultRules = (function() { 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; @@ -308,12 +308,12 @@ globalThis.DefaultRules = (function() { 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; @@ -323,12 +323,12 @@ globalThis.DefaultRules = (function() { 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; @@ -338,12 +338,12 @@ globalThis.DefaultRules = (function() { 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; @@ -353,13 +353,13 @@ globalThis.DefaultRules = (function() { 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; @@ -367,7 +367,7 @@ globalThis.DefaultRules = (function() { 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; } @@ -387,12 +387,12 @@ globalThis.DefaultRules = (function() { 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; @@ -402,12 +402,12 @@ globalThis.DefaultRules = (function() { 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; @@ -417,12 +417,12 @@ globalThis.DefaultRules = (function() { 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; @@ -430,7 +430,7 @@ globalThis.DefaultRules = (function() { 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; } @@ -464,50 +464,50 @@ globalThis.DefaultRules = (function() { 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; } } @@ -525,50 +525,50 @@ globalThis.DefaultRules = (function() { 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; } } @@ -586,49 +586,49 @@ globalThis.DefaultRules = (function() { 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; } } @@ -649,29 +649,29 @@ globalThis.DefaultRules = (function() { 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; } } @@ -691,9 +691,9 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -702,9 +702,9 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -723,9 +723,9 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -735,9 +735,9 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -746,9 +746,9 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -764,7 +764,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -779,14 +779,14 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -800,7 +800,7 @@ globalThis.DefaultRules = (function() { 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); } } @@ -811,7 +811,7 @@ globalThis.DefaultRules = (function() { 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); } } @@ -842,50 +842,50 @@ globalThis.DefaultRules = (function() { 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; } } @@ -903,50 +903,50 @@ globalThis.DefaultRules = (function() { 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; } } @@ -968,11 +968,11 @@ globalThis.DefaultRules = (function() { 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,33 +984,32 @@ globalThis.DefaultRules = (function() { * @param {FC.RA.RuleSetters} rule */ function ProcessBellyImplant(slave, rule) { - // Here is belly implant size control, it's used in Surgery Degradation passage to setup devotion and trust changes. + // 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); } } } @@ -1068,10 +1067,10 @@ globalThis.DefaultRules = (function() { 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; } } @@ -1106,34 +1105,34 @@ globalThis.DefaultRules = (function() { 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); } } @@ -1150,16 +1149,16 @@ globalThis.DefaultRules = (function() { 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); @@ -1177,7 +1176,7 @@ globalThis.DefaultRules = (function() { 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 ( @@ -1260,10 +1259,11 @@ globalThis.DefaultRules = (function() { * @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; } @@ -1274,71 +1274,71 @@ globalThis.DefaultRules = (function() { 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); @@ -1523,10 +1523,10 @@ globalThis.DefaultRules = (function() { } 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); } } } @@ -1539,12 +1539,12 @@ globalThis.DefaultRules = (function() { 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; @@ -1554,11 +1554,11 @@ globalThis.DefaultRules = (function() { } } 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") { @@ -1577,15 +1577,15 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -1610,17 +1610,17 @@ globalThis.DefaultRules = (function() { 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); @@ -1631,17 +1631,17 @@ globalThis.DefaultRules = (function() { 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); @@ -1655,15 +1655,15 @@ globalThis.DefaultRules = (function() { 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); @@ -1673,56 +1673,56 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -1730,18 +1730,18 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -1759,10 +1759,10 @@ globalThis.DefaultRules = (function() { 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]); } } } @@ -1777,15 +1777,15 @@ globalThis.DefaultRules = (function() { 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; } } @@ -1799,7 +1799,7 @@ globalThis.DefaultRules = (function() { 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; } } @@ -1809,16 +1809,17 @@ globalThis.DefaultRules = (function() { * @param {FC.SlaveState} slave * @param {number} hormones * @param {string} slaveClass + * @param {string} source */ - const 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); } } - }; + } /** * @param {App.Entity.SlaveState} slave @@ -1827,9 +1828,9 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -1840,7 +1841,7 @@ globalThis.DefaultRules = (function() { */ 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); } } @@ -1852,25 +1853,25 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -1883,26 +1884,26 @@ globalThis.DefaultRules = (function() { 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(); @@ -1920,7 +1921,7 @@ globalThis.DefaultRules = (function() { // 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); } } } @@ -1935,27 +1936,27 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -1969,7 +1970,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -1988,21 +1989,24 @@ globalThis.DefaultRules = (function() { '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; } } @@ -2015,7 +2019,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2029,7 +2033,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2042,7 +2046,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2055,7 +2059,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2069,30 +2073,30 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2106,12 +2110,12 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2126,12 +2130,12 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2146,9 +2150,9 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2164,36 +2168,36 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2271,7 +2275,7 @@ globalThis.DefaultRules = (function() { } } 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]); } } @@ -2286,7 +2290,7 @@ globalThis.DefaultRules = (function() { 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); } } @@ -2295,7 +2299,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2305,7 +2309,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2315,7 +2319,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2327,20 +2331,20 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2351,10 +2355,10 @@ globalThis.DefaultRules = (function() { 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; @@ -2365,10 +2369,10 @@ globalThis.DefaultRules = (function() { 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; } } @@ -2379,7 +2383,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2389,7 +2393,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2399,7 +2403,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2409,7 +2413,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2419,7 +2423,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2429,7 +2433,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2439,7 +2443,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2449,7 +2453,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2459,7 +2463,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2469,19 +2473,19 @@ globalThis.DefaultRules = (function() { 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"; } @@ -2491,11 +2495,11 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2509,13 +2513,13 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2524,11 +2528,11 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2539,17 +2543,17 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2560,11 +2564,11 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2575,11 +2579,11 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2590,12 +2594,12 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2604,11 +2608,11 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2617,11 +2621,11 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2630,11 +2634,11 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2643,11 +2647,11 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2656,11 +2660,11 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2669,11 +2673,11 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2682,11 +2686,11 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2695,11 +2699,11 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2709,9 +2713,9 @@ globalThis.DefaultRules = (function() { 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; } @@ -2738,7 +2742,7 @@ globalThis.DefaultRules = (function() { // 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; @@ -2747,13 +2751,13 @@ globalThis.DefaultRules = (function() { 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; @@ -2762,13 +2766,13 @@ globalThis.DefaultRules = (function() { 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; @@ -2777,13 +2781,13 @@ globalThis.DefaultRules = (function() { 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; @@ -2801,7 +2805,7 @@ globalThis.DefaultRules = (function() { 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); } } @@ -2809,7 +2813,7 @@ globalThis.DefaultRules = (function() { 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); } } @@ -2817,7 +2821,7 @@ globalThis.DefaultRules = (function() { 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); } } @@ -2826,7 +2830,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -2835,7 +2839,7 @@ globalThis.DefaultRules = (function() { 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); } } @@ -2843,7 +2847,7 @@ globalThis.DefaultRules = (function() { 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); } } @@ -2851,7 +2855,7 @@ globalThis.DefaultRules = (function() { 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); } } @@ -2859,21 +2863,21 @@ globalThis.DefaultRules = (function() { 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); } } @@ -2881,7 +2885,7 @@ globalThis.DefaultRules = (function() { 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); } } @@ -2889,21 +2893,21 @@ globalThis.DefaultRules = (function() { 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; } } @@ -2912,14 +2916,14 @@ globalThis.DefaultRules = (function() { 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; } } @@ -3043,18 +3047,18 @@ globalThis.DefaultRules = (function() { // 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; } @@ -3063,7 +3067,7 @@ globalThis.DefaultRules = (function() { 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; } @@ -3089,7 +3093,7 @@ globalThis.DefaultRules = (function() { 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 @@ -3100,7 +3104,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -3112,15 +3116,15 @@ globalThis.DefaultRules = (function() { */ 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. @@ -3133,7 +3137,7 @@ globalThis.DefaultRules = (function() { 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); } } @@ -3146,7 +3150,7 @@ globalThis.DefaultRules = (function() { 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); } } } @@ -3157,8 +3161,24 @@ globalThis.DefaultRules = (function() { } } - return DefaultRules; -})(); + /** + * @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; + } } } } diff --git a/src/npc/descriptions/ears.js b/src/npc/descriptions/ears.js index 48bfeb01cfcf6ecb4b550ab4d046ffb5a27797ed..29f4fadf1fae867e10a02ea35450c4795c54eb40 100644 --- a/src/npc/descriptions/ears.js +++ b/src/npc/descriptions/ears.js @@ -71,7 +71,7 @@ App.Desc.ears = function(slave) { } r.push(`${either(`tend to droop when ${he} is relaxed or sad`, `twitch at the slightest touch`)}.`); } else if (slave.earT === "leopard") { - r.push(`On top of ${his} head ${he} has a pair of cute leopard ears. the ears are`); + r.push(`On top of ${his} head ${he} has a pair of cute leopard ears. The ears are`); if (slave.earTColor === "hairless") { r.push(`hairless.`); } else { diff --git a/src/npc/interaction/fFeelings.js b/src/npc/interaction/fFeelings.js index d7934e5ce6015e92be758340fd0609e24e878c88..11e922b93b07f2039e45cce75a6b6d03b6e23cbd 100644 --- a/src/npc/interaction/fFeelings.js +++ b/src/npc/interaction/fFeelings.js @@ -410,7 +410,7 @@ App.Interact.fFeelings = function(slave) { } text.push(`cum in my belly. Oh! I like my belly, too, and that warm, sloshy feeling as it's packed full of baby juice. It's so — I'm sorry, ${Master}. I think my mouth is watering. Please give me a moment to collect myself.`); } else if (V.PC.dick !== 0) { - text.push(`is my tummy${(slave.vagina > -1) ? ` — and my womb` : ``}! The sloshy feeling when I'm all packed full of cum in both ends gets me so incredibly horny. sometimes I wonder what it would be like if I were just a puffed up cum-balloon of a ${woman}, helpless and filled with cum, over, and over, and — I'm sorry, ${Master}. I'm being weird again, aren't I?`); + text.push(`is my tummy${(slave.vagina > -1) ? ` — and my womb` : ``}! The sloshy feeling when I'm all packed full of cum in both ends gets me so incredibly horny. Sometimes I wonder what it would be like if I were just a puffed up cum-balloon of a ${woman}, helpless and filled with cum, over, and over, and — I'm sorry, ${Master}. I'm being weird again, aren't I?`); } else { text.push(`is my mouth, I love how it feels to — to eat pussy, ${Master}. I love eating out your pussy. Especially when it's been filled up with some`); if (canTaste(slave)) { @@ -1916,13 +1916,13 @@ App.Interact.fFeelings = function(slave) { if (sex > 0 && beauty > 0 && combat > 0) { text.push(`${Spoken(slave, `${His2} P-Limbs do look cool and I like how strong they can make ${him2} but they scare me a little, sometimes. Though of course ${he2} disables the weapons when we're together."`)} ${He} giggles. ${Spoken(slave, `"${He2} has vibe fingers, so that's awesome.`)}`); } else if (sex > 0 && beauty > 0) { - text.push(`${Spoken(slave, `I really like ${his2} P-Limbs. They're very pretty, but kind of cold. That's just how ${he2} is."`)} ${He} giggles. ${Spoken(slave, `" ${He2} has vibe fingers. so that's awesome.`)}`); + text.push(`${Spoken(slave, `I really like ${his2} P-Limbs. They're very pretty, but kind of cold. That's just how ${he2} is."`)} ${He} giggles. ${Spoken(slave, `" ${He2} has vibe fingers. So that's awesome.`)}`); } else if (beauty > 0 && combat > 0) { text.push(`${Spoken(slave, `${His2} P-Limbs do look cool and I like how strong they can make ${him2} but they scare me a little, sometimes. Though of course ${he2} disables the weapons when we're together.`)}`); } else if (sex > 0 && combat > 0) { - text.push(`${Spoken(slave, `${His2} P-Limbs do scare me a little, sometimes. Though of course ${he2} disables the weapons when we're together."`)} ${He} giggles. ${Spoken(slave, `"${He2} has vibe fingers. so that's awesome.`)}`); + text.push(`${Spoken(slave, `${His2} P-Limbs do scare me a little, sometimes. Though of course ${he2} disables the weapons when we're together."`)} ${He} giggles. ${Spoken(slave, `"${He2} has vibe fingers. So that's awesome.`)}`); } else if (sex > 0) { - text.push(`${Spoken(slave, `And, um."`)} ${He} giggles. ${Spoken(slave, `"${He2} has vibe fingers. so that's awesome.`)}`); + text.push(`${Spoken(slave, `And, um."`)} ${He} giggles. ${Spoken(slave, `"${He2} has vibe fingers. So that's awesome.`)}`); } else if (beauty > 0) { text.push(`${Spoken(slave, `I really like ${his2} P-Limbs. They're very pretty, but kind of cold. That's just how ${he2} is.`)}`); } else if (combat > 0) { @@ -2022,7 +2022,7 @@ App.Interact.fFeelings = function(slave) { } else if (slave.devotion > 20) { text.push(`${Spoken(slave, `I'm proud to be a slave of the new Pharaoh.`)}`); } else { - text.push(`${Spoken(slave, `Being a slave in this new Egypt is a little reassuring. some of the other slavs say they used to use slaves for great things, anyway.`)}`); + text.push(`${Spoken(slave, `Being a slave in this new Egypt is a little reassuring. Some of the other slaves say they used to use slaves for great things, anyway.`)}`); } } if (V.arcologies[0].FSChattelReligionist >= 10) { diff --git a/src/pregmod/FCTV/FCTVshows.js b/src/pregmod/FCTV/FCTVshows.js index 1d3a2dfa50b511697ba43ff8fc4ba47c5c035d28..a099f8d79bc1527157f29f65325b8f4334b721a7 100644 --- a/src/pregmod/FCTV/FCTVshows.js +++ b/src/pregmod/FCTV/FCTVshows.js @@ -2263,7 +2263,7 @@ App.Data.FCTV.channels = { r.push(`<p>At this point, her stomach is so distended that the black pitch is showing around individual feathers. Annie and Dakota lock eyes and giggle, while Kate moves to where the noose is tied.</p>`); r.push(`<p>"Ready?" They ask the girl. She can barely open her eyes and doesn't move her head. "Ok then, here we go!"</p>`); - r.push(`<p>Kate loosens the rope just as Annie and Dakota each lift a leg. With nothing else to support her, the girl's full weight comes to bear on the plug, which finally smears its tarry way home with a "pop." The Indian girl shudders with an impossible... orgasm? and screams.</p>`); + r.push(`<p>Kate loosens the rope just as Annie and Dakota each lift a leg. With nothing else to support her, the girl's full weight comes to bear on the plug, which finally smears its tarry way home with a "pop." The Indian girl screams and shudders with an impossible... orgasm?</p>`); r.push(`<p>Annie releases the noose from the scaffold and shoves her over on her back. "You LIKED that? You disgust me." She is powerless to move, and lays there groaning and drooling beneath the weight of her stomach.</p>`); r.push(`<p>"Better finish your drink, little chicken." Dakota wrings out the skin, and the liquid has nowhere to go but in. She neatly wraps rawhide around the bag to make sure the inflation can't reverse, and then covers the whole thing with pitch. It will not be coming undone soon.</p>`);