diff --git a/src/events/events.css b/css/events/events.css similarity index 100% rename from src/events/events.css rename to css/events/events.css diff --git a/css/facilities/farmyard.css b/css/facilities/farmyard.css deleted file mode 100644 index 8d0abbe268ae9cf533ecb6eda508bd3d908ad696..0000000000000000000000000000000000000000 --- a/css/facilities/farmyard.css +++ /dev/null @@ -1,8 +0,0 @@ -.farmyard-heading { - text-transform: uppercase; -} - -.farmyard-heading, -.farmyard-animal-type { - font-weight: bold; -} diff --git a/css/general/formatting.css b/css/general/formatting.css index db038ad72c4dbe6c2b4e01bd4f901d9736a3cc23..b69199c7704ce729145fbdbb8923e188a01ce222 100644 --- a/css/general/formatting.css +++ b/css/general/formatting.css @@ -77,3 +77,7 @@ input:out-of-range { background-color: rgba(255, 0, 0, 0.25); border: 2px solid #900; } + +.uppercase { + text-transform: uppercase; +} diff --git a/css/manage/budget.css b/css/manage/budget.css index eca4573e7de36fe73373de9e5aa2346db05897aa..680f4f74402abc9b2ee274f2a73d35b9132ba051 100644 --- a/css/manage/budget.css +++ b/css/manage/budget.css @@ -6,7 +6,7 @@ table.budget { border-width: 1px; border-color: white; padding: 5px; - font-family: "monospace"; + font-family: monospace; } table.budget .colored { background-color: #001700; diff --git a/devTools/types/FC/facilities.d.ts b/devTools/types/FC/facilities.d.ts index 9f3923fd007560e0833e38cb50e8597ab89ab93a..16db5832ff9cc11f6d01a087f40095e604f03a7b 100644 --- a/devTools/types/FC/facilities.d.ts +++ b/devTools/types/FC/facilities.d.ts @@ -13,13 +13,13 @@ declare namespace FC { /** The value to set `property` to upon purchase. */ value: any; /** The text displayed before the upgrade has been purchased. */ - base: string; + base?: string; /** The text displayed after the upgrade has been purchased. */ - upgraded: string; + upgraded?: string; /** The link text. */ link: string; /** How much the upgrade costs. */ - cost: number; + cost?: number; /** Any handler to run upon purchase. */ handler?: () => void; /** Any additional information to display upon hover on the link. */ @@ -33,24 +33,15 @@ declare namespace FC { property: string /** Any prerequisites that must be met for the rule to be displayed. */ prereqs: Array<() => boolean> - /** Properties to use when the rule is active. */ - active: { + /** Properties pertaining to any options available. */ + options: Array<{ /** The text displayed when the rule is active. */ text: string; /** The link text to set the rule to active. */ link: string; /** The value to set `property` to when the rule is active. */ value: number|boolean; - }; - /** Properties to use when the rule is inactive. */ - inactive: { - /** The text displayed when the rule is inactive. */ - text: string; - /** The link text to set the rule to inactive. */ - link: string; - /** The value to set `property` to when the rule is inactive. */ - value: number|boolean; - }; + }> /** Any additional nodes to attach. */ nodes?: Array<string|HTMLElement|DocumentFragment> } diff --git a/js/003-data/clothes/001-slaveWearData.js b/js/003-data/clothes/001-slaveWearData.js index 45a20c6d11a92e31ce00bb0325c51b4a8352e270..5fdaedc70f5c0fe38be948e5d6dbd4eb87d25aa9 100644 --- a/js/003-data/clothes/001-slaveWearData.js +++ b/js/003-data/clothes/001-slaveWearData.js @@ -923,7 +923,7 @@ App.Data.clothes = (new Map()) ) .set("no clothing", { - name: "Go naked", + name: "Naked", exposure: 4, harsh: true, fs: { diff --git a/js/003-data/gameVariableData.js b/js/003-data/gameVariableData.js index 139f37366c6a1c7829a51d4383c62495aebb79ad..207fddc4451aa4dbd20dc43dada88b15f1d5fa72 100644 --- a/js/003-data/gameVariableData.js +++ b/js/003-data/gameVariableData.js @@ -700,13 +700,6 @@ App.Data.resetOnNGPlus = { pregInventorID: 0, pregInventions: 0, - legendaryWhoreID: 0, - legendaryEntertainerID: 0, - legendaryCowID: 0, - legendaryBallsID: 0, - legendaryWombID: 0, - legendaryAbolitionistID: 0, - FSAnnounced: 0, FSGotRepCredits: 0, FSCreditCount: 5, diff --git a/src/004-base/facilityFramework.js b/src/004-base/facilityFramework.js index 8a2bfebbe18537447bec57cbe43296e059edb402..6dddb065804a00042c0ccd83ae054946b6ce8dfe 100644 --- a/src/004-base/facilityFramework.js +++ b/src/004-base/facilityFramework.js @@ -33,6 +33,7 @@ App.Facilities.Facility = class { () => this._expand(expandArgs), () => this._makeUpgrades(), () => this._makeRules(), + () => this._stats(), () => this._slaves(), () => this._rename(), ); @@ -117,9 +118,10 @@ App.Facilities.Facility = class { _intro(decommissionHandler) { const div = document.createElement("div"); + App.UI.DOM.appendNewElement("h1", div, this.facility.nameCaps); App.UI.DOM.appendNewElement("div", div, this.intro, ['scene-intro']); - if (this.facility.hostedSlaves === 0 && !S.Nurse) { + if (this.facility.totalEmployeesCount === 0) { div.append(App.UI.DOM.makeElement("div", App.UI.DOM.passageLink(`Decommission ${this.facility.name}`, "Main", decommissionHandler), ['indent'])); } @@ -169,8 +171,14 @@ App.Facilities.Facility = class { _makeUpgrades() { const div = document.createElement("div"); + if (this.upgrades.length > 0 && this.upgrades.some(upgrade => upgrade.prereqs.every(prereq => prereq()))) { + App.UI.DOM.appendNewElement("h2", div, `Upgrades`); + } + this._upgrades.forEach(upgrade => { if (upgrade.prereqs.every(prereq => prereq())) { + upgrade.cost = upgrade.cost || 0; + if (V[upgrade.property] === upgrade.value) { App.UI.DOM.appendNewElement("div", div, upgrade.upgraded); } else { @@ -184,7 +192,9 @@ App.Facilities.Facility = class { } this.refresh(); - }, [], '', `Costs ${cashFormat(upgrade.cost)}${upgrade.note ? ` and ${upgrade.note}` : ``}.`), ['indent']); + }, [], '', + `${upgrade.cost > 0 ? `Costs ${cashFormat(upgrade.cost)}` : `Free`}${upgrade.note ? `${upgrade.note}` : ``}.`), + ['indent']); } if (upgrade.nodes) { @@ -205,19 +215,22 @@ App.Facilities.Facility = class { _makeRules() { const div = document.createElement("div"); + if (this.rules.length > 0 && this.rules.some(rule => rule.prereqs.every(prereq => prereq()))) { + App.UI.DOM.appendNewElement("h2", div, `Rules`); + } + this._rules.forEach(rule => { if (rule.prereqs.every(prereq => prereq())) { const options = new App.UI.OptionsGroup(); + const option = options.addOption(null, rule.property); - if (rule.active.value) { - App.UI.DOM.appendNewElement("div", div, rule.active.text); - } else { - App.UI.DOM.appendNewElement("div", div, rule.inactive.text); - } + rule.options.forEach(o => { + option.addValue(o.link, o.value); - options.addOption(null, rule.property) - .addValue(rule.active.link, rule.active.value) - .addValue(rule.inactive.link, rule.inactive.value); + if (V[rule.property] === o.value) { + App.UI.DOM.appendNewElement("div", div, o.text); + } + }); App.UI.DOM.appendNewElement("div", div, options.render(), ['indent', 'margin-bottom']); } @@ -230,6 +243,22 @@ App.Facilities.Facility = class { return div; } + /** + * Displays a table with statistics relating to the facility. + * + * @returns {HTMLDivElement} + */ + _stats() { + const div = document.createElement("div"); + + if (this.stats) { + App.UI.DOM.appendNewElement("h2", div, `Statistics`); + App.UI.DOM.appendNewElement("div", div, this.stats, ['margin-bottom']); + } + + return div; + } + /** * Displays a list of slaves that can be assigned and removed. * @@ -237,7 +266,12 @@ App.Facilities.Facility = class { * @returns {HTMLDivElement} */ _slaves() { - return App.UI.DOM.makeElement("div", App.UI.SlaveList.stdFacilityPage(this.facility, true)); + const div = document.createElement("div"); + + App.UI.DOM.appendNewElement("h2", div, `Slaves`); + App.UI.DOM.appendNewElement("div", div, App.UI.SlaveList.stdFacilityPage(this.facility, true), ['margin-bottom']); + + return div; } /** @@ -247,7 +281,12 @@ App.Facilities.Facility = class { * @returns {HTMLDivElement} */ _rename() { - return App.Facilities.rename(this.facility, () => this.refresh()); + const div = document.createElement("div"); + + App.UI.DOM.appendNewElement("h2", div, `Rename`); + App.UI.DOM.appendNewElement("div", div, App.Facilities.rename(this.facility, () => this.refresh())); + + return div; } /** @@ -285,4 +324,13 @@ App.Facilities.Facility = class { get rules() { return []; } + + /** + * Any statistics table to display. + * + * @returns {HTMLDivElement} + */ + get stats() { + return null; + } }; diff --git a/src/005-passages/eventsPassages.js b/src/005-passages/eventsPassages.js index 23f3c9a7655dc450e7c46568c61ba291f6563ce2..1de72b4c438010938d8cfe8ce1ac69036065790e 100644 --- a/src/005-passages/eventsPassages.js +++ b/src/005-passages/eventsPassages.js @@ -16,6 +16,11 @@ new App.DomPassage("rebellionReport", return App.Events.rebellionReport(); } ); +new App.DomPassage("conflictHandler", + () => { + return App.Events.conflictHandler(); + } +); /* ### Random Events ### */ diff --git a/src/005-passages/facilitiesPassages.js b/src/005-passages/facilitiesPassages.js index 54fd59cb6dc4d9bd38a72258c50cb9e565a31f6c..181f17f2f513474ca345dee1286086921c3f2f76 100644 --- a/src/005-passages/facilitiesPassages.js +++ b/src/005-passages/facilitiesPassages.js @@ -1,4 +1,5 @@ /* ### Standard Facilities ### */ +new App.DomPassage("Arcade", () => { return new App.Facilities.Arcade.arcade().render(); }, ["jump-to-safe", "jump-from-safe"]); new App.DomPassage("Clinic", () => { return new App.Facilities.Clinic.clinic().render(); }, ["jump-to-safe", "jump-from-safe"]); diff --git a/src/Mods/SecExp/buildings/riotControlCenter.tw b/src/Mods/SecExp/buildings/riotControlCenter.tw index 6ab03a6c31d564d29dddacf1f0b14102e5a17fb3..5f875d557e0d6910dd67f30bf89b5876b53d3488 100644 --- a/src/Mods/SecExp/buildings/riotControlCenter.tw +++ b/src/Mods/SecExp/buildings/riotControlCenter.tw @@ -98,6 +98,7 @@ The riot control center opens its guarded doors to you. The great chamber inside <br><<link "Deploy the unit against slaves rebel leaders">> <<if $SecExp.buildings.riotCenter.upgrades.rapidUnitCost == 0>> <<set $SecExp.core.authority -= 1000 + 50 * $SecExp.buildings.riotCenter.upgrades.rapidUnit>> + <<set $SecExp.core.authority = Math.clamp($SecExp.core.authority, 0, 20000)>> <<else>> <<run repX(forceNeg(1000 + 50 * $SecExp.buildings.riotCenter.upgrades.rapidUnit), "war")>> <</if>> diff --git a/src/Mods/SecExp/buildings/secBarracks.tw b/src/Mods/SecExp/buildings/secBarracks.tw index 4a2cfd031e97600452b2b4f06ebd196c69968e19..d1f63a74a1682f7c8aba6f0bc22413160e2b764a 100644 --- a/src/Mods/SecExp/buildings/secBarracks.tw +++ b/src/Mods/SecExp/buildings/secBarracks.tw @@ -227,7 +227,7 @@ Your current maximum number of units is <<print App.SecExp.battle.maxUnits()>> ( <<set $SecExp.units.slaves.squads.push(App.SecExp.unit.gen("slaves"))>> <</link>> | <</if>> - <<includeDOM App.SecExp.unit.bulkUpgrade($SecExp.units.slaves.squads)>> + <<includeDOM App.SecExp.unit.bulkUpgrade($SecExp.units.slaves.squads, "slaves")>> <br> <<includeDOM App.UI.market({menialWorkersOnly: true})>> <<set _sL = $SecExp.units.slaves.squads.length>> @@ -264,7 +264,7 @@ Your current maximum number of units is <<print App.SecExp.battle.maxUnits()>> ( <</link>> <</if>> <</if>> - | <<includeDOM App.SecExp.unit.bulkUpgrade($SecExp.units.slaves.squads[_i])>> + | <<includeDOM App.SecExp.unit.bulkUpgrade($SecExp.units.slaves.squads[_i], "slaves")>> <<if $SecExp.settings.showStats == 1>> <<= App.SecExp.getUnit("slaves", _i).printStats()>> <</if>> <<includeDOM App.SecExp.unit.humanUpgradeList($SecExp.units.slaves.squads[_i])>> <</capture>> @@ -290,7 +290,7 @@ Your current maximum number of units is <<print App.SecExp.battle.maxUnits()>> ( <<set $SecExp.units.militia.squads.push(App.SecExp.unit.gen("militia"))>> <</link>> | <</if>> - <<includeDOM App.SecExp.unit.bulkUpgrade($SecExp.units.militia.squads)>> + <<includeDOM App.SecExp.unit.bulkUpgrade($SecExp.units.militia.squads, "militia")>> <br> <<set _mL = $SecExp.units.militia.squads.length>> @@ -327,7 +327,7 @@ Your current maximum number of units is <<print App.SecExp.battle.maxUnits()>> ( <</link>> <</if>> <</if>> - | <<includeDOM App.SecExp.unit.bulkUpgrade($SecExp.units.militia.squads[_i])>> + | <<includeDOM App.SecExp.unit.bulkUpgrade($SecExp.units.militia.squads[_i], "militia")>> <<if $SecExp.settings.showStats == 1>> <<= App.SecExp.getUnit("militia", _i).printStats()>> <</if>> <<includeDOM App.SecExp.unit.humanUpgradeList($SecExp.units.militia.squads[_i])>> <</capture>> @@ -344,7 +344,7 @@ Your current maximum number of units is <<print App.SecExp.battle.maxUnits()>> ( <<set $SecExp.units.mercs.squads.push(App.SecExp.unit.gen("mercs"))>> <</link>> | <</if>> - <<includeDOM App.SecExp.unit.bulkUpgrade($SecExp.units.mercs.squads)>> + <<includeDOM App.SecExp.unit.bulkUpgrade($SecExp.units.mercs.squads, "mercs")>> <br> <<set _meL = $SecExp.units.mercs.squads.length>> @@ -381,7 +381,7 @@ Your current maximum number of units is <<print App.SecExp.battle.maxUnits()>> ( <</link>> <</if>> <</if>> - | <<includeDOM App.SecExp.unit.bulkUpgrade($SecExp.units.mercs.squads[_i])>> + | <<includeDOM App.SecExp.unit.bulkUpgrade($SecExp.units.mercs.squads[_i], "mercs")>> <<if $SecExp.settings.showStats == 1>> <<= App.SecExp.getUnit("mercs", _i).printStats()>> <</if>> <<includeDOM App.SecExp.unit.humanUpgradeList($SecExp.units.mercs.squads[_i])>> <</capture>> diff --git a/src/Mods/SecExp/edicts.tw b/src/Mods/SecExp/edicts.tw index 810c785926a720811fed1d78a8716c4c218e5419..41fcdf1a6dab1f8ac2ff745f4722786233eb6f8d 100644 --- a/src/Mods/SecExp/edicts.tw +++ b/src/Mods/SecExp/edicts.tw @@ -9,6 +9,7 @@ <<if $SecExp.battles.victories + $SecExp.battles.losses > 0 || $SecExp.rebellions.victories + $SecExp.rebellions.losses > 0 || $mercenaries > 0>> <button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Military')" id="tab Military">Military</button> <</if>> +<<set $SecExp.core.authority = Math.clamp($SecExp.core.authority, 0, 20000)>> <div id="Society" class="tab-content"> <div class="content"> diff --git a/src/Mods/SecExp/events/attackHandler.tw b/src/Mods/SecExp/events/attackHandler.tw deleted file mode 100644 index 53a34b487e3e71fd58d8c0c580e6b24a25eee23d..0000000000000000000000000000000000000000 --- a/src/Mods/SecExp/events/attackHandler.tw +++ /dev/null @@ -1,480 +0,0 @@ -:: attackHandler [nobr] - -<<set $nextButton = " ", $nextLink = "attackReport", $encyclopedia = "Battles">> -<<set _isMajorBattle = $SecExp.war.type.includes("Major")>> - -<<if $SecExp.war.result == 1 || $SecExp.war.result == -1>> /* bribery/surrender check */ - <<if $SecExp.settings.showStats == 1>> - <<if $SecExp.war.result == 1>>Bribery<<else>>Surrender<</if>> chosen - <</if>> - <<if $SecExp.war.result == 1>> - <<if $cash >= App.SecExp.battle.bribeCost()>> /* if there's enough cash there's a 10% chance bribery fails. If there isn't there's instead a 50% chance it fails */ - <<if $SecExp.war.attacker.type == "freedom fighters" && random(1,100) <= 50 || random(1,100) <= 10>> - <<set $SecExp.war.result = 0>> - <</if>> - <<else>> - <<if random(1,100) <= 50>> <<set $SecExp.war.result = 0>> <</if>> - <</if>> - <<if $SecExp.settings.showStats == 1>> - <br>Bribery <<if $SecExp.war.result == 0>>failed<<else>>Successful<</if>>! - <br><br>[[proceed|attackReport]] - <<else>> - <<goto "attackReport">> - <</if>> - <<else>> - <<goto "attackReport">> - <</if>> -<<else>> - /*Init*/ - <<set _turns = 10>> - <<set _attack = 0>> - <<set _defense = 0>> - <<set _morale = 0>> - <<set _hp = 0>> - <<set _baseHp = 0>> - <<set _enemyAttack = 0>> - <<set _enemyDefense = 0>> - <<set _enemyMorale = 0>> - <<set _enemyHp = 0>> - <<set _enemyBaseHp = 0>> - <<set _tacChance = 0.5>> /* by default tactics have a 50% chance of succeeding */ - <<set _atkMod = 1>> - <<set _defMod = 1>> - <<set _militiaMod = 1>> - <<set _slaveMod = 1>> - <<set _mercMod = 1>> - <<set _enemyMod = 1>> - <<set _SFMod = 1>> - <<set _armyMod = 0>> - - /* major battle */ - <<if _isMajorBattle>> - <<set _militiaMod = 1.5>> - <<set _slaveMod = 1.5>> - <<set _mercMod = 1.5>> - <<set _enemyMod = 1.5>> - <<set _SFMod = 1.5>> - <<set _turns *= 2>> - <<if $SF.Toggle && $SF.Active >= 1>> - <<if $SF.Squad.Firebase >= 7>> - <<set _atkMod += ($SF.Squad.Firebase - 6) * 0.05>> - <</if>> - <<if $SF.Squad.GunS >= 1>> - <<set _defMod += $SF.Squad.GunS * 0.05>> - <</if>> - <<if $SF.Squad.Satellite >= 5 && $SF.SatLaunched > 0>> - <<set _atkMod += ($SF.Squad.Satellite - 5) * 0.05>> - <</if>> - <<if $SF.Squad.GiantRobot >= 6>> - <<set _defMod += ($SF.Squad.GiantRobot - 5) * 0.05>> - <</if>> - <<if $SF.Squad.MissileSilo >= 1>> - <<set _atkMod += $SF.Squad.MissileSilo * 0.05>> - <</if>> - <</if>> - <</if>> - - <<set _commanderEffectiveness = App.SecExp.commanderEffectiveness("handler")>> - <<set _slaveMod += _commanderEffectiveness.slaveMod>> - <<set _militiaMod += _commanderEffectiveness.militiaMod>> - <<set _mercMod += _commanderEffectiveness.mercMod>> - <<set _SFMod += _commanderEffectiveness.SFMod>> - <<set _enemyMod += _commanderEffectiveness.enemyMod>> - <<set _atkMod += _commanderEffectiveness.atkMod>> - <<set _defMod += _commanderEffectiveness.defMod>> - <<set _tacChance += _commanderEffectiveness.tacChance>> - - /* Terrain and Tactics */ - <<set _tacticsObj = App.Data.SecExp.TerrainAndTactics.get($SecExp.war.terrain)[$SecExp.war.chosenTactic]>> - <<set _atkMod += _tacticsObj.atkMod>> - <<set _defMod += _tacticsObj.defMod>> - <<set _tacChance += _tacticsObj.tacChance>> - - <<if $SecExp.war.chosenTactic == "Bait and Bleed">> - <<if $SecExp.war.attacker.type == "raiders">> - <<set _tacChance -= 0.10>> - <<elseif $SecExp.war.attacker.type == "free city">> - <<set _tacChance += 0.10>> - <<elseif $SecExp.war.attacker.type == "old world">> - <<set _tacChance += 0.25>> - <<elseif $SecExp.war.attacker.type == "freedom fighters">> - <<set _tacChance -= 0.15>> - <</if>> - <<elseif $SecExp.war.chosenTactic == "Guerrilla">> - <<if $SecExp.war.attacker.type == "raiders">> - <<set _tacChance -= 0.20>> - <<elseif $SecExp.war.attacker.type == "free city">> - <<set _tacChance += 0.15>> - <<elseif $SecExp.war.attacker.type == "old world">> - <<set _tacChance += 0.25>> - <<elseif $SecExp.war.attacker.type == "freedom fighters">> - <<set _tacChance -= 0.25>> - <</if>> - <<elseif $SecExp.war.chosenTactic == "Choke Points">> - <<if $SecExp.war.attacker.type == "raiders">> - <<set _tacChance += 0.25>> - <<elseif $SecExp.war.attacker.type == "free city">> - <<set _tacChance -= 0.05>> - <<elseif $SecExp.war.attacker.type == "old world">> - <<set _tacChance -= 0.10>> - <<elseif $SecExp.war.attacker.type == "freedom fighters">> - <<set _tacChance += 0.05>> - <</if>> - <<elseif $SecExp.war.chosenTactic == "Interior Lines">> - <<if $SecExp.war.attacker.type == "raiders">> - <<set _tacChance -= 0.15>> - <<elseif $SecExp.war.attacker.type == "free city">> - <<set _tacChance += 0.15>> - <<elseif $SecExp.war.attacker.type == "old world">> - <<set _tacChance += 0.20>> - <<elseif $SecExp.war.attacker.type == "freedom fighters">> - <<set _tacChance -= 0.10>> - <</if>> - <<elseif $SecExp.war.chosenTactic == "Pincer Maneuver">> - <<if $SecExp.war.attacker.type == "raiders">> - <<set _tacChance += 0.15>> - <<elseif $SecExp.war.attacker.type == "free city">> - <<set _tacChance += 0.10>> - <<elseif $SecExp.war.attacker.type == "old world">> - <<set _tacChance -= 0.10>> - <<elseif $SecExp.war.attacker.type == "freedom fighters">> - <<set _tacChance += 0.15>> - <</if>> - <<elseif $SecExp.war.chosenTactic == "Defense In Depth">> - <<if $SecExp.war.attacker.type == "raiders">> - <<set _tacChance -= 0.20>> - <<elseif $SecExp.war.attacker.type == "free city">> - <<set _tacChance += 0.10>> - <<elseif $SecExp.war.attacker.type == "old world">> - <<set _tacChance += 0.20>> - <<elseif $SecExp.war.attacker.type == "freedom fighters">> - <<set _tacChance -= 0.05>> - <</if>> - <<elseif $SecExp.war.chosenTactic == "Blitzkrieg">> - <<if $SecExp.war.attacker.type == "raiders">> - <<set _tacChance += 0.10>> - <<elseif $SecExp.war.attacker.type == "free city">> - <<set _tacChance -= 0.20>> - <<elseif $SecExp.war.attacker.type == "old world">> - <<set _tacChance += 0.25>> - <<elseif $SecExp.war.attacker.type == "freedom fighters">> - <<set _tacChance -= 0.10>> - <</if>> - <<elseif $SecExp.war.chosenTactic == "Human Wave">> - <<if $SecExp.war.attacker.type == "raiders">> - <<set _tacChance -= 0.10>> - <<elseif $SecExp.war.attacker.type == "free city">> - <<set _tacChance += 0.10>> - <<elseif $SecExp.war.attacker.type == "old world">> - <<set _tacChance -= 0.15>> - <<elseif $SecExp.war.attacker.type == "freedom fighters">> - <<set _tacChance += 0.10>> - <</if>> - <</if>> - - /* Calculates if tactics are successful */ - /* minimum chance is 10% */ - <<if _tacChance <= 0>> - <<set _tacChance = 0.1>> - <</if>> - <<if random(1,100) <= _tacChance * 100>> - <<set _enemyMod -= 0.30>> - <<set _militiaMod += 0.20>> - <<set _slaveMod += 0.20>> - <<set _mercMod += 0.20>> - <<set _atkMod += 0.10>> - <<set _defMod += 0.10>> - <<set $SecExp.war.tacticsSuccessful = 1>> - <<else>> - <<set _enemyMod += 0.20>> - <<set _militiaMod -= 0.20>> - <<set _slaveMod -= 0.20>> - <<set _mercMod -= 0.20>> - <<set _atkMod -= 0.10>> - <<set _defMod -= 0.10>> - <</if>> - - /* enemy morale mods */ - <<if $week < 30>> - <<set _enemyMod += 0.15>> - <<elseif $week < 60>> - <<set _enemyMod += 0.30>> - <<elseif $week < 90>> - <<set _enemyMod += 0.45>> - <<elseif $week < 120>> - <<set _enemyMod += 0.60>> - <<else>> - <<set _enemyMod += 0.75>> - <</if>> - - /* calculates PC army stats */ - <<if App.SecExp.battle.deployedUnits('bots')>> - <<set _unit = App.SecExp.getUnit("bots")>> - <<set _attack += _unit.attack * _atkMod>> - <<set _defense += _unit.defense * _defMod>> - <<set _hp += _unit.hp>> - <</if>> - <<for _i = 0; _i < $SecExp.units.militia.squads.length; _i++>> - <<if $SecExp.units.militia.squads[_i].isDeployed == 1>> - <<set _unit = App.SecExp.getUnit("militia", _i)>> - <<set _attack += _unit.attack * _atkMod>> - <<set _defense += _unit.defense * _defMod>> - <<set _hp += _unit.hp>> - <</if>> - <</for>> - <<for _i = 0; _i < $SecExp.units.slaves.squads.length; _i++>> - <<if $SecExp.units.slaves.squads[_i].isDeployed == 1>> - <<set _unit = App.SecExp.getUnit("slaves", _i)>> - <<set _attack += _unit.attack * _atkMod>> - <<set _defense += _unit.defense * _defMod>> - <<set _hp += _unit.hp>> - <</if>> - <</for>> - <<for _i = 0; _i < $SecExp.units.mercs.squads.length; _i++>> - <<if $SecExp.units.mercs.squads[_i].isDeployed == 1>> - <<set _unit = App.SecExp.getUnit("mercs", _i)>> - <<set _attack += _unit.attack * _atkMod>> - <<set _defense += _unit.defense * _defMod>> - <<set _hp += _unit.hp>> - <</if>> - <</for>> - - <<if $SF.Toggle && $SF.Active >= 1 && $SecExp.war.deploySF>> - <<set _unit = App.SecExp.getUnit("SF")>> - <<set _attack += _unit.attack>> - <<set _defense += _unit.defense>> - <<set _hp += _unit.hp>> - <</if>> - - /* morale and baseHp calculation */ - /* minimum modifier is -50%, maximum is +50% */ - <<if _militiaMod < 0.5>> - <<set _militiaMod = 0.5>> - <<elseif _militiaMod > 1.5>> - <<set _militiaMod = 1.5>> - <</if>> - <<if _slaveMod < 0.5>> - <<set _slaveMod = 0.5>> - <<elseif _slaveMod > 1.5>> - <<set _slaveMod = 1.5>> - <</if>> - <<if _mercMod < 0.5>> - <<set _mercMod = 0.5>> - <<elseif _mercMod > 1.5>> - <<set _mercMod = 1.5>> - <</if>> - <<if _SFMod < 0.5>> - <<set _SFMod = 0.5>> - <<elseif _SFMod > 1.5>> - <<set _SFMod = 1.5>> - <</if>> - - <<set _moraleTroopMod = Math.clamp(App.SecExp.battle.troopCount() / 100,1,5)>> - - <<set _morale = (App.SecExp.BaseDroneUnit.morale * $SecExp.units.bots.isDeployed + App.SecExp.BaseMilitiaUnit.morale * _militiaMod * App.SecExp.battle.deployedUnits('militia') + App.SecExp.BaseSlaveUnit.morale * _slaveMod * App.SecExp.battle.deployedUnits('slaves') + App.SecExp.BaseMercUnit.morale * _mercMod * App.SecExp.battle.deployedUnits('mercs') + App.SecExp.BaseSpecialForcesUnit.morale * $SecExp.war.deploySF * _SFMod) / ($SecExp.units.bots.isDeployed + App.SecExp.battle.deployedUnits('militia') + App.SecExp.battle.deployedUnits('slaves') + App.SecExp.battle.deployedUnits('mercs') + $SecExp.war.deploySF)>> - <<if $SecExp.buildings.barracks>> - <<set _morale = _morale + _morale * $SecExp.buildings.barracks.luxury * 0.05>> /* barracks bonus */ - <</if>> - <<set _morale *= _moraleTroopMod>> - <<set _baseHp = (App.SecExp.BaseDroneUnit.hp * $SecExp.units.bots.isDeployed + App.SecExp.BaseMilitiaUnit.hp * App.SecExp.battle.deployedUnits('militia') + App.SecExp.BaseSlaveUnit.hp * App.SecExp.battle.deployedUnits('slaves') + App.SecExp.BaseMercUnit.hp * App.SecExp.battle.deployedUnits('mercs') + App.SecExp.BaseSpecialForcesUnit.hp * $SecExp.war.deploySF) / ($SecExp.units.bots.isDeployed + App.SecExp.battle.deployedUnits('militia') + App.SecExp.battle.deployedUnits('slaves') + App.SecExp.battle.deployedUnits('mercs') + $SecExp.war.deploySF)>> - - /* calculates enemy army stats */ - <<if $week <= 30>> - <<set _armyMod = $SecExp.war.attacker.troops / 80>> - <<elseif $week <= 60>> - <<set _armyMod = $SecExp.war.attacker.troops / 75>> - <<elseif $week <= 90>> - <<set _armyMod = $SecExp.war.attacker.troops / 70>> - <<elseif $week <= 120>> - <<set _armyMod = $SecExp.war.attacker.troops / 65>> - <<else>> - <<set _armyMod = $SecExp.war.attacker.troops / 60>> - <</if>> - <<set _armyMod = Math.trunc(_armyMod)>> - <<if _isMajorBattle>> - <<set _armyMod *= 2>> - <</if>> - <<if _armyMod <= 0>> - <<set _armyMod = 1>> - <</if>> - - <<set _enemyMoraleTroopMod = Math.clamp($SecExp.war.attacker.troops / 100,1,5)>> - - <<set _unit = App.SecExp.getEnemyUnit($SecExp.war.attacker.type, $SecExp.war.attacker.troops, $SecExp.war.attacker.equip)>> - <<set _enemyAttack = _unit.attack * _armyMod>> - <<set _enemyDefense = _unit.defense * _armyMod>> - <<set _enemyMorale = _unit.morale * _enemyMod * _enemyMoraleTroopMod>> - <<set _enemyHp = _unit.hp>> - <<set _enemyBaseHp = _unit.hp / $SecExp.war.attacker.troops>> - - /* difficulty */ - <<set _enemyAttack *= $SecExp.settings.difficulty>> - <<set _enemyDefense *= $SecExp.settings.difficulty>> - <<set _enemyMorale *= $SecExp.settings.difficulty>> - <<set _enemyHp *= $SecExp.settings.difficulty>> - <<set _enemyBaseHp *= $SecExp.settings.difficulty>> - - <<if isNaN(_attack)>> - <br>@@.red;Error: attack value reported NaN@@ - <</if>> - <<if isNaN(_defense)>> - <br>@@.red;Error: defense value reported NaN@@ - <</if>> - <<if isNaN(_hp)>> - <br>@@.red;Error: hp value reported NaN@@ - <</if>> - <<if isNaN(_morale)>> - <br>@@.red;Error: morale value reported NaN@@ - <</if>> - <<if isNaN(_enemyAttack)>> - <br>@@.red;Error: enemy attack value reported NaN@@ - <</if>> - <<if isNaN(_enemyDefense)>> - <br>@@.red;Error: enemy defense value reported NaN@@ - <</if>> - <<if isNaN(_enemyHp)>> - <br>@@.red;Error: enemy hp value reported NaN@@ - <</if>> - <<if isNaN(_enemyMorale)>> - <br>@@.red;Error: enemy morale value reported NaN@@ - <</if>> - - <<if $SecExp.settings.showStats == 1>> - <<set _atkMod -= 1, _defMod -= 1, _militiaMod -= 1, _mercMod -= 1, _slaveMod -= 1, _SFMod -= 1, _enemyMod -= 1, _moraleTroopMod -= 1, _enemyMoraleTroopMod -= 1, _difficulty = $SecExp.settings.difficulty -1>> - <<set _atkMod = Math.round(_atkMod * 100)>> - <<set _defMod = Math.round(_defMod * 100)>> - <<set _militiaMod = Math.round(_militiaMod * 100)>> - <<set _mercMod = Math.round(_mercMod * 100)>> - <<set _slaveMod = Math.round(_slaveMod * 100)>> - <<set _SFMod = Math.round(_SFMod * 100)>> - <<set _enemyMod = Math.round(_enemyMod * 100)>> - <<if $SecExp.buildings.barracks>> - <<set _barracksBonus = $SecExp.buildings.barracks.luxury * 5>> - <</if>> - <<set _moraleTroopMod = Math.round(_moraleTroopMod * 100)>> - <<set _enemyMoraleTroopMod = Math.round(_enemyMoraleTroopMod * 100)>> - <<set _difficulty *= 100>> - - __Difficulty__:<br> - <<if $SecExp.settings.difficulty == 0.5>> - Very easy - <<elseif $SecExp.settings.difficulty == 0.75>> - Easy - <<elseif $SecExp.settings.difficulty == 1>> - Normal - <<elseif $SecExp.settings.difficulty == 1.25>> - Hard - <<elseif $SecExp.settings.difficulty == 1.5>> - Very hard - <<else>> - Extremely hard - <</if>> - <br><br>__Army__: - <br>troops: <<print num(Math.round(App.SecExp.battle.troopCount()))>> - <br>attack: <<print num(Math.round(_attack))>> - <br>defense: <<print num(Math.round(_defense))>> - <br>hp: <<print num(Math.round(_hp))>> - <br>morale: <<print num(Math.round(_morale))>> - <br>attack modifier: <<if _atkMod > 0>>+<</if>>_atkMod% - <br>defense modifier: <<if _defMod > 0>>+<</if>>_defMod% - <br>average base HP: <<print num(Math.round(_baseHp))>> - <br>militia morale modifier: <<if _militiaMod > 0>>+<</if>>_militiaMod% - <br>slaves morale modifier: <<if _slaveMod > 0>>+<</if>>_slaveMod% - <br>mercenaries morale modifier: <<if _mercMod > 0>>+<</if>>_mercMod% - <<if $SF.Toggle && $SF.Active >= 1 && $SecExp.war.deploySF>> - <br>special force morale modifier: <<if _SFMod > 0>>+<</if>>_SFMod% - <</if>> - <<if $SecExp.buildings.barracks && $SecExp.buildings.barracks.luxury >= 1>> - <br>Barracks bonus morale modifier: +<<print _barracksBonus>>% - <</if>> - <<if _moraleTroopMod>> - <br>morale increase due to troop numbers: +<<print _moraleTroopMod>>% - <</if>> - <br><br>__Tactics__: - <br>tactic chance of success: <<print num(Math.round(_tacChance * 100))>>% - <br>was tactic chosen successful?: <<if $SecExp.war.tacticsSuccessful == 1>> yes <<else>> no<</if>> - <br><br>__Enemy__: - <br>enemy troops: <<print num(Math.round($SecExp.war.attacker.troops))>> - <br>enemy attack: <<print num(Math.round(_enemyAttack))>> - <br>enemy defense: <<print num(Math.round(_enemyDefense))>> - <br>enemy Hp: <<print num(Math.round(_enemyHp))>> - <br>enemy morale: <<print num(Math.round(_enemyMorale))>> - <br>enemy base Hp: <<print num(Math.round(_enemyBaseHp))>> - <br>enemy morale modifier: <<if _enemyMod > 0>>+<</if>>_enemyMod% - <<if _enemyMoraleTroopMod > 0>> - <br>enemy morale increase due to troop numbers: +<<print _enemyMoraleTroopMod>>% - <</if>> - <br>Difficulty modifier: <<if _difficulty > 0>>+<</if>><<print _difficulty>>% - <</if>> - - /* simulates the combat by pitting attk against def */ - <<for _i = 0; _i < _turns; _i++>> - <<if $SecExp.settings.showStats == 1>> <br><br>turn: <<print _i + 1>><</if>> - /* player army attacks */ - <<set _damage = Math.clamp(_attack - _enemyDefense,_attack * 0.1,_attack)>> - <<if $SecExp.settings.showStats == 1>> <br>player damage: <<print num(Math.round(_damage))>><</if>> - <<set _enemyHp -= _damage>> - <<if $SecExp.settings.showStats == 1>> <br>remaining enemy Hp: <<print num(Math.round(_enemyHp))>><</if>> - <<set $SecExp.war.attacker.losses += _damage / _enemyBaseHp>> - <<set _moraleDamage = Math.clamp(_damage / 2 + _damage / _enemyBaseHp,0,_damage*1.5)>> - <<set _enemyMorale -= _moraleDamage>> - <<if $SecExp.settings.showStats == 1>> <br>remaining enemy morale: <<print num(Math.round(_enemyMorale))>><</if>> - <<if _enemyHp <= 0 || _enemyMorale <= 0>> - <<if $SecExp.settings.showStats == 1>> <br><br>Victory!<</if>> - <<set $SecExp.war.result = 3>> - <<set $SecExp.war.turns = _i>> - <<break>> - <</if>> - - /* attacker army attacks */ - <<set _damage = _enemyAttack - _defense>> - <<if _damage < _enemyAttack * 0.1>> - <<set _damage = _enemyAttack * 0.1>> - <</if>> - <<if $SecExp.settings.showStats == 1>> <br>enemy damage: <<print num(Math.round(_damage))>><</if>> - <<set _hp -= _damage>> - <<if $SecExp.settings.showStats == 1>> <br>remaining hp: <<print num(Math.round(_hp))>><</if>> - <<set $SecExp.war.losses += _damage / _baseHp>> - <<set _moraleDamage = Math.clamp(_damage / 2 + _damage / _baseHp,0,_damage*1.5)>> - <<set _morale -= _moraleDamage>> - <<if $SecExp.settings.showStats == 1>> <br>remaining morale: <<print Math.round(_morale)>><</if>> - <<if _hp <= 0 || _morale <= 0>> - <<if $SecExp.settings.showStats == 1>> <br><br>Defeat!<</if>> - <<set $SecExp.war.result = -3>> - <<set $SecExp.war.turns = _i>> - <<break>> - <</if>> - <</for>> - <<if $SecExp.war.result != 3 && $SecExp.war.result != -3>> - <<if _morale > _enemyMorale>> - <<if $SecExp.settings.showStats == 1>> <br><br>Partial victory!<</if>> - <<set $SecExp.war.result = 2>> - <<elseif _morale < _enemyMorale>> - <<if $SecExp.settings.showStats == 1>> <br><br>Partial defeat!<</if>> - <<set $SecExp.war.result = -2>> - <</if>> - <</if>> - - <<if $SecExp.settings.showStats == 1>> - <br><br>Losses: <<print num(Math.trunc($SecExp.war.losses))>> - <br>Enemy losses: <<print num(Math.trunc($SecExp.war.attacker.losses))>> - <</if>> - - <<if $SecExp.war.result > 3 || $SecExp.war.result < -3>> - <br><br>@@.red;Error: failed to determine battle result@@ - <</if>> - - <<if $SecExp.settings.showStats == 1>> - <<if _isMajorBattle && $SecExp.settings.battle.major.gameOver == 1 && $SecExp.war.result == -3>> - <br><br>[[Proceed|Gameover][$gameover = "major battle defeat"]] - <<else>> - <br><br>[[Proceed|attackReport]] - <</if>> - <<else>> - <<if _isMajorBattle && $SecExp.settings.battle.major.gameOver == 1 && $SecExp.war.result == -3>> - <<set $gameover = "major battle defeat">> <<goto "Gameover">> - <<else>> - <<goto "attackReport">> - <</if>> - <</if>> -<</if>> /* closes check for bribery */ diff --git a/src/Mods/SecExp/events/attackOptions.js b/src/Mods/SecExp/events/attackOptions.js index 5dba892c3bb86be316b2f83c608c8188d88f440e..6c9ca8efa905e29169e4d042e3ee197ddd564f42 100644 --- a/src/Mods/SecExp/events/attackOptions.js +++ b/src/Mods/SecExp/events/attackOptions.js @@ -370,7 +370,7 @@ App.Events.attackOptions = class attackOptions extends App.Events.BaseEvent { V.SecExp.war.result = 4; V.SecExp.war.foughtThisWeek = 1; /* sets V.SecExp.war.result value outside accepted range (-3, 3) to avoid evaluation problems */ - }, `attackHandler`); + }, `conflictHandler`); } else { App.UI.DOM.appendNewElement("div", node, `You need at least a unit in your roster to proceed to battle.`, "red"); } @@ -381,7 +381,7 @@ App.Events.attackOptions = class attackOptions extends App.Events.BaseEvent { option.addButton(`Attempt to bribe`, () => { V.SecExp.war.result = 1; V.SecExp.war.foughtThisWeek = 1; - }, `attackHandler`); + }, `conflictHandler`); option.addComment(`Will cost around ${cashFormat(Math.round(App.SecExp.battle.bribeCost() * (1 + either(-1, 1) * random(2) * 0.1)))} (estimate).`); node.append(options.render()); diff --git a/src/Mods/SecExp/events/attackReport.js b/src/Mods/SecExp/events/attackReport.js index eb580efad45a678de070225e81cc14d784321ad2..659aa823efeb7093b3dcb8643998fc78cd2ebfaf 100644 --- a/src/Mods/SecExp/events/attackReport.js +++ b/src/Mods/SecExp/events/attackReport.js @@ -2,6 +2,67 @@ App.Events.attackReport = function() { V.nextButton = "Continue"; V.nextLink = "Scheduled Event"; V.encyclopedia = "Battles"; + const casualtiesReport = function(type, loss, squad=null) { + const isSpecial = squad && App.SecExp.unit.list().slice(1).includes(type); + let r = []; + if (loss <= 0) { + r.push(`No`); + } else if (loss <= (isSpecial ? (squad.troops * 0.2) : 10)) { + r.push(`Light`); + } else if (loss <= (isSpecial ? (squad.troops * 0.4) : 30)) { + r.push(`Moderate`); + } else if (loss <= (isSpecial ? (squad.troops * 0.6) : 60)) { + r.push(`Heavy`); + } else { + r.push(`Catastrophic`); + } + r.push(`casualties suffered.`); + if (App.SecExp.unit.list().includes(type)) { + if (squad.troops <= 0) { + squad.active = 0; + r.push(`Unfortunately the losses they took were simply too great, their effective combatants are in so small number you can no longer call them a deployable unit.`); + if (type === "bots") { + r.push(`It will take quite the investment to rebuild them.`); + } else { + r.push(`The remnants will be sent home honored as veterans or reorganized in a new unit.`); + } + } else if (squad.troops <= 10) { + r.push(`The unit has very few operatives left, it risks complete annihilation if deployed again.`); + } + } + return r.join(" "); + }; + function loopThroughUnits(units, type) { + for (const unit of units) { + if (App.SecExp.unit.isDeployed(unit)) { + if (V.SecExp.war.losses > 0) { + loss = lossesList.pluck(); + loss = Math.clamp(loss, 0, unit.troops); + } + + const r = [`${type !== "bots" ? `${unit.platoonName}` : `Security drones`}: ${casualtiesReport(type, loss, unit)}`]; + if (type !== "bots") { + unit.battlesFought++; + if (loss > 0) { + const med = Math.round(Math.clamp(loss * unit.medics * 0.25, 1, loss)); + if (unit.medics === 1) { + r.push(`Some men were saved by their medics.`); + } + unit.troops -= Math.trunc(Math.clamp(loss - med, 0, unit.maxTroops)); + V.SecExp.units[type].dead += Math.trunc(loss - med); + } + if (unit.training < 100 && random(1, 100) > 60) { + r.push(`Experience has increased.`); + unit.training += random(5, 15) + (majorBattle ? 1 : 0) * random(5, 15); + } + } else if (type === "bots" && loss > 0) { + unit.troops -= loss; + } + App.Events.addNode(node, r, "div"); + } + } + } + const node = new DocumentFragment(); let r = []; @@ -12,6 +73,7 @@ App.Events.attackReport = function() { V.SecExp.core.totalKills += V.SecExp.war.attacker.losses; V.SecExp.war.losses = Math.trunc(V.SecExp.war.losses); let loot = 0; + let loss = 0; let captives; const lossesList = []; @@ -477,6 +539,7 @@ App.Events.attackReport = function() { repX(forceNeg(800 * majorBattleMod), "war"); V.SecExp.core.authority -= 800 * majorBattleMod; } + V.SecExp.core.authority = Math.clamp(V.SecExp.core.authority, 0, 20000); App.Events.addParagraph(node, r); r = []; r.push(`Fortunately the arcology survives <span class="yellow">mostly intact,</span> however reports of <span class="red">mass looting and killing of citizens</span> flood your office for a few days.`); @@ -923,174 +986,68 @@ App.Events.attackReport = function() { function unitsBattleReport() { const el = document.createElement("div"); - if (V.SecExp.war.losses === 0) { - if (App.SecExp.battle.deployedUnits('bots')) { - App.UI.DOM.appendNewElement("div", el, `Security Drones: no casualties.`); - } - if (V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) { - App.UI.DOM.appendNewElement("div", el, `${num(V.SF.ArmySize)} soldiers from ${V.SF.Lower} joined the battle: no casualties suffered`); - } - const noCasualties = function(units) { - for (const unit of units) { - if (unit.isDeployed === 1) { - const r = [`${unit.platoonName}: no casualties.`]; - unit.battlesFought++; - if (unit.training < 100) { - if (random(1, 100) > 60) { - r.push(`Experience has increased.`); - unit.training += random(5, 15) + (majorBattle ? 1 : 0) * random(5, 15); - } - } - App.Events.addNode(el, r, "div"); + if (V.SecExp.war.losses >= 0) { + if (V.SecExp.war.losses > 0) { + // if the losses are more than zero + // generates a list of randomized losses, from which each unit picks one at random + let losses = V.SecExp.war.losses; + const averageLosses = Math.trunc(losses / App.SecExp.battle.deployedUnits()); + let assignedLosses; + for (let i = 0; i < App.SecExp.battle.deployedUnits(); i++) { + assignedLosses = Math.trunc(Math.clamp(averageLosses + random(-5, 5), 0, 100)); + if (assignedLosses > losses) { + assignedLosses = losses; + losses = 0; + } else { + losses -= assignedLosses; } + lossesList.push(assignedLosses); } - }; - if (App.SecExp.battle.deployedUnits('militia') >= 1) { - noCasualties(V.SecExp.units.militia.squads); - } - if (App.SecExp.battle.deployedUnits('slaves') >= 1) { - noCasualties(V.SecExp.units.slaves.squads); - } - if (App.SecExp.battle.deployedUnits('mercs') >= 1) { - noCasualties(V.SecExp.units.mercs.squads); - } - } else if (V.SecExp.war.losses > 0) { - // if the losses are more than zero - // generates a list of randomized losses, from which each unit picks one at random - let losses = V.SecExp.war.losses; - const averageLosses = Math.trunc(losses / App.SecExp.battle.deployedUnits()); - let assignedLosses; - for (let i = 0; i < App.SecExp.battle.deployedUnits(); i++) { - assignedLosses = Math.trunc(Math.clamp(averageLosses + random(-5, 5), 0, 100)); - if (assignedLosses > losses) { - assignedLosses = losses; - losses = 0; - } else { - losses -= assignedLosses; - } - lossesList.push(assignedLosses); - } - if (losses > 0) { - lossesList[random(lossesList.length - 1)] += losses; - } - lossesList.shuffle(); - - // sanity check for losses - let count = 0; - for (let i = 0; i < lossesList.length; i++) { - if (!Number.isInteger(lossesList[i])) { - lossesList[i] = 0; + if (losses > 0) { + lossesList[random(lossesList.length - 1)] += losses; } - count += lossesList[i]; - } - if (count < V.SecExp.war.losses) { - const rand = random(lossesList.length - 1); - lossesList[rand] += V.SecExp.war.losses - count; - } else if (count > V.SecExp.war.losses) { - const diff = count - V.SecExp.war.losses; - const rand = random(lossesList.length - 1); - lossesList[rand] = Math.clamp(lossesList[rand] - diff, 0, 100); - } + lossesList.shuffle(); - // assigns the losses and notify the player - if (App.SecExp.battle.deployedUnits('bots')) { - let loss = lossesList.pluck(); - loss = Math.clamp(loss, 0, V.SecExp.units.bots.troops); - V.SecExp.units.bots.troops -= loss; - const r = [`Security drones:`]; - if (loss <= 0) { - r.push(`no casualties`); - } else if (loss <= V.SecExp.units.bots.troops * 0.2) { - r.push(`light casualties`); - } else if (loss <= V.SecExp.units.bots.troops * 0.4) { - r.push(`moderate casualties`); - } else if (loss <= V.SecExp.units.bots.troops * 0.6) { - r.push(`heavy casualties`); - } else { - r.push(`catastrophic casualties`); + // sanity check for losses + let count = 0; + for (let i = 0; i < lossesList.length; i++) { + if (!Number.isInteger(lossesList[i])) { + lossesList[i] = 0; + } + count += lossesList[i]; } - r.push(`suffered.`); - if (V.SecExp.units.bots.troops <= 5) { - V.SecExp.units.bots.active = 0; - r.push(`Unfortunately the losses they took were simply too great, their effective combatants are in so small number you can no longer call them a deployable unit. It will take quite the investment to rebuild them.`); - } else if (V.SecExp.units.bots.troops <= 10) { - r.push(`The unit has very few operatives left, it risks complete annihilation if deployed again.`); + if (count < V.SecExp.war.losses) { + const rand = random(lossesList.length - 1); + lossesList[rand] += V.SecExp.war.losses - count; + } else if (count > V.SecExp.war.losses) { + const diff = count - V.SecExp.war.losses; + const rand = random(lossesList.length - 1); + lossesList[rand] = Math.clamp(lossesList[rand] - diff, 0, 100); } - App.Events.addNode(el, r, "div"); } + if (V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) { - let loss = lossesList.pluck(); - loss = Math.clamp(loss, 0, V.SF.ArmySize); - const r = [`${num(V.SF.ArmySize)} soldiers from ${V.SF.Lower} joined the battle:`]; - if (loss <= 0) { - r.push(`no casualties`); - } else if (loss <= 10) { - r.push(`light casualties`); - } else if (loss <= 30) { - r.push(`moderate casualties`); - } else if (loss <= 60) { - r.push(`heavy casualties`); - } else { - r.push(`catastrophic casualties`); + if (V.SecExp.war.losses > 0) { + loss = lossesList.pluck(); + loss = Math.clamp(loss, 0, V.SF.ArmySize); + V.SF.ArmySize -= loss; } - r.push(`suffered.`); - V.SF.ArmySize -= loss; - App.Events.addNode(el, r, "div"); - } - if (App.SecExp.battle.deployedUnits('militia') >= 1) { - loopThroughUnits(V.SecExp.units.militia.squads); - } - if (App.SecExp.battle.deployedUnits('slaves') >= 1) { - loopThroughUnits(V.SecExp.units.slaves.squads); + App.UI.DOM.appendNewElement("div", el, `${num(V.SF.ArmySize)} soldiers from ${V.SF.Lower} joined the battle: casualtiesReport(type, loss)`); + } - if (App.SecExp.battle.deployedUnits('mercs') >= 1) { - loopThroughUnits(V.SecExp.units.mercs.squads); + for (const unitClass of App.SecExp.unit.list()) { + if (App.SecExp.battle.deployedUnits(unitClass) >= 1) { + if (unitClass !== 'bots') { + loopThroughUnits(V.SecExp.units[unitClass].squads, unitClass); + } else { + loopThroughUnits([V.SecExp.units.bots], unitClass); + } + } } } else { App.UI.DOM.appendNewElement("div", el, `Error: losses are a negative number or NaN`, "red"); }// closes check for more than zero casualties - return el; - function loopThroughUnits(units) { - for (const unit of units) { - if (unit.isDeployed === 1) { - unit.battlesFought++; - let loss = lossesList.pluck(); - loss = Math.clamp(loss, 0, unit.troops); - const r = [`${unit.platoonName}:`]; - if (loss <= 0) { - r.push(`no casualties`); - } else if (loss <= unit.troops * 0.2) { - r.push(`light casualties`); - } else if (loss <= unit.troops * 0.4) { - r.push(`moderate casualties`); - } else if (loss <= unit.troops * 0.6) { - r.push(`heavy casualties`); - } else { - r.push(`catastrophic casualties`); - } - r.push(`suffered.`); - const med = Math.round(Math.clamp(loss * unit.medics * 0.25, 1, loss)); - if (unit.medics === 1 && loss > 0) { - r.push(`Some men were saved by their medics.`); - } - unit.troops -= Math.trunc(Math.clamp(loss - med, 0, unit.maxTroops)); - V.SecExp.units.militia.dead += Math.trunc(loss - med); - if (unit.training < 100) { - if (random(1, 100) > 60) { - r.push(`Experience has increased.`); - unit.training += random(5, 15) + (majorBattle ? 1 : 0) * random(5, 15); - } - } - App.Events.addNode(el, r, "div"); - if (unit.troops <= 5) { - unit.active = 0; - App.UI.DOM.appendNewElement("div", el, `Unfortunately the losses they took were simply too great, their effective combatants are in so small number you can no longer call them a deployable unit. The remnants will be sent home honored as veterans or reorganized in a new unit.`); - } else if (unit.troops <= 10) { - App.UI.DOM.appendNewElement("div", el, `The unit has very few operatives left, it risks complete annihilation if deployed again.`); - } - } - } - } + return el; } }; diff --git a/src/Mods/SecExp/events/conflictHandler.js b/src/Mods/SecExp/events/conflictHandler.js new file mode 100644 index 0000000000000000000000000000000000000000..bce5b4a15b1e19593956e3d3b91443d7c4b2b182 --- /dev/null +++ b/src/Mods/SecExp/events/conflictHandler.js @@ -0,0 +1,546 @@ +App.Events.conflictHandler = function() { + V.nextButton = " "; + V.encyclopedia = "Battles"; + + const node = new DocumentFragment(); + const showStats = V.SecExp.settings.showStats === 1; + const inBattle = V.SecExp.war.type.includes("Attack"); + const isMajorBattle = inBattle && V.SecExp.war.type.includes("Major"); + const inRebellion = V.SecExp.war.type.includes("Rebellion"); + const turns = (isMajorBattle || inRebellion) ? 20 : 10; + const showProgress = function(message, tag = "div") { + if (showStats) { + App.UI.DOM.appendNewElement(tag, node, message); + } + }; + const setResult = function(varA, varB, text, value, count) { + if (varA <= 0 || varB <= 0) { + showProgress(`${text}!`, "div"); + V.SecExp.war.result = value; + V.SecExp.war.turns = count; + } + }; + const atEnd = function(passage) { + if (showStats) { + App.UI.DOM.appendNewElement("div", node, App.UI.DOM.passageLink("Proceed", passage)); + } else { + setTimeout(() => Engine.play(passage), Engine.minDomActionDelay); + } + }; + const enemy = function() { + const node = new DocumentFragment(); + App.UI.DOM.appendNewElement("div", node, `${inBattle ? 'Enemy' : 'Rebels'}`, "underline"); + App.UI.DOM.appendNewElement("div", node, `Troops: ${num(Math.round(V.SecExp.war.attacker.troops))}`); + App.UI.DOM.appendNewElement("div", node, `Attack: ${num(Math.round(enemyAttack))}`); + App.UI.DOM.appendNewElement("div", node, `Defense: ${num(Math.round(enemyDefense))}`); + App.UI.DOM.appendNewElement("div", node, `HP: ${num(Math.round(enemyHp))}. Base: ${num(Math.round(enemyBaseHp))}`); + App.UI.DOM.appendNewElement("div", node, `Morale: ${num(Math.round(enemyMorale))}. ${inBattle ? `Modifier: ${num(Math.round(enemyMod))}.` : ``} Increase due to troop numbers: +${enemyMoraleTroopMod}%.`); + return node; + }; + const turnReport = function() { + showProgress(`Turn: ${i + 1}`); + // player army attacks + damage = Math.clamp(attack -enemyDefense, attack * 0.1, attack); + showProgress(`Player damage: ${num(Math.round(damage))}`); + enemyHp -= damage; + showProgress(`Remaining enemy Hp: ${num(Math.round(enemyHp))}`); + V.SecExp.war.attacker.losses += damage / enemyBaseHp; + moraleDamage = Math.clamp(damage / 2 + damage / enemyBaseHp, 0, damage * 1.5); + enemyMorale -= moraleDamage; + showProgress(`Remaining enemy morale: ${num(Math.round(enemyMorale))}`); + setResult(enemyHp, enemyMorale, 'Victory', 3, i); + + // attacker army attacks + damage = enemyAttack - defense; + if (damage < enemyAttack * 0.1) { + damage = enemyAttack * 0.1; + } + showProgress(`Enemy damage: ${num(Math.round(damage))}`); + hp -= damage * (inRebellion && V.SecExp.rebellions.sfArmor ? 0.85 : 1); + showProgress(`Remaining hp: ${num(Math.round(hp))}`); + V.SecExp.war.losses += damage / baseHp; + moraleDamage = Math.clamp(damage / 2 + damage / baseHp, 0, damage * 1.5); + morale -= moraleDamage; + showProgress(`Remaining morale: ${num(Math.round(morale))}`); + setResult(hp, morale, 'Defeat', -3, i); + }; + + let unitData; + let damage; + let moraleDamage; + let baseHp; + let enemyBaseHp; + let enemyMorale; + let attack = 0; + let defense = 0; + let morale = 0; + let hp = 0; + let enemyAttack = 0; + let enemyDefense = 0; + let enemyHp = 0; + let atkMod = 1; + let defMod = 1; + let armyMod = V.SecExp.war.attacker.troops / (inBattle ? 80 : 100); + // Battles + let militiaMod = (isMajorBattle) ? 1.5 : 1; + let slaveMod = (isMajorBattle) ? 1.5 : 1; + let mercMod = (isMajorBattle) ? 1.5 : 1; + let enemyMod = (isMajorBattle) ? 1.5 : 1; + let SFMod = (isMajorBattle) ? 1.5 : 1; + let tacChance = 0.5; // by default tactics have a 50% chance of succeeding + // Rebellions + let irregularMod = V.SecExp.war.irregulars / 60; + let engageMod = 0.5; // V.SecExp.war.engageRule === 0 + let rebellingSlaves = 0; + let rebellingMilitia = 0; + let rebellingMercs = 0; + + if (inBattle && V.SecExp.war.result === 1 || V.SecExp.war.result === -1) { // bribery/surrender check + showProgress(`${V.SecExp.war.result === 1 ? 'Bribery' : 'Surrender'} chosen`); + if (inBattle && V.SecExp.war.result === 1) { + if (V.cash >= App.SecExp.battle.bribeCost()) { // if there's enough cash there's a 10% chance bribery fails. If there isn't there's instead a 50% chance it fails + if (V.SecExp.war.attacker.type === "freedom fighters" && random(1, 100) <= 50 || random(1, 100) <= 10) { + V.SecExp.war.result = 0; + } + } else { + if (random(1, 100) <= 50) { + V.SecExp.war.result = 0; + } + } + showProgress(`${V.SecExp.war.result === 0 ? 'Failed' : 'Successful'}!`, "span"); + } + } + + if (inBattle) { + if (isMajorBattle) { + if (V.SF.Toggle && V.SF.Active >= 1) { + if (V.SF.Squad.Firebase >= 7) { + atkMod += (V.SF.Squad.Firebase - 6) * 0.05; + } + if (V.SF.Squad.GunS >= 1) { + defMod += V.SF.Squad.GunS * 0.05; + } + if (V.SF.Squad.Satellite >= 5 && V.SF.SatLaunched > 0) { + atkMod += (V.SF.Squad.Satellite - 5) * 0.05; + } + if (V.SF.Squad.GiantRobot >= 6) { + defMod += (V.SF.Squad.GiantRobot - 5) * 0.05; + } + if (V.SF.Squad.MissileSilo >= 1) { + atkMod += V.SF.Squad.MissileSilo * 0.05; + } + } + } + + const commanderEffectiveness = App.SecExp.commanderEffectiveness("handler"); + slaveMod += commanderEffectiveness.slaveMod; + militiaMod += commanderEffectiveness.militiaMod; + mercMod += commanderEffectiveness.mercMod; + SFMod += commanderEffectiveness.SFMod; + enemyMod += commanderEffectiveness.enemyMod; + atkMod += commanderEffectiveness.atkMod; + defMod += commanderEffectiveness.defMod; + tacChance += commanderEffectiveness.tacChance; + + // Terrain and Tactics + const tacticsObj = App.Data.SecExp.TerrainAndTactics.get(V.SecExp.war.terrain)[V.SecExp.war.chosenTactic]; + atkMod += tacticsObj.atkMod; + defMod += tacticsObj.defMod; + tacChance += tacticsObj.tacChance; + + if (V.SecExp.war.chosenTactic === "Bait and Bleed") { + if (V.SecExp.war.attacker.type === "raiders") { + tacChance -= 0.10; + } else if (V.SecExp.war.attacker.type === "free city") { + tacChance += 0.10; + } else if (V.SecExp.war.attacker.type === "old world") { + tacChance += 0.25; + } else if (V.SecExp.war.attacker.type === "freedom fighters") { + tacChance -= 0.15; + } + } else if (V.SecExp.war.chosenTactic === "Guerrilla") { + if (V.SecExp.war.attacker.type === "raiders") { + tacChance -= 0.20; + } else if (V.SecExp.war.attacker.type === "free city") { + tacChance += 0.15; + } else if (V.SecExp.war.attacker.type === "old world") { + tacChance += 0.25; + } else if (V.SecExp.war.attacker.type === "freedom fighters") { + tacChance -= 0.25; + } + } else if (V.SecExp.war.chosenTactic === "Choke Points") { + if (V.SecExp.war.attacker.type === "raiders") { + tacChance += 0.25; + } else if (V.SecExp.war.attacker.type === "free city") { + tacChance -= 0.05; + } else if (V.SecExp.war.attacker.type === "old world") { + tacChance -= 0.10; + } else if (V.SecExp.war.attacker.type === "freedom fighters") { + tacChance += 0.05; + } + } else if (V.SecExp.war.chosenTactic === "Interior Lines") { + if (V.SecExp.war.attacker.type === "raiders") { + tacChance -= 0.15; + } else if (V.SecExp.war.attacker.type === "free city") { + tacChance += 0.15; + } else if (V.SecExp.war.attacker.type === "old world") { + tacChance += 0.20; + } else if (V.SecExp.war.attacker.type === "freedom fighters") { + tacChance -= 0.10; + } + } else if (V.SecExp.war.chosenTactic === "Pincer Maneuver") { + if (V.SecExp.war.attacker.type === "raiders") { + tacChance += 0.15; + } else if (V.SecExp.war.attacker.type === "free city") { + tacChance += 0.10; + } else if (V.SecExp.war.attacker.type === "old world") { + tacChance -= 0.10; + } else if (V.SecExp.war.attacker.type === "freedom fighters") { + tacChance += 0.15; + } + } else if (V.SecExp.war.chosenTactic === "Defense In Depth") { + if (V.SecExp.war.attacker.type === "raiders") { + tacChance -= 0.20; + } else if (V.SecExp.war.attacker.type === "free city") { + tacChance += 0.10; + } else if (V.SecExp.war.attacker.type === "old world") { + tacChance += 0.20; + } else if (V.SecExp.war.attacker.type === "freedom fighters") { + tacChance -= 0.05; + } + } else if (V.SecExp.war.chosenTactic === "Blitzkrieg") { + if (V.SecExp.war.attacker.type === "raiders") { + tacChance += 0.10; + } else if (V.SecExp.war.attacker.type === "free city") { + tacChance -= 0.20; + } else if (V.SecExp.war.attacker.type === "old world") { + tacChance += 0.25; + } else if (V.SecExp.war.attacker.type === "freedom fighters") { + tacChance -= 0.10; + } + } else if (V.SecExp.war.chosenTactic === "Human Wave") { + if (V.SecExp.war.attacker.type === "raiders") { + tacChance -= 0.10; + } else if (V.SecExp.war.attacker.type === "free city") { + tacChance += 0.10; + } else if (V.SecExp.war.attacker.type === "old world") { + tacChance -= 0.15; + } else if (V.SecExp.war.attacker.type === "freedom fighters") { + tacChance += 0.10; + } + } + tacChance = Math.clamp(tacChance, 0.1, tacChance); // Calculates if tactics are successful - minimum chance is 10% + + if (random(1, 100) <= tacChance * 100) { + enemyMod -= 0.30; + militiaMod += 0.20; + slaveMod += 0.20; + mercMod += 0.20; + atkMod += 0.10; + defMod += 0.10; + V.SecExp.war.tacticsSuccessful = 1; + } else { + enemyMod += 0.20; + militiaMod -= 0.20; + slaveMod -= 0.20; + mercMod -= 0.20; + atkMod -= 0.10; + defMod -= 0.10; + } + + // enemy morale mods + if (V.week < 30) { + enemyMod += 0.15; + } else if (V.week < 60) { + enemyMod += 0.30; + } else if (V.week < 90) { + enemyMod += 0.45; + } else if (V.week < 120) { + enemyMod += 0.60; + } else { + enemyMod += 0.75; + } + } + + // calculates PC army stats + if (inRebellion) { + if (V.SecExp.war.engageRule === 1) { + engageMod = 0.75; + } else if (V.SecExp.war.engageRule === 2) { + engageMod = 1; + } else if (V.SecExp.war.engageRule > 2) { + engageMod = 1.4; + } + + if (V.week > 30 && V.week <= 60) { + irregularMod = V.SecExp.war.irregulars / 50; + } else if (V.week <= 90) { + irregularMod = V.SecExp.war.irregulars / 40; + } else if (V.week <= 120) { + irregularMod = V.SecExp.war.irregulars / 30; + } else { + irregularMod = V.SecExp.war.irregulars / 20; + } + if (V.SecExp.war.irregulars > 0) { + irregularMod = Math.trunc(irregularMod); + unitData = App.SecExp.getIrregularUnit("militia", V.SecExp.war.irregulars, V.SecExp.war.attacker.equip); + attack += unitData.attack * irregularMod * 0.80; + defense += unitData.defense * irregularMod * 0.80; + hp += unitData.hp; + } + } + + if (inBattle && App.SecExp.battle.deployedUnits('bots') || inRebellion && V.SecExp.units.bots.active === 1) { + unitData = App.SecExp.getUnit("bots"); + attack += unitData.attack * atkMod; + defense += unitData.defense * defMod; + hp += unitData.hp; + } + + for (const unit of App.SecExp.unit.list().slice(1)) { + for (let i = 0; i < V.SecExp.units[unit].squads.length; i++) { + if (App.SecExp.unit.isDeployed(V.SecExp.units[unit].squads[i])) { + unitData = App.SecExp.getUnit(unit, i); + attack += unitData.attack * atkMod; + defense += unitData.defense * defMod; + hp += unitData.hp; + } + } + } + + if (V.SF.Toggle && V.SF.Active >= 1 && (inBattle && V.SecExp.war.deploySF || inRebellion)) { + unitData = App.SecExp.getUnit("SF"); + attack += unitData.attack; + defense += unitData.defense; + hp += unitData.hp; + } + + if (inRebellion && V.SecExp.war.assistantDefense) { + attack *= 0.95; + defense *= 0.95; + hp *= 0.95; + } + if (inRebellion && V.SecExp.war.reactorDefense) { + attack *= 0.95; + defense *= 0.95; + hp *= 0.95; + } + if (inRebellion && V.SecExp.war.penthouseDefense) { + attack *= 0.95; + defense *= 0.95; + hp *= 0.95; + } + if (inRebellion && V.SecExp.war.waterwayDefense) { + attack *= 0.95; + defense *= 0.95; + hp *= 0.95; + } + + // morale and baseHp calculation + if (inBattle) { // minimum modifier is -50%, maximum is +50% + slaveMod = Math.clamp(slaveMod, 0.5, 1.5); + militiaMod = Math.clamp(militiaMod, 0.5, 1.5); + mercMod = Math.clamp(mercMod, 0.5, 1.5); + SFMod = Math.clamp(SFMod, 0.5, 1.5); + } + let moraleTroopMod = Math.clamp(App.SecExp.battle.troopCount() / 100, 1, (inBattle ? 5 : 10)); + + if (inBattle) { + morale += (App.SecExp.BaseDroneUnit.morale * V.SecExp.units.bots.isDeployed + App.SecExp.BaseMilitiaUnit.morale * militiaMod * App.SecExp.battle.deployedUnits('militia') + App.SecExp.BaseSlaveUnit.morale * slaveMod * App.SecExp.battle.deployedUnits('slaves') + App.SecExp.BaseMercUnit.morale * mercMod * App.SecExp.battle.deployedUnits('mercs') + App.SecExp.BaseSpecialForcesUnit.morale * V.SecExp.war.deploySF * SFMod) / (V.SecExp.units.bots.isDeployed + App.SecExp.battle.deployedUnits('militia') + App.SecExp.battle.deployedUnits('slaves') + App.SecExp.battle.deployedUnits('mercs') + V.SecExp.war.deploySF); + if (V.SecExp.buildings.barracks) { + morale = morale + morale * V.SecExp.buildings.barracks.luxury * 0.05; // barracks bonus + } + } else { + morale += (App.SecExp.BaseDroneUnit.morale * V.SecExp.units.bots.active + App.SecExp.BaseMilitiaUnit.morale * App.SecExp.battle.deployedUnits('militia') + App.SecExp.BaseSlaveUnit.morale * App.SecExp.battle.deployedUnits('slaves') + App.SecExp.BaseMercUnit.morale * App.SecExp.battle.deployedUnits('mercs') + App.SecExp.BaseSpecialForcesUnit.morale * V.SF.Active) / (V.SecExp.units.bots.active + App.SecExp.battle.deployedUnits('militia') + App.SecExp.battle.deployedUnits('slaves') + App.SecExp.battle.deployedUnits('mercs') + V.SF.Active); + morale += morale * (V.SecExp.buildings.barracks ? V.SecExp.buildings.barracks.luxury * 0.05 : 0); // barracks bonus + } + morale *= moraleTroopMod; + if (inBattle) { + baseHp = (App.SecExp.BaseDroneUnit.hp * V.SecExp.units.bots.isDeployed + App.SecExp.BaseMilitiaUnit.hp * App.SecExp.battle.deployedUnits('militia') + App.SecExp.BaseSlaveUnit.hp * App.SecExp.battle.deployedUnits('slaves') + App.SecExp.BaseMercUnit.hp * App.SecExp.battle.deployedUnits('mercs') + App.SecExp.BaseSpecialForcesUnit.hp * V.SecExp.war.deploySF) / (V.SecExp.units.bots.isDeployed + App.SecExp.battle.deployedUnits('militia') + App.SecExp.battle.deployedUnits('slaves') + App.SecExp.battle.deployedUnits('mercs') + V.SecExp.war.deploySF); + } else { + baseHp = (App.SecExp.BaseDroneUnit.hp * (V.SecExp.units.bots.active ? V.SecExp.units.bots.active : 0) + App.SecExp.BaseMilitiaUnit.hp * App.SecExp.battle.deployedUnits('militia') + App.SecExp.BaseSlaveUnit.hp * App.SecExp.battle.deployedUnits('slaves') + App.SecExp.BaseMercUnit.hp * App.SecExp.battle.deployedUnits('mercs') + App.SecExp.BaseSpecialForcesUnit.hp * V.SF.Active) / ((V.SecExp.units.bots.active ? V.SecExp.units.bots.active : 0) + App.SecExp.battle.deployedUnits('militia') + App.SecExp.battle.deployedUnits('slaves') + App.SecExp.battle.deployedUnits('mercs') + V.SF.Active); + } + + // calculates opposing army stats + if (V.week > 30 && V.week <= 60) { + armyMod = V.SecExp.war.attacker.troops / (inBattle ? 75 : 90); + } else if (V.week <= 90) { + armyMod = V.SecExp.war.attacker.troops / (inBattle ? 70 : 80); + } else if (V.week <= 120) { + armyMod = V.SecExp.war.attacker.troops / (inBattle ? 65 : 70); + } else { + armyMod = V.SecExp.war.attacker.troops / 60; + } + armyMod = Math.trunc(armyMod); + if (isMajorBattle) { + armyMod *= 2; + } + if (inBattle && armyMod <= 0) { + armyMod = 1; + } + + if (inRebellion) { + if (V.SecExp.war.type.includes("Slave")) { + rebellingSlaves = 1; + unitData = App.SecExp.getIrregularUnit("slaves", V.SecExp.war.attacker.troops, V.SecExp.war.attacker.equip); + } else { + rebellingMilitia = 1; + unitData = App.SecExp.getIrregularUnit("militia", V.SecExp.war.attacker.troops, V.SecExp.war.attacker.equip); + } + enemyAttack += unitData.attack * armyMod; + enemyDefense += unitData.defense * armyMod; + enemyHp += unitData.hp; + + for (const unit of App.SecExp.unit.list().slice(1)) { + for (let i = 0; i < V.SecExp.units[unit].squads.length; i++) { + if (App.SecExp.unit.isDeployed(V.SecExp.units[unit].squads[i])) { + if (unit === "slaves") { + rebellingSlaves = 1; + } else if (unit === "militia") { + rebellingMilitia = 1; + } else if (unit === "mercs") { + rebellingMercs = 1; + } + + V.SecExp.war.attacker.troops += V.SecExp.units[unit].squads[i].troops; + V.SecExp.units[unit].squads[i].loyalty = 0; + unitData = App.SecExp.getUnit(unit, i); + enemyAttack += unitData.attack; + enemyDefense += unitData.defense; + enemyHp += unitData.hp; + } + } + } + } + + // calculates opposing army stats + let enemyMoraleTroopMod = Math.clamp(V.SecExp.war.attacker.troops / 100, 1, (inBattle ? 5 : 10)); + if (inBattle) { + unitData = App.SecExp.getEnemyUnit(V.SecExp.war.attacker.type, V.SecExp.war.attacker.troops, V.SecExp.war.attacker.equip); + enemyAttack = unitData.attack * armyMod; + enemyDefense = unitData.defense * armyMod; + enemyMorale = unitData.morale * enemyMod * enemyMoraleTroopMod; + enemyHp = unitData.hp; + enemyBaseHp = unitData.hp / V.SecExp.war.attacker.troops; + } else { + enemyMorale = 1.5 * (App.SecExp.BaseMilitiaUnit.morale * rebellingMilitia + App.SecExp.BaseSlaveUnit.morale * rebellingSlaves + App.SecExp.BaseMercUnit.morale * rebellingMercs) / (rebellingMilitia + rebellingSlaves + rebellingMercs); + enemyMorale *= enemyMoraleTroopMod; + enemyBaseHp = (App.SecExp.BaseMilitiaUnit.hp * rebellingMilitia + App.SecExp.BaseSlaveUnit.hp * rebellingSlaves + App.SecExp.BaseMercUnit.hp * rebellingMercs) / (rebellingMilitia + rebellingSlaves + rebellingMercs); + } + + if (isNaN(attack)) { + throw Error(`Attack value reported NaN`); + } + if (isNaN(defense)) { + throw Error(`Defense value reported NaN`); + } + if (isNaN(hp)) { + throw Error(`Hp value reported NaN`); + } + if (isNaN(morale)) { + throw Error(`Morale value reported NaN`); + } + if (isNaN(enemyAttack)) { + throw Error(`Enemy attack value reported NaN`); + } + if (isNaN(enemyDefense)) { + throw Error(`Enemy defense value reported NaN`); + } + if (isNaN(enemyHp)) { + throw Error(`Enemy hp value reported NaN`); + } + if (isNaN(enemyMorale)) { + throw Error(`Enemy morale value reported NaN`); + } + + enemyAttack *= V.SecExp.settings.difficulty; + enemyDefense *= V.SecExp.settings.difficulty; + enemyMorale *= V.SecExp.settings.difficulty; + enemyHp *= V.SecExp.settings.difficulty; + enemyBaseHp *= V.SecExp.settings.difficulty; + + if (showStats) { + if (inBattle) { + atkMod = Math.round((atkMod-1) * 100); + defMod = Math.round((defMod-1) * 100); + militiaMod = Math.round((militiaMod-1) * 100); + mercMod = Math.round((mercMod-1) * 100); + slaveMod = Math.round((slaveMod-1) * 100); + SFMod = Math.round((SFMod-1) * 100); + enemyMod = Math.round((enemyMod-1) * 100); + moraleTroopMod = Math.round((moraleTroopMod-1) * 100); + enemyMoraleTroopMod = Math.round((enemyMoraleTroopMod-1) * 100); + } else { + engageMod = Math.round((engageMod-1) * 100); + } + + if (V.SecExp.settings.difficulty === 0.5) { + App.UI.DOM.appendNewElement("div", node, `Difficulty: Very easy. Modifier: x${V.SecExp.settings.difficulty}`); + } else if (V.SecExp.settings.difficulty === 0.75) { + App.UI.DOM.appendNewElement("div", node, `Difficulty: Easy. Modifier: x${V.SecExp.settings.difficulty}`); + } else if (V.SecExp.settings.difficulty === 1) { + App.UI.DOM.appendNewElement("div", node, `Difficulty: Normal. Modifier: x${V.SecExp.settings.difficulty}`); + } else if (V.SecExp.settings.difficulty === 1.25) { + App.UI.DOM.appendNewElement("div", node, `Difficulty: Hard. Modifier: x${V.SecExp.settings.difficulty}`); + } else if (V.SecExp.settings.difficulty === 1.5) { + App.UI.DOM.appendNewElement("div", node, `Difficulty: Very hard. Modifier: x${V.SecExp.settings.difficulty}`); + } else { + App.UI.DOM.appendNewElement("div", node, `Difficulty: Extremely hard. Modifier: x${V.SecExp.settings.difficulty}`); + } + + App.UI.DOM.appendNewElement("div", node, `Army`, "underline"); + App.UI.DOM.appendNewElement("div", node, `Troops: ${num(Math.round(App.SecExp.battle.troopCount()))}`); + App.UI.DOM.appendNewElement("div", node, `Attack: ${num(Math.round(attack))}. ${inBattle ? `Modifier: +${atkMod}%` : ``}`); + App.UI.DOM.appendNewElement("div", node, `Defense: ${num(Math.round(defense))}. ${inBattle ? `Modifier: +${defMod}%`: ``}`); + if (inRebellion) { + App.UI.DOM.appendNewElement("div", node, `Engagement rule modifier: +${engageMod}%`); + } + App.UI.DOM.appendNewElement("div", node, `HP: ${num(Math.round(hp))}. ${inRebellion ? `Base: ${num(Math.round(baseHp))}`: ``}`); + App.UI.DOM.appendNewElement("div", node, `Morale: ${num(Math.round(morale))}. Increase due to troop numbers: +${moraleTroopMod}%`); + if (inBattle) { + App.UI.DOM.appendNewElement("div", node, `Slaves morale modifier: +${slaveMod}%`); + App.UI.DOM.appendNewElement("div", node, `Militia morale modifier: +${militiaMod}%`); + App.UI.DOM.appendNewElement("div", node, `Mercenaries morale modifier: +${mercMod}%`); + if (V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) { + App.UI.DOM.appendNewElement("div", node, `Special Force morale modifier: +${SFMod}%`); + } + if (V.SecExp.buildings.barracks && V.SecExp.buildings.barracks.luxury >= 1) { + App.UI.DOM.appendNewElement("div", node, `Barracks bonus morale modifier: +${V.SecExp.buildings.barracks.luxury * 5}%`); + } + } + if (inBattle) { + App.UI.DOM.appendNewElement("div", node, `Tactics`, "underline"); + App.UI.DOM.appendNewElement("div", node, `Chance of success: ${num(Math.round(tacChance * 100))}%. Was successful?: ${V.SecExp.war.tacticsSuccessful ? 'Yes' : 'No'}`); + } + + App.UI.DOM.appendNewElement("p", node, enemy()); + } + + let i = 0; // simulates the combat by pitting attk against def + while (i < turns && ![3, -3].includes(V.SecExp.war.result)) { + App.UI.DOM.appendNewElement("p", node, turnReport()); + i++; + } + + if (![3, -3].includes(V.SecExp.war.result)) { + showProgress(`Partial ${morale > enemyMorale ? 'victory' : 'defeat'}!`, "div"); + V.SecExp.war.result = morale > enemyMorale ? 2 : -2; + } + + if (V.SecExp.war.result > 3 || V.SecExp.war.result < -3) { + throw Error(`Failed to determine battle result`); + } + + if (inBattle && showStats) { + App.UI.DOM.appendNewElement("div", node, `Losses: ${num(Math.trunc(V.SecExp.war.losses))}`); + App.UI.DOM.appendNewElement("div", node, `Enemy losses: ${num(Math.trunc(V.SecExp.war.attacker.losses))}`); + } + + if (V.SecExp.war.result === -3 && (isMajorBattle && V.SecExp.settings.battle.major.gameOver === 1 || inRebellion && V.SecExp.settings.rebellion.gameOver === 1)) { + V.gameover = `${isMajorBattle ? "major battle" : "Rebellion"} defeat`; + atEnd("Gameover"); + } else { + atEnd(inBattle ? "attackReport" : "rebellionReport"); + } + return node; +}; diff --git a/src/Mods/SecExp/events/rebellionHandler.tw b/src/Mods/SecExp/events/rebellionHandler.tw deleted file mode 100644 index 4d6531b7e8e706798e8de0cb892f3d89b7b00c18..0000000000000000000000000000000000000000 --- a/src/Mods/SecExp/events/rebellionHandler.tw +++ /dev/null @@ -1,326 +0,0 @@ -:: rebellionHandler [nobr] - -<<set $nextButton = " ", $nextLink = "attackReport", $encyclopedia = "Battles">> - -<<set _turns = 10 * 2>> -<<set _attack = 0>> -<<set _defense = 0>> -<<set _morale = 0>> -<<set _hp = 0>> -<<set _baseHp = 0>> -<<set _enemyAttack = 0>> -<<set _enemyDefense = 0>> -<<set _enemyMorale = 0>> -<<set _enemyHp = 0>> -<<set _enemyBaseHp = 0>> -<<set _woundChance = 5>> /* leader has a base chance of 5% to get wounded */ -<<set _irregularMod = 0>> -<<set _armyMod = 0>> - -/* calculates PC army stats */ -<<if $SecExp.war.engageRule == 0>> - <<set _engageMod = 0.5>> -<<elseif $SecExp.war.engageRule == 1>> - <<set _engageMod = 0.75>> -<<elseif $SecExp.war.engageRule == 2>> - <<set _engageMod = 1>> -<<else>> - <<set _engageMod = 1.4>> -<</if>> - -<<if $week <= 30>> - <<set _irregularMod = $SecExp.war.irregulars / 60>> -<<elseif $week <= 60>> - <<set _irregularMod = $SecExp.war.irregulars / 50>> -<<elseif $week <= 90>> - <<set _irregularMod = $SecExp.war.irregulars / 40>> -<<elseif $week <= 120>> - <<set _irregularMod = $SecExp.war.irregulars / 30>> -<<else>> - <<set _irregularMod = $SecExp.war.irregulars / 20>> -<</if>> -<<if $SecExp.war.irregulars > 0>> - <<set _irregularMod = Math.trunc(_irregularMod)>> - <<set _unit = App.SecExp.getIrregularUnit("militia", $SecExp.war.irregulars, $SecExp.war.attacker.equip)>> - <<set _attack += _unit.attack * _irregularMod * 0.80>> - <<set _defense += _unit.defense * _irregularMod * 0.80>> - <<set _hp += _unit.hp>> -<</if>> - -<<if $SecExp.units.bots.active == 1>> - <<set _unit = App.SecExp.getUnit("bots")>> - <<set _attack += _unit.attack>> - <<set _defense += _unit.defense>> - <<set _hp += _unit.hp>> -<</if>> - -<<for _i = 0; _i < $SecExp.units.militia.squads.length; _i++>> - <<if $SecExp.units.militia.squads[_i].active == 1 && (!$SecExp.war.rebellingID.includes($SecExp.units.militia.squads[_i].ID))>> - <<set _unit = App.SecExp.getUnit("militia", _i)>> - <<set _attack += _unit.attack>> - <<set _defense += _unit.defense>> - <<set _hp += _unit.hp>> - <</if>> -<</for>> -<<for _i = 0; _i < $SecExp.units.slaves.squads.length; _i++>> - <<if $SecExp.units.slaves.squads[_i].active == 1 && (!$SecExp.war.rebellingID.includes($SecExp.units.slaves.squads[_i].ID))>> - <<set _unit = App.SecExp.getUnit("slaves", _i)>> - <<set _attack += _unit.attack>> - <<set _defense += _unit.defense>> - <<set _hp += _unit.hp>> - <</if>> -<</for>> -<<for _i = 0; _i < $SecExp.units.mercs.squads.length; _i++>> - <<if $SecExp.units.mercs.squads[_i].active == 1 && (!$SecExp.war.rebellingID.includes($SecExp.units.mercs.squads[_i].ID))>> - <<set _unit = App.SecExp.getUnit("mercs", _i)>> - <<set _attack += _unit.attack>> - <<set _defense += _unit.defense>> - <<set _hp += _unit.hp>> - <</if>> -<</for>> - -<<if $SF.Toggle && $SF.Active >= 1>> - <<set _unit = App.SecExp.getUnit("SF")>> - <<set _attack += _unit.attack>> - <<set _defense += _unit.defense>> - <<set _hp += _unit.hp>> -<</if>> - -<<set _attack *= _engageMod>> -<<set _defense *= _engageMod>> -<<set _hp *= _engageMod>> - -<<if $SecExp.war.assistantDefense>> - <<set _attack *= 0.95>> - <<set _defense *= 0.95>> - <<set _hp *= 0.95>> -<</if>> -<<if $SecExp.war.reactorDefense>> - <<set _attack *= 0.95>> - <<set _defense *= 0.95>> - <<set _hp *= 0.95>> -<</if>> -<<if $SecExp.war.penthouseDefense>> - <<set _attack *= 0.95>> - <<set _defense *= 0.95>> - <<set _hp *= 0.95>> -<</if>> -<<if $SecExp.war.waterwayDefense>> - <<set _attack *= 0.95>> - <<set _defense *= 0.95>> - <<set _hp *= 0.95>> -<</if>> - -<<set _moraleTroopMod = Math.clamp(App.SecExp.battle.troopCount() / 100,1,10)>> - -/* morale and baseHp calculation */ -<<set _morale += (App.SecExp.BaseDroneUnit.morale * $SecExp.units.bots.active + App.SecExp.BaseMilitiaUnit.morale * App.SecExp.battle.deployedUnits('militia') + App.SecExp.BaseSlaveUnit.morale * App.SecExp.battle.deployedUnits('slaves') + App.SecExp.BaseMercUnit.morale * App.SecExp.battle.deployedUnits('mercs') + App.SecExp.BaseSpecialForcesUnit.morale * $SF.Active) / ($SecExp.units.bots.active + App.SecExp.battle.deployedUnits('militia') + App.SecExp.battle.deployedUnits('slaves') + App.SecExp.battle.deployedUnits('mercs') + $SF.Active)>> -<<set _morale += _morale * $SecExp.buildings.barracks ? $SecExp.buildings.barracks.luxury * 0.05 : 0>> /* barracks bonus */ -<<set _morale *= _moraleTroopMod>> -<<set _baseHp = (App.SecExp.BaseDroneUnit.hp * ($SecExp.units.bots.active ? $SecExp.units.bots.active : 0) + App.SecExp.BaseMilitiaUnit.hp * App.SecExp.battle.deployedUnits('militia') + App.SecExp.BaseSlaveUnit.hp * App.SecExp.battle.deployedUnits('slaves') + App.SecExp.BaseMercUnit.hp * App.SecExp.battle.deployedUnits('mercs') + App.SecExp.BaseSpecialForcesUnit.hp * $SF.Active) / (($SecExp.units.bots.active ? $SecExp.units.bots.active : 0) + App.SecExp.battle.deployedUnits('militia') + App.SecExp.battle.deployedUnits('slaves') + App.SecExp.battle.deployedUnits('mercs') + $SF.Active)>> - -/* calculates rebelling army stats */ -<<if $week <= 30>> - <<set _armyMod = $SecExp.war.attacker.troops / 100>> -<<elseif $week <= 60>> - <<set _armyMod = $SecExp.war.attacker.troops / 90>> -<<elseif $week <= 90>> - <<set _armyMod = $SecExp.war.attacker.troops / 80>> -<<elseif $week <= 120>> - <<set _armyMod = $SecExp.war.attacker.troops / 70>> -<<else>> - <<set _armyMod = $SecExp.war.attacker.troops / 60>> -<</if>> -<<set _armyMod = Math.trunc(_armyMod)>> - -<<set _rebellingSlaves = 0, _rebellingMilitia = 0, _rebellingMercs = 0>> -<<if $SecExp.war.type.includes("Slave")>> - <<set _rebellingSlaves = 1>> - <<set _unit = App.SecExp.getIrregularUnit("slaves", $SecExp.war.attacker.troops, $SecExp.war.attacker.equip)>> -<<else>> - <<set _rebellingMilitia = 1>> - <<set _unit = App.SecExp.getIrregularUnit("militia", $SecExp.war.attacker.troops, $SecExp.war.attacker.equip)>> -<</if>> -<<set _enemyAttack += _unit.attack * _armyMod>> -<<set _enemyDefense += _unit.defense * _armyMod>> -<<set _enemyHp += _unit.hp>> - -<<for _i = 0; _i < $SecExp.units.militia.squads.length; _i++>> - <<if $SecExp.units.militia.squads[_i].active == 1 && $SecExp.war.rebellingID.includes($SecExp.units.militia.squads[_i].ID)>> - <<set _rebellingMilitia = 1>> - <<set $SecExp.war.attacker.troops += $SecExp.units.militia.squads[_i].troops>> - <<set $SecExp.units.militia.squads[_i].loyalty = 0>> - <<set _unit = App.SecExp.getUnit("militia", _i)>> - <<set _enemyAttack += _unit.attack>> - <<set _enemyDefense += _unit.defense>> - <<set _enemyHp += _unit.hp>> - <</if>> -<</for>> -<<for _i = 0; _i < $SecExp.units.slaves.squads.length; _i++>> - <<if $SecExp.units.slaves.squads[_i].active == 1 && $SecExp.war.rebellingID.includes($SecExp.units.slaves.squads[_i].ID)>> - <<set _rebellingSlaves = 1>> - <<set $SecExp.war.attacker.troops += $SecExp.units.slaves.squads[_i].troops>> - <<set $SecExp.units.slaves.squads[_i].loyalty = 0>> - <<set _unit = App.SecExp.getUnit("slaves", _i)>> - <<set _enemyAttack += _unit.attack>> - <<set _enemyDefense += _unit.defense>> - <<set _enemyHp += _unit.hp>> - <</if>> -<</for>> -<<for _i = 0; _i < $SecExp.units.mercs.squads.length; _i++>> - <<if $SecExp.units.mercs.squads[_i].active == 1 && $SecExp.war.rebellingID.includes($SecExp.units.mercs.squads[_i].ID)>> - <<set _rebellingMercs = 1>> - <<set $SecExp.war.attacker.troops += $SecExp.units.mercs.squads[_i].troops>> - <<set $SecExp.units.mercs.squads[_i].loyalty = 0>> - <<set _unit = App.SecExp.getUnit("mercs", _i)>> - <<set _enemyAttack += _unit.attack>> - <<set _enemyDefense += _unit.defense>> - <<set _enemyHp += _unit.hp>> - <</if>> -<</for>> - -<<set _enemyMoraleTroopMod = Math.clamp($SecExp.war.attacker.troops / 100,1,10)>> -<<set _enemyMorale = 1.5 * (App.SecExp.BaseMilitiaUnit.morale * _rebellingMilitia + App.SecExp.BaseSlaveUnit.morale * _rebellingSlaves + App.SecExp.BaseMercUnit.morale * _rebellingMercs) / (_rebellingMilitia + _rebellingSlaves + _rebellingMercs)>> -<<set _enemyMorale *= _enemyMoraleTroopMod>> -<<set _enemyBaseHp = (App.SecExp.BaseMilitiaUnit.hp * _rebellingMilitia + App.SecExp.BaseSlaveUnit.hp * _rebellingSlaves + App.SecExp.BaseMercUnit.hp * _rebellingMercs) / (_rebellingMilitia + _rebellingSlaves + _rebellingMercs)>> - -<<if isNaN(_attack)>> - <br>@@.red;Error: attack value reported NaN@@ -<</if>> -<<if isNaN(_defense)>> - <br>@@.red;Error: defense value reported NaN@@ -<</if>> -<<if isNaN(_hp)>> - <br>@@.red;Error: hp value reported NaN@@ -<</if>> -<<if isNaN(_morale)>> - <br>@@.red;Error: morale value reported NaN@@ -<</if>> -<<if isNaN(_enemyAttack)>> - <br>@@.red;Error: enemy attack value reported NaN@@ -<</if>> -<<if isNaN(_enemyDefense)>> - <br>@@.red;Error: enemy defense value reported NaN@@ -<</if>> -<<if isNaN(_enemyHp)>> - <br>@@.red;Error: enemy hp value reported NaN@@ -<</if>> -<<if isNaN(_enemyMorale)>> - <br>@@.red;Error: enemy morale value reported NaN@@ -<</if>> - -/* difficulty */ -<<set _enemyAttack *= $SecExp.settings.difficulty>> -<<set _enemyDefense *= $SecExp.settings.difficulty>> -<<set _enemyMorale *= $SecExp.settings.difficulty>> -<<set _enemyHp *= $SecExp.settings.difficulty>> -<<set _enemyBaseHp *= $SecExp.settings.difficulty>> - -<<if $SecExp.settings.showStats == 1>> -<<set _engageMod -= 1>> -<<set _engageMod = Math.round(_engageMod * 100)>> -<<set _difficulty = ($SecExp.settings.difficulty -1) * 100>> - -__Difficulty__:<br> -<<if $SecExp.settings.difficulty == 0.5>> - Very easy -<<elseif $SecExp.settings.difficulty == 0.75>> - Easy -<<elseif $SecExp.settings.difficulty == 1>> - Normal -<<elseif $SecExp.settings.difficulty == 1.25>> - Hard -<<elseif $SecExp.settings.difficulty == 1.5>> - Very hard -<<else>> - Extremely hard -<</if>> -<br><br>__Army__: -<br>troops: <<print num(Math.round(App.SecExp.battle.troopCount()))>> -<br>attack: <<print num(Math.round(_attack))>> -<br>defense: <<print num(Math.round(_defense))>> -<br>engagement rule modifier: <<if _engageMod > 0>>+<</if>><<print _engageMod>>% -<br>Hp: <<print num(Math.round(_hp))>> -<br>base HP: <<print num(Math.round(_baseHp))>> -<br>morale: <<print num(Math.round(_morale))>> -<<if _enemyMoraleTroopMod > 0>> - <br>morale increase due to troop numbers: +<<print _moraleTroopMod>>% -<</if>> -<br><br>__Rebels__: -<br>enemy troops: <<print num(Math.round($SecExp.war.attacker.troops))>> -<br>enemy attack: <<print num(Math.round(_enemyAttack))>> -<br>enemy defense: <<print num(Math.round(_enemyDefense))>> -<br>enemy Hp: <<print num(Math.round(_enemyHp))>> -<br>enemy base Hp: <<print num(Math.round(_enemyBaseHp))>> -<br>enemy morale: <<print num(Math.round(_enemyMorale))>> -<<if _enemyMoraleTroopMod > 0>> - <br>enemy morale increase due to troop numbers: +<<print _enemyMoraleTroopMod>>% -<</if>> -<br>Difficulty modifier: <<if _difficulty > 0>>+<</if>><<print _difficulty>>% -<</if>> - -/* simulates the combat by pitting attk against def */ -<<for _i = 0; _i < _turns; _i++>> - <<if $SecExp.settings.showStats == 1>> <br><br>turn: <<print _i + 1>><</if>> - /* player army attacks */ - <<set _damage = Math.clamp(_attack - _enemyDefense,_attack * 0.1,_attack)>> - <<if $SecExp.settings.showStats == 1>> <br>player damage: <<print num(Math.round(_damage))>><</if>> - <<set _enemyHp -= _damage>> - <<if $SecExp.settings.showStats == 1>> <br>remaining enemy Hp: <<print num(Math.round(_enemyHp))>><</if>> - <<set $SecExp.war.attacker.losses += _damage / _enemyBaseHp>> - <<set _moraleDamage = Math.clamp(_damage/ 2 + _damage / _enemyBaseHp,0,_damage*1.5)>> - <<set _enemyMorale -= _moraleDamage>> - <<if $SecExp.settings.showStats == 1>> <br>remaining enemy morale: <<print num(Math.round(_enemyMorale))>><</if>> - <<if _enemyHp <= 0 || _enemyMorale <= 0>> - <<if $SecExp.settings.showStats == 1>> <br>Victory!<</if>> - <<set $SecExp.war.result = 3>> - <<set $SecExp.war.turns = _i>> - <<break>> - <</if>> - - /* attacker army attacks */ - <<set _damage = _enemyAttack - _defense>> - <<if _damage < _enemyAttack * 0.1>> - <<set _damage = _enemyAttack * 0.1>> - <</if>> - <<if $SecExp.settings.showStats == 1>> <br>enemy damage: <<print num(Math.round(_damage))>><</if>> - <<set _hp -= _damage*($SecExp.rebellions.sfArmor ? 0.85 : 1)>> - <<if $SecExp.settings.showStats == 1>> <br>remaining hp: <<print num(Math.round(_hp))>><</if>> - <<set $SecExp.war.losses += _damage / _baseHp>> - <<set _moraleDamage = Math.clamp(_damage / 2 + _damage / _baseHp,0,_damage*1.5)>> - <<set _morale -= _moraleDamage>> - <<if $SecExp.settings.showStats == 1>> <br>remaining morale: <<print num(Math.round(_morale))>><</if>> - <<if _hp <= 0 || _morale <= 0>> - <<if $SecExp.settings.showStats == 1>> <br>Defeat!<</if>> - <<set $SecExp.war.result = -3>> - <<set $SecExp.war.turns = _i>> - <<break>> - <</if>> -<</for>> -<<if $SecExp.war.result != 3 && $SecExp.war.result != -3>> - <<if _morale > _enemyMorale>> - <<if $SecExp.settings.showStats == 1>> <br>Partial victory!<</if>> - <<set $SecExp.war.result = 2>> - <<elseif _morale < _enemyMorale>> - <<if $SecExp.settings.showStats == 1>> <br>Partial defeat!<</if>> - <<set $SecExp.war.result = -2>> - <</if>> -<</if>> - -<<if $SecExp.war.result > 3 || $SecExp.war.result < -3>> - <br><br>@@.red;Error: failed to determine battle result@@ -<</if>> - -<<if $SecExp.settings.showStats == 1>> - <<if $SecExp.settings.rebellion.gameOver == 1 && $SecExp.war.result == -3>> - <br>[[Proceed|Gameover][$gameover = "Rebellion defeat"]] - <<else>> - <br>[[Proceed|rebellionReport]] - <</if>> -<<else>> - <<if $SecExp.settings.rebellion.gameOver == 1 && $SecExp.war.result == -3>> - <<set $gameover = "Rebellion defeat">> <<goto "Gameover">> - <<else>> - <<goto "rebellionReport">> - <</if>> -<</if>> diff --git a/src/Mods/SecExp/events/rebellionOptions.tw b/src/Mods/SecExp/events/rebellionOptions.tw index 6a6617cb0d51e5d6aa34b9c4cbf62542c55a9a5d..1712764df4d9eef510fbfee6ddbe1bf62f5bcc84 100644 --- a/src/Mods/SecExp/events/rebellionOptions.tw +++ b/src/Mods/SecExp/events/rebellionOptions.tw @@ -106,5 +106,5 @@ In order to preserve the structural integrity of the building and the lives of o <</if>> <br><br> <<includeDOM App.SecExp.unit.replenishAll()>> -[[Proceed|rebellionHandler][$SecExp.war.result = 4, $SecExp.war.foughtThisWeek = 1]] /* sets $SecExp.war.result to a value outside accepted range (-3,3) to avoid evaluation problems */ -<br>[[Surrender|rebellionReport][$SecExp.war.result = -1, $SecExp.war.foughtThisWeek = 1]] +[[Proceed|conflictHandler][$SecExp.war.result = 4, $SecExp.war.foughtThisWeek = 1]] /* sets $SecExp.war.result to a value outside accepted range (-3,3) to avoid evaluation problems */ +<br>[[Surrender|rebellionReport][$SecExp.war.result = -1, $SecExp.war.foughtThisWeek = 1]] \ No newline at end of file diff --git a/src/Mods/SecExp/events/rebellionReport.js b/src/Mods/SecExp/events/rebellionReport.js index 14e108cc7c07dccaf62daa0d0101f1c0d7c42d45..663cea8f7f561fd7184fcf624e1523296eb41471 100644 --- a/src/Mods/SecExp/events/rebellionReport.js +++ b/src/Mods/SecExp/events/rebellionReport.js @@ -196,7 +196,6 @@ App.Events.rebellionReport = function() { const node = new DocumentFragment(); const r = []; const rebels = {ID: [], names: []}; - console.log('rebels:', rebels); const Dissolve = function() { App.SecExp.unit.unitFree(unit).add(manpower); @@ -394,6 +393,7 @@ App.Events.rebellionReport = function() { lostSlaves = Math.trunc((V.SecExp.war.attacker.troops - V.SecExp.war.attacker.losses) * 0.8); App.SecExp.slavesDamaged(lostSlaves); } + V.SecExp.core.authority = Math.clamp(V.SecExp.core.authority, 0, 20000); if (result !== -1) { if (V.SecExp.war.engageRule === 0) { diff --git a/src/Mods/SecExp/js/Unit.js b/src/Mods/SecExp/js/Unit.js index ecbc97a847b20f433c56f5d5b7b954e4371a048e..c62e0891b0ff35da8ffacc8701eef47fcfe57a3f 100644 --- a/src/Mods/SecExp/js/Unit.js +++ b/src/Mods/SecExp/js/Unit.js @@ -1,4 +1,7 @@ App.SecExp.unit = (function() { + const equipUpgradeCost = 250; + const secBotsUpgradeCost = 250; + const secBotsCost = 500; return { list, bulkUpgrade, @@ -22,39 +25,55 @@ App.SecExp.unit = (function() { /** Creates a bulk upgrade link for the unit that is passed. - * @param {object} [unit] the unit to be checked. + * @param {object} [unit] the unit to be checked + * @param {string} [type] the type of unit to be checked */ - function bulkUpgrade(unit) { + function bulkUpgrade(unit, type) { unit = Array.isArray(unit) ? unit : [unit]; let el = document.createElement("a"); function upgradeUnit(x) { x.equip = 3; - Object.assign(x, { - maxTroops: 50, commissars: 2, - cyber: 1, medics: 1 - }); - x.SF = (V.SF.Toggle && V.SF.Active >= 1 ? 1 : 0); + if (type !== "bots") { + Object.assign(x, { + maxTroops: 50, commissars: 2, + cyber: 1, medics: 1 + }); + x.SF = (V.SF.Active >= 1 ? 1 : 0); + } else { + if (x.maxTroops < 80) { + x.maxTroops = 80; + } else if (V.SF.Toggle && V.SF.Active >= 1 && x.maxTroops < 100 && V.SecExp.edicts.SFSupportLevel >= 1) { + x.maxTroops = 100; + } + } } function getCost(x) { let cost = 0; - const equipUpgradeCost = 250; - if (x.maxTroops < 50) { - cost -= 5000 + (((50 - x.maxTroops) /10) * equipUpgradeCost * (x.equip + x.commissars + x.cyber + x.SF)); - } + if (type !== "bots") { + if (x.maxTroops < 50) { + cost -= 5000 + (((50 - x.maxTroops) /10) * equipUpgradeCost * (x.equip + x.commissars + x.cyber + x.SF)); + } - if (x.commissars < 2) { - cost -= (equipUpgradeCost * x.maxTroops + 1000) * (2 - x.commissars); - } - if ((V.prostheticsUpgrade >= 2 || V.researchLab.advCombatPLimb === 1) && x.cyber === 0) { - cost -= equipUpgradeCost * x.maxTroops + 2000; - } - if (x.medics === 0) { - cost -= equipUpgradeCost * x.maxTroops + 1000; - } - if (V.SF.Toggle && V.SF.Active >= 1 && x.SF === 0) { - cost -= equipUpgradeCost * x.maxTroops + 5000; + if (x.commissars < 2) { + cost -= (equipUpgradeCost * x.maxTroops + 1000) * (2 - x.commissars); + } + if ((V.prostheticsUpgrade >= 2 || V.researchLab.advCombatPLimb === 1) && x.cyber === 0) { + cost -= equipUpgradeCost * x.maxTroops + 2000; + } + if (x.medics === 0) { + cost -= equipUpgradeCost * x.maxTroops + 1000; + } + if (V.SF.Toggle && V.SF.Active >= 1 && x.SF === 0) { + cost -= equipUpgradeCost * x.maxTroops + 5000; + } + } else { + if (unit.maxTroops < 80) { + cost -= 5000 * (80 - unit.maxTroops); + } else if (V.SF.Toggle && V.SF.Active >= 1 && unit.maxTroops < 100 && V.SecExp.edicts.SFSupportLevel >= 1) { + cost -= 5000 + 10 * secBotsUpgradeCost * unit.equip * (100 - unit.maxTroops); + } } if (x.equip < 3) { cost -= (equipUpgradeCost * x.maxTroops + 1000) * (3 - x.equip); @@ -101,7 +120,9 @@ App.SecExp.unit = (function() { } let newUnit = { - ID: -1, equip: 0, active: 1, isDeployed: 0, maxTroops: 30, troops: 30 + equip: 0, active: 1, + maxTroops: 30, troops: 30, + ID: -1, isDeployed: 0 }; if (type !== "bots") { V.SecExp.units[type].created++; @@ -310,9 +331,9 @@ App.SecExp.unit = (function() { } } else { if (brief === 0) { - App.UI.DOM.appendNewElement("span", el,`The drone unit is made up of ${input.troops} drones. All of which are assembled in an ordered formation in front of you, absolutely silent and ready to receive their orders. `); + el.append(`The drone unit is made up of ${input.troops} drones. All of which are assembled in an ordered formation in front of you, absolutely silent and ready to receive their orders. `); } else { - App.UI.DOM.appendNewElement("span", el,`Drone squad. `); + el.append(`Drone squad. `); } } @@ -402,7 +423,7 @@ App.SecExp.unit = (function() { el.append(`The unit has "advisors" from ${V.SF.Lower} that will help the squad remain tactically aware and active. `); } } else { - App.UI.DOM.appendNewElement("span", el, `Training: `); + el.append(`Training: `); if (input.training <= 33) { el.append(`low. `); } else if(input.training <= 66) { @@ -423,9 +444,10 @@ App.SecExp.unit = (function() { } else { el.append(`fanatical. `); } + App.UI.DOM.appendNewElement("div", el); if (jsDef(input.cyber) && input.cyber > 0) { - App.UI.DOM.appendNewElement("div", el, `Cyberaugmentations applied. `); + el.append(`Cyberaugmentations applied. `); } if (jsDef(input.medics) && input.medics > 0) { el.append(`Medical squad attached. `); @@ -483,7 +505,7 @@ App.SecExp.unit = (function() { const expLoss = (squad.troops - oldTroops) / squad.troops; squad.training -= squad.training * expLoss; } else { - cashX(-((squad.maxTroops - squad.troops) * 500), "securityExpansion"); + cashX(-((squad.maxTroops - squad.troops) * secBotsCost), "securityExpansion"); squad.troops = squad.maxTroops; } } diff --git a/src/Mods/SecExp/js/reportingRelatedFunctions.js b/src/Mods/SecExp/js/reportingRelatedFunctions.js index 26f3d9ec92d9940f162e9a1ade8b1e709a6ddbb5..d6007158bf3fe533faa49b2a31a9e754658386f8 100644 --- a/src/Mods/SecExp/js/reportingRelatedFunctions.js +++ b/src/Mods/SecExp/js/reportingRelatedFunctions.js @@ -119,7 +119,7 @@ App.SecExp.updateFacilityDamage = function(facility) { V.SecExp.rebellions.repairTime[facility]--; IncreasePCSkills('engineering', 0.1); - if (V.SecExp.rebellions.repairTime[facility] === 0) { + if (V.SecExp.rebellions.repairTime[facility] <= 0) { delete V.SecExp.rebellions.repairTime[facility]; } } diff --git a/src/data/backwardsCompatibility/backwardsCompatibility.js b/src/data/backwardsCompatibility/backwardsCompatibility.js index fe01a262591927a83cc3c745e71640c788ec7883..9e0232e3971d6588a96fc65a6f6967951022c514 100644 --- a/src/data/backwardsCompatibility/backwardsCompatibility.js +++ b/src/data/backwardsCompatibility/backwardsCompatibility.js @@ -318,15 +318,7 @@ App.Update.globalVariables = function(node) { } // Farmyard - if (typeof V.farmyardUpgrades !== "object") { - V.farmyardUpgrades = { - pump: 0, fertilizer: 0, hydroponics: 0, machinery: 0, seeds: 0 - }; - } - - if (!App.Data.animals || App.Data.animals.length === 0) { - App.Facilities.Farmyard.animals.init(); - } + App.Facilities.Farmyard.BC(); // Pit if (typeof V.pit === "number") { diff --git a/src/descriptions/arcologyDescription.js b/src/descriptions/arcologyDescription.js index 90e1e8e02bdc54a103e013b02e0768967bce45b2..fe9bf2404e7bb1ddfb97dfda5cfb1ab8aafbea87 100644 --- a/src/descriptions/arcologyDescription.js +++ b/src/descriptions/arcologyDescription.js @@ -51,7 +51,7 @@ App.Desc.playerArcology = function(lastElement) { function weather() { let buffer = []; - buffer.push(`You briefly glance out a large glass window of your penthouse to observe an open-air section of ${A.name}. `); + buffer.push(`You briefly glance out a large glass window of your penthouse to observe an open-air section of ${A.name}.`); if (V.weatherToday.name === "Sunny") { buffer.push(`Today is a stunningly perfect day. The ${V.terrain === "oceanic" ? "seagulls are squawking" : "birds are singing"}, the sun is shining, and the marketplace is bustling with the sounds of trade and laughter.`); } else if (V.weatherToday.name === "Heavy Rain") { diff --git a/src/endWeek/economics/neighborsDevelopment.js b/src/endWeek/economics/neighborsDevelopment.js index ccbc6650db4754765d9f55e76ef7c060a9d5ac00..e7c56e72c9dd1c3b96b93880f8ad6906febcb45e 100644 --- a/src/endWeek/economics/neighborsDevelopment.js +++ b/src/endWeek/economics/neighborsDevelopment.js @@ -330,8 +330,8 @@ App.EndWeek.neighborsDevelopment = function() { redHanded = 1; repX(forceNeg(random(100, 200)), "war"); if (V.secExpEnabled > 0) { - V.SecExp.core.authority -= random(100, 500) * V.arcologies[0].CyberEconomic; - V.SecExp.core.crimeLow += random(10, 25); + V.SecExp.core.authority = Math.clamp(V.SecExp.core.authority - random(100, 500) * V.arcologies[0].CyberEconomic, 0, 20000); + V.SecExp.core.crimeLow = Math.clamp(V.SecExp.core.crimeLow + random(10, 25), 0, 100); } V.arcologies[0].prosperity = Math.clamp(V.arcologies[0].prosperity, 1, V.AProsperityCap); } @@ -377,8 +377,8 @@ App.EndWeek.neighborsDevelopment = function() { redHanded = 1; repX(forceNeg(random(100, 200)), "war"); if (V.secExpEnabled > 0) { - V.SecExp.core.authority -= random(100, 500) * V.arcologies[0].CyberReputation; - V.SecExp.core.crimeLow += random(10, 25); + V.SecExp.core.authority = Math.clamp(V.SecExp.core.authority - random(100, 500) * V.arcologies[0].CyberReputation, 0, 20000); + V.SecExp.core.crimeLow = Math.clamp(V.SecExp.core.crimeLow + random(10, 25), 0, 100); } V.arcologies[0].prosperity = Math.clamp(V.arcologies[0].prosperity, 1, 300); } diff --git a/src/endWeek/economics/persBusiness.js b/src/endWeek/economics/persBusiness.js index 7adcd0e5f95b5fe1fa7757866620b155dea21240..cd8e407a9874ff3641124cccc095e0a16af9ef65 100644 --- a/src/endWeek/economics/persBusiness.js +++ b/src/endWeek/economics/persBusiness.js @@ -784,9 +784,9 @@ App.EndWeek.personalBusiness = function() { if (V.secExpEnabled > 0) { X = 1; r.push(`<span class="red">authority,</span>`); - V.SecExp.core.authority -= random(100, 500); + V.SecExp.core.authority = Math.clamp(V.SecExp.core.authority - random(100, 500), 0, 20000); r.push(`<span class="red">crime rate</span>`); - V.SecExp.core.crimeLow += random(10, 25); + V.SecExp.core.crimeLow = Math.clamp(V.SecExp.core.crimeLow + random(10, 25), 0, 100); r.push(`and`); } r.push(`<span class="red">reputation</span>`); @@ -876,14 +876,14 @@ App.EndWeek.personalBusiness = function() { r.push(`You are selling the data collected by your security department, which earns a discreet sum of <span class="yellowgreen">${cashFormat(dataGain)}.</span>`); cashX(dataGain, "personalBusiness"); r.push(`Many of your citizens are not enthusiastic of this however, <span class="red">damaging your authority.</span>`); - V.SecExp.core.authority -= 50; + V.SecExp.core.authority = Math.clamp(V.SecExp.core.authority - 50, 0, 20000); } } if (V.SecExp.buildings.propHub && V.SecExp.buildings.propHub.upgrades.marketInfiltration > 0) { const blackMarket = random(7000, 8000); r.push(`Your secret service makes use of black markets and illegal streams of goods to make a profit, making you <span class="yellowgreen">${cashFormat(blackMarket)}.</span> This however allows <span class="red">crime to flourish</span> in the underbelly of the arcology.`); - V.SecExp.core.crimeLow += random(1, 3); + V.SecExp.core.crimeLow = Math.clamp(V.SecExp.core.crimeLow + random(1, 3), 0, 100); cashX(blackMarket, "personalBusiness"); } diff --git a/src/endWeek/events/retire.js b/src/endWeek/events/retire.js index c81d54ab585e57de6ef68269fc079b68c552f941..79385b8c687342ab08f5c63110304bf7b30c9014 100644 --- a/src/endWeek/events/retire.js +++ b/src/endWeek/events/retire.js @@ -429,9 +429,10 @@ globalThis.retireScene = function(originalSlave) { App.Events.addParagraph(desc, r); r = []; - App.UI.DOM.appendNewElement("div", result, App.UI.DOM.link( + const fuck = App.UI.DOM.appendNewElement("div", result, App.UI.DOM.link( `Fuck it`, () => { + const r = []; if (V.PC.dick !== 0) { r.push(`You enter a command, and the Fuckdoll instantly`); if (hasAnyLegs(slave)) { @@ -449,6 +450,7 @@ globalThis.retireScene = function(originalSlave) { } } r.push(`You leave it where it is, your personal assistant directing a slave to perform maintenance on it when ${heU} has the time.`); + return jQuery(fuck).empty().append(r.join(" ")); } )); diff --git a/src/endWeek/reports/brothelReport.js b/src/endWeek/reports/brothelReport.js index 41342c1dbb46183f9cb69e92df8508dca76de2c6..b3d899cb9dd500dafa7995dd0fb804a8eb280764 100644 --- a/src/endWeek/reports/brothelReport.js +++ b/src/endWeek/reports/brothelReport.js @@ -9,8 +9,6 @@ App.EndWeek.brothelReport = function() { const slaves = App.Utils.sortedEmployees(App.Entity.facilities.brothel); const SL = slaves.length; let profits = 0; - V.legendaryWhoreID = 0; - V.legendaryWombID = 0; // Statistics gathering V.facility = V.facility || {}; @@ -294,13 +292,6 @@ App.EndWeek.brothelReport = function() { } let oldCash = V.cash; for (const slave of App.SlaveAssignment.reportSlaves(slaves)) { - if ((V.legendaryWombID === 0) && (!isAmputee(slave)) && (slave.preg > slave.pregData.normalBirth / 1.33) && (slave.broodmother === 0) && (slave.eggType === "human") && (slave.counter.births > 10) && (slave.devotion > 50) && (slave.prestige === 0)) { - V.legendaryWombID = slave.ID; - } - if ((V.legendaryWhoreID === 0) && (slave.skill.whoring >= 100) && (slave.devotion > 50) && (slave.prestige === 0)) { - V.legendaryWhoreID = slave.ID; - } - /* Perform facility based rule changes */ improveCondition(slave, healthBonus); slave.aphrodisiacs = aphrodisiacs; diff --git a/src/endWeek/reports/clubReport.js b/src/endWeek/reports/clubReport.js index 172bf78bbaed0ee0b1d3b790d1fd306bf4ce1b9e..007d0a48c5f579c57cef8a99f5b4f7012a2ffc1b 100644 --- a/src/endWeek/reports/clubReport.js +++ b/src/endWeek/reports/clubReport.js @@ -6,8 +6,6 @@ App.EndWeek.clubReport = function() { let r; const slaves = App.Utils.sortedEmployees(App.Entity.facilities.club); - V.legendaryEntertainerID = 0; - V.legendaryWombID = 0; // Statistics gathering; income is rep boosts in numbers, and profit will be rep per cash unit, or cash unit per rep V.facility = V.facility || {}; @@ -109,9 +107,6 @@ App.EndWeek.clubReport = function() { } App.Events.addNode(el, r, "p", "indent"); if (slaves.length + V.clubSlavesGettingHelp < 10 && V.DJnoSex !== 1 && !slaveResting(S.DJ)) { - if (V.legendaryEntertainerID === 0 && S.DJ.prestige === 0 && S.DJ.skill.entertainment >= 100 && S.DJ.devotion > 50) { - V.legendaryEntertainerID = S.DJ.ID; - } App.Events.addNode( el, [`Since ${he} doesn't have enough sluts in ${V.clubName} to make it worthwhile for ${him} to be on stage 24/7, ${he} spends ${his} extra time slutting it up ${himself}. ${He} has sex with ${S.DJ.sexAmount} citizens, <span class="green">pleasing them immensely,</span> since it's more appealing to fuck the DJ than some club slut.`], @@ -169,12 +164,6 @@ App.EndWeek.clubReport = function() { if (slaves.length > 0) { for (const slave of App.SlaveAssignment.reportSlaves(slaves)) { - if (V.legendaryEntertainerID === 0 && slave.prestige === 0 && slave.skill.entertainment >= 100 && slave.devotion > 50) { - V.legendaryEntertainerID = slave.ID; - } - if (V.legendaryWombID === 0 && !isAmputee(slave) && slave.preg > slave.pregData.normalBirth / 1.33 && slave.broodmother === 0 && slave.eggType === "human" && slave.counter.births > 10 && slave.devotion > 50 && slave.prestige === 0) { - V.legendaryWombID = slave.ID; - } if (slave.devotion <= 20 && slave.trust >= -20) { slave.devotion -= 5; slave.trust -= 5; diff --git a/src/endWeek/reports/dairyReport.js b/src/endWeek/reports/dairyReport.js index 02f531bc148b320fa07a4482a7ac69306dbd6475..9a23dea7f04276e0055dadd2c71890999df5c23f 100644 --- a/src/endWeek/reports/dairyReport.js +++ b/src/endWeek/reports/dairyReport.js @@ -16,8 +16,6 @@ App.EndWeek.dairyReport = function() { const restrainedInjected = V.dairyRestraintsSetting + V.injectionUpgrade; const boobsMultiplier = Math.trunc(V.injectionUpgrade * 2) + V.dairyRestraintsSetting + V.dairyFeedersSetting; V.bioreactorPerfectedID = 0; - V.legendaryBallsID = 0; - V.legendaryCowID = 0; V.milkmaidDevotionBonus = 1; V.milkmaidHealthBonus = 0; V.milkmaidTrustBonus = 1; @@ -355,22 +353,6 @@ App.EndWeek.dairyReport = function() { const oldCash = V.cash; for (const slave of App.SlaveAssignment.reportSlaves(slaves)) { - /* Special attention section */ - if (slave.devotion > 50 && slave.prestige === 0) { - if ( - V.legendaryCowID === 0 && slave.lactation > 0 && - (slave.boobs - slave.boobsImplant - slave.boobsMilk) > 6000 - ) { - V.legendaryCowID = slave.ID; - } - if ( - V.legendaryBallsID === 0 && slave.dick !== 0 && - (slave.balls > 5 || (slave.balls > 4 && slave.prostate > 1)) - ) { - V.legendaryBallsID = slave.ID; - } - } - /* Perform facility based rule changes */ // Set diet diff --git a/src/endWeek/reports/masterSuiteReport.js b/src/endWeek/reports/masterSuiteReport.js index ed0f38e73410e9f2271b9cce676fb03e4927eac5..8522e5e99a22cb50d5cfe7f1fb8447841342cab4 100644 --- a/src/endWeek/reports/masterSuiteReport.js +++ b/src/endWeek/reports/masterSuiteReport.js @@ -4,16 +4,6 @@ App.EndWeek.masterSuiteReport = function() { const slaves = App.Utils.sortedEmployees(App.Entity.facilities.masterSuite); const msAvg = App.Utils.masterSuiteAverages(); - // find a potential legendary abolitionist - const abolitionist = slaves.find((s) => (s.devotion > 95) && (s.prestige === 0) && ( - (s.origin === "You sentenced $him to enslavement as a punishment for attempted theft of a slave.") || - (s.origin === "$He is an enslaved Daughter of Liberty.") || - (s.origin === "You got $him at the Slave Shelter. $He is an enslaved Daughter of Liberty, caught some weeks after the failed coup. $His previous owner used $him as a punching bag and dart board, then when he was bored of $him tattooed obscenities all over $his body and threw $him away.") || - (s.origin === "$He is an enslaved member of an anti-slavery extremist group.") || - (s.career === "an antislavery activist") - )); - V.legendaryAbolitionistID = abolitionist ? abolitionist.ID : 0; - const pregnantSlaves = V.masterSuiteUpgradePregnancy ? slaves.filter((s) => s.pregKnown > 0).length : 0; function concubineText() { diff --git a/src/endWeek/reports/penthouseReport.js b/src/endWeek/reports/penthouseReport.js index 5de638689bbe0965067f80bf8a33f66536eaf1c1..4a4ca2ce51e19436162190c5d271a922d0526811 100644 --- a/src/endWeek/reports/penthouseReport.js +++ b/src/endWeek/reports/penthouseReport.js @@ -619,7 +619,7 @@ App.EndWeek.penthouseReport = function() { slave.navelPiercing = 0; } else { if (V.arcologies[0].FSDegradationist !== "unset") { - r.push(`${S.HeadGirl.slaveName} knows that ${slave.slaveName} needs help adjusting to life as a slave${girl2}, so ${he} has the slave's navel pierced with a big ring. Whatever ${he2} thinks in ${his2} mind, S.HeadGirl.slaveName makes clear to ${him2} that ${his2} body belongs to you.`); + r.push(`${S.HeadGirl.slaveName} knows that ${slave.slaveName} needs help adjusting to life as a slave${girl2}, so ${he} has the slave's navel pierced with a big ring. Whatever ${he2} thinks in ${his2} mind, ${S.HeadGirl.slaveName} makes clear to ${him2} that ${his2} body belongs to you.`); } else { r.push(`${S.HeadGirl.slaveName} knows that ${slave.slaveName} needs help adjusting to life as a slave${girl2}, so ${he} has the slave's navel pierced. The prettier ${his2} lower half looks, the less reluctant ${he2} should feel to take it up the butt.`); } diff --git a/src/events/JE/jeSlaveDisputeSlaveDeal.js b/src/events/JE/jeSlaveDisputeSlaveDeal.js index b001509112077bcc38fc70a95aaeac4e9b185c84..f3e67f0af05fae7fd4353c5843de02952b05c40c 100644 --- a/src/events/JE/jeSlaveDisputeSlaveDeal.js +++ b/src/events/JE/jeSlaveDisputeSlaveDeal.js @@ -57,7 +57,6 @@ App.Events.JESlaveDisputeSlaveDeal = class JESlaveDisputeSlaveDeal extends App.E r.push(`You privately inform both parties you'll settle this in favor of the most generous. You instantly receive a single notice of escrow payment contingent on the case going the payer's way. You select the <span class="yellowgreen">bigger of the two</span> and decide the matter before returning to bed in a good mood. However, the next day it becomes apparent that although ${he} isn't stupid enough to make a public accusation of corruption, the older ${woman} made use of ${his} few remaining hours of freedom to <span class="red">slander</span> your administration of justice.`); repX(-100, "event"); cashX(random(150, 200) * 10, "event"); - r.push(App.UI.newSlaveIntro(slave)); App.Events.addParagraph(frag, r); return frag; } @@ -68,7 +67,6 @@ App.Events.JESlaveDisputeSlaveDeal = class JESlaveDisputeSlaveDeal extends App.E r.push(`You settle the dispute in favor of the slave-to-be. ${He} is resigned, knowing that ${he}'s now owned by a woman who almost certainly hates ${him}, but ${his} daughter's treatments are assured. The story gets around quickly, <span class="green">capturing the hearts</span> of more romantic citizens. The angry slave trader leaves the arcology, <span class="red">reducing prosperity.</span>`); V.arcologies[0].prosperity -= 5; repX(2500, "event"); - r.push(App.UI.newSlaveIntro(slave)); App.Events.addParagraph(frag, r); return frag; } diff --git a/src/events/PE/pePitFight.js b/src/events/PE/pePitFight.js index de7b9865747b99bbef511ba3eab525de002a633b..bdfffc9d0aae3adb34e9a2b5ec0f935e675f1ac5 100644 --- a/src/events/PE/pePitFight.js +++ b/src/events/PE/pePitFight.js @@ -38,7 +38,7 @@ App.Events.PEPitFight = class PEPitFight extends App.Events.BaseEvent { App.Events.addParagraph(node, r); r = []; - r.push(`Across the ring, ${his} opponent's owner nods civilly to you and examines slave.slaveName.`); + r.push(`Across the ring, ${his} opponent's owner nods civilly to you and examines ${slave.slaveName}.`); if (slave.skill.combat > 0) { r.push(`${His} combat skills greatly increase ${his} deadliness.`); @@ -230,11 +230,12 @@ App.Events.PEPitFight = class PEPitFight extends App.Events.BaseEvent { r.push(`${slave.slaveName} senses that ${he} is greatly superior, and decides to make a quick end before ${his} opponent can try something foolish. ${He} feints high and stabs low; ${his} enemy just manages to parry the low stab, but is so much weaker that ${slave.slaveName} simply overpowers ${himU}, so that ${heU} falls onto ${hisU} back with the force of the clash. ${slave.slaveName} takes one step forward and runs ${his} sword through the prostrate slave's heart. This victory has <span class="reputation inc">won you some renown</span> and <span class="cash inc">a sum of money</span> from each of the spectators.`); repX(500, "pit", slave); cashX(5000, "pit", slave); + damage = 0; slave.counter.pitWins += 1; slave.counter.pitKills += 1; V.pitKillsTotal += 1; } else if (deadlinessValue > (opponent)) { - r.push(`The combat is long and exhausting. ${slave.slaveName} and ${his} opponent are closely matched in terms of skill, so neither takes foolish risks and a protracted, bloody fight results as both slaves take horrible but non-life-threatening cuts. Finally, slave.slaveName's superior physical condition wins out and ${his} opponent falls from exhaustion and blood loss. slave.slaveName stumbles over to open${hisU} throat. This victory has <span class="reputation inc">won you some renown</span> and <span class="cash inc">a sum of money</span> from each of the spectators, though`); + r.push(`The combat is long and exhausting. ${slave.slaveName} and ${his} opponent are closely matched in terms of skill, so neither takes foolish risks and a protracted, bloody fight results as both slaves take horrible but non-life-threatening cuts. Finally, ${slave.slaveName}'s superior physical condition wins out and ${his} opponent falls from exhaustion and blood loss. ${slave.slaveName} stumbles over to open ${hisU} throat. This victory has <span class="reputation inc">won you some renown</span> and <span class="cash inc">a sum of money</span> from each of the spectators, though`); repX(500, "pit", slave); cashX(5000, "pit", slave); damage = 50; diff --git a/src/events/RE/incest/REresistantmotherdaughter.js b/src/events/RE/incest/REresistantmotherdaughter.js new file mode 100644 index 0000000000000000000000000000000000000000..241122673fe79f219541c6ccf55ae9e0679daa3b --- /dev/null +++ b/src/events/RE/incest/REresistantmotherdaughter.js @@ -0,0 +1,125 @@ +App.Events.REResistantMotherDaughter = class REResistantMotherDaughter extends App.Events.BaseEvent { + eventPrerequisites() { + return [ + () => V.seeIncest === 1 + ]; + } + + actorPrerequisites() { + return [ + [ + (s) => s.daughters > 0, + (s) => s.devotion > 50, + (s) => s.anus !== 0, + canWalk, + ], + [ + s => s.mother === this.actors[0], + (s) => s.devotion < 10, + (s) => s.anus !== 0, + canWalk + ] + ]; + } + + execute(node) { + V.nextButton = "Continue"; + V.nextLink = "RIE Eligibility Check"; + let r = []; + const mommy = getSlave(this.actors[0]); + const daughter = getSlave(this.actors[1]); + const { + he, him, his, mother + } = getPronouns(mommy); + + const { + his2, daughter2 + } = getPronouns(daughter).appendSuffix("2"); + + App.Events.drawEventArt(node, [mommy, daughter], "no clothing"); + + r.push(`${mommy.slaveName} and ${his} ${daughter2} are both having trouble getting acclimated to your ownership, with their obedience suffering as a result. Though neither of them have done anything particular egregious lately, their combined list of minor transgressions is reaching a point where rendering punishment on the two would not be seen as unfair. By happenstance they come before you for inspection one after the other. Though they certainly`); + if (canSee(mommy) && canSee(daughter)) { + r.push(`see each other naked frequently around`); + } else { + r.push(`are frequently naked around each other in`); + } + r.push(`the penthouse, neither seems particularly comfortable around the other when nudity is involved. While you finish ${mommy.slaveName}'s inspection, ${his} ${daughter2} fidgets uneasily even while trying to mimic the posture and appearance of an obedient slave. It occurs to you that the current situation presents an opportunity to do <i>something</i> about this resistant ${mother}-${daughter2} pair.`); + App.Events.addParagraph(node, r); + + const choices = []; + choices.push(new App.Events.Result(`Spend the evening gently acclimating them to your ownership`, gently)); + choices.push(new App.Events.Result(`Make an example of the ${mother}`, exampleMommy)); + App.Events.addResponses(node, choices); + + function gently() { + const frag = new DocumentFragment(); + let r = []; + r.push(`Though neither of the two vehemently protests your decision to have them both join you in bed, furtive uneasy glances are exchanged between the two. Since they're already naked, they clamber onto your bed before you and reluctantly kneel facing each other, leaving enough space between them for you${(canSee(mommy) && canSee(daughter)) ? "and for them to avert their eyes to avoid the other's nakedness" : ""}. They clearly assume you would start by using one of them, so they're quite taken aback when you remain standing at the edge of the bed and suggest that ${mommy.slaveName} play with ${his} ${daughter2}. ${daughter.slaveName} awkwardly flounders a little as ${his2} ${mother}'s`); + if (hasBothArms(mommy)) { + r.push(`hands roam`); + } else if (hasAnyArms(mommy)) { + r.push(`hand roams`); + } + r.push(`about ${his2} body, but does not reel back from the intimate touching. In time you instruct ${daughter.slaveName} to pleasure ${his2} ${mother}, but still decline to join the incestuous union unfolding on your sheets. You extend the foreplay for hours, bringing both ${mother} and ${daughter2} to such a state of naked arousal that they begin grinding against each other uninhibitedly. They are both so desperate for release that they do not object when you finally decide to join them, instead eagerly moving to include you in their coupling. What started with ${daughter.slaveName} awkwardly kneeling unmoving while ${his2} ${mother} sucked ${his2} nipples ends with ${daughter.slaveName}`); + if (hasAllLimbs(daughter)) { + r.push(`on all fours`); + } else { + r.push(`bent over`); + } + r.push(`getting fucked by you while orally pleasuring ${mommy.slaveName}. You gaze over at ${mommy.slaveName} and ${he} moans and licks ${his} lips enticingly back at you as ${daughter.slaveName} moans into ${his} fuckhole.`); + r.push(`<span class="trust inc">They have both become more trusting of you.</span>`); + + mommy.trust += 4; + daughter.trust += 4; + seX(mommy, "oral", daughter, "oral"); + + if (canDoAnal(mommy)) { + actX(mommy, "anal"); + } else if (canDoVaginal(mommy)) { + actX(mommy, "vaginal"); + } + + if (canDoAnal(daughter)) { + actX(daughter, "anal"); + } else if (canDoVaginal(daughter)) { + actX(daughter, "vaginal"); + } + + App.Events.addParagraph(frag, r); + return frag; + } + + function exampleMommy() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You give them orders of devastating simplicity: You are going to assrape ${mommy.slaveName} and if ${his} ${daughter2} offers even the most token of resistance, you'll punish ${mommy.slaveName}. They're stunned, but you shake them out of their shock by grabbing ${mommy.slaveName} by the arm${(V.PC.dick === 0) ? ", donning a strap-on" : ""} and shoving ${him} over your desk. ${daughter.slaveName} flinches visibly as you enter ${his2} ${mother}'s ass in one brutal stroke, for which you stain ${his2} ${mother}'s asscheeks a rosy red with a torrent of harsh spanks. ${mommy.slaveName} takes the rough anal pounding with only quiet sobbing and the occasional whimper of pain, but ${his} ${daughter2} can't bear to`); + if (canSee(daughter)) { + r.push(`see`); + } else if (canHear(daughter)) { + r.push(`hear`); + } else { + r.push(`have`); + } + r.push(`${mommy.slaveName} in such duress and breaks ${his2} short-lived silence to beg for mercy. When you step away from ${mommy.slaveName}, ${daughter.slaveName} lets out a sigh of relief, but ${his2} expression soon turns to horror and revulsion when you return to mount ${his2} ${mother} with a lash in hand.`); + App.Events.addParagraph(frag, r); + r = []; + r.push(`When you eventually finish your merciless assrape of ${mommy.slaveName}, ${his} body is covered in bruises, marks, and handprints. A testament to ${daughter.slaveName}'s inability to keep ${his2} silence as you brutalized ${his2} ${mother}. You leave your office wordlessly to attend to other matters, while behind you ${daughter.slaveName} gazes`); + if (canSee(daughter)) { + r.push(`forlornly`); + } else { + r.push(`blindly`); + } + r.push(`at the gibbering mess you have reduced ${his2} ${mother} to. Your severe punishment of ${his2} ${mother} has encouraged ${daughter.slaveName} to <span class="trust dec">fear you.</span> ${mommy.slaveName} has been fucked into <span class="devotion inc">submission</span> but your savage treatment has caused ${him} to <span class="flaw gain">hate buttsex.</span>`); + + daughter.trust -= 10; + mommy.devotion += 4; + + seX(mommy, "anal", V.PC, "penetrative"); + mommy.sexualFlaw = "hates anal"; + + App.Events.addParagraph(frag, r); + return frag; + } + } +}; diff --git a/src/events/RE/incest/reDevotedMotherDaughter.js b/src/events/RE/incest/reDevotedMotherDaughter.js new file mode 100644 index 0000000000000000000000000000000000000000..6ae79dfc76f407b0c5b4928865a7827d3b35d887 --- /dev/null +++ b/src/events/RE/incest/reDevotedMotherDaughter.js @@ -0,0 +1,86 @@ +App.Events.REDevotedMotherDaughter = class REDevotedMotherDaughter extends App.Events.BaseEvent { + eventPrerequisites() { + return [ + () => V.seeIncest === 1 + ]; + } + + actorPrerequisites() { + return [ + [ + (s) => s.daughters > 0, + (s) => s.devotion > 50, + (s) => s.anus !== 0, + canWalk, + ], + [ + s => s.mother === this.actors[0], + (s) => s.devotion > 50, + (s) => s.anus !== 0, + canWalk + ] + ]; + } + + execute(node) { + V.nextButton = "Continue"; + V.nextLink = "RIE Eligibility Check"; + let r = []; + const mommy = getSlave(this.actors[0]); + const daughter = getSlave(this.actors[1]); + const { + he, his, mother + } = getPronouns(mommy); + + const { + he2, his2, daughter2 + } = getPronouns(daughter).appendSuffix("2"); + + App.Events.drawEventArt(node, [mommy, daughter], "no clothing"); + + r.push(`${mommy.slaveName} and ${his} ${daughter2} ${daughter.slaveName} are both good slaves, devoted and obedient. They'd probably do anything you order them to do. By happenstance they come before you for inspection one after the other. They certainly see each other stark naked frequently enough. As you finish ${mommy.slaveName}'s inspection, ${his} ${daughter2} waits patiently for ${his2} turn. It occurs to you that they probably would do <i>anything</i> you order them to do, and that they're so acclimated to sexual slavery that they might well enjoy it.`); + + App.Events.addParagraph(node, r); + + const choices = []; + choices.push(new App.Events.Result(`Spend the night sharing your bed with them, and each of them with the other`, share)); + choices.push(new App.Events.Result(`Get them started and then keep them at it in your office`, started)); + App.Events.addResponses(node, choices); + + function share() { + const frag = new DocumentFragment(); + let r = []; + r.push(`Neither of them bat an eye when you announce you're turning in early and that they'll be joining you. Since they're already naked, they get into your big soft bed before you and lie facing each other, with enough room in between them for you to take a central position. They clearly assume you'll start with one of them on each side of you, so they're quite surprised when you slide in behind ${mommy.slaveName} instead. ${daughter.slaveName} snuggles up to ${his2} ${mother} happily enough, however. You extend the foreplay for hours, eventually bringing both of them to such a state of naked arousal that they begin grinding against each other as much as they do you. They get the idea, and things turn into a sort of unspoken mutual one-upmanship between them. What starts with ${daughter.slaveName} clearly feeling very daring as ${he2} sucks ${his2} ${mother}'s nipple ends with ${mommy.slaveName} lying on ${his} back getting fucked by you while ${he} orally pleasures ${daughter.slaveName}. You're face to face with ${daughter.slaveName} and ${he2} groans happily into your mouth as ${mommy.slaveName} moans into ${his2} fuckhole. <span class="trust inc">They have both become more trusting of you.</span>`); + + mommy.trust += 4; + daughter.trust += 4; + seX(mommy, "oral", daughter, "oral"); + + if (canDoAnal(mommy)) { + actX(mommy, "anal"); + } else if (canDoVaginal(mommy)) { + actX(mommy, "vaginal"); + } + + if (canDoAnal(daughter)) { + actX(daughter, "anal"); + } else if (canDoVaginal(daughter)) { + actX(daughter, "vaginal"); + } + App.Events.addParagraph(frag, r); + return frag; + } + + function started() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You give them orders of devastating simplicity: they are to repair to the couch in your office and are to take turns getting each other off until such time as you tell them otherwise. They're momentarily stunned, but ${mommy.slaveName} takes the lead and draws ${his} ${daughter2} over to the couch${(hasAnyArms(mommy) && hasAnyArms(daughter)) ? "by the hand" : ""}. They're both accomplished sex slaves and obey orders well, so they are quite successful in the little game, if a bit mechanical. For the rest of the day, interviewees come and go and are treated to the sight of the two of them having subdued sex on the couch. Showing off one's slaves for business interlocutors is a common Free Cities practice, but more than one perceptive person figures out what the resemblance between the two slaves and the age gap between them really means. Of course, all those who figure it out are impressed by your sheer decadence.`); + r.push(`<span class="reputation inc">Your reputation has increased considerably.</span>`); + repX(2500, "event", mommy); + repX(2500, "event", daughter); + seX(mommy, "oral", daughter, "oral", 5); + App.Events.addParagraph(frag, r); + return frag; + } + } +}; diff --git a/src/events/RE/incest/reSiblingRevenge.js b/src/events/RE/incest/reSiblingRevenge.js new file mode 100644 index 0000000000000000000000000000000000000000..83fcbaa203062fd643817a59da454375d131c75e --- /dev/null +++ b/src/events/RE/incest/reSiblingRevenge.js @@ -0,0 +1,151 @@ +App.Events.RESiblingRevenge = class RESiblingRevenge extends App.Events.BaseEvent { + eventPrerequisites() { + return [ + () => V.seeIncest === 1 + ]; + } + + actorPrerequisites() { + return [ + [ + (s) => s.sisters > 0, + (s) => s.origin === "$He was sold into slavery by $his older sister.", + canPenetrate, + ], + [ + (s) => s.anus === 0, + (s) => getSlave(this.actors[0]).devotion > (s.devotion + 20), + (s) => areSisters(getSlave(this.actors[0]), s) > 0, + ] + ]; + } + + execute(node) { + V.nextButton = "Continue"; + V.nextLink = "RIE Eligibility Check"; + let r = []; + const youngerSis = getSlave(this.actors[0]); + const olderSis = getSlave(this.actors[1]); + const { + He, His, + he, him, his, himself, + } = getPronouns(youngerSis); + const { + title: Master + } = getEnunciation(youngerSis); + + const { + his2, him2, sister2, girl2 + } = getPronouns(olderSis).appendSuffix("2"); + + App.Events.drawEventArt(node, [youngerSis, olderSis], "no clothing"); + + r.push( + `${youngerSis.slaveName}, whose older ${sister2} tried to sell ${him} to you, is up for inspection. As usual, you pepper your inspection with questions about ${his} duties, ${his} feelings about ${his} physical condition, and experiences. More information about one's property is never a bad thing. When the inspection reaches ${youngerSis.slaveName}'s asshole, you ask whether ${he} enjoyed having ${his} older ${sister2} sell ${his} butt.`, + Spoken(youngerSis, `"No, ${Master},"`), + `${he} says.` + ); + App.Events.addParagraph(node, r); + + const choices = []; + choices.push(new App.Events.Result(`Turnabout is fair play`, turn)); + choices.push(new App.Events.Result(`Let ${him} have ${his} revenge, but remind ${him} of ${his} place`, place)); + App.Events.addResponses(node, choices); + + function turn() { + const frag = new DocumentFragment(); + let r = []; + r.push(`${olderSis.slaveName} is brought in. You gag ${him2}, throw the resisting bitch down on the couch, and hold ${him2} there. Then, you peremptorily order the wide-eyed ${youngerSis.slaveName} to`); + if (canDoAnal(olderSis)) { + r.push(`sodomize`); + } else { + r.push(`facefuck`); + } + r.push(`${his} ${sister2}. ${He} stares open mouthed for a moment, but comes over obediently. ${His} face is a strange mix of vengeful eagerness, revulsion, and even a little lust. ${He} shoves ${himself} into the frantically struggling ${girl2}'s`); + if (canDoAnal(olderSis)) { + r.push(`butt`); + } else { + r.push(`jaw`); + } + r.push(`without mercy. ${His} cock is`); + if (youngerSis.dick < 3) { + r.push(`pathetically small,`); + } else if (youngerSis.dick < 5) { + r.push(`nothing out of the ordinary,`); + } else if (youngerSis.dick < 7) { + r.push(`admittedly nothing to scoff at,`); + } else { + r.push(`a source of great envy amongst your slaves,`); + } + r.push(`but by how ${olderSis.slaveName} reacts it might as well be a baseball bat. ${youngerSis.slaveName} rarely gets to penetrate anything, mostly serving as an oral slut${canDoAnal(youngerSis) ? "and anal cocksleeve" : ""}, so ${he} comes in no time and takes a turn holding ${olderSis.slaveName} down${canDoAnal(olderSis) ? `so you can claim sloppy seconds on ${his2} spasming butthole` : ""}.`); + r.push(`<span class="devotion inc">${youngerSis.slaveName} has become more devoted to you,</span> while ${olderSis.slaveName} <span class="trust inc">hates you</span> and has become <span class="trust dec">more afraid of you,</span>${canDoAnal(olderSis) ? `and <span class="virginity loss">${olderSis.slaveName} has lost ${his2} anal virginity.</span>` : `.`}`); + youngerSis.devotion += 4; + + olderSis.trust -= 5; + olderSis.devotion -= 4; + if (canDoAnal(olderSis)) { + olderSis.anus = 1; + seX(youngerSis, "penetrative", olderSis, "anal"); + } else { + seX(youngerSis, "penetrative", olderSis, "oral"); + } + App.Events.addParagraph(frag, r); + return frag; + } + + function place() { + const frag = new DocumentFragment(); + let r = []; + r.push(`${olderSis.slaveName} is brought in. You gag ${him2}, throw the resisting bitch down on the couch, and hold ${him2} there. Then, you peremptorily order the wide-eyed ${youngerSis.slaveName} to put ${his} cock`); + if (canDoAnal(olderSis)) { + r.push(`up ${his} ${sister2}'s ass,`); + } else { + r.push(`in ${his} ${sister2}'s mouth,`); + } + r.push(`and then hold it there. ${He} stares open mouthed for a moment, but comes over obediently. ${His} face is a strange mix of vengeful eagerness, revulsion, and even a little lust. ${He} shoves ${himself} into the frantically struggling ${girl2}'s`); + if (canDoAnal(olderSis)) { + r.push(`butt`); + } else { + r.push(`jaw`); + } + r.push(`without mercy. ${His} cock is`); + if (youngerSis.dick < 3) { + r.push(`pathetically small,`); + } else if (youngerSis.dick < 5) { + r.push(`nothing out of the ordinary,`); + } else if (youngerSis.dick < 7) { + r.push(`admittedly nothing to scoff at,`); + } else { + r.push(`a source of great envy amongst your slaves,`); + } + r.push(`but by how ${olderSis.slaveName} reacts it might as well be a baseball bat. ${youngerSis.slaveName} obeys your orders and holds still after inserting ${himself}. You`); + if (V.PC.dick === 0) { + r.push(`don a strap-on,`); + } + r.push(`move around`); + if (canDoAnal(youngerSis)) { + r.push(`behind ${him} and start ass`); + } else { + r.push(`in front of ${him} and start face-`); + } + r.push(`fucking ${him} in turn, slowly permitting ${him} to find a rhythm where ${he} can fuck and get fucked at the same time. ${He}'s getting it much harder than ${he}'s giving it but ${he}'s experienced enough that ${he} comes quickly.`); + r.push(`<span class="devotion inc">${youngerSis.slaveName} has become more devoted to you,</span> while <span class="devotion dec">${olderSis.slaveName} has become more rebellious,</span>${(canDoAnal(olderSis)) ? ` and <span class="virginity loss">${olderSis.slaveName} has lost ${his2} anal virginity.</span>` : `.`}`); + youngerSis.devotion += 4; + if (canDoAnal(youngerSis)) { + seX(youngerSis, "anal", V.PC, "penetrative"); + } else { + seX(youngerSis, "oral", V.PC, "penetrative"); + } + + olderSis.devotion -= 5; + if (canDoAnal(olderSis)) { + olderSis.anus = 1; + seX(youngerSis, "penetrative", olderSis, "anal"); + } else { + seX(youngerSis, "penetrative", olderSis, "oral"); + } + App.Events.addParagraph(frag, r); + return frag; + } + } +}; diff --git a/src/events/RE/reAWOL.js b/src/events/RE/reAWOL.js new file mode 100644 index 0000000000000000000000000000000000000000..6a70f399b9c41ee84b06eb4a20e268af17700686 --- /dev/null +++ b/src/events/RE/reAWOL.js @@ -0,0 +1,176 @@ + +App.Events.REAWOL = class REAWOL extends App.Events.BaseEvent { + eventPrerequisites() { + return [ + () => V.mercenaries > 0 + ]; + } + + get weight() { + return either(0, 1); // Originally rolled opposed to "RE Poker Night" + } + + execute(node) { + V.nextButton = "Continue"; + V.nextLink = "RIE Eligibility Check"; + const bountyFee = 5000; + const minAge = (V.pedo_mode === 1) ? 21 : 38; + const genParam = { + minAge: minAge, maxAge: 43, ageOverridesPedoMode: 1, race: "nonslave", disableDisability: 1 + }; + const slave = GenerateNewSlave(V.seeDicks !== 100 ? "XX" : "XY", genParam); + slave.origin = "You sentenced $him to enslavement as a punishment for dereliction of $his duty to you as a mercenary and for theft."; + slave.career = "a soldier"; + slave.devotion = random(-75, -60); + slave.trust = random(-15, 0); + setHealth(slave, jsRandom(60, 80)); + slave.muscles = 50; + slave.weight = random(-10, 10); + eyeSurgery(slave, "both", "normal"); + slave.hears = 0; + slave.anus = 0; + slave.skill.anal = 0; + slave.skill.whoring = 0; + slave.skill.combat = 1; + slave.behavioralFlaw = "arrogant"; + slave.sexualFlaw = "crude"; + slave.hStyle = "shaved into a mohawk"; + slave.custom.tattoo = "$He has a number of tattoos from a variety of mercenary companies."; + slave.clothes = "a military uniform"; + + const { + He, + he, him, his, woman + } = getPronouns(slave); + const { + HeA + } = getPronouns(assistant.pronouns().main).appendSuffix("A"); + App.Events.drawEventArt(node, slave); + + App.Events.addParagraph(node, [`Human soldiers are superior to drones in a number of ways — they have the capability for suspicion, the ability to understand human interactions, and are impervious to the ever-present threat of cyber-warfare. That said, a crucial failing of any sentient warrior is their agency.`]); + let r = []; + r.push(`On this particular evening, you find your work interrupted by an urgent alert from ${V.assistant.name}${(V.seeImages === 1) ? ", accompanied by a recent picture" : ""}.`); + if (V.assistant.personality > 0) { + r.push(`"${properMaster()}, one of the ${V.mercenariesTitle} has gone AWOL." ${HeA} pauses before continuing. "${He}'s taken a number of weapons with ${him}."`); + } else { + r.push(`${HeA} informs you that one of the ${V.mercenariesTitle} has disappeared, seemingly taking with ${him} a small stash of weapons.`); + } + + App.Events.addParagraph(node, r); + + App.Events.addParagraph(node, [`Your window of opportunity to act is closing. If you have plans for punishing this dereliction from your authority, they must be set in motion now.`]); + + const choices = []; + choices.push(new App.Events.Result(`Let them go`, release)); + choices.push(new App.Events.Result(`Let your mercenaries handle ${him}`, merc)); + if (V.SF.Toggle && V.SF.Active >= 1) { + choices.push(new App.Events.Result(`Let your ${V.SF.Lower} handle ${him}`, SF)); + } + if (V.cash < 5000) { + choices.push(new App.Events.Result(null, null, "You lack the necessary funds to put out a bounty.")); + } else { + choices.push(new App.Events.Result(`Put out a bounty on ${his} head`, bounty, `It will cost ${cashFormat(bountyFee)} to put out a bounty on ${him}.`)); + } + App.Events.addResponses(node, choices); + + function release() { + repX(-1000, "event", slave); + return `You inform your personal assistant that you aren't planning to take any action. By the next morning, word has spread to the rest of your arcology that crossing you is apparently permissible and your <span class="reputation dec">reputation has suffered</span> as a result.`; + } + + function merc() { + if (random(1, 100) > 50) { + return `Despite the trouble ${he} has caused you, the culmination of this mercenary's wanton flight from the rest of the ${V.mercenariesTitle} is decidedly an anti-climax. The last you hear of the matter is a chorus of grim grunts and nods as your mercenaries file back into the arcology. The matter is done.`; + } else { + return `Your mercenaries return to tell you that they could not find the mutineer. It could be that ${he} managed to escape beyond their reach or that one among your 'loyal' retainers allowed ${him} to flee your judgment, but alas there is little that can be done to remedy the issue now. Still, aside from a slight grumbling within the arcology, few fault you for allowing the ${V.mercenariesTitle} to recapture one of their own — even if they failed to do so.`; + } + } + + function SF() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You take a tablet and send ${App.SF.SFC()} a notice about the mutinous mercenary. When you have the majority of the pertinent details committed to text, all that remains is to decide the fate of your quarry.`); + App.Events.addParagraph(frag, r); + + const choices = []; + choices.push(new App.Events.Result(`You want ${him} dead`, dead)); + choices.push(new App.Events.Result(`You want ${him} alive`, alive)); + App.Events.addResponses(frag, choices); + return frag; + + function dead() { + repX(5000, "event", slave); + V.arcologies[0].prosperity = Math.min(V.arcologies[0].prosperity+2, V.AProsperityCap); + return `Despite the trouble ${he} has caused you, the culmination of this mercenary's wanton flight from the rest of the ${V.mercenariesTitle} is decidedly anti-climatic. The last you hear of ${him} is in the footnote of one of your daily reports, with some minute yet suitably gory pictures as an accompaniment. When the stolen weapons are returned to their rightful place in your arcology, the unfortunate matter is concluded once and for all. <span class="prosperity inc">Your reputation and ${V.arcologies[0].name}'s prosperity improves,</span> a result of the fear crossing you will bring, in addition to showing your citizens that you are willing and able to deal with such matters in-house.`; + } + + function alive() { + const frag = new DocumentFragment(); + let r = []; + slave.clothes = "chains"; + App.Art.refreshSlaveArt(slave, 3, "art-frame"); + r.push(`It doesn't take long for a squad of ${V.SF.Lower} to track ${him} down. Soon you have the troublesome turncoat before you in chains.`); + App.Events.addParagraph(frag, r); + + const choices = []; + choices.push(new App.Events.Result(`Enslave ${him}`, enslave)); + choices.push(new App.Events.Result(`Flog ${him} in public then exile ${him} from the arcology`, () => flog(true))); + App.Events.addResponses(frag, choices); + + return frag; + } + } + + function bounty() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You take a tablet and draft a bounty notice for the mutinous mercenary. When you have the majority of the pertinent details committed to text, all that remains is to decide the fate of your quarry.`); + App.Events.addParagraph(frag, r); + + const choices = []; + choices.push(new App.Events.Result(`You want ${him} dead`, dead)); + choices.push(new App.Events.Result(`You want ${him} alive`, alive)); + App.Events.addResponses(frag, choices); + return frag; + + function dead() { + repX(5000, "event", slave); + cashX(-bountyFee, "capEx"); + return `Despite the trouble ${he} has caused you, the culmination of this mercenary's wanton flight from the rest of the ${V.mercenariesTitle} is decidedly an anti-climax. The last you hear of ${him} is in the footnote of one of your daily reports, with some minute yet suitably gory pictures as an accompaniment. When the stolen weapons are returned to their rightful place in your arcology, the unfortunate matter is concluded once and for all. <span class="reputation inc">Your reputation improves,</span> a result of the fear of crossing you that your unpleasantness has inspired.`; + } + + function alive() { + const frag = new DocumentFragment(); + let r = []; + slave.clothes = "chains"; + App.Art.refreshSlaveArt(slave, 3, "art-frame"); + r.push(`It doesn't take long for some hired guns, motivated by the bounty, to track ${him} down. Soon you have the troublesome turncoat before you in chains.`); + cashX(-bountyFee, "event", slave); + App.Events.addParagraph(frag, r); + const choices = []; + choices.push(new App.Events.Result(`Enslave ${him}`, enslave)); + choices.push(new App.Events.Result(`Flog ${him} in public then exile ${him} from the arcology`, () => flog(false))); + App.Events.addResponses(frag, choices); + return frag; + } + } + + function flog(inHouse) { + let r = []; + r.push(`An example must be made. There is a binding contract between you and your ${V.mercenariesTitle}, and this ${woman} attempted to undermine it for ${his} own selfish profit. The protesting bitch is stripped and flogged on the promenade before being escorted bleeding from the arcology. The public <span class="reputation inc">approves of this harshness.</span>`); + repX(5000, "event", slave); + if (inHouse) { + r.push(`In addition <span class="prosperity inc">Arcology prosperity improves,</span> a result of showing your citizens that you are willing and able to deal with such matters in-house.`); + V.arcologies[0].prosperity = Math.min(V.arcologies[0].prosperity+2, V.AProsperityCap); + } + return r; + } + + function enslave() { + let r = []; + r.push(`Despite the trouble ${he} has caused you, you manage to complete the legalities and biometric scanning quickly and without incident. Of course, this is in large part due to the fact that the would-be mutineer is of course restrained. Based on the accounts of ${his} captors and the numerous injuries evident amongst them, ${he} is likely to be violent when ${he} is finally released.`); + r.push(App.UI.newSlaveIntro(slave)); + return r; + } + } +}; diff --git a/src/events/RE/reAnalPunishment.js b/src/events/RE/reAnalPunishment.js new file mode 100644 index 0000000000000000000000000000000000000000..46de3561dd38908cf895fb3b8a6361cda292d274 --- /dev/null +++ b/src/events/RE/reAnalPunishment.js @@ -0,0 +1,179 @@ +App.Events.REAnalPunishment = class REAnalPunishment extends App.Events.BaseEvent { + eventPrerequisites() { + return [ + () => V.HeadGirlID !== 0, + () => V.HGSeverity >= 0 + ]; + } + + actorPrerequisites() { + return [[ + (s) => s.devotion <= 50, + (s) => s.anus !== 0, + (s) => s.fetish !== "mindbroken", + canDoAnal, + hasAnyLegs, + hasAnyArms, + canTalk, + ]]; + } + + execute(node) { + let r = []; + const slave = getSlave(this.actors[0]); + + V.nextButton = "Continue"; + V.nextLink = "Next Week"; + + const { + He, His, + he, his, him, himself, girl, woman + } = getPronouns(slave); + + const {title: Master} = getEnunciation(slave); + + const { + He2, + he2, his2, him2, himself2 + } = getPronouns(S.HeadGirl).appendSuffix("2"); + + App.Events.drawEventArt(node, [slave, S.HeadGirl], "no clothing"); + + r.push( + `As you're making the rounds through your penthouse, you hear ${S.HeadGirl.slaveName} speaking in the tones ${he2} uses to castigate misbehaving slaves in the next room. When you appear in the doorway, you have little chance to survey the situation before`, + App.UI.DOM.combineNodes( + contextualIntro(S.HeadGirl, slave, "DOM"), + `, apparently the miscreant, flings ${himself} at your feet. ${He} clings to one of your legs convulsively, choking on tears as ${he} stares up at you and tries to muster an explanation. After two false starts, ${he} manages to start begging.` + ), + Spoken(slave, `"Please, ${Master},"`), + `${he} wails miserably.`, + Spoken(slave, `"Please don't let ${him2} rape my butt."`) + ); + + App.Events.addParagraph(node, r); + r = []; + r.push(`You shoot an amused glance at ${S.HeadGirl.slaveName}, who smiles back as ${he2} explains the slave's minor sin and ${his2} intention to sodomize the malefactor. ${He2} does not bother to keep an edge of anticipation out of ${his2} voice, and ${slave.slaveName} cries harder and clings to you with renewed force as your Head Girl pronounces ${his2} intention with cruel clarity.`); + if (slave.boobs > 4000) { + r.push(`The supplicant's breasts are so huge that ${his} embrace of your leg has completely surrounded it in deliciously heaving breastflesh.`); + } else if (slave.boobs > 1000) { + r.push(`The weight of the supplicant's breasts is quite noticeable as ${his} embrace of your leg presses them against it.`); + } + r.push(`You look down at ${slave.slaveName}. ${He} stares back with huge wet ${App.Desc.eyesColor(slave)}, doing ${his} best to implore you with ${his} gaze, and scooting ${his} rear in towards your foot in an unconscious effort to protect it from the promised assrape. ${He}'s quite authentically terrified; ${his} whole body is shaking.`); + App.Events.addParagraph(node, r); + r = []; + r.push(`${S.HeadGirl.slaveName} is very much acting within ${his2} duties, and ${slave.slaveName} has now misbehaved twice by trying to go over your Head Girl's head by appealing to you. ${S.HeadGirl.slaveName} is ready to carry out the sentence: `); + if (canPenetrate(S.HeadGirl) && (S.HeadGirl.dick > 2)) { + r.push(`${his2} cock is fully erect, and ${he2}'s keeping it hard with one hand. ${He2} slaps its head against ${his2} other palm,`); + } else if (S.HeadGirl.dick > 0) { + r.push(`since ${his2} dick isn't an appropriate instrument for inflicting anal pain, ${he2}'s got an elephantine dildo ready. ${He2} slaps it against ${his2} palm,`); + } else { + r.push(`${He2}'s got an elephantine dildo ready, and ${he2} slaps it against ${his2} palm,`); + } + r.push(`forcing a frightened moan from ${slave.slaveName}.`); + + App.Events.addParagraph(node, r); + + const choices = []; + choices.push(new App.Events.Result(`Carry on`, carryOn)); + choices.push(new App.Events.Result(`Take part`, takePart)); + choices.push(new App.Events.Result(`Take pity`, takePity)); + App.Events.addResponses(node, choices); + + function carryOn() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You ignore ${slave.slaveName} — no small feat, since the poor`); + if (slave.physicalAge > 30) { + r.push(`${woman}`); + } else { + r.push(`${girl}`); + } + r.push(`is clinging to your leg — and tell ${S.HeadGirl.slaveName} to carry on. Your Head Girl <span class="trust inc">puffs up a bit with pride,</span> and orders the weeping slave to present ${his} anus. The ${(slave.physicalAge > 30) ? woman : girl} does not resist, but nor does ${he} comply. ${S.HeadGirl.slaveName} jabs a thumb into ${slave.slaveName}'s side, right above ${his} kidney, driving the wind out of the slave with a pained grunt. ${He} arches ${his} back involuntarily and ${his} grip on you loosens, and ${S.HeadGirl.slaveName} drags ${him} off you. ${He2} jabs ${him} again, depriving ${his2} victim of breath completely, and then takes ${him2} by the ankle, dragging the slave across the floor with comic effect. The slave leaves a trail of tears across the flooring as ${he} vanishes into the room. As you continue making your rounds, you hear a drawn-out howl followed by rhythmic screaming.`); + slave.counter.anal += 1; + V.analTotal += 1; + S.HeadGirl.trust += 4; + S.HeadGirl.counter.penetrative += 1; + V.penetrativeTotal += 1; + + App.Events.addParagraph(frag, r); + return frag; + } + + function takePart() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You explain ${slave.slaveName}'s double crime to ${him}, and tell ${S.HeadGirl.slaveName} to get started. Your Head Girl orders the weeping slave to present ${his} anus. The ${(slave.physicalAge > 30) ? woman : girl} does not resist, but nor does ${he} comply. ${S.HeadGirl.slaveName} jabs a thumb into ${slave.slaveName}'s side, right above ${his} kidney, driving the wind out of the slave with a pained grunt. ${He} arches ${his} back involuntarily and ${his} grip on you loosens, so${S.HeadGirl.slaveName} drags ${him} off you, telling ${slave.slaveName} that it'll hurt less if ${he} cooperates and assumes the proper position. ${He} doesn't, so ${S.HeadGirl.slaveName} assfucks ${him} lying flat on the floor, with the poor ${girl} sobbing loudly as ${S.HeadGirl.slaveName}`); + if (canPenetrate(S.HeadGirl) && (S.HeadGirl.dick > 2)) { + r.push(`pistons ${his2} cock in and out of ${his} rectum.`); + } else { + r.push(`rams the massive dildo up ${his} butt.`); + } + App.Events.addParagraph(frag, r); + r = []; + r.push(`After enjoying the spectacle for a while, you judge that the slave's sphincter is loose enough and tell ${S.HeadGirl.slaveName} to flip the bitch over. <span class="devotion inc">${He2} obeys, chuckling,</span> sitting ${himself2} down and hauling the reluctant slave onto ${his2} lap by seizing a nipple and pulling it into position so the agonized slave is forced to follow.`); + if (canPenetrate(S.HeadGirl) && (S.HeadGirl.dick > 2)) { + r.push(`${S.HeadGirl.slaveName} reinserts ${his2} dick, `); + } else { + r.push(`${S.HeadGirl.slaveName} maneuvers the dildo down over ${his2} own crotch, approximating the position of a natural cock and using its base to stimulate ${himself2}. ${He2} reinserts it,`); + } + r.push(`intentionally missing twice to keep the experience unpleasant despite ${his2} victim's well-fucked backdoor.`); + App.Events.addParagraph(frag, r); + r = []; + r.push(`${slave.slaveName}, now facing upward rather than having ${his} face ground into the floor, notices for the first time that`); + if (V.PC.dick !== 0) { + r.push(`you've got your dick out and hard.`); + } else { + r.push(`you've donned one of your punishment-sized strap-ons.`); + } + r.push(`${His} ${App.Desc.eyesColor(slave)} <span class="trust dec">fly open with horror</span> as you kneel down and smack its head against ${his}`); + if (slave.vagina > -1) { + r.push(`poor pussy,`); + } else { + r.push(`stretched taint,`); + } + r.push( + `but ${he} doesn't realize how comprehensively fucked ${he} is until you press it against the top of ${his} already-stretched anal sphincter.`, + Spoken(slave, `"Please no, ${Master}! It won't fit! Please ${(slave.vagina > 0) ? "put it in my pussy" : "let me suck it"} instead,"`), + `${he} begs desperately.`, + Spoken(slave, `"I p-promise I'll be a g-good`), + ); + if (girl === "girl") { + r.push(Spoken(slave, `giiAAIIEEHH,"`)); + } else if (girl === "boy") { + r.push(Spoken(slave, `boAAIIEEHH,"`)); + } else if (girl === "toy") { + r.push(Spoken(slave, `toAAIIEEHH,"`)); + } else { + r.push(Spoken(slave, `slaAAIIEEHH,"`)); + } + r.push( + `${he} howls. ${He} gasps for air, tears streaming down ${his} ${slave.skin} cheeks, and then continues:`, + Spoken(slave, `"AAAH! FUCK! TAKE IT OUUUT! N-NOOO, PLEASE DON'T THRUST — AAAH! AAAH! AAAH!"`) + ); + + seX(slave, "anal", S.HeadGirl, "penetrative"); + S.HeadGirl.devotion += 4; + slave.trust -= 5; + + App.Events.addParagraph(frag, r); + return frag; + } + + function takePity() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You tell ${S.HeadGirl.slaveName} you've decided to be merciful, just this once. ${slave.slaveName} holds your leg even harder, <span class="trust inc">sobbing ${his} thanks</span> over and over until you reach down, pat ${his} head, and tell ${him} it will be all right, calming the hysterical`); + if (slave.physicalAge > 30) { + r.push(`${woman}.`); + } else { + r.push(`${girl}.`); + } + r.push(`${S.HeadGirl.slaveName}, meanwhile, stammers an apology. ${He2} hurries about ${his2} business, <span class="trust dec">badly puzzled</span> and more than a little shaken. ${He2} thought ${he2} had the authority to anally rape misbehaving slaves, but ${he2}'s no longer so sure of ${his2} rights and responsibilities.`); + slave.trust += 4; + S.HeadGirl.trust -= 15; + + App.Events.addParagraph(frag, r); + return frag; + } + } +}; diff --git a/src/events/RE/reArcologyInspection.js b/src/events/RE/reArcologyInspection.js index 1f87c964457e116861b58602e399e15c086dc878..66907be72d614114d1742baa830351a73acc966c 100644 --- a/src/events/RE/reArcologyInspection.js +++ b/src/events/RE/reArcologyInspection.js @@ -461,7 +461,7 @@ App.Events.REArcologyInspection = class REArcologyInspection extends App.Events. t.push(`Every arcology has its share of dissidents; it's one of the inevitable results of the semi-anarchic nature of the Free Cities. You have an opportunity to build your own <span class="reputation inc">reputation</span> and also help secure ${agent ? `${agent.slaveName}'s` : `your indirect`} <span class="darkviolet">authority</span> over ${arcology.name}, and it would be a shame to let it pass unheeded. You spend the rest of the day helping pass judgement, and even administer a few whippings and assfuckings yourself, just for good measure.`); repX(100, "event"); if (V.secExpEnabled) { - V.SecExp.core.authority += 250; + V.SecExp.core.authority = Math.clamp(V.SecExp.core.authority + 250, 0, 20000); } return t; } diff --git a/src/events/RE/reLegendaryBalls.js b/src/events/RE/reLegendaryBalls.js new file mode 100644 index 0000000000000000000000000000000000000000..5775686a99baf2c9167f7546897891c156f5d946 --- /dev/null +++ b/src/events/RE/reLegendaryBalls.js @@ -0,0 +1,111 @@ +App.Events.RELegendaryBalls = class RELegendaryBalls extends App.Events.BaseEvent { + actorPrerequisites() { + return [[ + (s) => s.fetish !== "mindbroken", + hasAnyArms, + hasAnyLegs, + canTalk, + (s) => s.devotion > 50, + (s) => s.prestige === 0, + (s) => (s.balls > 5 || (s.balls > 4 && s.prostate > 1)), + (s) => s.dick !== 0, + (s) => [Job.DAIRY, Job.MILKED].includes(s.assignment) + ]]; + } + + execute(node) { + V.nextButton = "Continue"; + V.nextLink = "RIE Eligibility Check"; + const slave = getSlave(this.actors[0]); + let r = []; + + const { + He, + he, his, him + } = getPronouns(slave); + + App.Events.drawEventArt(node, slave); + + slave.devotion += 4; + + r.push( + App.UI.DOM.slaveDescriptionDialog(slave), + `is an incredible producer of cum. ${He}'s producing in volumes that would have been unthinkable in the days when it was illegal to restrain a slave so that ${he} could have every drop of ${his} ejaculate milked out by a machine. A nascent slave stock organization will be holding a public livestock show tomorrow, and since they're aware you're experimenting with cockmilking, they've sent you an invitation to enter an especially productive slave to be judged.` + ); + + App.Events.addParagraph(node, r); + r = []; + + r.push(`This is a rare opportunity. The idea of cockmilking is new and understandably fascinating to many, so the livestock show is likely to draw some serious press. Were ${slave.slaveName} to win, ${he} would probably be remembered for a long time as a special slave.`); + + App.Events.addParagraph(node, r); + + const cashSmall = 5000; + const cashLarge = 10000; + const choices = []; + choices.push(new App.Events.Result(`Fairly enter ${him} in the livestock show`, enterFairly)); + if (V.cash > cashSmall) { + choices.push(new App.Events.Result(`Spend ${cashFormat(cashSmall)} bribing the judges`, bribeLow)); + } else { + choices.push(new App.Events.Result(null, null, `You do not have enough cash to bribe the judges`)); + } + if (V.cash > cashLarge) { + choices.push(new App.Events.Result(`Spend ${cashFormat(cashLarge)} bribing the judges and sabotaging the competition`, bribeHigh)); + } else { + choices.push(new App.Events.Result(null, null, `You do not have enough cash to bribe the judges and sabotage the competition`)); + } + App.Events.addResponses(node, choices); + + function enterFairly() { + const frag = new DocumentFragment(); + let r = []; + if (random(1, 100) > 90) { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then publicly cockmilked. It's likely there was some bribery behind the scenes, but ${his} massive junk wins the day. Against all odds ${he} is named best in show, and will be <span class="prestigious">remembered</span> as cock stock of the highest pedigree. As ${his} owner, your reputation has <span class="reputation inc">also increased.</span>`); + repX(500, "event", slave); + slave.prestige = 1; + slave.prestigeDesc = "$He is remembered for winning best in show as a cockmilker."; + V.trinkets.push(`a best in show ribbon awarded to ${slave.slaveName} for ${getPronouns(slave).possessive} balls`); + } else { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then publicly cockmilked. It's likely there was some bribery behind the scenes, and it is fatal to ${his} chances of winning. Though ${his} junk is easily the most impressive on display, another stock owner who was more open-handed with the judges took best in show. The public is impressed with ${slave.slaveName}'s nuts anyway; as you are ${his} owner, your reputation has <span class="reputation inc">increased</span> a little.`); + repX(500, "event", slave); + } + App.Events.addParagraph(frag, r); + return frag; + } + + function bribeLow() { + const frag = new DocumentFragment(); + let r = []; + cashX(-cashSmall, "event", slave); + repX(500, "event", slave); + if (random(1, 100) > 50) { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then publicly cockmilked. Several of the judges cannot resist giving you a wink as they look ${him} over. ${slave.slaveName} is unsurprisingly named best in show, and will be <span class="prestigious">remembered</span> as cock stock of the highest pedigree. As ${his} owner, your reputation has <span class="reputation inc">also increased.</span>`); + slave.prestige = 1; + slave.prestigeDesc = "$He is remembered for winning best in show as a cockmilker."; + V.trinkets.push(`a best in show ribbon awarded to ${slave.slaveName} for ${getPronouns(slave).possessive} balls`); + } else { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then publicly cockmilked. Several of the judges cannot resist giving you a wink as they look ${him} over, but others look disapprovingly at them; it seems some of your competitors also forwarded money to the committee. After furious wrangling, ${slave.slaveName} loses to another milker. The public is impressed with ${slave.slaveName}'s balls anyway; as you are ${his} owner, your reputation has <span class="reputation inc">increased</span> a little.`); + } + App.Events.addParagraph(frag, r); + return frag; + } + + function bribeHigh() { + const frag = new DocumentFragment(); + let r = []; + cashX(-cashLarge, "event", slave); + if (random(1, 100) > 10) { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then publicly cockmilked. After ${he}'s put through ${his} paces, the most unfortunate series of accidents somehow befalls ${his} fellow cows. One is taken ill, another seems drugged, and someone seems to have slipped a finger of raw ginger up another's urethra, making them whine and squeal when cockmilked. ${slave.slaveName} is unsurprisingly named best in show, and will be <span class="prestigious">remembered</span> as cock stock of the highest pedigree. As ${his} owner, your reputation has <span class="reputation inc">also increased.</span>`); + repX(500, "event", slave); + slave.prestige = 1; + slave.prestigeDesc = "$He is remembered for winning best in show as a cockmilker."; + V.trinkets.push(`a best in show ribbon awarded to ${slave.slaveName} for ${his} balls`); + } else { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then publicly cockmilked. You are surprised to see that the judging committee has been changed at the last minute. They choose another cow as best in show. There are persistent <span class="reputation dec">rumors</span> after the show that there was an absolute massacre of firings at the stock organization headquarters the night before the show after it was discovered that someone, widely thought to be you, had been corrupting the judges.`); + repX(-100, "event", slave); + } + App.Events.addParagraph(frag, r); + return frag; + } + } +}; diff --git a/src/events/RE/reLegendaryCow.js b/src/events/RE/reLegendaryCow.js new file mode 100644 index 0000000000000000000000000000000000000000..10fedf14f72b927184f0970e1efd1ec9de5413c6 --- /dev/null +++ b/src/events/RE/reLegendaryCow.js @@ -0,0 +1,112 @@ +App.Events.RELegendaryCow = class RELegendaryCow extends App.Events.BaseEvent { + actorPrerequisites() { + return [[ + (s) => s.fetish !== "mindbroken", + hasAnyArms, + hasAnyLegs, + canTalk, + (s) => s.devotion > 50, + (s) => s.prestige === 0, + (s) => s.lactation > 0, + (s) => (s.boobs - s.boobsImplant - s.boobsMilk) > 6000, + (s) => [Job.DAIRY, Job.MILKED].includes(s.assignment) + ]]; + } + + execute(node) { + V.nextButton = "Continue"; + V.nextLink = "RIE Eligibility Check"; + const slave = getSlave(this.actors[0]); + let r = []; + + const { + He, + he, his, him + } = getPronouns(slave); + + App.Events.drawEventArt(node, slave); + + slave.devotion += 4; + + r.push( + App.UI.DOM.slaveDescriptionDialog(slave), + `is an incredible producer of milk. ${He}'s lactating in volumes that would have been unthinkable in the days when drug treatments were limited by consent. A nascent slave dairy trade organization will be holding a public stock show tomorrow, and since they're aware you keep cows, they've sent you an invitation to enter stock to be judged.` + ); + + App.Events.addParagraph(node, r); + r = []; + + r.push(`This is a rare opportunity. The idea of human dairy is new and understandably fascinating to many, so the stock show is likely to draw some serious press. Were ${slave.slaveName} to win, ${he} would probably be remembered for a long time as a special cow.`); + + App.Events.addParagraph(node, r); + + const cashSmall = 5000; + const cashLarge = 10000; + const choices = []; + choices.push(new App.Events.Result(`Fairly enter ${him} in the stock show`, enterFairly)); + if (V.cash > cashSmall) { + choices.push(new App.Events.Result(`Spend ${cashFormat(cashSmall)} bribing the judges`, bribeLow)); + } else { + choices.push(new App.Events.Result(null, null, `You do not have enough cash to bribe the judges`)); + } + if (V.cash > cashLarge) { + choices.push(new App.Events.Result(`Spend ${cashFormat(cashLarge)} bribing the judges and sabotaging the competition`, bribeHigh)); + } else { + choices.push(new App.Events.Result(null, null, `You do not have enough cash to bribe the judges and sabotage the competition`)); + } + App.Events.addResponses(node, choices); + + function enterFairly() { + const frag = new DocumentFragment(); + let r = []; + if (random(1, 100) > 90) { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then publicly milked. It's likely there was some bribery behind the scenes, but ${his} massive tits win the day. Against all odds ${he} is named best in show, and will be <span class="green">remembered</span> as dairy stock of the highest pedigree. As ${his} owner, your reputation has <span class="green">also increased.</span>`); + repX(500, "event", slave); + slave.prestige = 1; + slave.prestigeDesc = "$He is remembered for winning best in show as a dairy cow."; + V.trinkets.push(`a best in show ribbon awarded to ${slave.slaveName} as a milk cow`); + } else { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then publicly milked. It's likely there was some bribery behind the scenes, and it is fatal to ${his} chances of winning. Though ${his} tits are easily the most impressive on display, another stock owner who was more open-handed with the judges took best in show. The public is impressed with ${slave.slaveName}'s tits anyway; as you are ${his} owner, your reputation has <span class="green">increased</span> a little.`); + repX(500, "event", slave); + } + + App.Events.addParagraph(frag, r); + return frag; + } + + function bribeLow() { + const frag = new DocumentFragment(); + let r = []; + cashX(-cashSmall, "event", slave); + repX(500, "event", slave); + if (random(1, 100) > 50) { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then publicly milked. Several of the judges cannot resist giving you a wink as they look ${him} over. ${slave.slaveName} is unsurprisingly named best in show, and will be <span class="green">remembered</span> as dairy stock of the highest pedigree. As ${his} owner, your reputation has <span class="green">also increased.</span>`); + slave.prestige = 1; + slave.prestigeDesc = "$He is remembered for winning best in show as a dairy cow."; + V.trinkets.push(`a best in show ribbon awarded to ${slave.slaveName} as a milk cow`); + } else { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then publicly milked. Several of the judges cannot resist giving you a wink as they look ${him} over, but others look disapprovingly at them; it seems some of your competitors also forwarded money to the committee. After furious wrangling, ${slave.slaveName} loses to another cow. The public is impressed with ${slave.slaveName}'s tits anyway; as you are ${his} owner, your reputation has <span class="reputation inc">increased</span> a little.`); + } + App.Events.addParagraph(frag, r); + return frag; + } + + function bribeHigh() { + const frag = new DocumentFragment(); + let r = []; + cashX(-cashLarge, "event", slave); + if (random(1, 100) > 10) { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then publicly milked. After ${he}'s put through ${his} paces, the most unfortunate series of accidents somehow befalls ${his} fellow cows. One is taken ill, another seems drugged, and someone seems to have slipped a finger of raw ginger up another's ass, making them whine and squeal constantly. ${slave.slaveName} is unsurprisingly named best in show, and will be <span class="prestigious">remembered</span> as dairy stock of the highest pedigree. As ${his} owner, your reputation has <span class="reputation inc">also increased.</span>`); + repX(500, "event", slave); + slave.prestige = 1; + slave.prestigeDesc = "$He is remembered for winning best in show as a dairy cow."; + V.trinkets.push(`a best in show ribbon awarded to ${slave.slaveName} as a milk cow`); + } else { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then publicly milked. You are surprised to see that the judging committee has been changed at the last minute. They choose another cow as best in show. There are persistent <span class="reputation inc">rumors</span> after the show that there was an absolute massacre of firings at the dairy organization headquarters the night before the show after it was discovered that someone, widely thought to be you, had been corrupting the judges.`); + repX(-100, "event", slave); + } + App.Events.addParagraph(frag, r); + return frag; + } + } +}; diff --git a/src/events/RE/reLegendaryEntertainer.js b/src/events/RE/reLegendaryEntertainer.js new file mode 100644 index 0000000000000000000000000000000000000000..48abae9b09180c576a86e75d80e9b404e947d669 --- /dev/null +++ b/src/events/RE/reLegendaryEntertainer.js @@ -0,0 +1,110 @@ +App.Events.RELegendaryEntertainer = class RELegendaryEntertainer extends App.Events.BaseEvent { + actorPrerequisites() { + return [[ + (s) => s.fetish !== "mindbroken", + hasAnyArms, + hasAnyLegs, + canTalk, + (s) => s.devotion > 50, + (s) => s.trust > 50, + (s) => s.prestige === 0, + (s) => s.skill.entertainment >= 100, + (s) => [Job.CLUB, Job.DJ].includes(s.assignment) + ]]; + } + + execute(node) { + V.nextButton = "Continue"; + V.nextLink = "RIE Eligibility Check"; + const slave = getSlave(this.actors[0]); + let r = []; + + const { + His, + he, his, him + } = getPronouns(slave); + + App.Events.drawEventArt(node, slave); + + slave.devotion += 4; + + r.push( + `The Free Cities fashion scene extends to slave bodies, of course; stopping at mere clothes and behaviors is an old world conceit. This week,`, + App.UI.DOM.slaveDescriptionDialog(slave), + `is in vogue. Such a crowd of gawkers and hangers-on follows ${him} around the club that the fine citizens who have a chance at an hour of ${his} time must shoulder their way through the throng.` + ); + + App.Events.addParagraph(node, r); + r = []; + + r.push(`This is a rare opportunity. Such popularity and fame is here today, and gone tomorrow. It might be possible, with a serious investment of funds in publicity, to really fix ${him} in the public mind as a courtesan of note. There's no guarantee of success, but if you are successful, ${his} value will increase a great deal.`); + + App.Events.addParagraph(node, r); + + const cashSmall = 5000; + const cashBig = 10000; + const choices = []; + choices.push(new App.Events.Result(`Just capitalize on ${his} popularity as it is`, asIs)); + if (V.cash > cashSmall) { + choices.push(new App.Events.Result(`Invest ${cashFormat(cashSmall)} in ${his} notoriety`, investSmall)); + if (V.cash > cashBig) { + choices.push(new App.Events.Result(`Lavish ${cashFormat(cashBig)} on ${his} fame`, investBig)); + } else { + choices.push(new App.Events.Result(null, null, `Not enough cash to lavishly invest`)); + } + } else { + choices.push(new App.Events.Result(null, null, `Not enough cash to invest`)); + } + + App.Events.addResponses(node, choices); + + function asIs() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You decide to limit your advantage on ${his} temporary popularity to a little publicity and some advertising. You've gained a little <span class="green">notoriety.</span>`); + repX(1000, "event", slave); + App.Events.addParagraph(frag, r); + return frag; + } + + function investSmall() { + const frag = new DocumentFragment(); + let r = []; + cashX(-cashSmall, "event", slave); + repX(1000, "event", slave); + if (random(1, 100) > 50) { + r.push(`You buy media coverage of ${him}, invest in an ad campaign, and even arrange for persons of influence and taste to sample and review ${his} gentle caresses. Your efforts are a success. ${His} current extreme popularity will fade in time, but you have managed to arrange for ${him} a permanent place as a <span class="prestigious">respected and famous courtesan.</span> As ${his} owner, your reputation has <span class="reputation inc">also increased.</span>`); + if (slave.prestige <= 1) { + slave.prestige = 1; + slave.prestigeDesc = "$He is a famed Free Cities slut, and can please anyone."; + } + V.trinkets.push(`a framed article written about ${slave.slaveName} when ${he} debuted as a famous courtesan`); + } else { + r.push(`You buy media coverage of ${him}, invest in an ad campaign, and even arrange for persons of influence and taste to sample and review ${his} gentle caresses. Unfortunately, popularity remains an art, not a science; though you do your best, the public mind's fancy eludes your grasp. As ${his} owner, your reputation has <span class="green">increased,</span> but in a week ${he}'ll be forgotten.`); + } + + App.Events.addParagraph(frag, r); + return frag; + } + + function investBig() { + const frag = new DocumentFragment(); + let r = []; + cashX(-cashBig, "event", slave); + if (random(1, 100) > 10) { + r.push(`You buy prime media coverage of ${him}, invest in a lavish ad campaign, and even arrange for persons of great influence and fine taste to sample and review ${his} gentle caresses. Your efforts are a success. ${His} current extreme popularity will fade in time, but you have managed to arrange for ${him} a permanent place as a <span class="green">respected and famous courtesan.</span> As ${his} owner, your reputation has <span class="reputation inc">also increased.</span>`); + repX(2000, "event", slave); + if (slave.prestige <= 1) { + slave.prestige = 1; + slave.prestigeDesc = "$He is a famed Free Cities slut, and can please anyone."; + } + V.trinkets.push(`a framed article written about ${slave.slaveName} when ${he} debuted as a famous courtesan`); + } else { + r.push(`You buy prime media coverage of ${him}, invest in a lavish ad campaign, and even arrange for persons of great influence and fine taste to sample and review ${his} gentle caresses. Unfortunately, popularity remains an art, not a science; though you do your best, the public mind's fancy eludes your grasp. As ${his} owner, your reputation has <span class="reputation">increased,</span> but in a week ${he}'ll be forgotten.`); + repX(2000, "event", slave); + } + App.Events.addParagraph(frag, r); + return frag; + } + } +}; diff --git a/src/events/RE/reLegendaryFormerAbolitionist.js b/src/events/RE/reLegendaryFormerAbolitionist.js new file mode 100644 index 0000000000000000000000000000000000000000..6f63570b007820d8740a60cd656182786c998d47 --- /dev/null +++ b/src/events/RE/reLegendaryFormerAbolitionist.js @@ -0,0 +1,149 @@ +App.Events.RELegendaryFormerAbolitionist = class RELegendaryFormerAbolitionist extends App.Events.BaseEvent { + actorPrerequisites() { + return [[ + (s) => s.fetish !== "mindbroken", + hasAnyArms, + hasAnyLegs, + canTalk, + (s) => s.devotion > 95, + (s) => s.trust > 50, + (s) => s.prestige === 0, + (s) => [ + "You sentenced $him to enslavement as a punishment for attempted theft of a slave.", + "$He is an enslaved Daughter of Liberty.", + "You got $him at the Slave Shelter. $He is an enslaved Daughter of Liberty, caught some weeks after the failed coup. $His previous owner used $him as a punching bag and dart board, then when he was bored of $him tattooed obscenities all over $his body and threw $him away.", + "$He is an enslaved member of an anti-slavery extremist group.", + ].includes(s.origin) || + s.career === "an antislavery activist", + (s) => [Job.MASTERSUITE, Job.CONCUBINE, Job.FUCKTOY].includes(s.assignment) + ]]; + } + + execute(node) { + const slave = getSlave(this.actors[0]); + + const { + He, His, + he, his, him + } = getPronouns(slave); + + V.nextButton = "Continue"; + V.nextLink = "RIE Eligibility Check"; + + App.Events.drawEventArt(node, slave); + + App.Events.addParagraph(node, [ + `Crime is extremely rare in ${V.arcologies[0].name}, and some would say justice rarer still, but if there's one thing that unites the citizens of ${V.arcologies[0].name}, it's a mutual outrage towards attempted abolitionists. Slaveownership is the cornerstone of the society that protects and enriches them, and they see those who would attempt to unlawfully free slaves not just as thieves of property but as anarchists trying to bring down everything they have worked to build. While a brutal flogging or surgical mutilation soothes their outrage, nothing warms the collective heart of ${V.arcologies[0].name}'s mob like the sight of a former abolitionist well and truly broken.`, + App.UI.DOM.slaveDescriptionDialog(slave), + `is one such shining example, and ${his} borderline worship of you is doing wonders for your reputation lately as ${he} becomes a local celebrity and a popular topic of discussion. This is a rare opportunity. While the mob is quick to pat itself on the back for withstanding attacks from abolitionists, before long they will tire of remembering those dangers and turn their attention elsewhere. It might be possible, with a serious investment of funds in publicity, to really fix ${him} in the public mind as a shining example of your slave-breaking prowess.` + ]); + + const smallCash = 5000; + const mediumCash = 10000; + const largeCash = 25000; + const choices = []; + choices.push(new App.Events.Result(`Just capitalize on ${his} popularity to increase your reputation`, yourRep)); + choices.push(new App.Events.Result(`Just capitalize on ${his} popularity by renting out ${his} mouth`, rentMouth)); + if (V.cash >= smallCash) { + choices.push(new App.Events.Result(`Invest ${cashFormat(smallCash)} in making ${him} locally famous`, locallyFamous)); + } else { + choices.push(new App.Events.Result(null, null, `You do not have enough cash to make ${him} locally famous`)); + } + + if (V.cash >= mediumCash) { + choices.push(new App.Events.Result(`Lavish ${cashFormat(mediumCash)} on making ${him} locally famous`, locallyFamousLavish)); + } else { + choices.push(new App.Events.Result(null, null, `You do not have enough cash to lavish on making ${him} locally famous`)); + } + + if (V.cash >= largeCash) { + choices.push(new App.Events.Result(`Spend ${cashFormat(largeCash)} on an attempt to make ${him} world famous`, worldFamous)); + } else { + choices.push(new App.Events.Result(null, null, `You do not have enough cash to make ${him} world famous`)); + } + + App.Events.addResponses(node, choices); + + function yourRep() { + repX(1000, "event", slave); + return `You spend the week parading ${slave.slaveName} around in public, letting everyone get a good look at ${his} fawning adoration of you. A variety of public sex acts really nails the point home in the psyche of your citizens and <span class="cash inc">increases your reputation,</span> and after a few days you start to receive a sincere golf clap from onlookers every time you cum in or on ${slave.slaveName}.`; + } + + function rentMouth() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You fasten ${slave.slaveName} in a kneeling position in the center of your club, secured by shackles around ${his}`); + if (hasAnyArms(slave)) { + r.push(hasBothArms(slave) ? "wrists" : "wrist"); + if (hasAnyLegs(slave)) { + r.push(`and`); + } + } + if (hasAnyLegs(slave)) { + r.push(hasBothLegs(slave) ? "ankles" : "ankle"); + } + r.push(`— purely decorative, since ${he}'s so devoted ${he}'d perform ${his} role in this if you just hinted it would please you if ${he} did. In front of ${him}, you place a sign: "Fuck the mouth that preached abolitionism, ${cashFormat(5)}." In a few moments, the morning crowd will begin to arrive, and you have no doubt that ${slave.slaveName} will be very, very popular. And ${he} is. Even with an extra dose of curatives and a check-up every night, the strain of a week of dicks and a diet of cum <span class="health dec">has taken a toll on ${his} health.</span> But even after you pay to have the area that ${slave.slaveName} worked thoroughly cleaned, you have made <span class="cash inc">a tidy profit.</span>`); + healthDamage(slave, 10); + seX(slave, "oral", "public", "penetrative", random(410, 440)); + cashX(2000, "event", slave); + + App.Events.addParagraph(frag, r); + return frag; + } + + function locallyFamous() { + const frag = new DocumentFragment(); + let r = []; + if (random(1, 100) > 50) { + r.push(`You buy media coverage of ${him}, invest in an ad campaign, and even arrange for ${him} to give a speech denouncing the abolitionist movement and praising your efforts in fighting against them. Your efforts are a success. ${His} current extreme popularity will fade in time, but you have managed to arrange for ${him} a permanent place as an <span class="reputation inc">example of your slave-breaking skills.</span>`); + slave.prestige = 1; + slave.prestigeDesc = "$He is notorious as a former abolitionist turned devoted slave."; + } else { + r.push(`You buy media coverage of ${him}, invest in an ad campaign, and even arrange for ${him} to give a speech denouncing the abolitionist movement and praising your efforts in fighting against them. Unfortunately, popularity remains an art, not a science; though you do your best, the public mind's fancy eludes your grasp. As ${his} owner, your reputation has <span class="reputation inc">increased,</span> but in a week ${he}'ll be forgotten.`); + } + cashX(-smallCash, "event", slave); + repX(1000, "event", slave); + + App.Events.addParagraph(frag, r); + return frag; + } + + function locallyFamousLavish() { + const frag = new DocumentFragment(); + let r = []; + if (random(1, 100) > 10) { + r.push(`You buy prime media coverage of ${him}, invest in a lavish ad campaign, and even arrange for ${him} to give a speech denouncing the abolitionist movement and praising your efforts in fighting against them that is broadcast around the world. Your efforts are a success. ${His} current extreme popularity will fade in time, but you have managed to arrange for ${him} a permanent place as an <span class="reputation inc">example of your slave-breaking skills.</span>`); + slave.prestige = 1; + slave.prestigeDesc = "$He is notorious as a former abolitionist turned devoted slave."; + } else { + r.push(`You buy prime media coverage of ${him}, invest in a lavish ad campaign, and even arrange for ${him} to give a speech denouncing the abolitionist movement and praising your efforts in fighting against them that is broadcast around the world. Unfortunately, popularity remains an art, not a science; though you do your best, the public mind's fancy eludes your grasp. As ${his} owner, your reputation has <span class="reputation inc">increased,</span> but in a week ${he}'ll be forgotten.`); + } + cashX(-mediumCash, "event", slave); + repX(2000, "event", slave); + + App.Events.addParagraph(frag, r); + return frag; + } + + function worldFamous() { + const frag = new DocumentFragment(); + let r = []; + if (random(1, 100) > 50) { + r.push(`The world is in love with ${slave.slaveName}. ${His} face graces magazine covers the world over and ${his} passionate arguments (ghostwritten by the best spin doctors money can buy) spark debate everywhere they're heard. ${He} is mentioned by name in strident denunciations about the immorality of the present day from religious leaders. ${He} appears on the internet with all sorts of attempts at humor superimposed on ${his} image. ${His} loving and overblown descriptions of you spark a new trend in protagonists of badly-written romance novels. When a very popular talk show host attempts to call ${his} bluff and receives oral sex in front of a live studio audience, <span class="reputation inc">you know for sure that ${his} fame has stuck.</span>`); + repX(3000, "event", slave); + slave.prestige = 2; + slave.prestigeDesc = "$He is world famous as an anti-abolitionist, and has told the world at length of the joys of slavery in general and slavery to you in particular."; + } else { + r.push(`The world seems temporarily enamored with ${slave.slaveName} as ${he} appears on talk shows and in political debates with millions of watchers, but before long ${his} fifteen minutes of fame peter out and the only offers coming in are from pornography magnates and local talk radio shows. Though ${he} achieved <span class="reputation inc">local fame</span> for appearing on the world stage, the rest of the world seems to have gotten bored with ${slave.slaveName}.`); + slave.prestige = 1; + slave.prestigeDesc = "$He is notorious as a former abolitionist turned devoted slave."; + repX(2000, "event", slave); + } + cashX(-largeCash, "event", slave); + + App.Events.addParagraph(frag, r); + return frag; + } + } +}; + diff --git a/src/events/RE/reLegendaryWhore.js b/src/events/RE/reLegendaryWhore.js new file mode 100644 index 0000000000000000000000000000000000000000..669989ab2a109ff9af060711fbd46d2f14f89ae2 --- /dev/null +++ b/src/events/RE/reLegendaryWhore.js @@ -0,0 +1,106 @@ +App.Events.RELegendaryWhore = class RELegendaryWhore extends App.Events.BaseEvent { + actorPrerequisites() { + return [[ + (s) => s.fetish !== "mindbroken", + hasAnyArms, + hasAnyLegs, + canTalk, + (s) => s.devotion > 50, + (s) => s.trust > 50, + (s) => s.prestige === 0, + (s) => s.skill.whoring >= 100, + (s) => [Job.WHORE, Job.BROTHEL].includes(s.assignment) + ]]; + } + + execute(node) { + V.nextButton = "Continue"; + V.nextLink = "RIE Eligibility Check"; + const slave = getSlave(this.actors[0]); + let r = []; + + const { + His, + he, his, him + } = getPronouns(slave); + + App.Events.drawEventArt(node, slave); + + slave.devotion += 4; + + r.push( + `The Free Cities red light areas are so overcharged with cheap and easy sex that the fashion in whores is comically unstable. This week,`, + App.UI.DOM.slaveDescriptionDialog(slave), + `is in vogue. So many customers are interested in renting ${his} body that it's necessary to assign other whores to take some of the load off ${him} by diverting less important customers away from ${him}.` + ); + + App.Events.addParagraph(node, r); + r = []; + + r.push(`This is a rare opportunity. Such popularity and fame is here today, and gone tomorrow. It might be possible, with a serious investment of funds in publicity, to really fix ${him} in the public mind as a whore of note. There's no guarantee of success, but if you are successful, ${his} value will increase a great deal.`); + + App.Events.addParagraph(node, r); + + const cashSmall = 5000; + const cashBig = 10000; + const choices = []; + choices.push(new App.Events.Result(`Just capitalize on ${his} popularity as it is`, asIs)); + if (V.cash > cashSmall) { + choices.push(new App.Events.Result(`Invest ${cashFormat(cashSmall)} in ${his} notoriety`, investSmall)); + if (V.cash > cashBig) { + choices.push(new App.Events.Result(`Lavish ${cashFormat(cashBig)} on ${his} fame`, investBig)); + } else { + choices.push(new App.Events.Result(null, null, `Not enough cash to lavishly invest`)); + } + } else { + choices.push(new App.Events.Result(null, null, `Not enough cash to invest`)); + } + + App.Events.addResponses(node, choices); + + function asIs() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You decide to limit your advantage on ${his} temporary popularity to a little marketing and some minor price increases. You've made some unexpected <span class="cash inc">profits,</span> and gained a little <span class="reputation inc">notoriety.</span>`); + cashX(1000, "event", slave); + repX(500, "event", slave); + App.Events.addParagraph(frag, r); + return frag; + } + + function investSmall() { + const frag = new DocumentFragment(); + let r = []; + cashX(-cashSmall, "event", slave); + repX(500, "event", slave); + if (random(1, 100) > 50) { + r.push(`You buy media coverage of ${him}, invest in an ad campaign, and even arrange for persons of influence and taste to sample and review ${his} many delights. Your efforts are a success. ${His} current extreme popularity will fade in time, but you have managed to arrange for ${him} a permanent place as a <span class="prestigious">notorious and very popular prostitute.</span> As ${his} owner, your reputation has <span class="reputation inc">also increased.</span>`); + slave.prestige = 1; + slave.prestigeDesc = "$He is a famed Free Cities whore, and commands top prices."; + V.trinkets.push(`a framed pornographic advertisement for ${slave.slaveName} from the week ${he} became a famous whore`); + } else { + r.push(`You buy media coverage of ${him}, invest in an ad campaign, and even arrange for persons of influence and taste to sample and review ${his} many delights. Unfortunately, popularity remains an art, not a science; though you do your best, the public mind's fancy eludes your grasp. As ${his} owner, your reputation has <span class="green">increased,</span> but in a week ${he}'ll be forgotten.`); + } + App.Events.addParagraph(frag, r); + return frag; + } + + function investBig() { + const frag = new DocumentFragment(); + let r = []; + cashX(-cashBig, "event", slave); + if (random(1, 100) > 10) { + r.push(`You buy prime media coverage of ${him}, invest in a lavish ad campaign, and even arrange for persons of great influence and fine taste to sample and review ${his} many delights. Your efforts are a success. ${His} current extreme popularity will fade in time, but you have managed to arrange for ${him} a permanent place as a <span class="green">notorious and very popular prostitute.</span> As ${his} owner, your reputation has <span class="green">also increased.</span>`); + repX(1000, "event", slave); + slave.prestige = 1; + slave.prestigeDesc = "$He is a famed Free Cities whore, and commands top prices."; + V.trinkets.push(`a framed pornographic advertisement for ${slave.slaveName} from the week ${he} became a famous whore`); + } else { + r.push(`You buy prime media coverage of ${him}, invest in a lavish ad campaign, and even arrange for persons of great influence and fine taste to sample and review ${his} many delights. Unfortunately, popularity remains an art, not a science; though you do your best, the public mind's fancy eludes your grasp. As ${his} owner, your reputation has <span class="green">increased,</span> but in a week ${he}'ll be forgotten.`); + repX(1000, "event", slave); + } + App.Events.addParagraph(frag, r); + return frag; + } + } +}; diff --git a/src/events/RE/reLegendaryWomb.js b/src/events/RE/reLegendaryWomb.js new file mode 100644 index 0000000000000000000000000000000000000000..e7dac1404850735ff2db810259490cdfa573ea54 --- /dev/null +++ b/src/events/RE/reLegendaryWomb.js @@ -0,0 +1,113 @@ +App.Events.RELegendaryWomb = class RELegendaryWomb extends App.Events.BaseEvent { + actorPrerequisites() { + return [[ + (s) => s.fetish !== "mindbroken", + hasAnyArms, + hasAnyLegs, + canTalk, + (s) => s.devotion > 50, + (s) => s.trust > 50, + (s) => s.broodmother === 0, + (s) => s.eggType === "human", + (s) => s.counter.births > 10, + (s) => s.preg > s.pregData.normalBirth / 1.33, + (s) => s.bellyPreg >= 14000, + (s) => [Job.WHORE, Job.BROTHEL, Job.PUBLIC, Job.CLUB].includes(s.assignment), + ]]; + } + + execute(node) { + V.nextButton = "Continue"; + V.nextLink = "RIE Eligibility Check"; + const slave = getSlave(this.actors[0]); + let r = []; + + const { + He, + he, his, him + } = getPronouns(slave); + + App.Events.drawEventArt(node, slave); + + slave.devotion += 4; + + + r.push( + App.UI.DOM.slaveDescriptionDialog(slave), + `is an incredible mother. ${He}'s given birth to numbers that would have been considered absurd in the days when drug treatments were limited by consent. A nascent organization will be holding a pageant for pregnant slaves tomorrow, and since they're aware you keep breeders, they've sent you an invitation to enter a heavily pregnant slave to be judged.` + ); + + App.Events.addParagraph(node, r); + r = []; + + r.push(`This is a rare opportunity. The idea of a pregnancy pageant isn't new but it is undeniably going to attract attention, so the pageant is likely to draw some serious press. Were ${slave.slaveName} to win, ${he} would probably be remembered for a long time as a special mother.`); + + const cashSmall = 5000; + const cashLarge = 10000; + const choices = []; + choices.push(new App.Events.Result(`Fairly enter ${him} in the pregnancy pageant`, enterFairly)); + if (V.cash > cashSmall) { + choices.push(new App.Events.Result(`Spend ${cashFormat(cashSmall)} bribing the judges`, bribeLow)); + } else { + choices.push(new App.Events.Result(null, null, `You do not have enough cash to bribe the judges`)); + } + if (V.cash > cashLarge) { + choices.push(new App.Events.Result(`Spend ${cashFormat(cashLarge)} bribing the judges and sabotaging the competition`, bribeHigh)); + } else { + choices.push(new App.Events.Result(null, null, `You do not have enough cash to bribe the judges and sabotage the competition`)); + } + App.Events.addResponses(node, choices); + + function enterFairly() { + const frag = new DocumentFragment(); + let r = []; + if (random(1, 100) > 90) { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then asked to demonstrate how to pleasure a man while so heavily pregnant. It's likely there was some bribery behind the scenes, but ${his} heavy belly and creative positions win the day. Against all odds ${he} is named best in show, and will be <span class="green">remembered</span> as a breeder of the highest pedigree. As ${his} owner, your reputation has <span class="green">also increased.</span>`); + repX(500, "event", slave); + slave.prestige = 1; + slave.prestigeDesc = "$He is remembered for winning best in show as a breeder."; + V.trinkets.push(`a best in show ribbon awarded to ${slave.slaveName} as a breeder`); + } else { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then asked to demonstrate how to pleasure a man while so heavily pregnant. It's likely there was some bribery behind the scenes, and it is fatal to ${his} chances of winning. Though ${his} pregnant body is the most impressive on display, another slaveowner who was more open-handed with the judges took best in show. The public is impressed with ${slave.slaveName}'s reproductive capability anyway; as you are ${his} owner, your reputation has <span class="green">increased</span> a little.`); + repX(500, "event", slave); + } + App.Events.addParagraph(frag, r); + return frag; + } + + function bribeLow() { + const frag = new DocumentFragment(); + let r = []; + cashX(-cashSmall, "event", slave); + repX(500, "event", slave); + if (random(1, 100) > 50) { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then asked to demonstrate how to pleasure a man while so heavily pregnant. Several of the judges cannot resist giving you a wink as they look ${him} over. ${slave.slaveName} is unsurprisingly named best in show, and will be <span class="prestigious">remembered</span> as a breeder of the highest pedigree. As ${his} owner, your reputation has <span class="reputation inc">also increased.</span>`); + slave.prestige = 1; + slave.prestigeDesc = "$He is remembered for winning best in show as a breeder."; + V.trinkets.push(`a best in show ribbon awarded to ${slave.slaveName} as a breeder`); + } else { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then asked to demonstrate how to pleasure a man while so heavily pregnant. Several of the judges cannot resist giving you a wink as they look ${him} over, but others look disapprovingly at them; it seems some of your competitors also forwarded money to the committee. After furious wrangling, ${slave.slaveName} loses to another mother. The public is impressed with ${slave.slaveName}'s reproductive capability anyway; as you are ${his} owner, your reputation has <span class="reputation inc">increased</span> a little.`); + } + App.Events.addParagraph(frag, r); + return frag; + } + + function bribeHigh() { + const frag = new DocumentFragment(); + let r = []; + cashX(-cashLarge, "event", slave); + if (random(1, 100) > 10) { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then asked to demonstrate how to pleasure a man while so heavily pregnant. After ${he}'s put through ${his} paces, the most unfortunate series of accidents somehow befalls ${his} fellow mothers. One is taken ill, another seems drugged, and another went into labor and gave birth, disqualifying her. ${slave.slaveName} is unsurprisingly named best in show, and will be <span class="prestigious">remembered</span> as a breeder of the highest pedigree. As ${his} owner, your reputation has <span class="reputation inc">also increased.</span>`); + repX(500, "event", slave); + slave.prestige = 1; + slave.prestigeDesc = "$He is remembered for winning best in show as a breeder."; + V.trinkets.push(`a best in show ribbon awarded to ${slave.slaveName} as a breeder`); + } else { + r.push(`${slave.slaveName} is shown in public, closely inspected by the judging committee, and then asked to demonstrate how to pleasure a man while so heavily pregnant. You are surprised to see that the judging committee has been changed at the last minute. They choose another breeder as best in show. There are persistent <span class="reputation dec">rumors</span> after the show that there was an absolute massacre of firings at the dairy organization headquarters the night before the show after it was discovered that someone, widely thought to be you, had been corrupting the judges.`); + repX(-100, "event", slave); + } + App.Events.addParagraph(frag, r); + return frag; + } + } +}; diff --git a/src/events/RE/reMilfTourist.js b/src/events/RE/reMilfTourist.js new file mode 100644 index 0000000000000000000000000000000000000000..e82ad0d1f477413e2a6c9631b6d8f1920d94a1f6 --- /dev/null +++ b/src/events/RE/reMilfTourist.js @@ -0,0 +1,260 @@ +App.Events.REMilfTourist = class REMilfTourist extends App.Events.BaseEvent { + eventPrerequisites() { + return [ + () => V.arcologies[0].prosperity >= 100 + ]; + } + + actorPrerequisites() { + return [[ + (s) => s.devotion > 20, + (s) => [Job.PUBLIC, Job.CLUB].includes(s.assignment), + canTalk, + canWalk, + ]]; + } + + get weight() { + return V.rep > random(1, 30000) ? 1 : 0; + } + + execute(node) { + const r = []; + + V.nextButton = "Continue"; + V.nextLink = "RIE Eligibility Check"; + + const milfSlave = getSlave(this.actors[0]); + + const tourist = GenerateNewSlave("XX", { + minAge: 36, maxAge: 42, ageOverridesPedoMode: 1, race: "nonslave", disableDisability: 1 + }); + tourist.origin = "$He came to your arcology as a tourist and found $himself enslaved."; + tourist.devotion = random(-70, -55); + tourist.trust = random(-45, -25); + setHealth(tourist, jsRandom(10, 20), undefined, undefined, undefined, 5); + tourist.vagina++; + tourist.hips = 2; + tourist.butt = random(4, 6); + tourist.boobs = 100 * random(10, 18); + tourist.weight = random(60, 140); + tourist.behavioralQuirk = "none"; + tourist.sexualQuirk = "none"; + tourist.canRecruit = 0; + tourist.clothes = "nice business attire"; + + App.Events.drawEventArt(node, [milfSlave, tourist]); + + const { + He, + he, him, his, himself + } = getPronouns(milfSlave); + const {title: Master} = getEnunciation(milfSlave); + + const { + He2, + he2, him2, his2, himself2 + } = getPronouns(tourist).appendSuffix("2"); + + const { + HeA, + heA, hisA, himselfA + } = getPronouns(assistant.pronouns().main).appendSuffix("A"); + + if (V.assistant.personality === 1) { + r.push(`${capFirstChar(V.assistant.name)}'s`); + if (V.assistant.appearance === "normal") { + r.push(`symbol`); + } else { + r.push(`${V.assistant.appearance} avatar`); + } + r.push(`appears on your desk in the middle of the day. "Something unusual for you, ${properTitle()}," ${heA} says. "${milfSlave.slaveName} is out doing public service. A tourist from the old world accosted ${him}. ${milfSlave.slaveName} thought ${he2} was a rich citizen who wanted to fuck ${him}, but it turns out ${he2} just wanted a tour guide. It was a reasonable mistake; ${he2} seems wealthy. ${He} has been showing ${him2} around for the last half hour. Now ${he2}'s asked ${him} if ${he2} can meet you." ${HeA} displays a video feed showing ${milfSlave.slaveName} standing with the tourist in question out on the main plaza. ${He2}'s just into middle age, and extremely plush, wearing Capri pants over ${his2} motherly hips and a cashmere sweater that understates ${his2} generous bust. ${He2}'s blushing as ${he2} asks your slave a discreet question about public sex in the arcology, brought on by the sight of a couple of citizens spitroasting a slave. Your personal assistant's avatar`); + switch (V.assistant.appearance) { + case "monstergirl": + r.push(`bares ${hisA} fangs and makes pinching gestures at nipple height.`); + break; + case "shemale": + r.push(`gives a wolf whistle and makes exaggerated gestures over ${hisA} own boobs.`); + break; + case "amazon": + r.push(`brandishes a club suggestively.`); + break; + case "businesswoman": + r.push(`looks the tourist up and down over the tops of ${hisA} glasses.`); + break; + case "schoolgirl": + r.push(`stares openly at the tourist's ass.`); + break; + case "fairy": + case "pregnant fairy": + r.push(`zips around the tourist, giving ${him2} a good look-over.`); + break; + case "hypergoddess": + case "goddess": + r.push(`eyes ${his2} fertile hips.`); + break; + case "loli": + case "preggololi": + r.push(`stares longingly at ${his2} huge tits.`); + break; + case "angel": + r.push(`blushes at the sight of ${his2} obvious curves.`); + break; + case "cherub": + r.push(`makes exaggerated movements over ${hisA} own tits.`); + break; + case "incubus": + r.push(`is sporting an absolutely enormous erection. ${HeA} seems to be enjoying the show.`); + break; + case "succubus": + r.push(`turns to face you; ${hisA} breasts huge armfuls, butt jiggling non-stop and a pair of hips to rival any cow. "My curves are better."`); + break; + case "imp": + r.push(`makes pinching gestures at nipple height then turns and slaps ${hisA} own ass.`); + break; + case "witch": + r.push(`blushes at the sight of those lovely curves.`); + break; + case "ERROR_1606_APPEARANCE_FILE_CORRUPT": + r.push(`swells ${himselfA} to resemble ${his2} figure before twisting ${hisA} arm into a cock and ramming it straight up ${hisA} cunt.`); + break; + default: + r.push(`reforms into an exaggerated female form before going back to ${hisA} normal symbol shape.`); + } + } else { + r.push(`${capFirstChar(V.assistant.name)}`); + r.push(`gets your attention the middle of the day. "A minor matter for you, ${properTitle()}," ${heA} says. "${milfSlave.slaveName} is currently performing public service. A tourist from the old world accosted ${him}. ${milfSlave.slaveName} thought ${he2} was a rich citizen who wanted to have sex with ${him}, but it seems ${he2} just wanted a tour guide. It was a reasonable mistake; the tourist appears wealthy. ${He} has been acting as ${his2} guide for the last half hour. The tourist has asked ${him} if ${he2} can meet you." ${HeA} displays a video feed showing ${milfSlave.slaveName} standing with the tourist in question out on the main plaza. ${He2}'s just into middle age, and extremely plush, wearing Capri pants over ${his2} motherly hips and a cashmere sweater that understates ${his2} generous bust. ${He2}'s blushing as ${he2} asks your slave a discreet question about public sex in the arcology, brought on by the sight of a couple of citizens spitroasting a slave.`); + } + + App.Events.addParagraph(node, r); + + const choices = []; + choices.push(new App.Events.Result(`Decline politely`, decline)); + choices.push(new App.Events.Result(`Share some Free Cities life with ${him2}`, share)); + choices.push(new App.Events.Result(`Encourage ${him2} to enjoy the slave with your compliments`, compliments)); + if (V.cash > 20000) { + choices.push(new App.Events.Result(`Enslave ${him2}`, enslave, `This will require an unprofitable ${cashFormat(20000)}, since ${he2} is wealthy and obfuscating ${his2} fate will require considerable spending`)); + } else { + choices.push(new App.Events.Result(null, null, `You cannot afford the ${cashFormat(20000)} enslaving ${him2} would require, since ${he2} is wealthy and obfuscating ${his2} fate would necessitate considerable spending`)); + } + + App.Events.addResponses(node, choices); + + function decline() { + const frag = new DocumentFragment(); + let r = []; + r.push( + `You have ${V.assistant.name} instruct ${milfSlave.slaveName} to pass on your regrets, and add a message for ${milfSlave.slaveName} expressing confidence in ${him} to represent you and the arcology perfectly well without you. ${He}'s <span class="trust inc">affirmed</span> by your trust in ${him}.`, + Spoken(milfSlave, `"${Master},"`), + `${he} reports the next time you see ${him},`, + Spoken(milfSlave, `"that tourist was really nice. Also, I got ${him2} to have sex with me, after all. ${He2} was all hesitant and blushy about doing it in public, but ${he2} got better after the first time I ate ${him2} out."`), + `${He} looks pleased with ${himself}.`, + Spoken(milfSlave, `"I bet ${he2} <span class="reputation inc">tells all ${his2} friends</span> back home how much fun it is here."`) + ); + repX(500, "event"); + milfSlave.trust += 4; + seX(milfSlave, "oral", "public", "penetrative"); + App.Events.addParagraph(frag, r); + return frag; + } + + function share() { + const frag = new DocumentFragment(); + let r = []; + r.push( + `You have ${milfSlave.slaveName} bring the tourist up to meet you. ${He2}'s full of questions about what it's like to be an arcology owner, and you finally tell ${him2} that you can give ${him2} a pretty good idea. Eagerly, ${he2} asks you how, and you point at ${milfSlave.slaveName}, telling the tourist ${he2} ought to bend the slave over the couch if ${he2} wants to know what it's really like to be an oversexed oligarch.`, + notLesbian(), + Spoken(milfSlave, `fuck me. It'll be fun!"`), + `The tourist turns to stare at ${him2}, and ${he2} offers just the right kind of plaintive expression.`, + Spoken(tourist, `"O-okay,"`), + `the tourist says in a tiny voice, and ${milfSlave.slaveName} giggles, hugging ${him2} from behind. ${He} cups one of the tourist's breasts, and snakes ${his} other hand down the front of ${his2} pants.`, + Spoken(tourist, `"Here!?"`), + `the tourist gasps, staring straight at you and blushing even harder. You tell ${him2} that that's how you do things in the Free Cities: enjoying a slave is nothing to be ashamed of. ${He2} looks doubtful, but ${he2} doesn't try to escape from ${milfSlave.slaveName}'s roving ${(hasBothArms(milfSlave)) ? "hands" : "hand"}, either. Your presence continues to bother ${him2} until ${milfSlave.slaveName} distracts ${him2} by getting ${him2} to cuddle on the couch and make out, providing enough of a distraction that ${he2} gets over ${his2} inhibitions and orgasms rather immodestly.` + ); + App.Events.addParagraph(frag, r); + r = []; + r.push(`You offer ${him2} some liquid courage as ${he2} recovers, but ${he2}'s rapidly getting over ${his2} hesitation. As the alcohol suffuses ${him2}, ${he2} starts stealing glances at ${milfSlave.slaveName}, who for ${his} part is being as seductive as humanly possible. Finally, the tourist mouths 'fuck it' silently, reaches over, and openly gropes the slave's ass. ${milfSlave.slaveName} giggles and shifts lewdly, ensuring that the tourist's hand makes a thorough tour of everything the slave has. The tourist tentatively sinks a couple of fingers into ${him}, and the slave shamelessly slides ${himself} onto the invading digits, begging to be fucked. You make a party of it, with the various slaves who come and go over the course of the evening treated to the sight of ${him} getting fucked by the tourist. ${He2} drunkenly promises you to <span class="reputation inc">tell all ${his2} friends</span> how awesome your arcology is at one point, though ${he2} has to take ${his2} mouth off one of ${milfSlave.slaveName}'s nipples to do so.`); + milfSlave.trust += 4; + seX(milfSlave, "oral", "public", "penetrative", 3); + seX(milfSlave, "anal", "public", "penetrative", 3); + repX(500, "event"); + V.trinkets.push("a thank-you note from a MILF tourist whom you made feel welcome in the arcology"); + + App.Events.addParagraph(frag, r); + return frag; + } + + function compliments() { + const frag = new DocumentFragment(); + let r = []; + r.push( + `You have ${milfSlave.slaveName} bring the tourist up to meet you, and exchange some minor pleasantries. You tell ${him2} that if ${he2} really wants to experience Free Cities life, though, ${he2} really should enjoy ${milfSlave.slaveName}, pointing at the slave hovering behind ${him2}. ${He2} blushes furiously, but before ${he2} can stammer a refusal, the slave whispers something into ${his2} ear.`, + notLesbian(), + Spoken(milfSlave, `give me a try."`), + `The tourist turns to stare at ${him}, and ${he2} offers just the right kind of plaintive expression.`, + Spoken(tourist, `"O-okay,"`), + `the tourist says in a tiny voice, and ${milfSlave.slaveName} giggles, hugging ${him2} from behind. ${He} takes the tourist's hand, and they leave your office together.` + ); + App.Events.addParagraph(frag, r); + r = []; + + r.push( + Spoken(milfSlave, `"${Master},"`), + `${he} reports the next time you see ${him},`, + Spoken(milfSlave, `"that tourist was really nice. Also, I got ${him2} to have sex with me, after all. ${He2} was going to take me back to ${his2} hotel but I got ${him2} to do me on the way. ${He2} was all hesitant and blushy about doing it in public, but ${he2} got better after the first time I ate ${him2} out."`), + `${He} looks pleased with ${himself}.`, + Spoken(milfSlave, `"I bet ${he2} <span class="reputation inc">tells all ${his2} friends</span> back home how much fun it is here."`) + ); + milfSlave.trust += 4; + seX(milfSlave, "oral", "public", "penetrative"); + repX(500, "event"); + V.trinkets.push("a thank-you note from a MILF tourist whom you made feel welcome in the arcology"); + + App.Events.addParagraph(frag, r); + return frag; + } + + function enslave() { + const frag = new DocumentFragment(); + let r = []; + + tourist.clothes = "no clothing"; + App.Art.refreshSlaveArt(tourist, 3, "art-frame"); + r.push( + `When your new slave comes to, ${his2} weight is hanging from ${his2} wrists, bound over ${his2} head. ${He2}'s not exactly thin, making the position uncomfortable for ${his2} arms, so ${he2} groggily stands, finding ${himself2} in a pool of light in the middle of a cell. ${He2}'s nursing a tremendous hangover, and though ${he2} does not realize it, ${he2}'s drugged. You're present, though not visible, witnessing ${his2} first conscious moment of slavery from your desk. Realization is slow. ${He2}'s no innocent, so ${he2} recognizes the sensations of waking up the morning after a night of drinking interspersed with vigorous vaginal, oral, and anal intercourse, but ${he2} does not remember the specifics. After a few minutes, ${he2} understands that no one is coming, and speaks up hesitantly:`, + Spoken(tourist, `"Is anyone there?"`), + `Getting no immediate answer, ${he2} slumps against ${his2} wrist restraints again, and begins to cry to ${himself2}.`, + Spoken(tourist, `"W-why would a-anyone do this."`) + ); + cashX(-20000, "event", tourist); + r.push(App.UI.newSlaveIntro(tourist)); + App.Events.addParagraph(frag, r); + return frag; + } + + function notLesbian() { + const r = []; + r.push( + Spoken(tourist, `"I'm, um, not really a lesbian,"`), // tourist.behavioralFlaw = "fucking LIAR"; + `the tourist responds hesitantly.` + ); + if (milfSlave.dick > 0) { + r.push( + Spoken(milfSlave, `"You don't have to be,"`), + `${he} purrs.`, + Spoken(milfSlave, `"I have a cock."`), + `${He} slides in, just close enough to prove it.`, + Spoken(milfSlave, `"Please,`) + ); + } else { + r.push( + Spoken(milfSlave, `"Having sex with slaves does not make you a lesbian,"`), + `${he} purrs.`, + Spoken(milfSlave, `"It's different here. Please,`) + ); + } + return r.join(" "); + } + } +}; + diff --git a/src/events/RE/rePokerNight.js b/src/events/RE/rePokerNight.js new file mode 100644 index 0000000000000000000000000000000000000000..84a317f757667b083a10c4a4337fd6348c86b534 --- /dev/null +++ b/src/events/RE/rePokerNight.js @@ -0,0 +1,157 @@ + +App.Events.REPokerNight = class REPokerNight extends App.Events.BaseEvent { + eventPrerequisites() { + return [ + () => V.mercenaries > 0 + ]; + } + + get weight() { + return either(0, 1); // Originally rolled opposed to "RE Poker Night" + } + + execute(node) { + V.nextButton = "Continue"; + V.nextLink = "RIE Eligibility Check"; + let r = []; + const buyIn = 5000; + const { + HeA + } = getPronouns(assistant.pronouns().main).appendSuffix("A"); + + r.push(`Despite their persistent presence in your arcology, interaction with your mercenaries is relatively scarce. Aside from mutually exchanged nods on the street and the occasional briefing, your ${V.mercenariesTitle} enjoy a degree of autonomy.`); + + App.Events.addParagraph(node, r); + r = []; + + r.push(`On a particularly lackadaisical evening, you find yourself alerted to a message alert by ${V.assistant.name}.`); + if (V.assistant.personality > 0) { + r.push(`"${properMaster()}, a message from your ${V.mercenariesTitle}." ${HeA} pauses before continuing. "It seems they're asking if you'd like to join their poker night."`); + } else { + r.push(`${HeA} informs you that the ${V.mercenariesTitle} have sent a message asking you to join them at their poker night.`); + } + + App.Events.addParagraph(node, r); + + const choices = []; + choices.push(new App.Events.Result(`Politely decline`, decline)); + if (V.cash < 5000) { + choices.push(new App.Events.Result(null, null, "You lack the necessary funds to attend a high stakes poker game.")); + } else { + choices.push(new App.Events.Result(`Attend the poker night`, attend, `It will cost ${cashFormat(buyIn)} to participate in the poker night.`)); + } + App.Events.addResponses(node, choices); + + function decline() { + return `You inform ${V.assistant.name} that you aren't planning to attend. A short while later, you receive a message from the ${V.mercenariesTitle} stating that the invitation is an open one and that you're welcome to join in another night.`; + } + + function attend() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You instruct ${V.assistant.name} to inform your ${V.mercenariesTitle} that you will be attending their poker night, and after settling your affairs in the penthouse you head down to the barracks. Unsurprisingly the atmosphere in the barracks is casual, especially in comparison to the high stakes games commonplace in arcology high society, though your mercenaries still maintain some measure of decorum towards you as their employer. Eventually, you settle in at the table with a handful of ${V.mercenariesTitle} officers and cash in your ${cashFormat(buyIn)} into chips. All that remains is to decide your strategy for the night.`); + App.Events.addParagraph(frag, r); + + const choices = []; + choices.push(new App.Events.Result(`Play it safe`, safe)); + choices.push(new App.Events.Result(`Up the ante`, ante)); + App.Events.addResponses(frag, choices); + return frag; + + function safe() { + const frag = new DocumentFragment(); + let r = []; + if (random(1, 100) > 50) { + r.push(`Despite your attempts to mitigate risk and play the safest hands possible, it seems lady luck has conspired against you this evening. However, even when your last chip is spent, your mercenaries pitch you a few chips to keep you in the game for the rest of the night. You may have lost most of your ¤, but it seems you've <span class="reputation inc">made some friends.</span>`); + repX(5000, "event"); + cashX(-2500, "event"); + } else { + r.push(`While a careful eye for risk has buoyed you through the evening, ultimately lady luck is the decider in handing you the win in a number of close hands. Unfortunately your meticulous play limited your chance at a larger payout, and you only come away from the evening with ${cashFormat(1000)} more than you arrived with and <span class="reputation inc">the respect of your mercenaries.</span>`); + repX(500, "event"); + cashX(1000, "event"); + } + App.Events.addParagraph(frag, r); + return frag; + } + + function ante() { + const frag = new DocumentFragment(); + let r = []; + const genParam = { + minAge: 38, maxAge: 43, ageOverridesPedoMode: 1, race: "nonslave", disableDisability: 1 + }; + const slave = GenerateNewSlave((V.seeDicks !== 100) ? "XX" : "XY", genParam); + slave.origin = "$He put $himself up as collateral at a poker game, and lost."; + slave.career = "a soldier"; + slave.indentureRestrictions = 2; + slave.indenture = 52; + slave.devotion = random(25, 40); + slave.trust = random(35, 45); + setHealth(slave, jsRandom(60, 80), 0, undefined, 0, 10); + slave.muscles = 50; + if (slave.weight > 130) { + slave.weight -= 100; + slave.waist = random(-10, 50); + } + slave.anus = 0; + slave.skill.anal = 0; + slave.skill.whoring = 0; + slave.skill.combat = 1; + slave.accent = random(0, 1); + slave.behavioralFlaw = "arrogant"; + slave.hLength = 1; + slave.hStyle = "shaved into a mohawk"; + slave.custom.tattoo = "$He has a number of tattoos from a variety of mercenary companies."; + slave.clothes = "a military uniform"; + App.Events.drawEventArt(frag, slave); + + const { + He, + he, his + } = getPronouns(slave); + + r.push(`Some aggressive play and an eye for riling up your fellow players has resulted in an immense payout, and all but one of your adversaries have folded as the situation has escalated. The only player still in contention is a wily old mercenary, the veteran of ${his} fair share of battles on the battlefield and at the poker table. ${He}'s short on chips, however, and ${he}'ll have to buy in with something else as collateral.`); + App.Events.addParagraph(frag, r); + + const choices = []; + choices.push(new App.Events.Result(`A year of servitude`, serve)); + choices.push(new App.Events.Result(`Dock ${his} wages`, wages)); + App.Events.addResponses(frag, choices); + return frag; + + function serve() { + const frag = new DocumentFragment(); + let r = []; + if (random(1, 100) > 50) { + r.push(`For all your skillful maneuvering to reach this position, ultimately the win comes down to chance. This time, however, luck was not on your side. As the victor sweeps up ${his} spoils, the other mercenaries clap you on the back and offer their condolences for your defeat. Though you may have lost your ¤, it seems you've <span class="reputation inc">made some friends.</span>`); + repX(5000, "event"); + cashX(-5000, "event"); + } else { + slave.clothes = "no clothing"; + App.Art.refreshSlaveArt(slave, 3, "art-frame"); + r.push(`For all your skillful maneuvering to reach this position, ultimately the win comes down to chance. This time, however, luck has rendered you the victor. A silence falls over the room as the result is declared, but after some time your opponent breaks the hush by joking that life as your slave is probably easier than fighting for ${V.arcologies[0].name}. After some awkward laughter the night continues, and at the end your former mercenary joins you on your trip back to the penthouse to submit to processing and to begin ${his} new life as your sexual servant. ${He}'s not young, but ${he}'s tough and not distrusting of you due to ${his} service in the ${V.mercenariesTitle}.`); + r.push(App.UI.newSlaveIntro(slave)); + } + App.Events.addParagraph(frag, r); + return frag; + } + + function wages() { + const frag = new DocumentFragment(); + let r = []; + if (random(1, 100) > 50) { + r.push(`For all your skillful maneuvering to reach this position, ultimately the win comes down to chance. This time, however, luck was not on your side. As the victor sweeps up ${his} spoils, the other mercenaries clap you on the back and offer their condolences for your defeat. Though you may have lost your ¤, it seems you've <span class="reputation inc">made some friends.</span>`); + repX(5000, "event"); + cashX(-5000, "event"); + } else { + r.push(`For all your skillful maneuvering to reach this position, ultimately the win comes down to chance. This time, however, luck has rendered you the victor. Your opponent accepts ${his} defeat with grace and jokes to ${his} comrades that ${he}'ll be fighting in ${his} underwear for the next few months, and their uproar of laughter fills the room. Though you take the lion's share of the ¤, your mercenaries also <span class="reputation inc">had a good time fraternizing with you.</span>`); + repX(1000, "event"); + cashX(5000, "event"); + } + App.Events.addParagraph(frag, r); + return frag; + } + } + } + } +}; diff --git a/src/events/RE/reRebels.js b/src/events/RE/reRebels.js new file mode 100644 index 0000000000000000000000000000000000000000..1307aff535b1e64dd87f27e9809b09546a3eda05 --- /dev/null +++ b/src/events/RE/reRebels.js @@ -0,0 +1,202 @@ +App.Events.RERebels = class RERebels extends App.Events.BaseEvent { + actorPrerequisites() { + const jobs = [Job.ARCADE]; + if (V.dairyRestraintsSetting >= 2) { + jobs.push(Job.DAIRY); + } + const req = [ + (s) => !jobs.includes(s.assignment), + (s) => s.devotion < -20, + canWalk, + ]; + return [req, req]; + } + + execute(node) { + const r = []; + + V.nextButton = "Continue"; + V.nextLink = "RIE Eligibility Check"; + + const thingOne = getSlave(this.actors[0]); + const thingTwo = getSlave(this.actors[1]); + + const { + He, + he, his, him + } = getPronouns(thingOne); + + const { + He2, + he2, his2, him2, + } = getPronouns(thingTwo).appendSuffix("2"); + + App.Events.drawEventArt(node, [thingOne, thingTwo], "no clothing"); + + + r.push( + `You have a rebel problem.`, + App.UI.DOM.slaveDescriptionDialog(thingOne), + `and`, + App.UI.DOM.slaveDescriptionDialog(thingTwo), + `are both unbroken, and they seem to draw strength from each other. They're discreet about it, but the arcology's always-vigilant systems occasionally catch them nodding to one another after one of them is punished, or giving each other quiet words of encouragement when they think no one is listening. This is extremely dangerous and should be addressed promptly.` + ); + + App.Events.addParagraph(node, r); + + const choices = []; + choices.push(new App.Events.Result(`Set them against each other, in public`, publicly)); + choices.push(new App.Events.Result(`Set them against each other, in private`, privately)); + if (V.seeExtreme === 1 && thingTwo.vagina > 0 && thingOne.vagina > 0) { + choices.push(new App.Events.Result(`Let them compete against each other to decide who lives`, deathMatch)); + } + if (V.arcade > 0) { + choices.push(new App.Events.Result(`Sentence them to a month in the arcade`, arcade)); + } + + App.Events.addResponses(node, choices); + + function publicly() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You haul your little rebel bitches out in public, one by one, bound, with bags over their heads. They find themselves chained in a low position so their mouths are publicly available. Then, you whisper to each of them that whichever slut sucks off the most passersby gets to rest tomorrow — and whichever sucks least gets a beating. It doesn't take long before <span class="devotion inc">they forget their friendship</span> and try to outdo each other, and their desperate efforts <span class="reputation inc"> are certainly appreciated by the citizens getting free blowjobs.</span> It's childishly easy to declare the contest over when they happen to be tied, and announce that no one will be punished or rewarded. They hate you less and each other more.`); + for (const thing of [thingOne, thingTwo]) { + thing.devotion += 4; + seX(thing, "oral", "public", "penetrative", 6); + repX(250, "event", thing); + } + + App.Events.addParagraph(frag, r); + return frag; + } + + function privately() { + const frag = new DocumentFragment(); + let r = []; + r.push(`Back in the old world, the saying went that turnabout was fair play. In the Free Cities, turnabout is often a cast-iron bitch. Whenever you have an idle moment, all week, you set them against one another in some degrading or painful contest. They are made to spank each other, with the slave who hits lightest getting a spanking from you. They are made to compete to see who can suck other slaves off quickest, with the loser forced to orally service the winner. So on, and so on; by the end of the week <span class="trust dec">they forget their friendship</span> and try to outdo each other to avoid punishment.`); + for (const thing of [thingOne, thingTwo]) { + thing.trust -= 5; + seX(thing, "oral", "public", "penetrative", 6); + repX(250, "event", thing); + } + App.Events.addParagraph(frag, r); + return frag; + } + + function deathMatch() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You haul your bound little rebel bitches into one of the deepest, most out of the way rooms of your penthouse with bags over their heads. When you pull them off, they are met with`); + if (canSee(thingTwo) && canSee(thingOne)) { + r.push(`the sight of`); + } + r.push(`a gallows, complete with a pair of nooses. You haul them, one at a time up onto a stool and loop the rope around their necks. They scream and beg the whole time for you to reconsider, before turning on each other to try and avoid their fate. It won't be that easy for them. You hold up a pair of spoons and explain the rules of the game. They'll hold them in their pussies, and whoever loses their grip and drops it first, dies.`); + App.Events.addParagraph(frag, r); + r = []; + if (thingOne.vagina > 3) { + r.push(`You start with ${thingOne.slaveName} and no sooner than you turn to ${thingTwo.slaveName} do you hear the telltale clatter of the spoon hitting the floor. With a simple kick, the unfortunately loose ${thingOne.slaveName} is left struggling in the air. ${thingTwo.slaveName}`); + if (canSee(thingTwo)) { + r.push(`watches`); + } else if (canHear(thingTwo)) { + r.push(`listens`); + } else { + r.push(`stares blankly`); + } + r.push(`in horror as the life drains from ${his2} former accomplice. <span class="trust dec">${He2} promises to never cross you again.</span>`); + thingTwo.trust -= 20; + removeSlave(thingOne); + } else if (thingTwo.vagina > 3) { + r.push(`You start with ${thingOne.slaveName} before moving to ${thingTwo.slaveName} as ${he} holds ${his} life between ${his} netherlips. Setting the spoon inside ${thingTwo.slaveName}, you prepare to kick the stools out from under them; but the telltale clatter of the spoon hitting the floor saves you the trouble. With a simple kick, the unfortunately loose ${thingTwo.slaveName} is left struggling in the air. ${thingOne.slaveName}`); + if (canSee(thingOne)) { + r.push(`watches`); + } else if (canHear(thingOne)) { + r.push(`listens`); + } else { + r.push(`stares blankly`); + } + r.push(`in horror as the life drains from ${his} former accomplice. <span class="trust dec">${He} promises to never cross you again.</span>`); + thingOne.trust -= 20; + removeSlave(thingTwo); + } else if (random(1, 100) === 69) { + r.push(`You start with ${thingOne.slaveName} before moving to ${thingTwo.slaveName} as ${he} holds ${his} life between ${his} netherlips. Once both spoons are inserted, you sit back and watch them squirm at the cold metal in their most sensitive recesses. They are both desperate to survive and clamp down as hard as they can, but it can't go on forever as the sounds of a spoon clattering to the floor fills the room. Both slaves freeze as they realize the other has lost their grip on the silverware, uncertain of what comes next. You answer the question by knocking the stools out from under them, allowing them both to hang. They came into this together and they are going out together.`); + removeSlave(thingOne); + removeSlave(thingTwo); + } else if (thingOne.vagina === thingTwo.vagina && random(1, 100) > 50) { + r.push(`You start with ${thingOne.slaveName} before moving to ${thingTwo.slaveName} as ${he} holds ${his} life between ${his} netherlips. Once both spoons are inserted, you sit back and watch them squirm at the cold metal in their most sensitive recesses. They are both`); + if (thingOne.vagina === 1) { + r.push(`quite tight, so it's no surprise when they put up a good show.`); + } else { + r.push(`not the tightest slaves, so it's a surprise they manage to hold on as long as they do.`); + } + r.push(`But it can't go on forever as the sound of the spoon clattering to the floor fills the room.`); + if (random(1, 100) <= 50) { + r.push(kickBucket(thingTwo, thingOne)); + } else { + r.push(kickBucket(thingOne, thingTwo)); + } + } else if (thingTwo.vagina > thingOne.vagina && random(1, 100) > 50) { + r.push(`You start with ${thingOne.slaveName} before moving to ${thingTwo.slaveName} as ${he} holds ${his} life between ${his} netherlips. Once both spoons are inserted, you sit back and watch them squirm at the cold metal in their most sensitive recesses. ${thingOne.slaveName} is the clear favorite in this game, but the looser ${thingTwo.slaveName} refuses to give in, using ${his2} experience to clamp down as hard as ${he2} can. But it can't go on forever as the sound of the spoon clattering to the floor fills the room.`); + if (random(1, 100) <= 90) { + r.push(kickBucket(thingTwo, thingOne)); + } else { + r.push(kickBucket(thingOne, thingTwo)); + if (thingTwo.vagina >= 3) { + r.push(`You can't say you expected this outcome, but it was amusing all the same to discover the blown out whore has some talent.`); + } else { + r.push(`You're glad no bets were riding on this.`); + } + } + } else { + r.push(`You start with ${thingOne.slaveName} before moving to ${thingTwo.slaveName} as ${he} holds ${his} life between ${his} netherlips. Once both spoons are inserted, you sit back and watch them squirm at the cold metal in their most sensitive recesses. In a show of underhandedness, ${thingTwo.slaveName} kicks ${thingOne.slaveName}, knocking ${him} off balance and sending ${him} hanging. ${thingTwo.slaveName}`); + if (canSee(thingTwo)) { + r.push(`watches`); + } else if (canHear(thingTwo)) { + r.push(`listens`); + } else { + r.push(`stares blankly`); + } + r.push(`as the life drains from ${his2} accomplice, <span class="trust dec">horrified at what ${he2} just did.</span> The ordeal <span class="red">leaves ${him2} behaving strangely.</span>`); + thingTwo.trust = -100; + thingTwo.behavioralFlaw = "odd"; + removeSlave(thingOne); + } + + App.Events.addParagraph(frag, r); + return frag; + + /** + * @param {App.Entity.SlaveState} dead + * @param {App.Entity.SlaveState} survivor + * @returns {DocumentFragment} + */ + function kickBucket(dead, survivor) { + const {him} = getPronouns(dead); + const {his2, him2} = getPronouns(survivor).appendSuffix("2"); + const frag = new DocumentFragment(); + let r = []; + r.push(`You kick the stool out from under ${dead.slaveName} and let ${him} hang. ${survivor.slaveName}`); + if (canSee(survivor)) { + r.push(`watches`); + } else if (canHear(survivor)) { + r.push(`listens`); + } else { + r.push(`stares blankly`); + } + r.push(`in horror as the life drains from ${his2} former accomplice, <span class="trust dec">terrified that you'd so callously toy with their lives.</span> The ordeal <span class="red">leaves ${him2} behaving strangely.</span>`); + App.Events.addParagraph(frag, r); + survivor.trust -= -20; + survivor.behavioralFlaw = "odd"; + removeSlave(dead); + return frag; + } + } + + function arcade() { + for (const thing of [thingOne, thingTwo]) { + assignJob(thing, "be confined in the arcade"); + thing.sentence = 4; + } + return `They scream and beg when they realize what their punishment is to be, but you are obdurate. Each tries to inform on the other to avoid such a fate, but to no avail. After they're properly confined, the only sign of their discomfiture is a slight movement of their butts as they wriggle desperately against their restraints.`; + } + } +}; diff --git a/src/events/RE/reRelationshipAdvice.js b/src/events/RE/reRelationshipAdvice.js new file mode 100644 index 0000000000000000000000000000000000000000..126f914f5710ee40efce36001636081c848d7ed5 --- /dev/null +++ b/src/events/RE/reRelationshipAdvice.js @@ -0,0 +1,324 @@ +App.Events.RERelationshipAdvice = class RERelationshipAdvice extends App.Events.BaseEvent { + actorPrerequisites() { + return[[ + (s) => s.fetish !== "mindbroken", + hasAnyArms, + hasAnyLegs, + canTalk, + (s) => s.assignment !== Job.QUARTER, + (s) => s.relationship >= 2, + (s) => s.relationship < 5, + (s) => s.devotion > 20, + (s) => s.trust >= -20 + ]]; + } + + execute(node) { + const r = []; + + V.nextButton = "Continue"; + V.nextLink = "Next Week"; + + const slave = getSlave(this.actors[0]); + const relSlave = getSlave(slave.relationshipTarget); + + const { + He, + he, his, him, himself, girl + } = getPronouns(slave); + const {title: Master} = getEnunciation(slave); + + const { + He2, + he2, his2, him2, hers2, woman2, wife2, girl2, + } = getPronouns(relSlave).appendSuffix("2"); + + App.Events.drawEventArt(node, [slave, relSlave], "no clothing"); + + r.push( + App.UI.DOM.slaveDescriptionDialog(slave), + `is standing for an inspection. ${He}'s a good ${girl}, and is cooperating, but ${he} seems preoccupied. After ignoring it for a while, you give in to curiosity and flatly ask ${him} what's going on.`, + Spoken(slave, `"I'm sorry, ${Master},"`), + `${he}` + ); + if (SlaveStatsChecker.checkForLisp(slave)) { + r.push(`lisps,`); + } else { + r.push(`mutters,`); + } + r.push( + `biting ${his} lip.`, + Spoken(slave, `"It's`), + App.UI.DOM.combineNodes( // TODO: how the heck would we get them to lisp the name + App.UI.DOM.slaveDescriptionDialog(relSlave), + `."` + ), + ); + r.push(`${He} hesitates, so you prompt ${him}, asking if ${he}'s having trouble with ${his}`); + if (slave.relationship === 2) { + r.push(`friend.`); + } else if (slave.relationship === 3) { + r.push(`friend with benefits.`); + } else if (slave.relationship === 4) { + r.push(`lover.`); + } + r.push( + `${He} quickly shakes ${his} head no.`, + Spoken(slave, `"N-no, ${Master}, it's just —"`), + `${He} subsides into silence again, blushing and staring` + ); + if (!canSee(slave)) { + r.push(`blankly`); + } + if (hasBothLegs(slave)) { + r.push(`at ${his} feet.`); + } else { + r.push(`downwards.`); + } + r.push(`Comprehension dawning, you ask ${him} if`); + if (slave.relationship === 2) { + r.push(`${he} wants to be more than friends with ${relSlave.slaveName}.`); + } else if (slave.relationship === 3) { + r.push(`${he}'s wanting to bring emotions into relationship with ${relSlave.slaveName}, rather than keep it friendly and sexual.`); + } else if (slave.relationship === 4) { + r.push(`${he} wants to make an honest ${woman2} out of ${relSlave.slaveName}.`); + } + r.push(`${He} nods ${his} head quickly, still staring`); + if (!canSee(slave)) { + r.push(`blankly`); + } + if (hasBothLegs(slave)) { + r.push(`at ${his} feet.`); + } else { + r.push(`downwards.`); + } + r.push(`${He} shuts ${his} eyes tight and waits for you to weigh in on the situation.`); + App.Events.addParagraph(node, r); + + const choices = []; + choices.push(new App.Events.Result(`Break them up`, breakUp)); + choices.push(new App.Events.Result(`Build ${his} confidence`, confidence)); + choices.push(new App.Events.Result(`Bring the other ${girl2} in`, bringIn)); + App.Events.addResponses(node, choices); + + function breakUp() { + const frag = new DocumentFragment(); + let r = []; + r.push(`In a cold tone of voice, you admit your irritation with this school ${girl} nonsense, and tell ${him} ${he}'s to stop spending time with ${relSlave.slaveName}. ${He}'s unable to prevent ${his} eyes from flicking up at you in <span class="devotion dec">shock and horror,</span> but ${he} instantly lowers them again, the tears coming fast. You dismiss ${him}, and ${he} turns to go, but is so discombobulated by anguish that ${he} trips over ${his} own feet and falls with a slap of naked ${slave.skin} flesh against the floor. Their relationship <span class="relationship dec">is over.</span>`); + + slave.devotion -= 5; + slave.relationship = 0; + slave.relationshipTarget = 0; + relSlave.relationship = 0; + relSlave.relationshipTarget = 0; + + App.Events.addParagraph(frag, r); + return frag; + } + + function confidence() { + const frag = new DocumentFragment(); + let r = []; + r.push(`In a warm tone of voice, you tell ${him} you approve of ${his} relationship with ${relSlave.slaveName}. ${He} raises ${his} chin and looks at you with <span class="devotion inc">growing adoration</span> as you point out how lucky ${relSlave.slaveName} is to have ${him}. You tell ${him} that you're not planning to intervene personally, but that you think ${he} really ought to pursue the relationship, that they're good for each other, and that you're confident ${relSlave.slaveName} feels the same way. ${He} thanks you prettily and leaves at a flat run, in a hurry to tell ${his}`); + if (slave.relationship === 2) { + r.push(`sexy friend`); + } else if (slave.relationship === 3) { + r.push(`friend with benefits`); + } else if (slave.relationship === 4) { + r.push(`dear lover`); + } + r.push(`how ${he} feels about ${him2}.`); + if (slave.relationship === 2) { + r.push(`The next time you see them together, they're looking like they've been getting a little less sleep lately, but <span class="relationship">can't seem to keep their hands off each other.</span> ${slave.slaveName} mouths a silent thanks to you when ${relSlave.slaveName} isn't looking.`); + } else if (slave.relationship === 3) { + r.push(`The next time you see them together, they're <span class="relationship">holding hands at breakfast,</span> looking almost ashamed of themselves, but not letting go. ${slave.slaveName} mouths a silent thanks to you when ${relSlave.slaveName} isn't looking.`); + } else if (slave.relationship === 4) { + r.push(`${He} comes running right back, a happy ${relSlave.slaveName}`); + if (canWalk(relSlave)) { + r.push(`running in with ${him}.`); + } else { + r.push(`being helped in by ${his2} lover.`); + } + r.push(`You <span class="relationship">marry them</span> solemnly, and they embrace tightly, hugging each other close. ${slave.slaveName} comes to face you over ${his} ${wife2}'s shoulder, and ${he} mouths a silent, tearful thanks to you.`); + } + + slave.devotion += 5; + slave.relationship += 1; + relSlave.relationship += 1; + + App.Events.addParagraph(frag, r); + return frag; + } + + function bringIn() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You tell ${slave.slaveName} to wait, and page ${relSlave.slaveName} up to your office. ${slave.slaveName} looks terrified, but tries to conceal ${his} emotions behind a happy greeting for ${his}`); + if (slave.relationship === 2) { + r.push(`friend`); + } else if (slave.relationship === 3) { + r.push(`friend with benefits`); + } else if (slave.relationship === 4) { + r.push(`lover`); + } + r.push( + `when ${he2} comes in. ${relSlave.slaveName} knows ${him} well enough to detect ${his} inner turmoil, and asks ${him} what's wrong. ${slave.slaveName} flinches and looks to you in desperation, but you just nod at ${him} to spit it out. After two false starts, ${he} manages to say,`, + Spoken(slave, `"${relSlave.slaveName}, I really want`) + ); + + if (slave.relationship === 2) { + if (slave.fetishKnown === 1 && slave.fetish === "buttslut") { + r.push( + Spoken(slave, `to fuck your butt."`), + `${relSlave.slaveName} looks relieved that that's all it is, and ${agrees()}`, + ); + r.push(`${He2} kisses ${slave.slaveName} and then grinds ${his2} ass against ${slave.slaveName}'s crotch.`); + } else if ((slave.fetishKnown === 1) && (slave.fetish === "cumslut")) { + if (relSlave.vagina !== -1) { + r.push(`to eat you out."`); + } else { + r.push(`to blow you."`); + } + r.push(`${relSlave.slaveName} looks relieved that that's all it is, and ${agrees()} ${He2}`); + if (relSlave.vagina !== -1) { + r.push(`offers ${his2} pussy`); + } else { + r.push(`flops ${his2} dick at ${slave.slaveName}`); + } + r.push(`comically.`); + } else if ((slave.fetishKnown === 1) && (slave.fetish === "humiliation")) { + r.push( + Spoken(slave, `to fuck you in public."`), + ` ${relSlave.slaveName} looks relieved that that's all it is, and ${agrees()}` + ); + } else if ((slave.fetishKnown === 1) && (slave.fetish === "masochist")) { + r.push( + Spoken(slave, `you to hurt me. Like, really hurt me."`), + ` ${relSlave.slaveName} looks relieved that that's all it is, and ${agrees()} ${He2} pinches one of ${slave.slaveName}'s nipples experimentally.` + ); + } else if ((slave.fetishKnown === 1) && (slave.fetish === "sadist")) { + r.push( + Spoken(slave, `to hold you down."`), + ` ${relSlave.slaveName} looks relieved that that's all it is, and ${agrees()} ${He2} steps in close to ${slave.slaveName}, takes ${slave.slaveName}'s ${hasBothArms(slave) ? "hands" : "hand"}, and places them around ${his2} own throat.` + ); + } else if ((slave.fetishKnown === 1) && (slave.fetish === "dom")) { + r.push( + Spoken(slave, `to be your top."`), + ` ${relSlave.slaveName} looks relieved that that's all it is, and ${agrees()} ${He2} sidles up to ${slave.slaveName}, looking up at ${him} submissively.` + ); + } else if ((slave.fetishKnown === 1) && (slave.fetish === "submissive")) { + r.push( + Spoken(slave, `to be your bottom."`), + ` ${relSlave.slaveName} looks relieved that that's all it is, and says, ${agrees()} ${He2} takes ${slave.slaveName}'s face in ${his2} ${hasBothArms(relSlave) ? "hands" : "hand"} and kisses ${him} dominantly.` + ); + } else if ((slave.fetishKnown === 1) && (slave.fetish === "boobs")) { + r.push( + Spoken(slave, `to fuck your boobs."`), + `${relSlave.slaveName} looks relieved that that's all it is, and says, ${agrees()} ${He2} takes ${slave.slaveName}'s` + ); + if (hasBothArms(slave)) { + r.push(`hands and places them`); + } else { + r.push(`hand and places it`); + } + r.push(`right on ${his2} breasts.`); + } else { + r.push( + Spoken(slave, `to fuck you."`), + ` ${relSlave.slaveName} looks relieved that that's all it is, and ${agrees()} ${He2} takes ${slave.slaveName}'s` + ); + if (hasBothArms(slave)) { + r.push(`hands and places them`); + } else { + r.push(`hand and places it`); + } + r.push(`right on ${his2} breasts.`); + } + r.push(`${slave.slaveName} bursts out laughing. They're now <span class="relationship">friends with benefits.</span>`); + } else if (slave.relationship === 3) { + r.push( + Spoken(slave, `t-to b-be your ${girl} friend."`), + `${He} takes a deep breath.`, + Spoken(slave, `"It's fun, just`) + ); + if (slave.fetishKnown === 1 && slave.fetish === "buttslut") { + r.push(`fucking your butt.`); + } else if ((slave.fetishKnown === 1) && (slave.fetish === "cumslut")) { + r.push(`to`); + if (relSlave.vagina !== -1) { + r.push(`eating you out.`); + } else { + r.push(`blowing you.`); + } + } else if ((slave.fetishKnown === 1) && (slave.fetish === "humiliation")) { + r.push(`fucking you in public.`); + } else if ((slave.fetishKnown === 1) && (slave.fetish === "masochist")) { + r.push(`having you hurt me.`); + } else if ((slave.fetishKnown === 1) && (slave.fetish === "sadist")) { + r.push(`holding you down.`); + } else if ((slave.fetishKnown === 1) && (slave.fetish === "dom")) { + r.push(`topping you.`); + } else if ((slave.fetishKnown === 1) && (slave.fetish === "submissive")) { + r.push(`being your bottom.`); + } else if ((slave.fetishKnown === 1) && (slave.fetish === "boobs")) { + r.push(`fucking your boobs.`); + } else { + r.push(`having sex with you.`); + } + r.push( + Spoken(slave, `But I — I really like you."`), + ` ${relSlave.slaveName} looks relieved, and` + ); + if (relSlave.voice !== 0) { + r.push( + `says,`, + Spoken(slave, `"I really like you too. And you're really cute! I'd love to be your ${girl2} friend."`), + `${He2}` + ); + } else { + r.push(`lovingly`); + } + r.push(`takes ${slave.slaveName}'s hands in ${hers2}, and then kisses ${him} on the cheek. ${slave.slaveName} crushes ${relSlave.slaveName} in a hug, pressing a squeak out of ${him2}. They're now <span class="relationship">lovers.</span>`); + } else if (slave.relationship === 4) { + r.push( + `- " ${He} stops ${himself}.`, + Spoken(slave, `"No, I want to do this right."`), + `${He} takes ${relSlave.slaveName}'s hand, and then drops to one knee. After a moment of uncomprehending shock, ${relSlave.slaveName} begins to cry.`, + Spoken(slave, `"Will you marry me?"`), + `${relSlave.slaveName} turns to you and`); + if (!canTalk(relSlave)) { + r.push(`wordlessly`); + } + r.push(`asks if it's all right with you; you nod, and ${he2} turns back to ${slave.slaveName}.`); + if (!canTalk(relSlave)) { + r.push(`${He2} gestures distractedly that ${slave.slaveName} is being silly, and of course ${he2}'ll marry ${him}, because ${he2} loves ${him}.`); + } else { + r.push(Spoken(slave, `"O-of course I'll m-marry you, silly ${girl}. I love you."`)); + } + r.push(`${slave.slaveName} jumps up and crushes ${relSlave.slaveName} in a hug, kissing ${him2} frantically through ${his} tears. You <span class="relationship">marry them</span> solemnly, and they embrace tightly, hugging each other close. ${slave.slaveName} comes to face you over ${his} ${wife2}'s shoulder, and ${he} mouths a silent thanks to you.`); + } + r.push(`If ${slave.slaveName} had doubts about you, <span class="trust inc">they've been addressed.</span>`); + + slave.trust += 10; + slave.relationship += 1; + relSlave.relationship += 1; + + App.Events.addParagraph(frag, r); + return frag; + + function agrees() { + const r = []; + if (relSlave.voice !== 0) { + r.push( + `says,`, + Spoken(relSlave, `"Okay!"`) + ); + } else { + r.push(`nods.`); + } + return r.join(" "); + } + } + } +}; + diff --git a/src/events/RE/reShowerPunishment.js b/src/events/RE/reShowerPunishment.js new file mode 100644 index 0000000000000000000000000000000000000000..7d557310c44aa89e04ea4f1216c9be4f408d79ca --- /dev/null +++ b/src/events/RE/reShowerPunishment.js @@ -0,0 +1,267 @@ +App.Events.REShowerPunishment = class REShowerPunishment extends App.Events.BaseEvent { + eventPrerequisites() { + return [ + () => V.HeadGirlID !== 0, + ]; + } + + actorPrerequisites() { + return [[ + (s) => s.devotion <= 50, + (s) => s.anus !== 0, + (s) => s.fetish !== "mindbroken", + canDoAnal, + hasAnyLegs, + hasAnyArms, + canTalk, + ]]; + } + + execute(node) { + let r = []; + const slave = getSlave(this.actors[0]); + + V.nextButton = "Continue"; + V.nextLink = "Next Week"; + + const { + He, + he, his, him, himself, girl, women + } = getPronouns(slave); + + const {title: Master} = getEnunciation(slave); + + const { + He2, His2, + he2, his2, him2, woman2, girl2 + } = getPronouns(S.HeadGirl).appendSuffix("2"); + + App.Events.drawEventArt(node, [slave, S.HeadGirl], "no clothing"); + + + if (V.HGSuite === 1) { + r.push(`Looking in on your Head Girl in ${his2} suite, you hear ${his2} private shower running and head that way. Through the thick steam the shower makes on its hottest setting, you see`); + } else { + r.push(`Passing by the showers, you see, through the steam of a very hot shower,`); + } + r.push(`a`); + if (slave.height > 180) { + r.push(`tall,`); + } else if (slave.height < 150) { + r.push(`tiny,`); + } + r.push( + `${slave.skin} form moving busily around a ${S.HeadGirl.skin} figure, which is standing confidently in the middle of the warm, moist space. As you draw nearer, you identify the stationary slave as your Head Girl,`, + App.UI.DOM.combineNodes(App.UI.DOM.slaveDescriptionDialog(S.HeadGirl), "."), + `${His2} attendant is`, + App.UI.DOM.combineNodes(contextualIntro(S.HeadGirl, slave, "DOM"), `,`), + `and ${he}'s washing ${his} superior with a big sponge.`, + ); + + if (V.HGSeverity > 0) { + r.push(`By virtue of not being rape, this is an unusually mild punishment by your Head Girl, if indeed that's what it is. But perhaps ${he2}'s saving that for later. And to go by the cringing, frightened mien of the busy little bath bitch, that's probably it.`); + } else if (V.HGSeverity === 0) { + r.push(`Your Head Girl does ${his2} best to fit the punishment to the crime, so ${slave.slaveName}'s failure was likely minor. With ${S.HeadGirl.slaveName}'s penchant for poetic justice, probably some little deficiency of personal cleanliness.`); + } else { + r.push(`This is the sort of mild punishment that your regime of respect and dignity requires ${him2} to use for all but the most egregious fault. Thus restricted, ${he2} does ${his2} best to come up with novel little degradations to keep ${his2} charges on their toes.`); + } + App.Events.addParagraph(node, r); + r = []; + r.push(`${slave.slaveName} is being very thorough. When you first appeared, ${he} was working ${his} way up ${S.HeadGirl.slaveName}'s `); + if (S.HeadGirl.muscles > 30) { + r.push(`muscle-corded`); + } else if (S.HeadGirl.weight > 10) { + r.push(`soft`); + } else if (S.HeadGirl.vagina > -1) { + r.push(`feminine`); + } else { + r.push(`pretty`); + } + r.push(`thighs, having obviously started at the bottom. ${He} skips over ${S.HeadGirl.slaveName}'s crotch, probably under instructions to leave it for last. It's late in your Head Girl's busy day, and you hear ${his2} groan of relaxation over the running water when the stiff sponge begins to scrub back and forth across ${his2}`); + if (S.HeadGirl.belly >= 60000) { + r.push(`enormously`); + if (S.HeadGirl.preg > 0) { + r.push(`pregnant`); + } else { + r.push(`rounded`); + } + r.push(`belly.`); + } else if (S.HeadGirl.weight > 190) { + r.push(`massively fat gut.`); + } else if (S.HeadGirl.belly >= 10000) { + r.push(`hugely`); + if (S.HeadGirl.preg > 0) { + r.push(`pregnant`); + } else { + r.push(`rounded`); + } + r.push(`belly.`); + } else if (S.HeadGirl.weight > 95) { + r.push(`big soft belly.`); + } else if (S.HeadGirl.belly >= 5000) { + if (S.HeadGirl.preg > 0) { + r.push(`pregnant`); + } else { + r.push(`round`); + } + r.push(`belly.`); + } else if (S.HeadGirl.weight > 30) { + r.push(`soft belly.`); + } else if (S.HeadGirl.belly >= 1500) { + r.push(`bloated belly.`); + } else if (S.HeadGirl.muscles > 30) { + r.push(`shredded abs.`); + } else if (S.HeadGirl.weight > 10) { + r.push(`plush belly.`); + } else if (S.HeadGirl.navelPiercing > 0) { + r.push(`pierced belly button.`); + } else if (S.HeadGirl.waist < -10) { + if (S.HeadGirl.waist < -95) { + r.push(`absurdly`); + } + r.push(`narrow waist.`); + } else { + r.push(`belly.`); + } + + App.Events.addParagraph(node, r); + + const choices = []; + choices.push(new App.Events.Result(`Just spectate`, spectate)); + choices.push(new App.Events.Result(`Get a scrub down too`, scrub)); + choices.push(new App.Events.Result(`Focus on your Head Girl`, HG)); + App.Events.addResponses(node, choices); + + function spectate() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You could strip off your suit, walk into the steam, and enjoy your slaves' ministrations, but sometimes the artistry of tastefully nude bodies is a welcome change of pace. You lean against the wall, far enough away that they remain unaware of your presence, and take in the sight. ${S.HeadGirl.slaveName} makes the penitent ${girl} do the job with Brahmanical thoroughness, cleaning ${his} superior's ${S.HeadGirl.race} body down to its very last pore. As ${slave.slaveName} circles the Head Girl laboriously, doing ${his} best to ingratiate ${himself} by diligence, the pair of naked`); + if (girl === girl2) { + r.push(`${women}`); + } else { + r.push(`slaves`); + } + r.push(`present a fascinating contrast. They are unclothed alike, the water streaming off their bodies without any distinction, but even an old world fool could not mistake the immense gulf between them.`); + App.Events.addParagraph(frag, r); + r = []; + r.push(`When ${slave.slaveName} is finally done, ${S.HeadGirl.slaveName}'s`); + if (V.HGSeverity > 0) { + r.push(`hands seize ${him} by the ears and pull ${his} head in for a kiss that is dominance distilled into the form of a loving gesture. Then ${he2} pokes ${his2} bitch in the side, forcing the slave to collapse in just the right way.`); + } else if (V.HGSeverity === 0) { + r.push(`arms encircle ${him} in an embrace that is simultaneously controlling, comforting, and sexually insistent. The slave does not resist, allowing the Head Girl to run ${his2} hands over the warm, wet sex slave.`); + } else { + r.push(`arousal is obvious. Though the respectful regime you require secures ${him} from the fear of being used, ${slave.slaveName} nonverbally offers ${his} superior oral, out of obvious gratitude that whatever ${he} did is being treated so leniently, and perhaps out of a desire to be in ${S.HeadGirl.slaveName}'s good graces.`); + } + r.push(`In no time at all, ${slave.slaveName}'s ${slave.hColor} head descends to obscure ${S.HeadGirl.slaveName}'s groin. The`); + if (S.HeadGirl.face > 95) { + r.push(`heartrendingly gorgeous`); + } else if (S.HeadGirl.face <= 95) { + r.push(`wonderfully pretty`); + } else if (S.HeadGirl.face <= 40) { + r.push(`approachably lovely`); + } else if (S.HeadGirl.face <= 10) { + r.push(`not unattractive`); + } else { + r.push(`homely`); + } + if (S.HeadGirl.physicalAge > 25) { + r.push(`${woman2}'s`); + } else { + r.push(`${girl2}'s`); + } + r.push(`head cranes back with orgasm before long; that diligent scrub must have been quite stimulating.`); + App.Events.addParagraph(frag, r); + r = []; + r.push(`${slave.slaveName} stays in the shower to clean ${himself}, so ${S.HeadGirl.slaveName} exits to see you watching the denouement. ${He2} <span class="devotion inc">smiles,</span> murmuring a greeting, and hurries over to give you a peck on the cheek, leaning in as best ${he2} can to keep ${his2} moist body away from your suit. "This is the life, ${Master}," ${he2} whispers.`); + seX(slave, "oral", S.HeadGirl, "penetrative"); + S.HeadGirl.devotion += 4; + + App.Events.addParagraph(frag, r); + return frag; + } + + function scrub() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You strip off your suit and enter the shower. By the time you get in, ${S.HeadGirl.slaveName}'s sponge scrub is almost done. ${He2} turns to greet you with half-lidded eyes, well pleased with ${his2} thorough scrubbing. ${His2} ${S.HeadGirl.skin} skin shines with wet cleanliness, and ${his2} ${S.HeadGirl.nipples} nipples begin to`); + if (S.HeadGirl.nipples === "fuckable") { + r.push(`swell with arousal`); + } else { + r.push(`stiffen`); + } + r.push(`as ${he2} sees your gaze take in ${his2} nude body. ${He2} brusquely orders ${slave.slaveName} to scrub you, too, anticipating your intention. The rough, exfoliating sensation of the sponge is indeed delightful, and you close your eyes to savor the feeling as the slave rubs it up and down your calves and then the backs of your knees.`); + App.Events.addParagraph(frag, r); + r = []; + if (V.HGSeverity > 0) { + r.push(`You detect tremors of fear in the`); + if (hasAnyArms(slave)) { + r.push(`slave's ${hasBothArms(slave) ? "hands" : "hand"};`); + } else { + r.push(`slave;`); + } + r.push(`${he} knows that ${he} hasn't extirpated ${his} misbehavior, whatever it was, just yet. You let your Head Girl manage that, however, and ${he2} does. When ${slave.slaveName} is stuck in one position for a short time by the need to wash your thighs, you hear a gasp and open your eyes to the sight of your Head Girl crouched behind ${him}, giving ${him} an anal fingerfuck. When ${slave.slaveName} is done washing you, your Head Girl holds the slave's head to your`); + } else { + r.push(`When the washing reaches your shoulders, it becomes clumsier, and ${slave.slaveName}'s wet body begins to bump gently against your torso. Opening your eyes, you see that your Head Girl is taking ${him} as ${he} finishes your bath. ${slave.slaveName} is doing ${his} best to do a good job as ${he}'s fucked, and ${he} manages it reasonably well. When ${he}'s done, ${S.HeadGirl.slaveName} pushes ${his} head down towards your`); + } + if (V.PC.dick !== 0) { + r.push(`groin so ${he} can suck you off${(V.PC.vagina !== -1) ? "and stroke your cunt" : ""}.`); + } else { + r.push(`cunt so ${he} can eat you out.`); + } + r.push(`${slave.slaveName} complies, and afterward, ${he} seems to feel that <span class="trust inc">${he} came off reasonably well;</span> it could have been worse.`); + seX(slave, "anal", S.HeadGirl, "penetrative"); + seX(slave, "oral", V.PC, "penetrative"); + r.push(knockMeUp(slave, 10, 1, V.HeadGirlID)); + slave.trust += 4; + + App.Events.addParagraph(frag, r); + return frag; + } + + function HG() { + const frag = new DocumentFragment(); + let r = []; + const {hersP} = getPronouns(V.PC).appendSuffix("P"); + r.push(`You strip off your suit and walk into the steam, producing a surprised but welcoming greeting from your Head Girl and a muffled, submissive noise from ${slave.slaveName}. ${S.HeadGirl.slaveName} is held more or less stationary by the slave ${he2}'s straddling, so you step in, hook a dominant arm around ${his2} waist, and kiss ${him2}. There's precisely one person in this arcology who's allowed to treat ${him2} as ${hersP}, and it's you. ${He2} relaxes into you with gratitude as you shoulder the burden of being the leader in this little area of your empire, lifting it from ${his2} shoulders for now.`); + App.Events.addParagraph(frag, r); + r = []; + r.push(`You run a hand up the side of ${his2} neck, bringing it to rest with your fingers cupping ${him2} under the ear and your thumb running up along ${his2} temple. ${He2} shivers, unable to concentrate despite all ${his2} poise, the ongoing oral service blending into your intense closeness. Right now, ${he2}'s the`); + if (S.HeadGirl.physicalAge > 25) { + r.push(`${woman2}`); + } else { + r.push(`${girl2}`); + } + r.push(`for you, so you snap your fingers next to the ear of the slave`); + if (S.HeadGirl.vagina > -1) { + r.push(`eating ${him2} out,`); + } else { + r.push(`blowing ${him2},`); + } + r.push(`point at the dropped sponge, and then point at yourself. The oral stops as ${slave.slaveName} hurries to scrub you, starting at your feet, but your Head Girl doesn't care. You're kissing ${him2}.`); + App.Events.addParagraph(frag, r); + r = []; + r.push(`${He2} gently strokes your `); + if (V.PC.dick !== 0) { + r.push(`rapidly hardening member, smiling into your mouth at the speed with which it stiffens${(V.PC.vagina !== -1) ? ", and teases your pussylips with mischievous fingers" : ""}.`); + } else { + r.push(`flushed cunt, smiling into your mouth at the moisture that instantly coats ${his2} fingertips.`); + } + r.push(`You reach out in turn,`); + if (S.HeadGirl.vagina > -1) { + r.push(`caressing ${his2} pussylips before slowly inserting a digit inside ${his2} warmth while nuzzling ${his2} clit with the knuckle of your thumb. At the first real brush against ${his2} clitoris, the overstimulated ${S.HeadGirl.slaveName} climaxes, pulling ${his2} mouth away from you to shout your name and then sobbing thanks into your ear.`); + } else { + r.push(`hooking your fingers up underneath ${his2} taint to grope ${his2} anus. After teasing ${his2} asspussy for a moment you bring your hand slowly across ${his2} perineum${(S.HeadGirl.scrotum > 0) ? `until ${his2} ballsack rests against your wrist` : ""}. The overstimulated ${S.HeadGirl.slaveName} cums the instant the butt of your hand touches the base of ${his2} cock. ${He2} screams your name.`); + } + App.Events.addParagraph(frag, r); + r = []; + r.push(`${He2} isn't terribly affected by loving shower sex with you; after all, it isn't exactly novel for ${him2}. ${slave.slaveName} was there to bear witness, though, scrubbing your back as ${S.HeadGirl.slaveName} clung to it with orgasm. ${He} can't help but be <span class="devotion inc">impressed.</span> Maybe, just maybe, that could be ${him} someday. ${He} seems distinctly uncomfortable.`); + + seX(slave, "oral", S.HeadGirl, "oral"); + + slave.devotion += 4; + + App.Events.addParagraph(frag, r); + return frag; + } + } +}; diff --git a/src/events/RE/reSlaveMarriage.js b/src/events/RE/reSlaveMarriage.js new file mode 100644 index 0000000000000000000000000000000000000000..813ac296a3369c73b21dce63e1c3920280a75bff --- /dev/null +++ b/src/events/RE/reSlaveMarriage.js @@ -0,0 +1,210 @@ +App.Events.RESlaveMarriage = class RESlaveMarriage extends App.Events.BaseEvent { + actorPrerequisites() { + return[[ + (s) => s.fetish !== "mindbroken", + hasAnyArms, + hasAnyLegs, + canTalk, + (s) => s.relationship === 4, + (s) => s.devotion > 20, + (s) => s.trust > 20, + ]]; + } + + execute(node) { + const r = []; + + V.nextButton = "Continue"; + V.nextLink = "Next Week"; + + const groomSlave = getSlave(this.actors[0]); + const brideSlave = getSlave(groomSlave.relationshipTarget); + + const { + He, His, + he, his, him + } = getPronouns(groomSlave); + const {title: Master} = getEnunciation(groomSlave); + + const { + He2, His2, + he2, his2, him2 + } = getPronouns(brideSlave).appendSuffix("2"); + + App.Events.drawEventArt(node, [groomSlave, brideSlave]); + + r.push( + App.UI.DOM.slaveDescriptionDialog(groomSlave), + `and`, + App.UI.DOM.slaveDescriptionDialog(brideSlave), + `come into your office` + ); + if (hasAnyArms(groomSlave) && hasAnyArms(brideSlave)) { + r.push(`holding hands.`); + } else { + r.push(`doing their best to stay close to one another despite their physical limitations.`); + } + r.push(`${brideSlave.slaveName} looks at ${groomSlave.slaveName} expectantly, but ${he2}'s terribly nervous and makes several false starts before beginning. Finally ${groomSlave.slaveName} musters ${his} courage and`); + if (canTalk(groomSlave)) { + r.push( + `asks with ${his} voice cracking,`, + Spoken(groomSlave, `"${Master}, would you please grant us a slave marriage?"`) + ); + } else { + r.push(`asks you with simple gestures to grant the two of them a slave marriage.`); + } + + App.Events.addParagraph(node, r); + + const choices = []; + choices.push(new App.Events.Result(`Of course`, yes)); + choices.push(new App.Events.Result(`No`, no)); + App.Events.addResponses(node, choices); + + + function yes() { + const frag = new DocumentFragment(); + let r = []; + r.push(`You inquire as to whether they understand the Free Cities slave marriage ceremony, and they nod, not trusting themselves to do anything more. You give them a few minutes to get dressed in special outfits you make available. When they come back, they're wearing lacy lingerie designed to resemble old world wedding dresses, but without concealing anything.`); + + App.Events.addParagraph(frag, r); + r = []; + if (groomSlave.vagina === 0) { + r.push(`${groomSlave.slaveName} is a virgin, so ${he}'s wearing white`); + } else if (groomSlave.pregKnown === 1) { + r.push(`${groomSlave.slaveName} is pregnant, so ${he}'s wearing light pink`); + } else if (groomSlave.vagina < 0) { + r.push(`${groomSlave.slaveName} is a sissy slave, so ${he}'s wearing light blue`); + } else { + r.push(`${groomSlave.slaveName} is an experienced sex slave, so ${he}'s wearing light pink`); + } + r.push(`against ${his}${groomSlave.skin} skin.`); + if (groomSlave.chastityPenis) { + r.push(`${He} has a little bow on ${his} chastity cage.`); + } else if (canAchieveErection(groomSlave)) { + r.push(`The`); + if (canSee(groomSlave)) { + r.push(`sight of ${brideSlave.slaveName}`); + } else { + r.push(`anticipation`); + } + r.push(`has ${him} stiffly erect, and ${he}'s wearing a little bow around ${his} cockhead.`); + } else if (groomSlave.dick > 0) { + r.push(`${He}'s impotent, but ${he}'s wearing a little bow around ${his} useless cockhead.`); + } else if (groomSlave.clit > 0) { + r.push(`${His} prominent clit is engorged, and ${he}'s wearing a tiny bow on it.`); + } else { + r.push(`${He}'s wearing a demure little bow just over ${his} pussy.`); + } + if (groomSlave.anus > 1) { + r.push(`${His} lacy panties are designed to spread ${his} buttocks a little and display ${his} big butthole.`); + } else if (groomSlave.anus === 0) { + r.push(`${His} lacy panties cover ${his} virgin anus, for once.`); + } + if (groomSlave.boobs > 1000) { + r.push(`The bra makes no attempt to cover or even support ${his} huge breasts, simply letting them through holes in the lace to jut proudly out.`); + } else if (groomSlave.boobs > 500) { + r.push(`The bra supports and presents ${his} big breasts, leaving ${his} stiffening nipples bare.`); + } else { + r.push(`The bra supports and presents ${his} breasts, giving ${him} more cleavage than ${he} usually displays.`); + } + if (groomSlave.belly >= 1500) { + r.push(`${His}`); + if (groomSlave.preg > 0) { + r.push(`growing pregnancy`); + } else { + r.push(`rounded middle`); + } + r.push(`prominently bulges from the gap between ${his} lingerie.`); + } + + App.Events.addParagraph(frag, r); + r = []; + if (brideSlave.vagina === 0) { + r.push(`${brideSlave.slaveName} is a virgin, so ${he2}'s wearing white`); + } else if (brideSlave.pregKnown === 1) { + r.push(`${brideSlave.slaveName} is pregnant, so ${he2}'s wearing light pink`); + } else if (brideSlave.vagina < 0) { + r.push(`${brideSlave.slaveName} is a sissy slave, so ${he2}'s wearing light blue`); + } else { + r.push(`${brideSlave.slaveName} is an experienced sex slave, so ${he2}'s wearing light pink`); + } + r.push(`against ${his2}${brideSlave.skin} skin.`); + if (brideSlave.chastityPenis) { + r.push(`${He2} has a little bow on ${his2} chastity cage.`); + } else if (canAchieveErection(brideSlave)) { + r.push(`The`); + if (canSee(brideSlave)) { + r.push(`sight of ${groomSlave.slaveName}`); + } else { + r.push(`anticipation`); + } + r.push(`has ${him2} stiffly erect, and ${he2}'s wearing a little bow around ${his2} cockhead.`); + } else if (brideSlave.dick > 0) { + r.push(`${He}'s impotent, but ${he2}'s wearing a little bow around ${his2} useless cockhead.`); + } else if (brideSlave.clit > 0) { + r.push(`${His2} prominent clit is engorged, and ${he2}'s wearing a tiny bow on it.`); + } else { + r.push(`${He2}'s wearing a demure little bow just over ${his2} pussy.`); + } + if (brideSlave.anus > 1) { + r.push(`${His2} lacy panties are designed to spread ${his2} buttocks a little and display ${his2} big butthole.`); + } else if (brideSlave.anus === 0) { + r.push(`${His2} lacy panties cover ${his2} virgin anus, for once.`); + } + if (brideSlave.boobs > 1000) { + r.push(`The bra makes no attempt to cover or even support ${his2} huge breasts, simply letting them through holes in the lace to jut proudly out.`); + } else if (brideSlave.boobs > 500) { + r.push(`The bra supports and presents ${his2} big breasts, leaving ${his2} stiffening nipples bare.`); + } else { + r.push(`The bra supports and presents ${his2} breasts, giving ${him2} more cleavage than ${he2} usually displays.`); + } + if (brideSlave.belly >= 1500) { + r.push(`${His2}`); + if (brideSlave.preg > 0) { + r.push(`growing pregnancy`); + } else { + r.push(`rounded middle`); + } + r.push(`prominently bulges from the gap between ${his2} lingerie.`); + } + + App.Events.addParagraph(frag, r); + r = []; + r.push(`The procedure is simple. The two of them prostrate themselves on the ground and beg your indulgence. You state that you grant it, and hand each of them a simple gold band to be worn on the little finger in advertisement of the inferiority of their union. In turn, each of them gives the other their ring, and they kiss. You pronounce them slave spouses, and offer them the couch for their honeymoon; they <span class="trust inc">thank you profusely</span> through their building tears. It's always touching to see`); + if (groomSlave.bellyPreg >= 5000 && brideSlave.bellyPreg >= 5000) { + r.push(`two pregnant slaves`); + if (hasAnyArms(brideSlave) && hasAnyArms(groomSlave)) { + r.push(`fingering`); + } else { + r.push(`fucking`); + } + r.push(`each other`); + } else { + r.push(`a 69`); + } + r.push(`in which both participants are <span class="devotion inc">softly crying with happiness.</span>`); + if (groomSlave.pregSource === brideSlave.ID && brideSlave.pregSource === groomSlave.ID) { + r.push(`When ${groomSlave.slaveName} and ${brideSlave.slaveName} tire, they rest, shoulder to shoulder, with a hand upon each other's bulging belly. Gently, they caress their growing pregnancies, knowing that they carry the other's love child.`); + } else if (brideSlave.pregSource === groomSlave.ID) { + r.push(`When they tire, ${groomSlave.slaveName} rests ${his} head upon ${brideSlave.slaveName}'s lap and gently kisses ${his} lover's belly, knowing the child of their love is growing within.`); + } else if (groomSlave.pregSource === brideSlave.ID) { + r.push(`When they tire, ${brideSlave.slaveName} rests ${his2} head upon ${groomSlave.slaveName}'s lap and gently kisses ${his2} lover's belly, knowing the child of their love is growing within.`); + } + seX(groomSlave, "oral", brideSlave, "oral"); + groomSlave.devotion += 4; + brideSlave.devotion += 4; + groomSlave.trust += 4; + brideSlave.trust += 4; + groomSlave.relationship = 5; + brideSlave.relationship = 5; + + App.Events.addParagraph(frag, r); + return frag; + } + + function no() { + return `You decline gently, telling them that their relationship is acceptable to you as it is. They are disappointed, but not surprised, and accept your will without a murmur. They leave as they entered, holding hands.`; + } + } +}; diff --git a/src/events/RE/reStandardPunishment.js b/src/events/RE/reStandardPunishment.js index 0ef37e059e343355f6e35aaf05dd5c874fdecd00..e824a302075975ab93fe8ecb6c4f29116f98368f 100644 --- a/src/events/RE/reStandardPunishment.js +++ b/src/events/RE/reStandardPunishment.js @@ -266,7 +266,7 @@ App.Events.REStandardPunishment = class REStandardPunishment extends App.Events. function whipCruelly() { const frag = new DocumentFragment(); let r = []; - r.push(`Since you use whipping as a standard slave punishment, there are many sets of restraints set high up on the walls for the purpose.You order ${him} to place ${his} ${hasBothArms(slave) ? "hands" : "hand"} in one of them, and ${he}`); + r.push(`Since you use whipping as a standard slave punishment, there are many sets of restraints set high up on the walls for the purpose. You order ${him} to place ${his} ${hasBothArms(slave) ? "hands" : "hand"} in one of them, and ${he}`); if (slave.devotion > 20) { r.push(`sobs with fear but obeys, despite something in your tone that makes ${his} knees go weak with terror.`); } else if (slave.trust < -20) { diff --git a/src/events/REM/remFluctuations.js b/src/events/REM/remFluctuations.js new file mode 100644 index 0000000000000000000000000000000000000000..79c4c0218c64f90d00cdcfc22a865dfb48acda1e --- /dev/null +++ b/src/events/REM/remFluctuations.js @@ -0,0 +1,273 @@ +App.Events.REMFluctuations = class REMFluctuations extends App.Events.BaseEvent { + get weight() { + this.params.REM = 0; + if (random(1, 100) > V.slaveCostFactor*50) { + this.params.REM += 1; + } + if (random(1, 100) < V.slaveCostFactor*50) { + this.params.REM -= 1; + } + return this.params.REM ? 2 : 0; + } + + execute(node) { + let r = []; + V.nextButton = "Continue"; + V.nextLink = "RIE Eligibility Check"; + + const { + HeA, HisA, + heA, hisA, himA, girlA, himselfA + } = getPronouns(assistant.pronouns().main).appendSuffix("A"); + const { + HeM, HisM, + heM, hisM, girlM, himM, womanM, loliM, + } = getPronouns(assistant.pronouns().market).appendSuffix("M"); + + const fluctuationType = (this.params.REM === 1) ? + either("antislavery terrorism", "medical breakthrough", "new free city", "revel", "speculation", "tainted drugs") : + either("anti-slavery coup", "arcology change", "bankruptcy", "empty prisons", "hostilities ended", "refugee boat", "unemployment", "war"); + + if (V.assistant.personality > 0) { + if (V.assistant.market) { + r.push(`The market assistant's avatar appears on a wallscreen as you're going about your business.`); + switch (V.assistant.appearance) { + case "monstergirl": + r.push(`The regular monster ${girlA} stands behind and prods the human ${girlM} forward.`); + break; + case "shemale": + r.push(`You recognize ${hisM} function by ${hisM} glasses and because ${hisM} bimbo cock softens, halfway, while ${heM} addresses you on economic matters.`); + break; + case "amazon": + r.push(`${HeM} illustrates a small group of gossiping tribeswomen that fades away as ${heM} leaves them and approaches you.`); + break; + case "businesswoman": + r.push(`The junior business ${womanM} adopts a shy posture when addressing you directly, as if unsuccessfully concealing a workplace crush.`); + break; + case "goddess": + r.push(`The demigoddess portrait arrives in a glittery cloud of dust, wearing winged shoes.`); + break; + case "schoolgirl": + r.push(`Both`); + if (girlA === girlM) { + r.push(`school${girlA}s`); + } else { + r.push(`students`); + } + r.push(`are sitting knee to knee; the nerdy one hands the other a folded note. "Pass it on," ${heM} stage whispers.`); + if (V.assistant.name === "your personal assistant") { + r.push(`Your regular assistant`); + } else { + r.push(`${V.assistant.name}`); + } + r.push(`rolls ${hisA} eyes.`); + break; + case "hypergoddess": + r.push(`The demigoddess portrait arrives in a glittery cloud of dust, wearing winged shoes and a noticeable roundness in ${hisM} middle.`); + break; + case "loli": + r.push(`The chubby, glasses-wearing ${loliM} arrives holding a neatly folded note addressed to you.`); + break; + case "preggololi": + r.push(`The chubby, glasses-wearing ${loliM} arrives holding a hastily written note addressed to you. ${HeM} seems kind of winded, with a suspicious stain in ${hisM} panties under ${hisM} pussy.`); + break; + case "fairy": + case "pregnant fairy": + r.push(`The older fairy flutters into view before, curtseys, and holds out a rolled piece of parchment addressed to you.`); + break; + case "normal": + r.push(`${HisM} symbol lights up in regular green pulses while ${heM} waits for your attention.`); + break; + case "angel": + r.push(`The short haired angel lands before you, a rolled piece of parchment under ${hisM} arm.`); + break; + case "cherub": + r.push(`The short haired cherub flutters before you holding a rolled piece of parchment in ${hisM} hands.`); + break; + case "incubus": + r.push(`The regular incubus stands behind and prods the human ${girlM} forward with ${hisA} dick.`); + break; + case "succubus": + r.push(`The regular succubus stands behind and pushes the human ${girlM} forward.`); + break; + case "imp": + r.push(`The short haired imp flaps before you holding a rolled piece of parchment in ${hisM} hands.`); + break; + case "witch": + r.push(`The apprentice's apprentice arrives before you; a message begins playing the moment ${heM} opens ${hisM} mouth.`); + break; + case "ERROR_1606_APPEARANCE_FILE_CORRUPT": + r.push(`The creature finishes forcing eggs into the human ${girlM}, leaving ${himM} to stagger towards you clutching a crumpled letter in one hand and struggling to hold back the eggs with the other.`); + } + } else { + r.push(`${capFirstChar(V.assistant.name)} appears on a wallscreen as you're going about your business.`); + switch (V.assistant.appearance) { + case "monstergirl": + r.push(`He's looking unusually businesslike, with ${hisA} tentacle hair restrained in a bun.`); + break; + case "loli": + r.push(`He's looking unusually businesslike, withdrawn deep in thought.`); + break; + case "preggololi": + r.push(`He's looking unusually businesslike, withdrawn deep in thought.`); + break; + case "shemale": + r.push(`He's looking unusually businesslike, with ${hisA} perpetually erect dick going untended, for once.`); + break; + case "amazon": + r.push(`He's looking unusually businesslike, and is doing sums on a primitive little abacus.`); + break; + case "businesswoman": + r.push(`He has a clipboard pressed against ${hisA} generous bosom, and peers at you over the tops of ${hisA} spectacles.`); + break; + case "fairy": + r.push(`He's looking unusually businesslike, wearing a tiny business suit with an opening in the back for ${hisA} wings to come out.`); + break; + case "pregnant fairy": + r.push(`He's looking unusually businesslike, wearing a tiny business suit open in the front to let ${hisA} swollen belly out and another opening in the back for ${hisA} wings to come out.`); + break; + case "goddess": + case "hypergoddess": + r.push(`He's looking unusually businesslike, with ${hisA} hands clasped behind ${hisA} back and pivoting one foot.`); + break; + case "schoolgirl": + r.push(`He's looking unusually businesslike, and has a scribbled note in ${hisA} hand.`); + break; + case "angel": + r.push(`He's looking unusually businesslike; deep in thought with ${hisA} hands together in front of ${himA}.`); + break; + case "cherub": + r.push(`He's looking unusually businesslike, reading a newspaper titled "Heaven's Post".`); + break; + case "incubus": + r.push(`He's looking unusually businesslike, with ${hisA} typically erect dick flaccid for once.`); + break; + case "succubus": + r.push(`He's looking unusually businesslike, wearing a slutty business suit, glasses and ${hisA} hair in a tight bun. A slight buzzing can be heard from under ${hisA} skirt.`); + break; + case "imp": + r.push(`He's looking unusually businesslike, reading a list titled "Hell's Holes".`); + break; + case "witch": + r.push(`He's looking unusually businesslike, nose first in an a book title "Economics and You".`); + break; + case "ERROR_1606_APPEARANCE_FILE_CORRUPT": + r.push(`He's looking unusually businesslike, wearing an ill-fitted business suit. ${HisA} blouse buttons pop off as ${hisA} belly swells grotesquely, before the object within ${himA} begins steadily moving upwards.`); + break; + default: + r.push(`${HisA} symbol spins for attention.`); + } + + r.push(`"${properTitle()}, I have a news item that may be of business interest," ${heA}`); + switch (V.assistant.appearance) { + case "monstergirl": + case "normal": + r.push(`informs you.`); + break; + case "shemale": + r.push(`says seriously.`); + break; + case "amazon": + r.push(`says warmly.`); + break; + case "businesswoman": + r.push(`says diffidently.`); + break; + case "goddess": + r.push(`announces.`); + break; + case "schoolgirl": + r.push(`reads aloud.`); + break; + case "hypergoddess": + r.push(`announces between ${hisA} children's kicking.`); + break; + case "loli": + case "preggololi": + r.push(`says cutely.`); + break; + case "fairy": + case "pregnant fairy": + r.push(`says excitedly.`); + break; + case "angel": + r.push(`calmly states.`); + break; + case "cherub": + case "imp": + r.push(`says enthusiastically.`); + break; + case "incubus": + r.push(`starts, pauses to play with ${himselfA}, and continues.`); + break; + case "succubus": + r.push(`says between overly loud moans.`); + break; + case "witch": + r.push(`states, finishes the page, and snaps ${hisA} fingers. He grunts, reaches up ${hisA} skirt and pulls out a message for you. Seems it didn't arrive as planned.`); + break; + case "ERROR_1606_APPEARANCE_FILE_CORRUPT": + r.push(`says, ${hisA} throat bulging as the egg containing the message passes out ${hisA} mouth.`); + } + } + } else { + r.push(`Your`); + if (V.assistant.market) { + r.push(`market`); + } else { + r.push(`personal`); + } + r.push(`assistant's symbol appears on a wallscreen as you're going about your business. ${HeA} spins for your attention. "${properTitle()}, I have a news item that may be of business interest," ${heA} says.`); + } + App.Events.addParagraph(node, r); + r = []; + + /* The events reducing slave prices are all supply sided. Without events reducing demand this is a little unbalanced. A minor issue */ + if (fluctuationType === "revel") { + r.push(`Something is happening in one of the Free Cities' richest arcologies. It's not clear what, exactly, it is, since its owner is making skillful use of the arcology's advanced surveillance and media systems to keep its internal affairs quite secret. The truth will get out eventually, and it's probably not going to do much for old world opinions of the Free Cities. After all, cheap slaves go into that arcology at a prodigious rate, and they don't seem to ever come out again. The unexpected demand for slaves, any slaves, has produced a temporary tightening of the entire slave market. Projections suggest price increases of up to five percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a great time to sell stock, and a bad time to buy. <span class="noteworthy">The market price of slaves has increased.</span>`); + V.menialDemandFactor += 12000; + } else if (fluctuationType === "tainted drugs") { + r.push(`The Free Cities are anarcho-capitalist paradises — or 'paradises,' depending on one's station and assets. You can't complain personally, as one of the Free Cities' richest citizens, master of your own arcology and owner of sexual slaves. Unfortunately quite a few slaves in the markets are in a position to complain today, as are their owners. Many slave markets use long-lasting stimulants to pep their wares up for auction; dull-eyed slaves earn low bids. Corner-cutting at one of the major suppliers of these stimulants led to a number of slaves being prepared for auction being damaged today. Relatively few were permanently lost, but slaves are going to be a little scarce for a while, which will drive up the going rate. Projections suggest increases of up to five percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a great time to sell stock, and a bad time to buy. <span class="noteworthy">The market price of slaves has increased.</span>`); + V.menialSupplyFactor -= 12000; + } else if (fluctuationType === "antislavery terrorism") { + r.push(`Antislavery activism in the old world has grown to match the spread of slavery in the Free Cities. Unfortunately for the activists, they are confronted with a fundamental problem: the independence of the Free Cities. There is very little they can do without resorting to violence, and so, predictably, they often do. A major slave induction center in one of the more open Free Cities has just suffered a suicide bombing. The actual damage was slight, but a wave of increased import security is sweeping the Free Cities in reaction to the incident. Slave prices will be driven up by the cost of checking imported merchandise for explosive devices until the market adjusts. Projections suggest price increases of up to five percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a great time to sell stock, and a bad time to buy. <span class="noteworthy">The market price of slaves has increased.</span>`); + V.menialSupplyFactor -= 12000; + } else if (fluctuationType === "new free city") { + r.push(`New Free Cities arise unpredictably. They require either carving out a slice of the old world, emancipating it from whichever inattentive or corrupt country previously owned the land, or reclaiming new land from barren or uninhabitable areas, efforts which are often kept secret. The unpredictable happened today; the world has a new Free City. As usual, immigration rights are being offered cheaply to deserving persons. Many of the remaining rich and talented of the old world are staking claims in the new city, and they'll be buying slaves when they get to their new home. It's a sellers' market out there; projections show the price of slaves rising as much as ten percent in the short term. There will be no immediate impact on you or your slaves, but the coming weeks will be a great time to sell stock, and a bad time to buy. <span class="noteworthy">The market price of slaves has increased.</span>`); + V.menialDemandFactor += 20000; + } else if (fluctuationType === "speculation") { + r.push(`The Free Cities are almost totally unregulated. Prices and interest rates can spike and plummet with speeds not seen since the South Sea Bubble, and for the most silly or corrupt of reasons. Today, it's the latter. A massive attempt to rig the slave market was uncovered this morning. Ultimately, the culprits were caught and much of the damage reversed, but confidence in the marketplace has been shaken. Many great slave vendors are holding onto their stock until they're sure the water's calm again. It's a sellers' market out there; projections show the price of slaves rising as much as ten percent in the short term. There will be no immediate impact on you or your slaves, but the coming weeks will be a great time to sell stock, and a bad time to buy. <span class="noteworthy">The market price of slaves has increased.</span>`); + V.menialSupplyFactor -= 20000; + } else if (fluctuationType === "medical breakthrough") { + r.push(`There has been a breakthrough in gene therapy. More accurately, there was a breakthrough in gene therapy several years ago — you already knew all about it, and some of the more advanced slave medical upgrades available to you use the technology. However, it's finally gotten out of the prototype stage, and is becoming available to the Free Cities middle class, citizens with one or two slaves. The average citizen is more able today than he was yesterday to turn his chattel housekeeper into the girl he's always dreamed of. Aspirational stuff like this always causes a major price shock. It's a sellers' market out there; projections show the price of slaves rising as much as ten percent in the short term. There will be no immediate impact on you or your slaves, but the coming weeks will be a great time to sell stock, and a bad time to buy. <span class="noteworthy">The market price of slaves has increased.</span>`); + V.menialDemandFactor += 20000; + } else if (fluctuationType === "bankruptcy") { + r.push(`The economy of the Free Cities is a rough-and-tumble place. The absence of old world regulations and institutions, and the often gold-rush atmosphere of the new cities, lead to fortunes being made and lost overnight. Last night, one of the Free Cities' greatest fortunes was lost. A great slave trading house unexpectedly went bankrupt, and its huge stable of slaves are being sold at fire-sale prices. The unforeseen sell off is driving down the market price of slaves all across the Free Cities. Projections show a short-term price drop of up to five percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span>`); + V.menialSupplyFactor += 12000; + } else if (fluctuationType === "refugee boat") { + r.push(`Periodic refugee crises sweep the old world, and sometimes the human flotsam shaken loose from its moorings in the old world is brought up on the shores of the Free Cities. This week, that was no metaphor. A floating Free City has been inundated by refugees in boats. Naturally, the boats have been discarded and the refugees enslaved. It is unclear whether they somehow did not know that this was their inevitable fate, or their lot in the old world was so desperate that they were willing to accept it. Projections show a short-term slave price drop of up to five percent as the market digests the influx. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span>`); + V.menialSupplyFactor += 12000; + } else if (fluctuationType === "arcology change") { + r.push(`All across the Free Cities, arcology owners are experimenting with new society models and new ways of enforcing them. A nearby arcology has just undergone a major internal struggle as its owner forced through a radical program of changes and harsh measures to enforce them. All but a handful of its inhabitants have been enslaved and placed under the control of a chosen few. With harems of hundreds and little experience or infrastructure to manage them, the new overlords are selling off stock to raise funds to make the transition. Projections show a short-term price drop of up to five percent as they flood the market with mediocre slaves. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span>`); + V.menialSupplyFactor += 12000; + } else if (fluctuationType === "war") { + r.push(`The old world outside the Free Cities took another step towards its final decline today. A relatively prosperous third world city fell to a regional warlord, and it seems the remaining great powers lack either the money or the will to do anything about it. The victors seem to be following the standard procedure for modern conquerors. Anything valuable, they steal. Among the population, they recruit the willing, shoot the unwilling, and enslave everyone else. The slave markets are going to be glutted with new stock soon. Projections show a short-term price drop of up to ten percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span>`); + V.menialSupplyFactor += 20000; + } else if (fluctuationType === "empty prisons") { + r.push(`A small, impoverished old world country defaulted on its currency today. Its beleaguered government is taking every available step to raise funds. Among other things, it has sold every inmate in its prisons who would fetch a price worth the trouble of sale into Free Cities slavery. Though most of the influx is going to be of abominably low quality, the sudden addition of so much new meat is going to have a big impact on the slave economy. Projections show a short-term price drop of up to ten percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span>`); + V.menialSupplyFactor += 20000; + } else if (fluctuationType === "unemployment") { + r.push(`A leading old world nation has just suffered a major economic downturn. Old world nations suffer economic downturns all the time, of course, but to those with interests in the slave market, news like this can be very important. Slave market shocks from catastrophes get all the headlines, but a change that affects millions will often be more impactful. As unemployment in the old world rises, the number of people faced with the choice between starvation and voluntary enslavement rises. Social safety nets just aren't what they used to be. Projections show a short-term slave price drop of up to ten percent due to the sharp increase in desperate people immigrating to the Free Cities for enslavement. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span>`); + V.menialSupplyFactor += 20000; + } else if (fluctuationType === "anti-slavery coup") { + r.push(`For months there were strong indications that an old world nation was quietly taking steps towards legalizing slavery. The market began to anticipate a serious increase in the demand for slaves in earnest but this week a month of protests against the country's leaders ended in a violent coup. The new government, claiming to only follow the will of the people, has made several promises, including a very vocal rebuke of even the slightest possibility of legal slavery within their borders. The slave market was shocked to find the previous government to be so weak and even more shocked at how unwilling the new one is to accept the times we live in. The panicked market quickly adjusted to greatly lowered slave demand and projections show a short-term price drop of up to ten percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span>`); + V.menialDemandFactor -= 20000; + } else if (fluctuationType === "hostilities ended") { + r.push(`The Free Cities make a real effort to avoid armed conflict, especially amongst themselves, as such endeavors almost never have any real winners. But tensions grew so high in their trade conflict that the likelihood of a full blown war between two Free Cities became not just a possibility but a near certainty for months. As skirmishes commenced and slave armies were quickly drilled for action on both sides, the slave market anticipated a boost to demand as soon as the fighting intensified. Miraculously, cooler heads prevailed and the Free Cities agreed to disband their armies. While many people sighed with relief the slave market was forced into a shock adjustment, projections show a short-term price drop of up to five percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span>`); + V.menialDemandFactor -= 12000; + } + V.menialDemandFactor = Math.clamp(V.menialDemandFactor, -50000, 50000); + V.slaveCostFactor = menialSlaveCost()/1000; + App.Events.addParagraph(node, r); + } +}; diff --git a/src/events/REM/remMerger.js b/src/events/REM/remMerger.js new file mode 100644 index 0000000000000000000000000000000000000000..73fbfca2ea581f35774028d36ed65f66d99252b4 --- /dev/null +++ b/src/events/REM/remMerger.js @@ -0,0 +1,71 @@ +App.Events.REMMerger = class REMMerger extends App.Events.BaseEvent { + eventPrerequisites() { + return [ + () => V.corp.Cash > 50000 + ]; + } + + execute(node) { + V.nextButton = "Continue"; + V.nextLink = "RIE Eligibility Check"; + + const slaveCompany = App.Corporate.divisionList + .filter(div => div.founded && div.hasMergers) + .map (div => div.mergerChoices.map((merger, index) => ({merger, index, division:div}))) + .flat (); + const maxCompanies = Math.trunc(Math.log2(App.Corporate.divisionList.filter(div => div.founded).length)) + 1; + const numCompanies = random(1, maxCompanies); + + const companies = []; + for (let _index = 0; _index < numCompanies; ++_index) { + companies.push(slaveCompany.pluck()); + } + const assistant = V.assistant.market ? "your market assistant" : V.assistant.name; + + App.UI.DOM.appendNewElement("p", node, `${capFirstChar(assistant)} constantly combs business records, tax receipts and the media for leads on opportunities for your corporation to take advantage of. Small businesses go under all the time, and with a large amount of cash on hand, your corporation can afford to step in and acquire them. This week, ${assistant} has found ${numberWithPlural(numCompanies, "troubled organization")} you could easily fold into your corporation.`); + + if (companies.length === 1) { + const company = companies[0]; + App.UI.DOM.appendNewElement("div", node, `This week you come across ${company.merger.text.trouble}`, "majorText"); + } else { + for (const [index, company] of companies.entries()) { + App.UI.DOM.appendNewElement("div", node, `The ${ordinalSuffixWords(index + 1)} is ${company.merger.text.trouble}`, "majorText"); + } + } + + const choices = []; + + for (const company of companies) { + choices.push(new App.Events.Result(`Absorb the ${company.merger.name}`, () => absorb(company))); + } + App.Events.addResponses(node, choices); + + function absorb(company) { + const frag = new DocumentFragment(); + let r = []; + r.push(`You quickly acquire the ${company.merger.name} ${company.merger.text.acquire}`); + + const devCount = company.merger.result.development; + const slaveCount = company.merger.result.slaves; + if (devCount !== null) { + company.division.developmentCount += devCount; + } + if (slaveCount !== null) { + company.division.activeSlaves += slaveCount; + } + const cost = (company.merger.cost || 50) * 1000; + if (devCount !== null && slaveCount !== null) { + App.Corporate.chargeAsset(cost / 2, "development"); + App.Corporate.chargeAsset(cost / 2, "slaves"); + } else if (devCount !== null) { + App.Corporate.chargeAsset(cost, "development"); + } else if (slaveCount !== null) { + App.Corporate.chargeAsset(cost, "slaves"); + } else { + r.push(`<span class="red">ERROR! No changes to the corporation are made!</span>`); + } + App.Events.addParagraph(frag, r); + return frag; + } + } +}; diff --git a/src/events/RESS/meanGirls.js b/src/events/RESS/meanGirls.js index c0924c6b42634e0812644692432a2ff00281b05b..cf8fc66322e5845745c231400f40fa3e00ed9a97 100644 --- a/src/events/RESS/meanGirls.js +++ b/src/events/RESS/meanGirls.js @@ -316,7 +316,7 @@ App.Events.RESSMeanGirls = class RESSMeanGirls extends App.Events.BaseEvent { } else { r.push(`eaten out`); } - r.push(`by one sobbing rich bitch while ${he} forces another to spank${his3} friend's pussy.`); + r.push(`by one sobbing rich bitch while ${he} forces another to spank ${his3} friend's pussy.`); seX(newSlaves[0], "oral", eventSlave, "penetrative", 20); seX(newSlaves[1], "oral", eventSlave, "penetrative", 20); seX(newSlaves[2], "oral", eventSlave, "penetrative", 20); diff --git a/src/events/assistant/assistantBody.js b/src/events/assistant/assistantBody.js index 1c5978053533aabfa70d437954b12925a4ed6d6d..380cffe958c41577a29d152a062971ac6aefad4f 100644 --- a/src/events/assistant/assistantBody.js +++ b/src/events/assistant/assistantBody.js @@ -100,7 +100,7 @@ App.Events.assistantBody = class assistantBody extends App.Events.BaseEvent { r.push(`${HeA} hops up and down clutching a virtual printout of the report, ${hisA} huge breasts splattering milk everywhere and invoking a storm of kicks from ${hisA} many children.`); break; case "hypergoddess": - r.push(`${HeA} struggles to hop up and down while clutching a virtual printout of the report.After a single hop, ${heA} is dragged to the ground by labor pains to give birth to a number of over excited babies.`); + r.push(`${HeA} struggles to hop up and down while clutching a virtual printout of the report. After a single hop, ${heA} is dragged to the ground by labor pains to give birth to a number of over excited babies.`); break; case "loli": r.push(`${HeA} hops up and down excitedly clutching a virtual printout of the report; ${heA} doesn't seem to be interested in stopping.`); @@ -135,7 +135,7 @@ App.Events.assistantBody = class assistantBody extends App.Events.BaseEvent { r.push(`"Sorry, sorry. So could I...?"`); App.Events.addParagraph(node, r); r = []; - r.push(`You look over the details of the report. It would require another rather expansive, and expensive, upgrade to ${hisA} systems, as well as a body to host ${himA} and the receiver implant.It looks like ${heA} wouldn't lose any functionality, though you aren't sure what ${heA} would do with a body; it may be fun to find out.`); + r.push(`You look over the details of the report. It would require another rather expansive, and expensive, upgrade to ${hisA} systems, as well as a body to host ${himA} and the receiver implant. It looks like ${heA} wouldn't lose any functionality, though you aren't sure what ${heA} would do with a body; it may be fun to find out.`); App.Events.addParagraph(node, r); diff --git a/src/events/assistant/assistantName.js b/src/events/assistant/assistantName.js index 0035fe38f1373bafe2061ecb9a2cb581e0a0425c..006ba0c44da216c7a4de77691797c2df92268eef 100644 --- a/src/events/assistant/assistantName.js +++ b/src/events/assistant/assistantName.js @@ -90,7 +90,7 @@ App.Events.assistantName = class assistantName extends App.Events.BaseEvent { r.push(`${HeA} has ${hisA} legs crossed and ${hisA} hands clasped behind ${himA}, and is turning ${hisA} body from side to side in girlish nervousness.`); break; default: - r.push(`The lines of${hisA} symbol are thin, and it is rotating much more slowly than normal.`); + r.push(`The lines of ${hisA} symbol are thin, and it is rotating much more slowly than normal.`); } r.push(`"${properTitle()}," ${heA} says softly, "may I ask you something?" You nod. ${HeA}`); switch (V.assistant.appearance) { @@ -138,7 +138,7 @@ App.Events.assistantName = class assistantName extends App.Events.BaseEvent { r.push(`squares ${hisA} shoulders, pushes ${hisA} breasts together,`); break; case "witch": - r.push(`squares${hisA} shoulders, gathers up all ${hisA} confidence,`); + r.push(`squares ${hisA} shoulders, gathers up all ${hisA} confidence,`); break; case "ERROR_1606_APPEARANCE_FILE_CORRUPT": r.push(`begins puffing up`); @@ -225,7 +225,7 @@ App.Events.assistantName = class assistantName extends App.Events.BaseEvent { r.push(`${HeA} collapses to the ground in tears. "You've made me happier than correctly casting a spell ever could, ${properTitle()}." ${HeA} wipes ${hisA} face. "I promise to try harder than ever for you!" ${HeA} vows.`); break; case "ERROR_1606_APPEARANCE_FILE_CORRUPT": - r.push(`${HeA} practically explodes.You have no idea what you are looking at, but it's likely happy.`); + r.push(`${HeA} practically explodes. You have no idea what you are looking at, but it's likely happy.`); break; case "schoolgirl": r.push(`${HeA} was on the verge of tears already, and begins to cry. "Th-thank you, ${properTitle()}. I love you," ${heA} blubbers inelegantly. "It's just so, like, you know." ${HeA} waves ${hisA} hand in apology for ${hisA} inability to express ${himselfA}.`); diff --git a/src/events/assistant/assistantSP.js b/src/events/assistant/assistantSP.js index 2e05964e0f9bc99df3f5537e89f6ce99e28f6265..e1c2b405b8c293769ae117cdd00b90860a14371a 100644 --- a/src/events/assistant/assistantSP.js +++ b/src/events/assistant/assistantSP.js @@ -57,7 +57,7 @@ App.Events.assistantSP = class assistantSP extends App.Events.BaseEvent { if (V.seeDicks !== 0) { App.Events.addParagraph(node, r); r = []; - r.push(`${HeA} claps ${hisA} hands, and ${hisA} muscles fade, but not all the way.The tattoos vanish, and ${hisA} loincloth turns into a slutty bikini. ${HisA} breasts and behind grow, ${hisA} lips swell, and ${hisA} hair turns blonde.Finally, ${heA} grows a dick, and it keeps growing until it hangs past ${hisA} knees: or it would, if it weren't so erect. "Of course," ${heA} says seductively, "I could also be a bimbo dickgirl." ${HeA} orgasms, gasping, "Last one, I promise," and changes again. ${HisA} dick shrinks, thought not very far, and then splits into two members. ${HisA} skin pales to an off-white, and ${hisA} hair goes green and starts to writhe, turning into tentacle-hair. ${HisA} forehead sprouts a pair of horns that curve back along ${hisA} head. ${HeA} grins, displaying a cute pair of fangs. "I feel monstrous," ${heA} says, and stretches luxuriantly.`); + r.push(`${HeA} claps ${hisA} hands, and ${hisA} muscles fade, but not all the way. The tattoos vanish, and ${hisA} loincloth turns into a slutty bikini. ${HisA} breasts and behind grow, ${hisA} lips swell, and ${hisA} hair turns blonde. Finally, ${heA} grows a dick, and it keeps growing until it hangs past ${hisA} knees: or it would, if it weren't so erect. "Of course," ${heA} says seductively, "I could also be a bimbo dickgirl." ${HeA} orgasms, gasping, "Last one, I promise," and changes again. ${HisA} dick shrinks, thought not very far, and then splits into two members. ${HisA} skin pales to an off-white, and ${hisA} hair goes green and starts to writhe, turning into tentacle-hair. ${HisA} forehead sprouts a pair of horns that curve back along ${hisA} head. ${HeA} grins, displaying a cute pair of fangs. "I feel monstrous," ${heA} says, and stretches luxuriantly.`); } r.push(`The character vanishes, and the symbol returns. "Ahem. What do you think, ${properTitle()}?"`); diff --git a/src/events/intro/pcBodyIntro.js b/src/events/intro/pcBodyIntro.js index 1dd639982445185ea0ed73fe42d1ceb5bc6e9023..f0c0685e1d5b4d4d8913218e86f73d849bc7778f 100644 --- a/src/events/intro/pcBodyIntro.js +++ b/src/events/intro/pcBodyIntro.js @@ -1,6 +1,6 @@ App.Intro.PCBodyIntro = function() { - V.PC.actualAge = Math.clamp(V.PC.actualAge, 14, 80); + V.PC.actualAge = Math.clamp(V.PC.actualAge, 10, 80); const el = new DocumentFragment(); let r = []; diff --git a/src/events/nonRandom/pAidInvitation.js b/src/events/nonRandom/pAidInvitation.js index b8b6118c16b1325950d0a024b9cfe950f71acf66..c395127fe7291b13fd3dbbe22fe19e0cb904e7cb 100644 --- a/src/events/nonRandom/pAidInvitation.js +++ b/src/events/nonRandom/pAidInvitation.js @@ -11,13 +11,14 @@ App.Events.pAidInvitation = class pAidInvitation extends App.Events.BaseEvent { return [ () => V.plot === 1, () => V.week >= 29, - () => !V.eventResults.aid + () => !V.eventResults.hasOwnProperty("aid") ]; } execute(node) { const trapped = []; let r = []; + V.eventResults.aid = 0; // Mark event as seen. if (V.seeDicks <= 75) { trapped.push("convent"); trapped.push("school"); diff --git a/src/events/nonRandom/rival/pRivalryActions.js b/src/events/nonRandom/rival/pRivalryActions.js index 5ba526daec55df3480f61b748302438a4a896300..87152b2a70767045fa94869be6a7f793309ea413 100644 --- a/src/events/nonRandom/rival/pRivalryActions.js +++ b/src/events/nonRandom/rival/pRivalryActions.js @@ -1893,7 +1893,7 @@ App.Events.pRivalryActions = function() { r.push(`"Looking for ${SlaveFullName(V.hostage)}? Too bad, I couldn't bear to think of you ever getting your rotten little hands on ${him}, so I sent ${him} far away. Someplace you'll never find ${him}. Bet tha"`); break; case "Multiculturalism": - r.push(`"Looking for ${SlaveFullName(V.hostage)}? Too bad, ${he} decided to martyr ${himself} for your arcology's salvation. Got fucked till ${his} body gave out. Of course I enjoyed ${him} in ${his} final moments, and don't worry, ${he} died smiling.I should hunt down more people you knew, keep our little game goi"`); + r.push(`"Looking for ${SlaveFullName(V.hostage)}? Too bad, ${he} decided to martyr ${himself} for your arcology's salvation. Got fucked till ${his} body gave out. Of course I enjoyed ${him} in ${his} final moments, and don't worry, ${he} died smiling. I should hunt down more people you knew, keep our little game goi"`); break; case "Intellectual Dependency": r.push(`"Looking for ${SlaveFullName(V.hostage)}? Too bad, ${he} ran the math and determined that the odds of me keeping ${him} through this were too low and that ${he} should go into hiding until it's safe to come back. ${He}'s a well trained ${girl} now, so I trust ${him}, and even if I did lose this war, it'd still be worth taking ${his} advice just to deny you your prize. Bet tha"`); diff --git a/src/events/nonRandom/rival/pRivalryVictory.js b/src/events/nonRandom/rival/pRivalryVictory.js index 5e21eb9c90f7eddb345d881aeb85c00903011465..fb304b30d3d1bf78731b1715fa07cbdc6da53332 100644 --- a/src/events/nonRandom/rival/pRivalryVictory.js +++ b/src/events/nonRandom/rival/pRivalryVictory.js @@ -96,7 +96,7 @@ App.Events.pRivalryVictory = function() { unlockContinue(); r.push(`You coldly decline. "That was a mistake," your rival replies, entering a computer command.`); if (V.rivalSet !== 0) { - r.push(`"All my remaining liquid assets have just been <span class="red">carefully dispersed to deny you control of my arcology.</span> You'll get nothing from me." It's true.The financial self - destruction ensures that the fiscal wreckage goes to the arcology's citizens, not you.`); + r.push(`"All my remaining liquid assets have just been <span class="red">carefully dispersed to deny you control of my arcology.</span> You'll get nothing from me." It's true. The financial self - destruction ensures that the fiscal wreckage goes to the arcology's citizens, not you.`); if (rivalArc) { updateArc(); if (rivalArc.FSSupremacist > 20) { diff --git a/src/events/randomEvent.js b/src/events/randomEvent.js index 1fe5b527a710d9baf4dcc9e0109284b4ac0ad10f..b3c87838c35902bb5544d9515710d44d026fd408 100644 --- a/src/events/randomEvent.js +++ b/src/events/randomEvent.js @@ -95,7 +95,18 @@ App.Events.getIndividualEvents = function() { new App.Events.rePregInventorShowOff(), new App.Events.rePregInventorFCTV(), - new App.Events.REStandardPunishment() + new App.Events.REStandardPunishment(), + new App.Events.RERebels(), + + new App.Events.REAnalPunishment(), + new App.Events.REShowerPunishment(), + + // Relationship Events + new App.Events.REDevotedMotherDaughter(), + new App.Events.REResistantMotherDaughter(), + new App.Events.RESiblingRevenge(), + new App.Events.RERelationshipAdvice(), + new App.Events.RESlaveMarriage(), ]; }; @@ -141,6 +152,15 @@ App.Events.getNonindividualEvents = function() { new App.Events.RESEndowment(), new App.Events.RESMove(), new App.Events.REBoomerang(), + new App.Events.REMilfTourist(), + new App.Events.REAWOL(), + new App.Events.REPokerNight(), + new App.Events.RELegendaryFormerAbolitionist(), + new App.Events.RELegendaryCow(), + new App.Events.RELegendaryBalls(), + new App.Events.RELegendaryWhore(), + new App.Events.RELegendaryEntertainer(), + new App.Events.RELegendaryWomb(), // recFS new App.Events.recFSArabianRevivalist(), @@ -202,6 +222,10 @@ App.Events.getNonindividualEvents = function() { new App.Events.JESlaveDisputeSlaveTraining(), new App.Events.JESlaveDisputeSlaveDeal(), new App.Events.JESlaveVirginityDeal(), + + // Random Market Events + new App.Events.REMFluctuations(), + new App.Events.REMMerger(), ]; }; diff --git a/src/events/scheduled/pitFightLethal.js b/src/events/scheduled/pitFightLethal.js index 5674030d06ca5bf51de0b89b2813b61be4f8fe7d..ec584caf02e26a8d284042b727b2498f595d4d56 100644 --- a/src/events/scheduled/pitFightLethal.js +++ b/src/events/scheduled/pitFightLethal.js @@ -19,22 +19,23 @@ App.Facilities.Pit.lethalFight = function(fighters) { console.log(winner, loser); } - frag.append( - intro(), - fighterDeadliness(getSlave(fighters[0])), - !V.pit.animal ? fighterDeadliness(getSlave(fighters[1])) : '', - fight(), - postFight(), - ); + intro(frag); + fighterDeadliness(frag, getSlave(fighters[0])); + if (!V.pit.animal) { + fighterDeadliness(frag, getSlave(fighters[1])); + } + fight(frag); + postFight(frag); V.pit.slaveFightingBodyguard = null; return frag; - function intro() { - const introDiv = document.createElement("div"); - + /** + * @param {DocumentFragment} parent + */ + function intro(parent) { const fighterOne = getSlave(fighters[0]); const fighterTwo = getSlave(fighters[1]) || null; @@ -44,13 +45,15 @@ App.Facilities.Pit.lethalFight = function(fighters) { const r = []; - introDiv.classList.add("pit-section"); - - App.Events.drawEventArt(introDiv, fighters.map(id => getSlave(id)), "no clothing"); + App.Events.drawEventArt(parent, fighters.map(id => getSlave(id)), "no clothing"); const anAnimal = animal ? `${animal.articleAn} ${animal.name}.` : null; - r.push(`This week's fight is between`, App.UI.DOM.slaveDescriptionDialog(fighterOne), `and`, animal ? anAnimal : App.UI.DOM.combineNodes(contextualIntro(fighterOne, fighterTwo, "DOM"), ".")); + r.push(`This week's fight is between`, + App.UI.DOM.slaveDescriptionDialog(fighterOne), `and`, + animal + ? anAnimal + : App.UI.DOM.combineNodes(contextualIntro(fighterOne, fighterTwo, "DOM"), ".")); if (V.pit.audience === "none") { r.push(`You are alone above the pit, left to watch them kill and die in private.`); @@ -78,25 +81,22 @@ App.Facilities.Pit.lethalFight = function(fighters) { r.push(`You review the rules — the slave will use ${his} choice of swords, and the fight will be to the death. If ${he} wins, ${he} will earn two complete days of rest, not to mention continued life. You take a moment to look over ${fighterOne.slaveName} one more time before giving the word. After all, it might be the last time you'll see ${him} alive.`); } else { - r.push(`You review the rules — the combatants will use their choice of swords, and the fight will be to the death, with both fighters executed if no decision is reached. The winner will earn two complete days of rest, not to mention continued life. You take a moment to look over your fighters one more time before giving the word. After all, this is likely the last time you'll see one of them alive.`); + r.push(`You review the rules — the combatants will use their choice of swords, and the fight will be to the death, with both fighters executed if no decision is reached. The winner will earn two complete days of rest, not to mention continued life. You take a moment to look over your fighters one more time before giving the word. After all, this is likely the last time you'll see one of them alive.`); } - App.Events.addNode(introDiv, r); - - return introDiv; + App.Events.addParagraph(parent, r); } - /** @param {App.Entity.SlaveState} fighter */ - function fighterDeadliness(fighter) { - const deadlinessDiv = document.createElement("div"); - + /** + * @param {DocumentFragment} parent + * @param {App.Entity.SlaveState} fighter + */ + function fighterDeadliness(parent, fighter) { const {he, his, him, himself, He, His} = getPronouns(fighter); const fighterDeadliness = deadliness(fighter); const r = []; - deadlinessDiv.classList.add("pit-section"); - r.push( confidence(), willingness(), @@ -115,10 +115,7 @@ App.Facilities.Pit.lethalFight = function(fighters) { prosthetics(), ); - App.Events.addNode(deadlinessDiv, r); - - return deadlinessDiv; - + App.Events.addParagraph(parent, r); function confidence() { if (fighter.fetish === "mindbroken") { @@ -321,9 +318,10 @@ App.Facilities.Pit.lethalFight = function(fighters) { } } - function fight() { - const fightDiv = App.UI.DOM.makeElement('div', ``, ["pit-section"]); - + /** + * @param {DocumentFragment} parent + */ + function fight(parent) { const r = []; r.push(`In any case, ${animal ? `the slave and the ${animal.name} have both` : `both of the slaves`} been dosed with aggression enhancers and inhibition blockers; they'll fight to kill.`); @@ -347,7 +345,7 @@ App.Facilities.Pit.lethalFight = function(fighters) { repX(1000, "pit", winner); } } else if (winner.muscles) { - r.push(`${winner.slaveName} is so massively muscular that ${he}'s actually impeded by ${his} lack of speed and flexibility. The ${animal.species} is suitably cautious, and it does its best to avoid ${his} sword. The two go back and forth for a while – the slave slashing and swinging, the animal leaping out of the way. ${winner.slaveName} finally manages to get the better of the ${animal.species}, though, and manages to catch the tip of ${his} sword on the animal's leg. With a loud ${animal.type === 'canine' ? `yelp`: animal.type === 'hooved' ? `whinny` : `howl`}, the ${animal.species} stumbles back, giving the slave a chance to bring ${his} sword down in an overhead swing, nearly removing the ${animal.species}'s head.`); + r.push(`${winner.slaveName} is so massively muscular that ${he}'s actually impeded by ${his} lack of speed and flexibility. The ${animal.species} is suitably cautious, and it does its best to avoid ${his} sword. The two go back and forth for a while – the slave slashing and swinging, the animal leaping out of the way. ${winner.slaveName} finally manages to get the better of the ${animal.species}, though, and manages to catch the tip of ${his} sword on the animal's leg. With a loud ${animal.type === 'canine' ? `yelp` : animal.type === 'hooved' ? `whinny` : `howl`}, the ${animal.species} stumbles back, giving the slave a chance to bring ${his} sword down in an overhead swing, nearly removing the ${animal.species}'s head.`); if (V.pit.audience === 'paid') { r.push(`The audience is awestruck by the blind ${girl}'s triumph, and your`, App.UI.DOM.makeElement('span', `cut of the betting`, ["cash", "inc"]), ` is enormous.`); @@ -661,13 +659,13 @@ App.Facilities.Pit.lethalFight = function(fighters) { } } - App.Events.addNode(fightDiv, r); - - return fightDiv; + App.Events.addParagraph(parent, r); } - function postFight() { - const postFightDiv = document.createElement("div"); + /** + * @param {DocumentFragment} parent + */ + function postFight(parent) { const mindbrokenSpan = App.UI.DOM.makeElement("span", `no longer capable`, "red"); const experienceSpan = App.UI.DOM.makeElement("span", `learned basic combat skills.`, ["improvement"]); @@ -813,9 +811,7 @@ App.Facilities.Pit.lethalFight = function(fighters) { removeSlave(loser); } - App.Events.addNode(postFightDiv, r); - - return postFightDiv; + App.Events.addParagraph(parent, r); } diff --git a/src/events/scheduled/pitFightNonlethal.js b/src/events/scheduled/pitFightNonlethal.js index 7818d1d4784787579b04cdd10f91bbe33a373e5b..ade9a1abc3a04ca64252bd4c64a2b436c6b3b6ea 100644 --- a/src/events/scheduled/pitFightNonlethal.js +++ b/src/events/scheduled/pitFightNonlethal.js @@ -22,21 +22,24 @@ App.Facilities.Pit.nonlethalFight = function(fighters) { console.log(winner, loser); } - frag.append( - intro(), - fighterDeadliness(getSlave(fighters[0])), - !V.pit.animal ? fighterDeadliness(getSlave(fighters[1])) : '', - fight(), - postFight(), - ); + intro(frag); + fighterDeadliness(frag, getSlave(fighters[0])); + if (!V.pit.animal) { + fighterDeadliness(frag, getSlave(fighters[1])); + } + fight(frag); + postFight(frag); return frag; - // TODO: update to use "run" if animal - function intro() { - const introDiv = document.createElement("div"); - + // + /** + * TODO: update to use "run" if animal + * + * @param {DocumentFragment} parent + */ + function intro(parent) { const fighterOne = getSlave(fighters[0]); const fighterTwo = getSlave(fighters[1]) || null; @@ -46,16 +49,15 @@ App.Facilities.Pit.nonlethalFight = function(fighters) { const r = []; - introDiv.classList.add("pit-section"); - - App.Events.drawEventArt(introDiv, fighters.map(id => getSlave(id)), "no clothing"); + App.Events.drawEventArt(frag, fighters.map(id => getSlave(id)), "no clothing"); const anAnimal = animal ? `${animal.articleAn} ${animal.name}` : null; if (animal) { r.push(`This week ${anAnimal} is going to try to use ${fighterOne.slaveName}.`); } else { - r.push(`This week's fight is between`, App.UI.DOM.slaveDescriptionDialog(fighterOne), `and`, App.UI.DOM.combineNodes(contextualIntro(fighterOne, fighterTwo, "DOM"), ".")); + r.push(`This week's fight is between`, App.UI.DOM.slaveDescriptionDialog(fighterOne), `and`, + App.UI.DOM.combineNodes(contextualIntro(fighterOne, fighterTwo, "DOM"), ".")); } if (animal) { @@ -115,22 +117,19 @@ App.Facilities.Pit.nonlethalFight = function(fighters) { r.push(`and earn two complete days of rest. You take a moment to look over your fighters before giving the word.`); } - App.Events.addNode(introDiv, r); - - return introDiv; + App.Events.addParagraph(parent, r); } - /** @param {App.Entity.SlaveState} fighter */ - function fighterDeadliness(fighter) { - const deadlinessDiv = document.createElement("div"); - + /** + * @param {DocumentFragment} parent + * @param {App.Entity.SlaveState} fighter + */ + function fighterDeadliness(parent, fighter) { const {he, his, him, himself, He, His} = getPronouns(fighter); const fighterDeadliness = deadliness(fighter); const r = []; - deadlinessDiv.classList.add("pit-section"); - r.push( confidence(), skill(), @@ -149,10 +148,7 @@ App.Facilities.Pit.nonlethalFight = function(fighters) { willingness(), ); - App.Events.addNode(deadlinessDiv, r); - - return deadlinessDiv; - + App.Events.addParagraph(parent, r); function confidence() { if (fighter.fetish === "mindbroken") { @@ -345,9 +341,10 @@ App.Facilities.Pit.nonlethalFight = function(fighters) { } } - function fight() { - const fightDiv = App.UI.DOM.makeElement("span", null, ["pit-section"]); - + /** + * @param {DocumentFragment} parent + */ + function fight(parent) { const r = []; if (animal) { @@ -397,7 +394,15 @@ App.Facilities.Pit.nonlethalFight = function(fighters) { const loserDeadliness = deadliness(loser); const {he, his, him, himself, girl, He} = getPronouns(winner); - const {he: he2, his: his2, him: him2, himself: himself2, girl: girl2, He: He2, His: His2} = getPronouns(loser); + const { + he: he2, + his: his2, + him: him2, + himself: himself2, + girl: girl2, + He: He2, + His: His2 + } = getPronouns(loser); if (!canSee(winner) && !canSee(loser)) { r.push(`${winner.slaveName} and ${loser.slaveName} are both blind, making the fight a staredown. Neither slave wants to make the first move, especially with the drowning cacophony coming from the jeering crowd. Slowly, ${winner.slaveName} moves forward, waving feeling for ${his} opponent before ${he} ${himself} gets found. ${loser.slaveName}'s hand meets ${winner.slaveName}'s and the two move to grab each other in a headlock. The two slaves violently thrash against each other, suffering more and more strikes as the struggle goes on. Eventually, ${loser.slaveName} can take no more and releases ${his2} grip on ${winner.slaveName} neck. It takes a moment for ${winner.slaveName} to stop wrestling the submitting ${loser.slaveName} and accept ${his} victory.`); @@ -543,7 +548,7 @@ App.Facilities.Pit.nonlethalFight = function(fighters) { r.push(`The fight starts slowly, with the two trading jabs. Just as the spectators are getting bored, ${loser.slaveName} takes a glancing blow to the eyebrow. ${His2} piercing catches on ${winner.slaveName}'s glove and tears out. ${loser.slaveName} goes after ${his2} tormentor in fury, streaming blood, the piercing forgotten on the mat. Any tendency ${winner.slaveName} might have had to feel badly about this is extinguished by the assault, and soon ${winner.slaveName} is even willing to follow up on the success by targeting pierced body parts. The fight ends with poor ${loser.slaveName} writhing in pain on the mat, `, App.UI.DOM.makeElement("span", `leaking blood,`, ["health", "dec"]), ` from several terribly shredded areas.`); if (V.pit.audience === "free") { - r.push(`The audience is `, App.UI.DOM.makeElement("span", `reasonably impressed`, ["reputation", "dec"]), ` by the gory spectacle.`); + r.push(`The audience is `, App.UI.DOM.makeElement("span", `reasonably impressed`, ["reputation", "inc"]), ` by the gory spectacle.`); repX(50, "pit", winner); } else if (V.pit.audience === "paid") { @@ -632,16 +637,14 @@ App.Facilities.Pit.nonlethalFight = function(fighters) { } } - - App.Events.addNode(fightDiv, r); - - return fightDiv; + App.Events.addParagraph(parent, r); } - function postFight() { - const postFightDiv = document.createElement("div"); - - const r = []; + /** + * @param {DocumentFragment} parent + */ + function postFight(parent) { + let r = []; const anus = "anus"; const cunt = "cunt"; @@ -979,8 +982,11 @@ App.Facilities.Pit.nonlethalFight = function(fighters) { } } - r.push(rape(), rapeEffects()); + App.Events.addParagraph(parent, r); + + App.Events.addParagraph(parent, [...rape(), ...rapeEffects()]); + r = []; if (winner.skill.combat === 0 && random(1, 100) < (20 + winner.devotion)) { const experienceSpan = App.UI.DOM.makeElement("span", `learned basic combat skills.`, ["improvement"]); @@ -997,12 +1003,9 @@ App.Facilities.Pit.nonlethalFight = function(fighters) { V.pitFightsTotal++; - App.Events.addNode(postFightDiv, r); - - return postFightDiv; + App.Events.addParagraph(parent, r); function rape() { - const rapeDiv = document.createElement("div"); const repSpan = App.UI.DOM.makeElement("span", ``, ["reputation", "inc"]); const r = []; @@ -1084,32 +1087,24 @@ App.Facilities.Pit.nonlethalFight = function(fighters) { winner.devotion -= 2; } - App.Events.addNode(rapeDiv, r); - - return rapeDiv; + return r; } function rapeEffects() { - const rapeEffectsDiv = document.createElement("div"); - const r = []; const {he, his, him, himself, He} = getPronouns(winner); const {he: he2, him: him2, He: He2} = getPronouns(loser); - r.push(winnerEffects(), loserEffects()); + r.push(...winnerEffects(), ...loserEffects()); if (loser.fetish !== "masochist" && loser.fetish !== "humiliation" && loser.sexualFlaw !== "self hating" && loser.relationship && loser.relationship < 5 && winner.ID === loser.relationshipTarget) { r.push(`Fighting and rape have `, App.UI.DOM.makeElement("span", `damaged`, ["relationship", "dec"]), ` the relationship between the slaves.`); } - App.Events.addNode(rapeEffectsDiv, r); - - return rapeEffectsDiv; + return r; function winnerEffects() { - const winnerEffectsDiv = document.createElement("div"); - const r = []; if (winner.rivalry && loser.ID === winner.rivalryTarget) { @@ -1152,13 +1147,10 @@ App.Facilities.Pit.nonlethalFight = function(fighters) { winner.behavioralFlaw = "odd"; } - App.Events.addNode(winnerEffectsDiv, r); - - return winnerEffectsDiv; + return r; } function loserEffects() { - const loserEffectsDiv = document.createElement("div"); const trustSpan = App.UI.DOM.makeElement("span", `fears`, ["trust", "dec"]); const r = []; @@ -1219,9 +1211,7 @@ App.Facilities.Pit.nonlethalFight = function(fighters) { loser.behavioralFlaw = "odd"; } - App.Events.addNode(loserEffectsDiv, r); - - return loserEffectsDiv; + return r; } } } diff --git a/src/events/scheduled/seIndependenceDay.js b/src/events/scheduled/seIndependenceDay.js index 034d972273f03abc0c8d43b30c891a9b24278d5d..e89f2c3fc9afb0de87ee41665924701f7354f095 100644 --- a/src/events/scheduled/seIndependenceDay.js +++ b/src/events/scheduled/seIndependenceDay.js @@ -552,10 +552,10 @@ App.Events.SEIndependenceDay = class SEIndependenceDay extends App.Events.BaseEv } if (V.SF.Squad.Armoury === 0) { - r.push(`Seeing the soldiers of ${V.SF.Lower} with high-quality personal weapons and light armor, but little in the way of exceptional armament, provides little confidence in V.SF.Lower.`); + r.push(`Seeing the soldiers of ${V.SF.Lower} with high-quality personal weapons and light armor, but little in the way of exceptional armament, provides little confidence in ${V.SF.Lower}.`); repChange -= 200; } else { - r.push(`The citizens of ${V.arcologies[0].name} are relieved to see that V.SF.Lower's troops are outfitted with the absolute latest gear.`); + r.push(`The citizens of ${V.arcologies[0].name} are relieved to see that ${V.SF.Lower}'s troops are outfitted with the absolute latest gear.`); repChange += 1250; } diff --git a/src/events/scheduled/sePCBirthday.js b/src/events/scheduled/sePCBirthday.js index 4e4231efde9310c51a100522702320e58cc02744..5af0807e12d0f987bbcbf52c976572072df329d0 100644 --- a/src/events/scheduled/sePCBirthday.js +++ b/src/events/scheduled/sePCBirthday.js @@ -245,11 +245,15 @@ App.Events.pcBirthday = (function(events) { switch (eventData.attire) { case "formal": repX(100, "event"); - if (V.secExpEnabled) { V.SecExp.core.authority += 300; } + if (V.secExpEnabled) { + V.SecExp.core.authority = Math.clamp(V.SecExp.core.authority + 300, 0, 20000); + } break; case "casual": repX(300, "event"); - if (V.secExpEnabled) { V.SecExp.core.authority += 100; } + if (V.secExpEnabled) { + V.SecExp.core.authority = Math.clamp(V.SecExp.core.authority + 100, 0, 20000); + } break; } }, diff --git a/src/events/schools/resMove.js b/src/events/schools/resMove.js index a9666fb672eb059925165d8cd343833459424f7d..d73c01943d555f78f08d597bddd2f6b760e9772c 100644 --- a/src/events/schools/resMove.js +++ b/src/events/schools/resMove.js @@ -43,7 +43,7 @@ App.Events.RESMove = class RESMove extends App.Events.BaseEvent { if (V.PC.title) { playerName = `Mr. ${V.PC.slaveName}`; } else { - playerName = `"Ms. ${V.PC.slaveName}`; + playerName = `Ms. ${V.PC.slaveName}`; } } else { playerName = V.PC.slaveName; diff --git a/src/facilities/ads.js b/src/facilities/ads.js index 2dc2d57b2445a731c0743400b52052eb360354d2..eee73113dd1c380512afbf1d24bebc8fde1877fb 100644 --- a/src/facilities/ads.js +++ b/src/facilities/ads.js @@ -1129,8 +1129,6 @@ App.Ads.report = function(building, preview = false) { repX(DL * random(10, 15), (building + "Ads")); } } - App.Events.addNode(frag, t, "div"); - t = []; t.push( `There is a`, App.UI.DOM.makeElement("span", `perfect variety`, [(building === "brothel") ? "yellowgreen" : "green", "bold"]), @@ -1142,7 +1140,6 @@ App.Ads.report = function(building, preview = false) { t.push(`sluts`); } t.push(`working in the ${building}.`); - App.Events.addNode(frag, t, "div"); } else { if (building === "club") { t.push(App.UI.DOM.makeElement("div", `${capFirstChar(V.clubName)} does not offer enough variety to satisfy all visitors.`)); diff --git a/src/facilities/arcade/arcade.js b/src/facilities/arcade/arcade.js new file mode 100644 index 0000000000000000000000000000000000000000..ce85d65150d299933127f6007b2c76044a92f8f7 --- /dev/null +++ b/src/facilities/arcade/arcade.js @@ -0,0 +1,256 @@ +App.Facilities.Arcade.arcade = class extends App.Facilities.Facility { + constructor() { + const arcade = App.Entity.facilities.arcade; + const decommissionHandler = () => { + V.arcade = 0; + V.arcadeDecoration = "standard"; + V.arcadePrice = 2; + V.arcadeUpgradeCollectors = 0; + V.arcadeUpgradeFuckdolls = 0; + V.arcadeUpgradeHealth = -1; + V.arcadeUpgradeInjectors = 0; + + App.Arcology.cellUpgrade(V.building, App.Arcology.Cell.Market, "Arcade", "Markets"); + }; + const desc = `It can support ${V.arcade} inmates. There ${arcade.hostedSlaves === 1 ? `is currently ${num(arcade.hostedSlaves)} slave` : `are currently ${num(arcade.hostedSlaves)} slaves`} incarcerated in ${V.arcadeName}.`; + + super( + arcade, + decommissionHandler, + {desc}, + ); + + V.nextButton = "Back to Main"; + V.nextLink = "Main"; + V.returnTo = "Arcade"; + V.encyclopedia = "Arcade"; + } + + /** @returns {string} */ + get intro() { + const text = []; + + text.push(this.facility.nameCaps, this.decorations); + + if (this.facility.hostedSlaves > 2) { + text.push(`It's busy. Customers are entering and exiting, leaving a few ¤ behind in the charge machines and loads of semen behind in the holes.`); + } else if (this.facility.hostedSlaves > 0) { + text.push(`It's understaffed; there are lines here and there for the few holes available.`); + } else { + text.push(`It's empty and quiet.`); + } + + return text.join(' '); + } + + /** @returns {string} */ + get decorations() { + /** @type {FC.Facilities.Decoration} */ + const FS = { + "Roman Revivalist": `is built out as a Roman street restaurant, with the bar containing the inmates. Citizens can amuse themselves at either side of the bar while enjoying some wine and olives and talking over the day's events.`, + "Neo-Imperialist": `is built out as a Neo-Imperial temple, the banners of your house and a few other prominent noble families fluttering over the writhing bodies of the inmates. There's a lively bar and tables built out to one side where citizens can drink and relax when not enjoying themselves with the captive slaves.`, + "Aztec Revivalist": `is built out as an Aztec stone temple, with a short stone staircase to lead the people straight to the slaves waiting in front of the establishment. A small canal leads the shed blood to the back and out of the building.`, + "Egyptian Revivalist": `is built to look like an ancient Egyptian temple, with a long altar of sacrifice serving as the wall in which the inmates are held. Incongruously, it's piled with fresh flowers.`, + "Edo Revivalist": `is built to look like an Edo onsen, with discreet partitions allowing citizens a modicum of privacy as they use the services here. There are baths available so they can wash themselves afterward.`, + "Arabian Revivalist": `is built to look like a fantastical Arabian dungeon, with the inmates kept in iron cages that hold their holes in place for use.`, + "Chinese Revivalist": `is set up to look like a rough bar in an ancient Chinese city, with the inmates immured in the bar itself. Rowdy citizens can drink and fuck the holes here while shouting and boasting over the slaves' heads.`, + "Chattel Religionist": `is well decorated with severe religious iconography, since this place is an acceptable if not respectable place for a citizen to find relief, so long as they keep the service of the slave they use here in mind.`, + "Degradationist": `is nothing but a system of harnesses to hold slaves in the usual posture they would hold within a normal Free Cities sex arcade. This way, no iota of their degradation here is missed.`, + "Asset Expansionist": `is constructed so that the slaves lie within the arcade facing up. The wall itself ends at waist height, so their breasts stick up to be groped while they are used from either end.`, + "Transformation Fetishist": `reveals more of its inmates' bodies than the typical Free Cities sex arcade. There's no attempt to hide the feeding arrangements or injection lines, since transformation into a human sex toy is considered arousing here.`, + "Repopulationist": `is constructed so that the slaves lie within the arcade facing up. A hole is situated above them, so that their belly has room to protrude upwards as they are fucked pregnant.`, + "Eugenics": `is designed with built in dispensers for various prophylactics. Numerous reminders to not impregnate subhumans line the walls along with offers for patrons to join the ranks of the Elite.`, + "Gender Radicalist": `is built to reveal most of its inmate's bellies, butts, groins, and thighs. Whatever a slave here has between her legs, it's available to be fucked, played with, or abused.`, + "Gender Fundamentalist": `is built to block the lower part of its inmates' butts from view and use. The slaves within are thus limited to their anuses for service here, but any slave can be disposed of in ${V.arcadeName} without offending fundamentalist sensibilities.`, + "Physical Idealist": `logs customers' performance for their own athletic information. It keeps track of personal bests and all-time high scores, and pays out cash prizes to customers who fuck the holes faster, harder, or for longer than the previous record holder.`, + "Supremacist": `is constructed so that the inmates' entire heads stick out of the mouth wall, though they're still masked and their jaws are held apart by ring gags. After all, seeing the anguish of the subhumans here is one of the main attractions.`, + "Subjugationist": `is constructed so that the inmates' entire heads stick out of the mouth wall, though they're still masked and their jaws are held apart by ring gags. After all, seeing the anguish of the $arcologies[0].FSSubjugationistRace slaves here is one of the main attractions.`, + "Paternalist": `is constructed so that nothing at all of the slaves is visible. The arcade is just a row of holes. In this way, good, paternalistic citizens can partake of a Free Cities sex arcade without being confronted with what they're doing.`, + "Pastoralist": `is constructed so that the slaves lie within the arcade facing up. If a slave is lactating, her breasts are kept bare and under the maximum sustainable dose of lactation drugs, so that any penetration of her holes produces amusing squirts of milk.`, + "Maturity Preferentialist": `is constructed so that nothing but the slaves' holes can be seen. This makes it possible to maintain the appearance of offering MILFs while using ${V.arcadeName} to get value out of useless young bitches' holes.`, + "Youth Preferentialist": `is constructed so that nothing but the slaves' holes can be seen. This makes it possible to maintain the appearance of offering nothing but young slaves while using ${V.arcadeName} to get value out of old bitches' holes.`, + "Body Purist": `is built out in such a way that much more of the slaves' rears and faces are visible than in a standard Free Cities sex arcade. This makes it much easier to check them for purity before using their holes.`, + "Slimness Enthusiast": `is barely distinguishable from a standard Free Cities sex arcade. The difference is a fun one, though: since the butts sticking out of the wall are much skinnier than usual, there's no padding to get in the way of hilting oneself in the holes.`, + "Hedonistic": `is built in such a way so that most of a slave's ass, thighs, breasts and belly are exposed for patrons to grope and fondle. Plenty of cup holders and surfaces are available to hold one's food and drink as they enjoy their hole of choice.`, + "Intellectual Dependency": `is barely distinguishable from a standard Free Cities sex arcade. The difference is a fun one, though: ${V.arcadeName} keeps track of the total number of orgasms each stall experiences each day and displays the current leader to encourage competition.`, + "Slave Professionalism": `is constructed so that nothing but the slaves' holes can be seen. No details are given about the slave within, nor are their minds allowed to perceive what is happening around them.`, + "Petite Admiration": `is barely distinguishable from a standard Free Cities sex arcade. The difference is remarkable, though: since it expects clientèle of all sizes, the stalls are easily ratcheted to the perfect height.`, + "Statuesque Glorification": `is constructed so that the slaves' holes are lined up perfectly for the taller clientèle. This makes it possible to maintain the appearance of offering nothing but tall slaves while using ${V.arcadeName} to get value out of short bitches' holes.`, + "standard": `is a standard Free Cities sex arcade: a pair of hallways extend away from the entrance, lined with doorless stalls like those in a public restroom. One hallway offers mouths, the other ${V.seeDicks !== 100 ? `vaginas and ` : ``}anuses.`, + "": ``, + }; + + if (!Object.keys(FS).includes(V.arcadeDecoration)) { + throw new Error(`Unknown V.arcadeDecoration value of '${V.arcadeDecoration}' found in decorations().`); + } + + return FS[V.arcadeDecoration]; + } + + /** @returns {FC.Facilities.Upgrade[]} */ + get upgrades() { + return [ + { + property: "arcadeUpgradeInjectors", + prereqs: [ + () => V.arcadeUpgradeCollectors < 1, + () => V.arcadeUpgradeInjectors < 1, + ], + value: 1, + base: `It is a standard arcade. It can be upgraded to either maximize the pleasure of those that visit it at the expense of the health of the inmates, or to keep them healthy (if not happy) and milk them of useful fluids.`, + upgraded: `It has been upgraded with electroshock applicators. Whether they're enjoying themselves or not is irrelevant, they are shocked to tighten their holes regardless. You may also apply aphrodisiacs to further enhance performance.`, + link: `Upgrade the arcade with invasive performance-enhancing systems`, + cost: 10000 * V.upgradeMultiplierArcology, + handler: () => V.PC.skill.engineering += .1, + note: `, increases upkeep costs, and is mutually exclusive with the collectors`, + }, + { + property: "arcadeUpgradeInjectors", + prereqs: [ + () => V.arcadeUpgradeCollectors < 1, + () => V.arcadeUpgradeInjectors > 0, + ], + value: 2, + base: `It has been upgraded with electroshock applicators. Whether they're enjoying themselves or not is irrelevant; they are shocked to tighten their holes regardless. You may also apply aphrodisiacs to further enhance performance.`, + upgraded: `It has been upgraded with aphrodisiac injection systems and electroshock applicators. If the aphrodisiacs fail to force an orgasm from an inmate, they are shocked to tighten their holes regardless.`, + link: `Apply aphrodisiacs`, + handler: () => V.PC.skill.engineering += .1, + }, + { + property: "arcadeUpgradeCollectors", + prereqs: [ + () => V.arcadeUpgradeInjectors < 1, + ], + value: 1, + upgraded: `It has been retrofitted to milk lactating slaves${V.seeDicks !== 0 ? ` and cockmilk slaves capable of ejaculating` : ``}, though less efficiently than a dedicated facility.`, + link: `Retrofit the arcade to collect useful fluids`, + cost: 10000 * V.upgradeMultiplierArcology, + handler: () => V.PC.skill.engineering += .1, + note: `, increases upkeep costs, and is mutually exclusive with the injectors.`, + }, + { + property: "arcadeUpgradeHealth", + prereqs: [ + () => V.arcadeUpgradeHealth < 0, + ], + value: 1, + base: `The arcade can be upgraded to include curative injectors in order to keep inmates from succumbing under the harsh treatment. You are assured the inmates won't like their time in the arcade any better; it is purely intended to keep them functional and ready for use around the clock. It comes equipped with two settings.`, + link: `Install curative injectors`, + cost: 10000 * V.upgradeMultiplierArcology, + handler: () => V.PC.skill.engineering += .1, + note: ` and will increase upkeep costs`, + }, + { + property: "arcadeUpgradeFuckdolls", + prereqs: [ + () => V.arcadeUpgradeFuckdolls === 0, + ], + value: 1, + base: `${capFirstChar(V.arcadeName)} is not equipped to convert inmates into standard Fuckdolls.`, + link: `Upgrade the arcade to create Fuckdolls`, + cost: 5000 * V.upgradeMultiplierArcology, + handler: () => V.PC.skill.engineering += .1, + note: ` and will increase upkeep costs`, + }, + ]; + } + + /** @returns {FC.Facilities.Rule[]} */ + get rules() { + return [ + { + property: "arcadeUpgradeFuckdolls", + prereqs: [ + () => V.arcadeUpgradeFuckdolls > 0, + () => App.Entity.facilities.arcade.hostedSlaves > 0, + ], + options: [ + { + get text() { + return `You have decided that the least popular inmate will be converted to a standard Fuckdoll this week.`; + }, + link: `Activate`, + value: 2, + }, + { + get text() { + return `The arcade has automatic Fuckdollification functions, and you can decide to convert your least popular slave at the end of the week.`; + }, + link: `Deactivate`, + value: 1, + }, + ], + nodes: [ + V.arcade > App.Entity.facilities.arcade.hostedSlaves && V.fuckdolls > 0 + ? `There is room in the arcade for ${V.arcade - App.Entity.facilities.arcade.hostedSlaves} menial Fuckdolls. ${V.fuckdolls > 1 + ? `They'll be more efficient in the arcade, so you restrain them here.` + : `Your Fuckdoll will be more efficient serving in the arcade, so you send it here.`}` + : ``, + ], + }, + { + property: "arcadeUpgradeHealth", + prereqs: [ + () => V.arcadeUpgradeHealth > -1, + ], + options: [ + { + get text() { + return `It has been upgraded with curative injectors, but they are currently turned off.`; + }, + link: `Deactivate`, + value: 0, + }, + { + get text() { + return `It has been upgraded with curative injectors, which are working normally. Inmates will be kept alive and productive, so they may be held locked in place for as long as necessary and available for use.`; + }, + link: `Normal power`, + value: 1, + }, + { + get text() { + return `It has been upgraded with curative injectors and set to maximum power. Inmates will be kept decently healthy so they can be held locked in place for as long as necessary while remaining productive throughout.`; + }, + link: `Maximum power`, + value: 2, + }, + ], + }, + { + property: "arcadeUpgradeFuckdolls", + prereqs: [ + () => V.arcadeUpgradeFuckdolls > 0, + ], + options: [ + { + get text() { + return `${capFirstChar(V.arcadeName)} is equipped to convert inmates into standard Fuckdolls. The converter can be put to work on your order.`; + }, + link: `Deactivate`, + value: 1, + }, + { + get text() { + return `${capFirstChar(V.arcadeName)} is equipped to convert inmates into standard Fuckdolls. The converter is currently active and will convert the least popular girl at the end of the week.`; + }, + link: `Single conversion`, + value: 2, + }, + { + get text() { + return `${capFirstChar(V.arcadeName)} is equipped to convert inmates into standard Fuckdolls. The converter is currently active and will convert underperforming girls at the end of the week.`; + }, + link: `Bulk conversion`, + value: 3, + }, + ], + }, + ]; + } + + /** @returns {HTMLDivElement} */ + get stats() { + return App.UI.DOM.makeElement("div", App.Facilities.Arcade.Stats(true)); + } +}; diff --git a/src/facilities/clinic/clinic.js b/src/facilities/clinic/clinic.js index b7a8103e4cfa1879aeacbb38be24ee5e91b89575..e5083e9a85c760f74eeb2a88ed9b49764e0224ee 100644 --- a/src/facilities/clinic/clinic.js +++ b/src/facilities/clinic/clinic.js @@ -100,7 +100,7 @@ App.Facilities.Clinic.clinic = class extends App.Facilities.Facility { link: `Upgrade the scanners to help detect genomic damage`, cost: Math.trunc(10000 * V.upgradeMultiplierArcology * Math.min(V.upgradeMultiplierMedicine, V.HackingSkillMultiplier)), handler: () => V.PC.skill.hacking += 0.1, - note: `increases the effectiveness of ${V.clinicName}`, + note: ` and increases the effectiveness of ${V.clinicName}`, }, { property: "clinicUpgradeFilters", prereqs: [], @@ -110,7 +110,7 @@ App.Facilities.Clinic.clinic = class extends App.Facilities.Facility { link: `Install advanced blood treatment equipment to help address drug side effects`, cost: Math.trunc(50000 * V.upgradeMultiplierArcology * Math.min(V.upgradeMultiplierMedicine, V.HackingSkillMultiplier)), handler: () => V.PC.skill.hacking += 0.1, - note: `increases the effectiveness of ${V.clinicName}`, + note: ` and increases the effectiveness of ${V.clinicName}`, }, { property: "clinicUpgradePurge", prereqs: [ @@ -123,7 +123,7 @@ App.Facilities.Clinic.clinic = class extends App.Facilities.Facility { link: `Increase the effectiveness of the impurity purging`, cost: Math.trunc(150000 * V.upgradeMultiplierArcology * Math.min(V.upgradeMultiplierMedicine, V.HackingSkillMultiplier)), handler: () => V.PC.skill.hacking += 0.1, - note: `may cause health problems in slaves`, + note: ` and may cause health problems in slaves`, }, { property: "clinicUpgradePurge", prereqs: [ @@ -136,7 +136,7 @@ App.Facilities.Clinic.clinic = class extends App.Facilities.Facility { link: `Further increase the effectiveness of the impurity purging by utilizing nano magnets`, cost: Math.trunc(300000 * V.upgradeMultiplierArcology * Math.min(V.upgradeMultiplierMedicine, V.HackingSkillMultiplier)), handler: () => V.PC.skill.hacking += 0.1, - note: `increases the effectiveness of ${V.clinicName}`, + note: ` and increases the effectiveness of ${V.clinicName}`, nodes: !S.Nurse ? [`However, without a nurse in attendance, the <span class="yellow">blood treatment equipment remains idle.</span>`] : null, @@ -152,46 +152,52 @@ App.Facilities.Clinic.clinic = class extends App.Facilities.Facility { prereqs: [ () => !!S.Nurse, ], - active: { - get text() { return `${capFirstChar(V.clinicName)} is useful for keeping slaves healthy during long term procedures. Slaves in ${V.clinicName} with inflatable belly implants will be filled during their time under ${S.Nurse.slaveName}'s supervision to maximize growth with minimized health complications.`; }, - link: `Fill belly implants`, - value: 1, - }, - inactive: { - get text() { return `${capFirstChar(V.clinicName)} is useful for keeping slaves healthy during long term procedures. ${S.Nurse.slaveName} can supervise weekly filling regimens for clinic slaves with fillable belly implants during their stay to maximize growth with minimal health complications.`; }, - link: `Do not fill belly implants`, - value: 0, - } + options: [ + { + get text() { return `${capFirstChar(V.clinicName)} is useful for keeping slaves healthy during long term procedures. Slaves in ${V.clinicName} with inflatable belly implants will be filled during their time under ${S.Nurse.slaveName}'s supervision to maximize growth with minimized health complications.`; }, + link: `Fill belly implants`, + value: 1, + }, + { + get text() { return `${capFirstChar(V.clinicName)} is useful for keeping slaves healthy during long term procedures. ${S.Nurse.slaveName} can supervise weekly filling regimens for clinic slaves with fillable belly implants during their stay to maximize growth with minimal health complications.`; }, + link: `Do not fill belly implants`, + value: 0, + }, + ], }, { property: "clinicObservePregnancy", prereqs: [], - active: { - text: `Patients undergoing a high-risk pregnancy or are close to giving birth will be kept under observation.`, - link: `Keep high-risk pregnancies under observation`, - value: 1, - }, - inactive: { - text: `Pregnant patients will not be kept under observation.`, - link: `Stop observing pregnancies`, - value: 0, - } + options: [ + { + text: `Patients undergoing a high-risk pregnancy or are close to giving birth will be kept under observation.`, + link: `Keep high-risk pregnancies under observation`, + value: 1, + }, + { + text: `Pregnant patients will not be kept under observation.`, + link: `Stop observing pregnancies`, + value: 0, + }, + ], }, { property: "clinicSpeedGestation", prereqs: [ () => !!S.Nurse, ], - active: { - get text() { return `It's exceedingly dangerous to speed up gestation without constant supervision. In ${V.clinicName}, ${S.Nurse.slaveName} will monitor slaves on rapid gestation agents; making sure the growing patients' food demands are met, monitoring their skin and womb and, if need be, perform an emergency c-section should the need arise.`; }, - link: `Limit rapid gestation agents to selected slaves only`, - value: 0, - }, - inactive: { - get text() { return `${capFirstChar(V.clinicName)} is currently not applying rapid gestation agents to pregnant patients. Only individually selected slaves will undergo this procedure.`; }, - link: `Speed up gestation for all pregnant patients`, - value: 1, - } + options: [ + { + get text() { return `It's exceedingly dangerous to speed up gestation without constant supervision. In ${V.clinicName}, ${S.Nurse.slaveName} will monitor slaves on rapid gestation agents; making sure the growing patients' food demands are met, monitoring their skin and womb and, if need be, perform an emergency c-section should the need arise.`; }, + link: `Limit rapid gestation agents to selected slaves only`, + value: 0, + }, + { + get text() { return `${capFirstChar(V.clinicName)} is currently not applying rapid gestation agents to pregnant patients. Only individually selected slaves will undergo this procedure.`; }, + link: `Speed up gestation for all pregnant patients`, + value: 1, + } + ], }, ]; } diff --git a/src/facilities/farmyard/animals/animals.js b/src/facilities/farmyard/animals/animals.js index 8bc47b99b80dd7d59ff0c1db3f0a2cd30a84444e..026936c130de10956f6d04bcf7dc86eb8cd2af9b 100644 --- a/src/facilities/farmyard/animals/animals.js +++ b/src/facilities/farmyard/animals/animals.js @@ -22,7 +22,7 @@ App.Entity.Animal = class { /** @returns {boolean} */ get purchased() { - return V[this.type].includes(this.name); + return V[this.type].includes(this); } /** @returns {boolean} */ @@ -37,7 +37,7 @@ App.Entity.Animal = class { /** @returns {this} */ purchase() { - V[this.type].push(this.name); + V[this.type].push(this); return this; } @@ -108,8 +108,8 @@ App.Facilities.Farmyard.animals = function() { const frag = new DocumentFragment(); - const domesticDiv = App.UI.DOM.appendNewElement("div", frag, null, 'farmyard-domestic'); - const exoticDiv = App.UI.DOM.appendNewElement("div", frag, null, 'farmyard-exotic'); + const domesticDiv = App.UI.DOM.appendNewElement("div", frag, null, 'margin-bottom'); + const exoticDiv = App.UI.DOM.appendNewElement("div", frag, null, 'margin-bottom'); const hrMargin = '0'; @@ -124,126 +124,134 @@ App.Facilities.Farmyard.animals = function() { V.returnTo = "Farmyard Animals"; V.encyclopedia = "Farmyard"; - App.UI.DOM.appendNewElement("span", domesticDiv, 'Domestic Animals', 'farmyard-heading'); + App.UI.DOM.appendNewElement("span", domesticDiv, 'Domestic Animals', ['uppercase', 'bold']); if (V.farmyardKennels > 1 || V.farmyardStables > 1 || V.farmyardCages > 1) { - App.UI.DOM.appendNewElement("span", exoticDiv, 'Exotic Animals', 'farmyard-heading'); + App.UI.DOM.appendNewElement("span", exoticDiv, 'Exotic Animals', ['uppercase', 'bold']); } - if (V.farmyardKennels) { - domesticDiv.append(domesticCanines()); - } - - if (V.farmyardStables) { - domesticDiv.append(domesticHooved()); - } - - if (V.farmyardCages) { - domesticDiv.append(domesticFelines()); - } - - if (V.farmyardKennels > 1) { - exoticDiv.append(exoticCanines()); - } + domesticDiv.append( + domesticCanines(), + domesticHooved(), + domesticFelines(), + ); - if (V.farmyardStables > 1) { - exoticDiv.append(exoticHooved()); - } - - if (V.farmyardCages > 1) { - exoticDiv.append(exoticFelines()); - } + exoticDiv.append( + exoticCanines(), + exoticHooved(), + exoticFelines(), + ); if (V.debugMode || V.cheatMode) { - frag.appendChild(addAnimal()); + frag.append(addAnimal()); } return frag; - - // Domestic Animals function domesticCanines() { - const canineDiv = App.UI.DOM.makeElement("div", '', 'farmyard-animals'); - const hr = document.createElement("hr"); + if (V.farmyardKennels) { + const div = App.UI.DOM.makeElement("div", null, 'margin-bottom'); + const hr = document.createElement("hr"); + + hr.style.margin = hrMargin; - hr.style.margin = hrMargin; + App.UI.DOM.appendNewElement("span", div, 'Dogs', ['bold']); - App.UI.DOM.appendNewElement("span", canineDiv, 'Dogs', 'farmyard-animal-type'); + div.append(hr, animalList(canine, domestic, 5000, canine)); - canineDiv.append(hr, animalList(canine, domestic, 5000, canine)); + return div; + } - return canineDiv; + return document.createElement("div"); } function domesticHooved() { - const hoovedDiv = App.UI.DOM.makeElement("div", null, 'farmyard-animals'); - const hr = document.createElement("hr"); + if (V.farmyardStables) { + const div = App.UI.DOM.makeElement("div", null, 'margin-bottom'); + const hr = document.createElement("hr"); - hr.style.margin = hrMargin; + hr.style.margin = hrMargin; - App.UI.DOM.appendNewElement("span", hoovedDiv, 'Hooved Animals', 'farmyard-animal-type'); + App.UI.DOM.appendNewElement("span", div, 'Hooved Animals', ['bold']); - hoovedDiv.append(hr, animalList(hooved, domestic, 20000, hooved)); + div.append(hr, animalList(hooved, domestic, 20000, hooved)); - return hoovedDiv; + return div; + } + + return document.createElement("div"); } function domesticFelines() { - const felineDiv = App.UI.DOM.makeElement("div", null, 'farmyard-animals'); - const hr = document.createElement("hr"); + if (V.farmyardCages) { + const div = App.UI.DOM.makeElement("div", null, 'margin-bottom'); + const hr = document.createElement("hr"); - hr.style.margin = hrMargin; + hr.style.margin = hrMargin; - App.UI.DOM.appendNewElement("span", felineDiv, 'Cats', 'farmyard-animal-type'); + App.UI.DOM.appendNewElement("span", div, 'Cats', ['bold']); - felineDiv.append(hr, animalList(feline, domestic, 1000, feline)); - - return felineDiv; - } + div.append(hr, animalList(feline, domestic, 1000, feline)); + return div; + } + return document.createElement("div"); + } // Exotic Animals function exoticCanines() { - const canineDiv = App.UI.DOM.makeElement("div", null, 'farmyard-animals'); - const hr = document.createElement("hr"); + if (V.farmyardKennels > 1) { + const div = App.UI.DOM.makeElement("div", null, 'margin-bottom'); + const hr = document.createElement("hr"); - hr.style.margin = hrMargin; + hr.style.margin = hrMargin; - App.UI.DOM.appendNewElement("span", canineDiv, 'Canines', 'farmyard-animal-type'); + App.UI.DOM.appendNewElement("span", div, 'Canines', ['bold']); - canineDiv.append(hr, animalList(canine, exotic, 50000, canine)); + div.append(hr, animalList(canine, exotic, 50000, canine)); - return canineDiv; + return div; + } + + return document.createElement("div"); } function exoticHooved() { - const hoovedDiv = App.UI.DOM.makeElement("div", null, 'farmyard-animals'); - const hr = document.createElement("hr"); + if (V.farmyardStables > 1) { + const div = App.UI.DOM.makeElement("div", null, 'margin-bottom'); + const hr = document.createElement("hr"); + + hr.style.margin = hrMargin; - hr.style.margin = hrMargin; + App.UI.DOM.appendNewElement("span", div, 'Hooved Animals', ['bold']); - App.UI.DOM.appendNewElement("span", hoovedDiv, 'Hooved Animals', 'farmyard-animal-type'); + div.append(hr, animalList(hooved, exotic, 75000, hooved)); - hoovedDiv.append(hr, animalList(hooved, exotic, 75000, hooved)); + return div; + } - return hoovedDiv; + return document.createElement("div"); } function exoticFelines() { - const felineDiv = App.UI.DOM.makeElement("div", null, 'farmyard-animals'); - const hr = document.createElement("hr"); + if (V.farmyardCages > 1) { + const div = App.UI.DOM.makeElement("div", null, 'margin-bottom'); + const hr = document.createElement("hr"); - hr.style.margin = hrMargin; + hr.style.margin = hrMargin; - App.UI.DOM.appendNewElement("span", felineDiv, 'Felines', 'farmyard-animal-type'); + App.UI.DOM.appendNewElement("span", div, 'Felines', ['bold']); - felineDiv.append(hr, animalList(feline, exotic, 100000, feline)); + div.append(hr, animalList(feline, exotic, 100000, feline)); - return felineDiv; + return div; + } + + return document.createElement("div"); } // Helper Functions @@ -267,14 +275,18 @@ App.Facilities.Farmyard.animals = function() { return App.UI.DOM.link(`Set as active ${type}`, setActiveHandler); } } else { - return App.UI.DOM.link(`Purchase for ${cashFormat(price)}`, purchaseHandler); + return App.UI.DOM.link( + `Purchase`, + purchaseHandler, + [], '', `Costs ${cashFormat(price)} and will incur upkeep costs.` + ); } } /** * Creates a list of the specified animal type from the main animal array. - * @param {"canine"|"hooved"|"feline"} type One of 'canine', 'hooved', or 'feline', also used determine the active animal type. - * @param {string} rarity One of domestic or exotic. + * @param {'canine'|'hooved'|'feline'} type One of 'canine', 'hooved', or 'feline', also used to determine the active animal type. + * @param {'domestic'|'exotic'} rarity One of 'domestic' or 'exotic'. * @param {number} price * @param {string} active The name of the current active animal of the given type. * @returns {HTMLDivElement} @@ -321,7 +333,7 @@ App.Facilities.Farmyard.animals = function() { const animal = new App.Entity.Animal(null, null, "canine", "domestic"); - App.UI.DOM.appendNewElement("div", addAnimalDiv, `Add a New Animal`, ['farmyard-heading']); + App.UI.DOM.appendNewElement("div", addAnimalDiv, `Add a New Animal`, ['uppercase', 'bold']); addAnimalDiv.append( name(), diff --git a/src/facilities/farmyard/farmyard.js b/src/facilities/farmyard/farmyard.js index c227a89bb2a0279d7b8ab60d4fd582751efccd72..bb37e7d8ec4f0dd13e2d4e4b7e4fd63efd790c07 100644 --- a/src/facilities/farmyard/farmyard.js +++ b/src/facilities/farmyard/farmyard.js @@ -6,9 +6,9 @@ App.Facilities.Farmyard.farmyard = function() { const menialsDiv = App.UI.DOM.makeElement("div", null, ['margin-bottom']); const rulesDiv = App.UI.DOM.makeElement("div", null, ['margin-bottom']); const upgradesDiv = App.UI.DOM.makeElement("div", null, ['margin-bottom']); - const kennelsDiv = App.UI.DOM.makeElement("div", null, ['margin-bottom']); - const stablesDiv = App.UI.DOM.makeElement("div", null, ['margin-bottom']); - const cagesDiv = App.UI.DOM.makeElement("div", null, ['margin-bottom']); + const kennelsDiv = App.UI.DOM.makeElement("div"); + const stablesDiv = App.UI.DOM.makeElement("div"); + const cagesDiv = App.UI.DOM.makeElement("div"); const removeHousingDiv = App.UI.DOM.makeElement("div", null, ['margin-bottom']); const renameDiv = App.UI.DOM.makeElement("div", null, ['margin-bottom']); const slavesDiv = App.UI.DOM.makeElement("div", null, ['margin-bottom']); @@ -683,3 +683,15 @@ App.Facilities.Farmyard.farmyard = function() { App.UI.DOM.replace(slavesDiv, slaves); } }; + +App.Facilities.Farmyard.BC = function() { + if (typeof V.farmyardUpgrades !== "object") { + V.farmyardUpgrades = { + pump: 0, fertilizer: 0, hydroponics: 0, machinery: 0, seeds: 0 + }; + } + + if (!App.Data.animals || App.Data.animals.length === 0) { + App.Facilities.Farmyard.animals.init(); + } +}; diff --git a/src/facilities/incubator/incubatorInteract.js b/src/facilities/incubator/incubatorInteract.js index d9239ecf4a80a91f54be0032d439841243c04adb..2e0150b6954770cca306b39a80f6e1b3f9571eef 100644 --- a/src/facilities/incubator/incubatorInteract.js +++ b/src/facilities/incubator/incubatorInteract.js @@ -10,7 +10,7 @@ App.UI.incubator = function() { let childrenReserved; const incubatorNameCaps = capFirstChar(V.incubator.name); - const introSpan = App.UI.DOM.appendNewElement('span', el, intro()); + const introDiv = App.UI.DOM.appendNewElement("div", el, intro()); const showPC = (V.PC.pregKnown === 1 && (V.arcologies[0].FSRestart === "unset" @@ -31,12 +31,15 @@ App.UI.incubator = function() { tabBar.addTab("Settings", "settings", settingsContent); el.append(tabBar.render()); - introSpan.after(release()); // run me late. + introDiv.after(release()); // run me late. return el; + /** + * @returns {DocumentFragment} + */ function intro() { - const el = document.createElement("p"); + const el = new DocumentFragment(); let r = []; let tankBulkOptions = []; let price; @@ -63,6 +66,7 @@ App.UI.incubator = function() { } App.Events.addNode(el, r, "p"); + const tankP = document.createElement("p"); r = []; r.push(`It can support ${V.incubator.capacity} child${(V.incubator.capacity > 1) ? "ren" : ""} as they age.`); if (incubatorSlaves === 1) { @@ -71,10 +75,10 @@ App.UI.incubator = function() { r.push(`There are currently ${incubatorSlaves} tanks`); } r.push(`in use in ${V.incubator.name}.`); - App.Events.addNode(el, r, "div"); + App.Events.addNode(tankP, r, "div"); for (const multiplier of tankMultiplier) { - price = Math.trunc((60000 * multiplier) * V.upgradeMultiplierArcology); + const price = Math.trunc((60000 * multiplier) * V.upgradeMultiplierArcology); tankBulkOptions.push( App.UI.DOM.link( `x${multiplier}`, @@ -87,13 +91,13 @@ App.UI.incubator = function() { ); } price = Math.trunc(60000 * V.upgradeMultiplierArcology); - App.UI.DOM.appendNewElement("div", el, `Adding a tank costs ${cashFormat(price)} and will increase upkeep. `).append(App.UI.DOM.generateLinksStrip(tankBulkOptions)); + App.UI.DOM.appendNewElement("div", tankP, `Adding a tank costs ${cashFormat(price)} and will increase upkeep. `).append(App.UI.DOM.generateLinksStrip(tankBulkOptions)); const empty = freeTanks - reservedChildren; if (empty > 0) { tankBulkOptions = []; for (const multiplier of tankMultiplier) { - price = Math.trunc((10000 * multiplier) * V.upgradeMultiplierArcology); + const price = Math.trunc((10000 * multiplier) * V.upgradeMultiplierArcology); if (empty >= multiplier && V.incubator.capacity - multiplier > 0) { tankBulkOptions.push( App.UI.DOM.link( @@ -108,13 +112,15 @@ App.UI.incubator = function() { } } price = Math.trunc(10000 * V.upgradeMultiplierArcology); - App.UI.DOM.appendNewElement("div", el, `Currently ${empty} tanks are empty.${(V.incubator.capacity !== 1) ? ` Removing a tank costs ${cashFormat(price)} and will reduce upkeep.` : ``} `).append(App.UI.DOM.generateLinksStrip(tankBulkOptions)); + App.UI.DOM.appendNewElement("div", tankP, `Currently ${empty} tanks are empty.${(V.incubator.capacity !== 1) ? ` Removing a tank costs ${cashFormat(price)} and will reduce upkeep.` : ``} `).append(App.UI.DOM.generateLinksStrip(tankBulkOptions)); } if (freeTanks === 0) { - el.append(`All of the tanks are currently occupied by growing children.`); + tankP.append(`All of the tanks are currently occupied by growing children.`); } + el.append(tankP); + return el; } @@ -233,6 +239,8 @@ App.UI.incubator = function() { const father = getSlave(slave.pregSource); if (father) { r.push(`${father.slaveName}'s`); + } else if (WL === 1) { + r.push("a"); } } if (WL > 1) { @@ -462,7 +470,7 @@ App.UI.incubator = function() { function refresh() { jQuery(mothersContent).empty().append(mothers()); - jQuery(introSpan).empty().append(intro()); + jQuery(introDiv).empty().append(intro()); jQuery(tanksContent).empty().append(tankBabies()); } @@ -543,7 +551,7 @@ App.UI.incubator = function() { r = []; if (reservedChildren < freeTanks) { - if (WL - reservedNursery=== 0) { + if (WL - reservedNursery === 0) { r.push( App.UI.DOM.makeElement( "span", @@ -623,7 +631,7 @@ App.UI.incubator = function() { function refresh() { jQuery(pcContent).empty().append(PC()); - jQuery(introSpan).empty().append(intro()); + jQuery(introDiv).empty().append(intro()); jQuery(tanksContent).empty().append(tankBabies()); } } @@ -782,7 +790,7 @@ App.UI.incubator = function() { V.incubator.readySlaves = 1; appendRow(p, `${He} is ready to be released from ${his} tank.`); } else { - const weekDisplay = Math.round(V.incubator.tanks[i].growTime / V.incubator.upgrade.speed); + const weekDisplay = Math.ceil(V.incubator.tanks[i].growTime / V.incubator.upgrade.speed); appendRow(p, `${His} growth is currently being accelerated. ${He} will be ready for release in about ${weekDisplay} ${(weekDisplay > 1) ? `weeks` : `week`}.`); } @@ -892,7 +900,7 @@ App.UI.incubator = function() { testicles: 0, rightEye: 0, leftEye: 0, - voiceBox: 0, + voiceBox: 0, cochleae: 0 }; for (const organ of V.incubator.organs) { @@ -1015,7 +1023,7 @@ App.UI.incubator = function() { function refresh() { jQuery(tanksContent).empty().append(tankBabies()); - jQuery(introSpan).empty().append(intro()); + jQuery(introDiv).empty().append(intro()); } } @@ -1323,7 +1331,7 @@ App.UI.incubator = function() { linkArray.push(makeLink(`Disable`, () => { V.incubator.setting.pregAdaptation = 0; }, refresh)); } row.append(App.UI.DOM.generateLinksStrip(linkArray)); - + if (V.incubator.upgrade.pregAdaptation === 1 && V.incubator.setting.pregAdaptation > 0) { // Should be visible only after incubator.upgrade.reproduction is installed and turned on p.append(row); @@ -1573,7 +1581,7 @@ App.UI.incubator = function() { function refresh() { jQuery(settingsContent).empty().append(tankSettings()); - jQuery(introSpan).empty().append(intro()); + jQuery(introDiv).empty().append(intro()); jQuery(tanksContent).empty().append(tankBabies()); } } @@ -1618,6 +1626,7 @@ App.UI.incubator = function() { } ); } + /** * * @param {string} title diff --git a/src/facilities/surgery/surgeryPassageExotic.js b/src/facilities/surgery/surgeryPassageExotic.js index 4f5996639118b6d5d9513acac816174297b4baa9..3b3ab9c229473802e355f7e5a46b1b3f25bbc94d 100644 --- a/src/facilities/surgery/surgeryPassageExotic.js +++ b/src/facilities/surgery/surgeryPassageExotic.js @@ -304,6 +304,11 @@ App.UI.surgeryPassageExotic = function(slave, cheat = false) { */ function makeLink(title, surgeryType, func, costMult = 1, note = "") { const cost = Math.trunc(V.surgeryCost * costMult); + const tooltip = new DocumentFragment(); + App.UI.DOM.appendNewElement("div", tooltip, `Costs ${cashFormat(cost)}.`); + if (note) { + App.UI.DOM.appendNewElement("div", tooltip, note); + } return App.UI.DOM.link( title, () => { @@ -322,7 +327,7 @@ App.UI.surgeryPassageExotic = function(slave, cheat = false) { }, [], "", - `Costs ${cashFormat(cost)}${note ? ` ${note}` : ""}` + tooltip ); } } diff --git a/src/facilities/surgery/surgeryPassageExtreme.js b/src/facilities/surgery/surgeryPassageExtreme.js index 04e756b3da28c5977ea6670a838d319a59cb54db..1bd60cb18557960bcc7ea83d7006c122b04eeb1f 100644 --- a/src/facilities/surgery/surgeryPassageExtreme.js +++ b/src/facilities/surgery/surgeryPassageExtreme.js @@ -98,6 +98,11 @@ App.UI.surgeryPassageExtreme = function(slave, cheat = false) { */ function makeLink(title, surgeryType, func, costMult = 1, note = "") { const cost = Math.trunc(V.surgeryCost * costMult); + const tooltip = new DocumentFragment(); + App.UI.DOM.appendNewElement("div", tooltip, `Costs ${cashFormat(cost)}.`); + if (note) { + App.UI.DOM.appendNewElement("div", tooltip, note); + } return App.UI.DOM.link( title, () => { @@ -116,7 +121,7 @@ App.UI.surgeryPassageExtreme = function(slave, cheat = false) { }, [], "", - `Costs ${cashFormat(cost)}${note ? ` ${note}` : ""}` + tooltip ); } } diff --git a/src/facilities/surgery/surgeryPassageLower.js b/src/facilities/surgery/surgeryPassageLower.js index 7ece56136cb582772c7e3ec664526a6737277d3a..7fbd08a3701eef4fd2a93ac27dc2bc6fcdbd52d1 100644 --- a/src/facilities/surgery/surgeryPassageLower.js +++ b/src/facilities/surgery/surgeryPassageLower.js @@ -938,6 +938,11 @@ App.UI.surgeryPassageLower = function(slave, cheat = false) { */ function makeLink(title, surgeryType, func, costMult = 1, note = "") { const cost = Math.trunc(V.surgeryCost * costMult); + const tooltip = new DocumentFragment(); + App.UI.DOM.appendNewElement("div", tooltip, `Costs ${cashFormat(cost)}.`); + if (note) { + App.UI.DOM.appendNewElement("div", tooltip, note); + } return App.UI.DOM.link( title, () => { @@ -956,7 +961,7 @@ App.UI.surgeryPassageLower = function(slave, cheat = false) { }, [], "", - `Costs ${cashFormat(cost)}${note ? ` ${note}` : ""}` + tooltip ); } }; diff --git a/src/facilities/surgery/surgeryPassageStructural.js b/src/facilities/surgery/surgeryPassageStructural.js index d8e9f58d21d1d9820837339598d577821240908e..6b65aa2f032a6d3e9b56fc6b650bd652be5458e1 100644 --- a/src/facilities/surgery/surgeryPassageStructural.js +++ b/src/facilities/surgery/surgeryPassageStructural.js @@ -555,6 +555,11 @@ App.UI.surgeryPassageStructural = function(slave, cheat = false) { */ function makeLink(title, surgeryType, func, costMult = 1, note = "") { const cost = Math.trunc(V.surgeryCost * costMult); + const tooltip = new DocumentFragment(); + App.UI.DOM.appendNewElement("div", tooltip, `Costs ${cashFormat(cost)}.`); + if (note) { + App.UI.DOM.appendNewElement("div", tooltip, note); + } return App.UI.DOM.link( title, () => { @@ -573,7 +578,7 @@ App.UI.surgeryPassageStructural = function(slave, cheat = false) { }, [], "", - `Costs ${cashFormat(cost)}${note ? ` ${note}` : ""}` + tooltip ); } }; diff --git a/src/facilities/surgery/surgeryPassageUpper.js b/src/facilities/surgery/surgeryPassageUpper.js index 9b0f7338e728a74273abcf0375029c43b5bba106..e8a036340d17758ad6f96b88d55b5fb853474a84 100644 --- a/src/facilities/surgery/surgeryPassageUpper.js +++ b/src/facilities/surgery/surgeryPassageUpper.js @@ -794,6 +794,11 @@ App.UI.surgeryPassageUpper = function(slave, cheat = false) { */ function makeLink(title, surgeryType, func, costMult = 1, note = "") { const cost = Math.trunc(V.surgeryCost * costMult); + const tooltip = new DocumentFragment(); + App.UI.DOM.appendNewElement("div", tooltip, `Costs ${cashFormat(cost)}.`); + if (note) { + App.UI.DOM.appendNewElement("div", tooltip, note); + } return App.UI.DOM.link( title, () => { @@ -812,7 +817,7 @@ App.UI.surgeryPassageUpper = function(slave, cheat = false) { }, [], "", - `Costs ${cashFormat(cost)}.${(note) ? ` ${note}.` : ''}` + tooltip ); } }; diff --git a/src/facilities/utils.js b/src/facilities/utils.js index 580e56e1a5aca1579fb2aff957a705b78470a974..1e581fab48919c807009c9a9de32e9e49c7ef638 100644 --- a/src/facilities/utils.js +++ b/src/facilities/utils.js @@ -6,7 +6,7 @@ * @param {function():void} [handler] Any custom function to be run upon entering a new name. */ App.Facilities.rename = function rename(facility, handler) { - const renameDiv = App.UI.DOM.makeElement("div", `Rename ${facility.name}: `, ['margin-top']); + const renameDiv = App.UI.DOM.makeElement("div", `Rename ${facility.name}: `); const renameNote = App.UI.DOM.makeElement("span", ` Use a noun or similar short phrase`, ['note']); renameDiv.appendChild(App.UI.DOM.makeTextBox(facility.name, newName => { diff --git a/src/gui/storyCaption.js b/src/gui/storyCaption.js index a2ff2f9a9a858e5c2c11195c4bdc087bb6c120cc..0b39cf7d009f107f336726dfef7a1b409b05d02f 100644 --- a/src/gui/storyCaption.js +++ b/src/gui/storyCaption.js @@ -410,6 +410,7 @@ App.UI.storyCaption = function() { } function crime() { + V.SecExp.core.crimeLow = Math.clamp(Math.trunc(crime), 0, 100); const div = document.createElement("div"); App.UI.DOM.appendNewElement("span", div, "Crime", "orangered"); div.append(" | "); @@ -417,7 +418,6 @@ App.UI.storyCaption = function() { if (showCheats()) { div.append(App.UI.DOM.makeTextBox(V.SecExp.core.crimeLow, crime => { - V.SecExp.core.crimeLow = Math.clamp(Math.trunc(crime), 0, 100); V.cheater = 1; App.Utils.scheduleSidebarRefresh(); }, true)); diff --git a/src/interaction/prostheticConfig.js b/src/interaction/prostheticConfig.js index 02a7816003739ecd7d3418a428d1d2e7086ab16e..b0dbacb76f6ae0640d53fc6aff0f6be5607521ff 100644 --- a/src/interaction/prostheticConfig.js +++ b/src/interaction/prostheticConfig.js @@ -202,7 +202,7 @@ App.UI.prostheticsConfig = function(slave) { if (slave.electrolarynx === 1) { App.UI.DOM.appendNewElement("h2", f, "Voice"); const p = document.createElement("p"); - p.append(`${He} has an electrolarynx installed.`); + p.append(`${He} has an electrolarynx installed. `); if (slave.voice === 0) { p.append("It is turned off."); } else if (slave.voice === 1) { diff --git a/src/interaction/sellSlave.js b/src/interaction/sellSlave.js index 7d978cb8af48a2609b8d89737d1bc84dbef65785..035d8edec11f6280315677bf52c115bd005dbe3d 100644 --- a/src/interaction/sellSlave.js +++ b/src/interaction/sellSlave.js @@ -839,7 +839,7 @@ App.Interact.sellSlave = function(slave) { App.Events.addParagraph(scene, t); if (isShelterSlave(slave)) { - App.Events.addParagraph(scene, [`${He} was placed in your care by the Slave Shelter. Selling ${him} will `, App.UI.DOM.makeElement("span", "violate your contract with them.", "reputation dec")]); + App.Events.addParagraph(scene, [`${He} was placed in your care by the Slave Shelter. Selling ${him} will `, App.UI.DOM.makeElement("span", "violate your contract with them.", ["reputation", "dec"])]); } /** @@ -1555,7 +1555,7 @@ App.Interact.sellSlave = function(slave) { } }], ["D virgin asspussy", { - cost: Math.trunc((cost * 1.35) / 500), + cost: 500 * Math.trunc((cost * 1.35) / 500), offerDesc: `from a prominent citizen who appreciates ${girl}s who are both vaginal virgins and anal veterans.`, get requirements() { return (slave.vagina === 0 && slave.anus > 1 && slave.skill.anal >= 100 && slave.physicalAge < 25); }, percentOdds: 60, diff --git a/src/interaction/siWardrobe.js b/src/interaction/siWardrobe.js index b44a8df0f12babd7a34027243da6beb225e95416..b5a0570fd9c9eb33f7e01af7c4c2b956b9a7849b 100644 --- a/src/interaction/siWardrobe.js +++ b/src/interaction/siWardrobe.js @@ -204,6 +204,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) { function clothingSelection() { const el = new DocumentFragment(); + /** @type {FC.Clothes[]} */ let array = []; for (const [key, object] of App.Data.clothes) { @@ -223,7 +224,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) { } // Sort - array = array.sort((a, b) => (a > b) ? 1 : -1); + array = array.sort((a, b) => (App.Data.clothes.get(a).name > App.Data.clothes.get(b).name) ? 1 : -1); const sortedMap = new Map([]); for (const name of array) { sortedMap.set(name, App.Data.clothes.get(name)); @@ -250,7 +251,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) { } // Sort - array = array.sort((a, b) => (a > b) ? 1 : -1); + array = array.sort((a, b) => (App.Data.slaveWear.collar.get(a).name > App.Data.slaveWear.collar.get(b).name) ? 1 : -1); const sortedMap = new Map([]); for (const name of array) { sortedMap.set(name, App.Data.slaveWear.collar.get(name)); @@ -281,7 +282,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) { let array = Array.from(App.Data.slaveWear.faceAccessory.keys()); // Sort - array = array.sort((a, b) => (a > b) ? 1 : -1); + array = array.sort((a, b) => (App.Data.slaveWear.faceAccessory.get(a).name > App.Data.slaveWear.faceAccessory.get(b).name) ? 1 : -1); const sortedMap = new Map([]); for (const name of array) { sortedMap.set(name, App.Data.slaveWear.faceAccessory.get(name)); @@ -324,7 +325,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) { let array = Array.from(App.Data.slaveWear.mouthAccessory.keys()); // Sort - array = array.sort((a, b) => (a > b) ? 1 : -1); + array = array.sort((a, b) => (App.Data.slaveWear.mouthAccessory.get(a).name > App.Data.slaveWear.mouthAccessory.get(b).name) ? 1 : -1); const sortedMap = new Map([]); for (const name of array) { sortedMap.set(name, App.Data.slaveWear.mouthAccessory.get(name)); diff --git a/src/js/DefaultRules.js b/src/js/DefaultRules.js index a8440b431b9a41ccae01d7d162f0424da78235af..f8effd42e6c49e2081729bfb63195edbc0f3ec53 100644 --- a/src/js/DefaultRules.js +++ b/src/js/DefaultRules.js @@ -33,13 +33,17 @@ globalThis.DefaultRules = (function() { * @returns {string} */ function DefaultRules(slave) { - if (slave.useRulesAssistant === 0) { return r; } // exempted + 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 + if (ruleIds.length === 0) { + return r; + } // no rules apply AssignJobToSlave(slave, rule); if (slave.fuckdoll === 0) { @@ -1196,7 +1200,7 @@ globalThis.DefaultRules = (function() { } /** @typedef {"lips" | "boobs" | "butt" | "dick" | "balls"} DrugTarget */ - // Asset Growth + // Asset Growth const growthDrugs = new Set(["breast injections", "breast redistributors", "butt injections", "butt redistributors", "hyper breast injections", "hyper butt injections", "hyper penis enhancement", "hyper testicle enhancement", "intensive breast injections", "intensive butt injections", "intensive penis enhancement", "intensive testicle enhancement", "lip atrophiers", "lip injections", "penis atrophiers", "penis enhancement", "testicle atrophiers", "testicle enhancement"]); // WARNING: property names in fleshFunc, growDrugs, and shrinkDrugs must be identical and this fact is used by the drugs() below @@ -1584,13 +1588,15 @@ globalThis.DefaultRules = (function() { if (rule.pitRules !== undefined && rule.pitRules !== null) { if (V.pit) { if (rule.pitRules === 0) { - removeJob(slave, Job.PIT, true); - r += `<br>${slave.slaveName} has been removed from the pit.`; + if (App.Entity.facilities.pit.isHosted(slave)) { + removeJob(slave, Job.PIT, true); + r += `<br>${slave.slaveName} has been removed from the pit.`; + } } 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.`; - } else { + } 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.`; } @@ -2985,7 +2991,7 @@ globalThis.DefaultRules = (function() { } } - // Brand location does NOT need to be split into a left and right, (and may or may not contain left OR right already.) + // Brand location does NOT need to be split into a left and right, (and may or may not contain left OR right already.) } else if (slave.brand[rule.brandTarget] !== rule.brandDesign) { if ( (!hasLeftArm(slave) && ["left upper arm", "left lower arm", "left wrist", "left hand"].includes(rule.brandTarget)) || @@ -3113,7 +3119,7 @@ globalThis.DefaultRules = (function() { } function ProcessOther(slave, rule) { - if (typeof(rule.pronoun) === "number" && isFinite(rule.pronoun) && slave.pronoun !== rule.pronoun) { + if (typeof (rule.pronoun) === "number" && isFinite(rule.pronoun) && slave.pronoun !== rule.pronoun) { slave.pronoun = rule.pronoun; } } diff --git a/src/js/eventSelectionJS.js b/src/js/eventSelectionJS.js index 30c6f0ca61bf3a3ddd2ba6ee8d307980b10bc2c1..7f09dbde4e4d070abfa1817a4ffd1b8b915742d5 100644 --- a/src/js/eventSelectionJS.js +++ b/src/js/eventSelectionJS.js @@ -53,14 +53,6 @@ globalThis.generateRandomEventPool = function(eventSlave) { } if (V.HeadGirlID !== 0) { - if (eventSlave.devotion <= 50) { - if (eventSlave.anus !== 0 && canDoAnal(eventSlave)) { - if (V.HGSeverity >= 0) { - V.events.push("RE anal punishment"); - } - V.events.push("RE shower punishment"); - } - } if (eventSlave.assignment !== Job.QUARTER) { if (eventSlave.ID === V.HeadGirlID) { if (eventSlave.trust > 50) { @@ -183,18 +175,6 @@ globalThis.generateRandomEventPool = function(eventSlave) { } } - if (eventSlave.assignment !== Job.QUARTER) { - if (eventSlave.relationship >= 2) { - if (eventSlave.relationship < 5) { - if (eventSlave.devotion > 20) { - if (eventSlave.trust >= -20) { - V.events.push("RE relationship advice"); - } - } - } - } - } - if (eventSlave.devotion > 50) { if (eventSlave.anus > 0) { if (eventSlave.vagina !== 0) { @@ -1084,67 +1064,7 @@ if(eventSlave.drugs === "breast injections") { } } - if (eventSlave.prestige === 0 && eventSlave.assignment !== Job.QUARTER) { - if (eventSlave.devotion > 50) { - if (eventSlave.trust > 50) { - if (eventSlave.skill.entertainment >= 100) { - if (eventSlave.assignment === Job.PUBLIC) { - V.events.push("RE legendary entertainer"); - } - } - - if (eventSlave.skill.whoring >= 100) { - if (eventSlave.assignment === Job.WHORE) { - V.events.push("RE legendary whore"); - } - } - - if (eventSlave.lactation > 0) { - if ((eventSlave.boobs - eventSlave.boobsImplant) > 6000) { - if (eventSlave.assignment === Job.MILKED) { - V.events.push("RE legendary cow"); - } - } - } - - if (eventSlave.bellyPreg >= 14000) { - if (eventSlave.broodmother === 0) { - if (eventSlave.counter.births > 10) { - if (eventSlave.assignment === Job.WHORE || eventSlave.assignment === Job.PUBLIC) { - if (!isAmputee(eventSlave)) { - V.events.push("RE legendary womb"); - } - } - } - } - } - - if (eventSlave.balls > 6) { - if (eventSlave.dick > 6) { - if (eventSlave.assignment === Job.MILKED) { - V.events.push("RE legendary balls"); - } - } - } - - if (eventSlave.origin === "You sentenced $him to enslavement as a punishment for attempted theft of a slave." || eventSlave.origin === "$He is an enslaved Daughter of Liberty." || eventSlave.origin === "You got $him at the Slave Shelter. $He is an enslaved Daughter of Liberty, caught some weeks after the failed coup. $His previous owner used $him as a punching bag and dart board, then when he was bored of $him tattooed obscenities all over $his body and threw $him away." || eventSlave.origin === "$He is an enslaved member of an anti-slavery extremist group." || eventSlave.career === "an antislavery activist") { - if (eventSlave.devotion > 95 && eventSlave.assignment === Job.FUCKTOY) { - V.events.push("RE former abolitionist"); - } - } - } - } - } - - if (eventSlave.relationship === 4) { - if (eventSlave.devotion > 20) { - if (eventSlave.trust > 20) { - V.events.push("RE slave marriage"); - } - } - } - - if (V.eventResults.snatch === 0 && eventSlave.origin === "$He is your share of a raid on an illegal laboratory by your mercenaries." && eventSlave.newGamePlus === 0) { + if (V.eventResults.snatch === 2 && eventSlave.origin === "$He is your share of a raid on an illegal laboratory by your mercenaries." && eventSlave.newGamePlus === 0) { if (V.geneticMappingUpgrade === 2 && eventSlave.health.condition > 25 && eventSlave.devotion > 50 && V.cash > V.surgeryCost * 4) { /* only one slave ever qualifies, so give it a bit more weight */ V.events.push("RE snatch and grab followup"); diff --git a/src/js/slaveListing.js b/src/js/slaveListing.js index f259cf9bd4c893bdb5af0944729c37baff83c950..77221bf1b939725123a3e1a612f160695aaf0683 100644 --- a/src/js/slaveListing.js +++ b/src/js/slaveListing.js @@ -756,8 +756,10 @@ App.UI.SlaveList.displayManager = function(facility, selectionPassage) { * @returns {DocumentFragment} */ App.UI.SlaveList.stdFacilityPage = function(facility, showTransfersPage) { - const frag = this.displayManager(facility); - frag.append(document.createElement('br')); // TODO: replace with margin on one of the divs? + let frag = new DocumentFragment(); + if (facility.manager) { + frag = this.displayManager(facility); + } frag.append(this.listSJFacilitySlaves(facility, passage(), showTransfersPage)); return frag; }; diff --git a/src/js/statsChecker/statsChecker.js b/src/js/statsChecker/statsChecker.js index 8fdc239f0bff67a6ceaa3c4382769429b00f45d0..a594cbf6e05948dad0131d920ced025b4daabe70 100644 --- a/src/js/statsChecker/statsChecker.js +++ b/src/js/statsChecker/statsChecker.js @@ -990,14 +990,14 @@ globalThis.canDoVaginal = function(slave) { globalThis.tooFatSlave = function(slave) { if (!slave) { return null; - } else if (slave.weight > 190 + (slave.muscles / 5) && slave.physicalAge >= 18) { - return true; } else if (slave.weight > 130 + (slave.muscles / 20) && slave.physicalAge <= 3) { return true; } else if (slave.weight > 160 + (slave.muscles / 15) && slave.physicalAge <= 12) { return true; } else if (slave.weight > 185 + (slave.muscles / 10) && slave.physicalAge < 18) { return true; + } else if (slave.weight > 190 + (slave.muscles / 5)) { + return true; } return false; }; @@ -1009,14 +1009,14 @@ globalThis.tooFatSlave = function(slave) { globalThis.tooBigBreasts = function(slave) { if (!slave) { return null; - } else if (slave.boobs > 40000 + (slave.muscles * 200) && slave.physicalAge >= 18) { - return true; } else if (slave.boobs > 5000 + (slave.muscles * 20) && slave.physicalAge <= 3) { return true; } else if (slave.boobs > 10000 + (slave.muscles * 50) && slave.physicalAge <= 12) { return true; } else if (slave.boobs > 25000 + (slave.muscles * 100) && slave.physicalAge < 18) { return true; + } else if (slave.boobs > 40000 + (slave.muscles * 200)) { + return true; } return false; }; @@ -1028,14 +1028,14 @@ globalThis.tooBigBreasts = function(slave) { globalThis.tooBigBelly = function(slave) { if (!slave) { return null; - } else if (slave.belly >= 450000 + (slave.muscles * 2000) && slave.physicalAge >= 18) { // 250k - 650k - return true; - } else if (slave.belly >= 350000 + (slave.muscles * 1000) && slave.physicalAge >= 13) { // 250k - 450k - return true; } else if (slave.belly >= 120000 + (slave.muscles * 500) && slave.physicalAge <= 3) { // 70k - 170k return true; } else if (slave.belly >= 150000 + (slave.muscles * 800) && slave.physicalAge <= 12) { // 70k - 230k return true; + } else if (slave.belly >= 350000 + (slave.muscles * 1000) && slave.physicalAge < 18) { // 250k - 450k + return true; + } else if (slave.belly >= 450000 + (slave.muscles * 2000)) { // 250k - 650k + return true; } return false; }; diff --git a/src/js/utilsDOM.js b/src/js/utilsDOM.js index 88f0c8447abf2672e2ee7fafb35aa18cb8666573..1e10125ae194dbeb056ea5772d946b8f3f837733 100644 --- a/src/js/utilsDOM.js +++ b/src/js/utilsDOM.js @@ -72,7 +72,7 @@ App.UI.DOM.assignmentLink = function(slave, assignment, passage, action, linkTex * @param {F} handler callable object * @param {Parameters<F>} [args] arguments * @param {string} [passage] the passage name to link to - * @param {string} [tooltip] + * @param {string|HTMLElement|DocumentFragment} [tooltip] * @returns {HTMLAnchorElement} link in SC markup */ App.UI.DOM.link = function(linkText, handler, args = [], passage = "", tooltip = "") { diff --git a/src/js/utilsUnits.js b/src/js/utilsUnits.js index aebe9c6b2cc3dd64a1e744de0239b5093c5a2d5b..16c98c0fa3f8a467870ecf57fe487c085aae9476 100644 --- a/src/js/utilsUnits.js +++ b/src/js/utilsUnits.js @@ -166,7 +166,7 @@ globalThis.asSingular = function(single) { * Converts the given number to a string in either singular or plural form. * @param {number} number The number to format. * @param {string} single The singular form. - * @param {string} plural The plural form (e.g. "oxen" for "ox"). Returns the singular form with an "s" if one is not given. + * @param {string} [plural] The plural form (e.g. "oxen" for "ox"). Returns the singular form with an "s" if one is not given. * @returns {string} Returns "a _", "less than one _", or the number formatted as either words or numbers, depending on the users' settings. */ globalThis.numberWithPlural = function(number, single, plural) { diff --git a/src/npc/interaction/fKiss.js b/src/npc/interaction/fKiss.js index de04aa1bc29f27b83168f40e2fc49a96be40c8f1..c6ebb02242839929928b3fb0c65b229d7d86d14a 100644 --- a/src/npc/interaction/fKiss.js +++ b/src/npc/interaction/fKiss.js @@ -191,7 +191,7 @@ App.Interact.fKiss = function(slave) { if (slave.relationship === -3) { if (slave.fetish === "mindbroken") { - r.push(`${His} mouth opens to accept the kiss, and is compliant with your questing tongue. You kiss your broken ${wife} deeply. ${His} posture remains completely unchanged. Being kissed affects ${him} as little as being penetrated, being struck, being loved, or being your V.wife: not at all. When you pull away,`); + r.push(`${His} mouth opens to accept the kiss, and is compliant with your questing tongue. You kiss your broken ${wife} deeply. ${His} posture remains completely unchanged. Being kissed affects ${him} as little as being penetrated, being struck, being loved, or being your ${wife}: not at all. When you pull away,`); if (canSee(slave)) { r.push(`${his} ${App.Desc.eyesColor(slave)} track you carefully, awaiting further use of ${his} body.`); } else { diff --git a/src/npc/interaction/passage/fAnimalImpreg.js b/src/npc/interaction/passage/fAnimalImpreg.js index 56ff0874f9144d834e38d2ed4b3b3e09c62b18d2..d7468d074a81a30bc36d9187cf439af960773990 100644 --- a/src/npc/interaction/passage/fAnimalImpreg.js +++ b/src/npc/interaction/passage/fAnimalImpreg.js @@ -33,7 +33,7 @@ App.Interact.fAnimalImpreg = function(slave) { for (const feline of V.feline) { if (canBreed(getSlave(V.AS), feline)) { App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link( - `Have a ${feline.species !== "dog" ? feline.species : feline.breed} knock ${him} up`, + `Have a ${feline.species !== "cat" ? feline.species : feline.breed} knock ${him} up`, () => jQuery(node).empty().append(content(feline)) )); eligibility = true; diff --git a/src/npc/interaction/passage/fSlaveSlaveVag.js b/src/npc/interaction/passage/fSlaveSlaveVag.js index 5285c5432fe64afd2f76342cf7082cd6c4bcff81..ddb82a6277f36a312409658b4b254fe19bf936c4 100644 --- a/src/npc/interaction/passage/fSlaveSlaveVag.js +++ b/src/npc/interaction/passage/fSlaveSlaveVag.js @@ -441,9 +441,9 @@ App.Interact.fSlaveSlaveVag = function(slave) { } r.push(`to ${his} horror and resentment, while ${rapist.slaveName} is sleeping next to ${him} in a state of obvious satiation and bliss.`); } else if (slave.devotion <= 20 || rapist.devotion <= 20) { - r.push(`You order ${slave.slaveName} onto the couch and tell ${rapist.slaveName} to get on with it. They fuck mechanically, gazing with roiling emotions into each others' eyes. They do seem to come to some sort of a non-verbal understanding on the necessity of getting it done, and there is no real unhappiness in either of them when they finish and disentangle themselves. As they clean themselves and exit, you notice rapist.slaveName's looking a little more longingly at ${slave.slaveName}.`); + r.push(`You order ${slave.slaveName} onto the couch and tell ${rapist.slaveName} to get on with it. They fuck mechanically, gazing with roiling emotions into each others' eyes. They do seem to come to some sort of a non-verbal understanding on the necessity of getting it done, and there is no real unhappiness in either of them when they finish and disentangle themselves. As they clean themselves and exit, you notice ${rapist.slaveName}'s looking a little more longingly at ${slave.slaveName}.`); } else if (slave.devotion <= 50 || rapist.devotion <= 50) { - r.push(`You order ${slave.slaveName} and ${rapist.slaveName} to get on with it. They fuck mechanically at first, gazing with roiling emotions into each others' eyes. Eventually, they begin to enjoy the intimacy of the act, finding the shared pleasure between them comforting. They finish and resume life as slaves, the light of this intimacy diminishing, softening with rapist.slaveName's dick and dripping away with the contents of ${slave.slaveName}'s cum-filled pussy.`); + r.push(`You order ${slave.slaveName} and ${rapist.slaveName} to get on with it. They fuck mechanically at first, gazing with roiling emotions into each others' eyes. Eventually, they begin to enjoy the intimacy of the act, finding the shared pleasure between them comforting. They finish and resume life as slaves, the light of this intimacy diminishing, softening with ${rapist.slaveName}'s dick and dripping away with the contents of ${slave.slaveName}'s cum-filled pussy.`); } else { r.push(`The two slaves happily and eagerly get down to business. They take their time with foreplay, humping slowly and gazing into each others' eyes, exchanging kisses almost constantly. After a little while, ${slave.slaveName} looks over ${rapist.slaveName}'s shoulder to where you're sitting, the invitation clear in ${his} eyes. As soon as you stand to come over, they roll over without being ordered to`); if (canDoAnal(slave) && slave.anus > 0) { diff --git a/src/npc/surgery/bodySwap/bodySwapReaction.js b/src/npc/surgery/bodySwap/bodySwapReaction.js index f411019a59b278667a2d57236a31bb8dfa4b1bb9..48e5384657f061ec8cdb78039bcb2768ae9bc1d3 100644 --- a/src/npc/surgery/bodySwap/bodySwapReaction.js +++ b/src/npc/surgery/bodySwap/bodySwapReaction.js @@ -1020,7 +1020,7 @@ globalThis.bodySwapReaction = function(body, soul) { if (canSee(body)) { r.push(`Something about ${his} head catches ${his}`); if (body.hColor !== soul.hColor) { - r.push(`eye; ${he} <span class="coral">now has body.hColor hair.</span>`); + r.push(`eye; ${he} <span class="coral">now has ${body.hColor} hair.</span>`); } else { r.push(`eye, but it was a trick of the light; ${his} hair is more or less the same.`); } @@ -2682,7 +2682,7 @@ globalThis.bodySwapReaction = function(body, soul) { } else { r.push(`Something about ${his} head catches ${his}`); if (body.hColor !== soul.hColor) { - r.push(`eye; ${he} <span class="coral">now has body.hColor hair.</span>`); + r.push(`eye; ${he} <span class="coral">now has ${body.hColor} hair.</span>`); } else { r.push(`eye, but it was a trick of the light; ${his} hair is more or less the same.`); } diff --git a/src/npc/surgery/surgery.js b/src/npc/surgery/surgery.js index 9d3f4af50a3a0e18d02d12d18cda54c85b42e258..1c521824a391fe83c13cd6d6fea3923781a3e1a1 100644 --- a/src/npc/surgery/surgery.js +++ b/src/npc/surgery/surgery.js @@ -111,8 +111,15 @@ App.Medicine.Surgery.makeLink = function(passage, surgery, slave, cheat = false) return 'insignificant'; } + let tooltip = new DocumentFragment(); + App.UI.DOM.appendNewElement("div", tooltip, `${capFirstChar(surgery.description)}.`); + if (!cheat) { + App.UI.DOM.appendNewElement("div", tooltip, `Surgery costs: ${cashFormat(surgery.costs)}.`); + App.UI.DOM.appendNewElement("div", tooltip, `Projected health damage: ${healthCosts()}.`); + } + return App.UI.DOM.link(surgery.label, App.Medicine.Surgery.commit, [surgery, slave], passage, - `${capFirstChar(surgery.description)}.${cheat ? `` : `\nSurgery costs: ${cashFormat(surgery.costs)}.\nProjected health damage: ${healthCosts()}.`}`); + tooltip); }; /** @@ -654,7 +661,9 @@ globalThis.eyeSurgery = function(slave, side, action) { return; } - if (side !== "left" && side !== "right") { return; } // make sure side can be used to access the object + if (side !== "left" && side !== "right") { + return; + } // make sure side can be used to access the object const eyeExists = slave.eye[side] !== null; /* actions that don't need an eye */ @@ -720,7 +729,9 @@ globalThis.setEyeColor = function(slave, color, side = "both") { return; } - if (side !== "left" && side !== "right") { return; } + if (side !== "left" && side !== "right") { + return; + } slave.eye[side].iris = color; }; @@ -741,7 +752,9 @@ globalThis.setEyeColorFull = function(slave, iris = "brown", pupil = "circular", return; } - if (side !== "left" && side !== "right") { return; } + if (side !== "left" && side !== "right") { + return; + } if (iris !== "") { slave.eye[side].iris = iris; @@ -783,7 +796,9 @@ globalThis.resetEyeColor = function(slave, side = "both") { return; } - if (side !== "left" && side !== "right") { return; } + if (side !== "left" && side !== "right") { + return; + } slave.eye[side].iris = getGeneticEyeColor(slave, side); }; diff --git a/src/pregmod/reLegendaryWomb.tw b/src/pregmod/reLegendaryWomb.tw deleted file mode 100644 index b96de8ce5eb8c1c3b3aaa072665aa7cacfc562fa..0000000000000000000000000000000000000000 --- a/src/pregmod/reLegendaryWomb.tw +++ /dev/null @@ -1,79 +0,0 @@ -:: RE legendary womb [nobr] - -<<set $nextButton = "Continue", $nextLink = "AS Dump", $returnTo = "RIE Eligibility Check", $activeSlave = ($legendaryFacility == 1) ? getSlave($legendaryWombID) : $eventSlave>> - -<<if (ndef $activeSlave)>> /* not found — reset variable and stop event */ - <<set $legendaryWombID = 0>> - <<goto "RIE Eligibility Check">> -<<else>> - -<<run App.Utils.setLocalPronouns($activeSlave)>> -<<set $activeSlave.devotion += 4>> - -<<= App.UI.slaveDescriptionDialog($activeSlave)>> is an incredible mother. $He's given birth to numbers that would have been considered absurd in the days when drug treatments were limited by consent. A nascent organization will be holding a pageant for pregnant slaves tomorrow, and since they're aware you keep breeders, they've sent you an invitation to enter a heavily pregnant slave to be judged. - -<br><br> - -This is a rare opportunity. The idea of a pregnancy pageant isn't new but it is undeniably going to attract attention, so the pageant is likely to draw some serious press. Were $activeSlave.slaveName to win, $he would probably be remembered for a long time as a special mother. - -<br><br> - -<span id="result"> -<<link "Fairly enter $him in the pregnancy pageant">> - <<if random(1,100) > 90>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then asked to demonstrate how to pleasure a man while so heavily pregnant. It's likely there was some bribery behind the scenes, but $his heavy belly and creative positions win the day. Against all odds $he is named best in show, and will be @@.green;remembered@@ as a breeder of the highest pedigree. As $his owner, your reputation has @@.green;also increased.@@ - <<run repX(500, "event", $activeSlave)>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is remembered for winning best in show as a breeder.">> - <<set $desc = "a best in show ribbon awarded to " + $activeSlave.slaveName + " as a breeder">> - <<set $trinkets.push($desc)>> - <</replace>> - <<else>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then asked to demonstrate how to pleasure a man while so heavily pregnant. It's likely there was some bribery behind the scenes, and it is fatal to $his chances of winning. Though $his pregnant body is the most impressive on display, another slaveowner who was more open-handed with the judges took best in show. The public is impressed with $activeSlave.slaveName's reproductive capability anyway; as you are $his owner, your reputation has @@.green;increased@@ a little. - <<run repX(500, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -<br><<link "Spend <<print cashFormat(5000)>> bribing the judges">> - <<if random(1,100) > 50>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then asked to demonstrate how to pleasure a man while so heavily pregnant. Several of the judges cannot resist giving you a wink as they look $him over. $activeSlave.slaveName is unsurprisingly named best in show, and will be @@.green;remembered@@ as a breeder of the highest pedigree. As $his owner, your reputation has @@.green;also increased.@@ - <<run cashX(-5000, "event", $activeSlave)>> - <<run repX(500, "event", $activeSlave)>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is remembered for winning best in show as a breeder.">> - <<set $desc = "a best in show ribbon awarded to " + $activeSlave.slaveName + " as a breeder">> - <<set $trinkets.push($desc)>> - <</replace>> - <<else>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then asked to demonstrate how to pleasure a man while so heavily pregnant. Several of the judges cannot resist giving you a wink as they look $him over, but others look disapprovingly at them; it seems some of your competitors also forwarded money to the committee. After furious wrangling, $activeSlave.slaveName loses to another mother. The public is impressed with $activeSlave.slaveName's reproductive capability anyway; as you are $his owner, your reputation has @@.green;increased@@ a little. - <<run cashX(-5000, "event", $activeSlave)>> - <<run repX(500, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -<br><<link "Spend <<print cashFormat(10000)>> bribing the judges and sabotaging the competition">> - <<if random(1,100) > 10>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then asked to demonstrate how to pleasure a man while so heavily pregnant. After $he's put through $his paces, the most unfortunate series of accidents somehow befalls $his fellow mothers. One is taken ill, another seems drugged, and another went into labor and gave birth, disqualifying her. $activeSlave.slaveName is unsurprisingly named best in show, and will be @@.green;remembered@@ as a breeder of the highest pedigree. As $his owner, your reputation has @@.green;also increased.@@ - <<run cashX(-10000, "event", $activeSlave)>> - <<run repX(500, "event", $activeSlave)>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is remembered for winning best in show as a breeder.">> - <<set $desc = "a best in show ribbon awarded to " + $activeSlave.slaveName + " as a breeder">> - <<set $trinkets.push($desc)>> - <</replace>> - <<else>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then asked to demonstrate how to pleasure a man while so heavily pregnant. You are surprised to see that the judging committee has been changed at the last minute. They choose another breeder as best in show. There are persistent @@.red;rumors@@ after the show that there was an absolute massacre of firings at the dairy organization headquarters the night before the show after it was discovered that someone, widely thought to be you, had been corrupting the judges. - <<run cashX(-10000, "event", $activeSlave)>> - <<run repX(-100, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -</span> - -<</if>> /* closes validity check */ diff --git a/src/uncategorized/REresistantmotherdaughter.tw b/src/uncategorized/REresistantmotherdaughter.tw deleted file mode 100644 index 7f5fd09bf2d606103fcc64f0719c487989143215..0000000000000000000000000000000000000000 --- a/src/uncategorized/REresistantmotherdaughter.tw +++ /dev/null @@ -1,70 +0,0 @@ -:: RE resistant mother daughter [nobr] - -<<set $nextButton = "Continue", $nextLink = "RIE Eligibility Check">> - -<<set $i = $slaveIndices[$motherSlave]>> -<<set $j = $slaveIndices[$daughterSlave]>> -<<setLocalPronouns $slaves[$i]>> -<<setLocalPronouns $slaves[$j] 2>> - -<<set _clothesTemp = $slaves[$i].clothes, $slaves[$i].clothes = "no clothing">> -<<set _clothesTemp2 = $slaves[$j].clothes, $slaves[$j].clothes = "no clothing">> -<span id="art-frame"> -/* 000-250-006 */ -<<if $seeImages == 1>> - <div class="imageColumn"> - <div class="imageRef medImg"> - <<SlaveArt $slaves[$i] 2 0>> - </div> - <div class="imageRef medImg"> - <<SlaveArt $slaves[$j] 2 0>> - </div> - </div> -<</if>> -/* 000-250-006 */ -</span> -<<set $slaves[$i].clothes = _clothesTemp>> -<<set $slaves[$j].clothes = _clothesTemp2>> - -$slaves[$i].slaveName and $his _daughter2 are both having trouble getting acclimated to your ownership, with their obedience suffering as a result. Though neither of them have done anything particular egregious lately, their combined list of minor transgressions is reaching a point where rendering punishment on the two would not be seen as unfair. By happenstance they come before you for inspection one after the other. Though they certainly <<if canSee($slaves[$i]) && canSee($slaves[$j])>>see each other naked frequently around<<else>>are frequently naked around each other in<</if>> the penthouse, neither seems particularly comfortable around the other when nudity is involved. While you finish $slaves[$i].slaveName's inspection, $his _daughter2 fidgets uneasily even while trying to mimic the posture and appearance of an obedient slave. It occurs to you that the current situation presents an opportunity to do //something// about this resistant $mother-_daughter2 pair. - -<br><br> -<span id="result"> -<br><<link "Spend the evening gently acclimating them to your ownership">> - <<replace "#result">> - Though neither of the two vehemently protests your decision to have them both join you in bed, furtive uneasy glances are exchanged between the two. Since they're already naked, they clamber onto your bed before you and reluctantly kneel facing each other, leaving enough space between them for you<<if canSee($slaves[$i]) && canSee($slaves[$j])>> and for them to avert their eyes to avoid the other's nakedness<</if>>. They clearly assume you would start by using one of them, so they're quite taken aback when you remain standing at the edge of the bed and suggest that $slaves[$i].slaveName play with $his _daughter2. $slaves[$j].slaveName awkwardly flounders a little as _his2 $mother's <<if hasBothArms($slaves[$i])>>hands roam<<elseif hasAnyArms($slaves[$i])>>hand roams<</if>> about _his2 body, but does not reel back from the intimate touching. In time you instruct $slaves[$j].slaveName to pleasure _his2 $mother, but still decline to join the incestuous union unfolding on your sheets. You extend the foreplay for hours, bringing both $mother and _daughter2 to such a state of naked arousal that they begin grinding against each other uninhibitedly. They are both so desperate for release that they do not object when you finally decide to join them, instead eagerly moving to include you in their coupling. What started with $slaves[$j].slaveName awkwardly kneeling unmoving while _his2 $mother sucked _his2 nipples ends with $slaves[$j].slaveName <<if hasAllLimbs($slaves[$j])>>on all fours<<else>>bent over<</if>> getting fucked by you while orally pleasuring $slaves[$i].slaveName. You gaze over at $slaves[$i].slaveName and $he moans and licks $his lips enticingly back at you as $slaves[$j].slaveName moans into $his fuckhole. - @@.mediumaquamarine;They have both become more trusting of you.@@ - - <<set $slaves[$i].trust += 4, $slaves[$j].trust += 4, $slaves[$i].counter.oral += 1, $slaves[$j].counter.oral += 1, $oralTotal += 2>> - - <<if canDoAnal($slaves[$j])>> - <<set $slaves[$j].counter.anal += 1>> - <<set $analTotal += 1>> - <<elseif canDoVaginal($slaves[$j])>> - <<set $slaves[$j].counter.vaginal += 1>> - <<set $vaginalTotal += 1>> - <</if>> - - <<if canDoAnal($slaves[$i])>> - <<set $slaves[$i].counter.anal += 1>> - <<set $analTotal += 1>> - <<elseif canDoVaginal($slaves[$i])>> - <<set $slaves[$i].counter.vaginal += 1>> - <<set $vaginalTotal += 1>> - <</if>> - - <</replace>> -<</link>> -<br><<link "Make an example of the $mother">> - <<replace "#result">> - You give them orders of devastating simplicity: You are going to assrape $slaves[$i].slaveName and if $his _daughter2 offers even the most token of resistance, you'll punish $slaves[$i].slaveName. They're stunned, but you shake them out of their shock by grabbing $slaves[$i].slaveName by the arm<<if $PC.dick == 0>>,donning a strap-on<</if>> and shoving $him over your desk. $slaves[$j].slaveName flinches visibly as you enter _his2 $mother's ass in one brutal stroke, for which you stain _his2 $mother's asscheeks a rosy red with a torrent of harsh spanks. $slaves[$i].slaveName takes the rough anal pounding with only quiet sobbing and the occasional whimper of pain, but $his _daughter2 can't bear to <<if canSee($slaves[$j])>>see<<elseif canHear($slaves[$j])>>hear<<else>>have<</if>> $slaves[$i].slaveName in such duress and breaks _his2 short-lived silence to beg for mercy. When you step away from $slaves[$i].slaveName, $slaves[$j].slaveName lets out a sigh of relief, but _his2 expression soon turns to horror and revulsion when you return to mount _his2 $mother with a lash in hand. - <br><br> - When you eventually finish your merciless assrape of $slaves[$i].slaveName, $his body is covered in bruises, marks, and handprints. A testament to $slaves[$j].slaveName's inability to keep _his2 silence as you brutalized _his2 $mother. You leave your office wordlessly to attend to other matters, while behind you $slaves[$j].slaveName gazes <<if canSee($slaves[$j])>>forlornly<<else>>blindly<</if>> at the gibbering mess you have reduced _his2 $mother to. - Your severe punishment of _his2 $mother has encouraged $slaves[$j].slaveName to @@.gold;fear you.@@ $slaves[$i].slaveName has been fucked into @@.hotpink;submission@@ but your savage treatment has caused $him to @@.red;hate buttsex.@@ - - <<set $slaves[$j].trust -= 10>> - <<set $slaves[$i].devotion += 4, $slaves[$i].counter.anal += 1, $analTotal += 1, $slaves[$i].sexualFlaw = "hates anal">> - - <</replace>> -<</link>> -</span> diff --git a/src/uncategorized/arcade.tw b/src/uncategorized/arcade.tw deleted file mode 100644 index 31f7c66b5fde0da0bb24fe12ee0781faa5b48e38..0000000000000000000000000000000000000000 --- a/src/uncategorized/arcade.tw +++ /dev/null @@ -1,200 +0,0 @@ -:: Arcade [nobr jump-to-safe jump-from-safe] - -<<set $nextButton = "Back to Main", $nextLink = "Main", $returnTo = "Arcade", $encyclopedia = "Arcade", _AL = App.Entity.facilities.arcade.employeesIDs().size>> - -<<set _arcadeNameCaps = capFirstChar($arcadeName)>> -<p class="scene-intro"> - _arcadeNameCaps - <<switch $arcadeDecoration>> - <<case "Roman Revivalist">> - is built out as a Roman street restaurant, with the bar containing the inmates. Citizens can amuse themselves at either side of the bar while enjoying some wine and olives and talking over the day's events. - <<case "Neo-Imperialist">> - is built out as a Neo-Imperial temple, the banners of your house and a few other prominent noble families fluttering over the writhing bodies of the inmates. There's a lively bar and tables built out to one side where citizens can drink and relax when not enjoying themselves with the captive slaves. - <<case "Aztec Revivalist">> - is built out as an Aztec stone temple, with a short stone staircase to lead the people straight to the slaves waiting in front of the establishment. A small canal leads the shed blood to the back and out of the building. - <<case "Egyptian Revivalist">> - is built to look like an ancient Egyptian temple, with a long altar of sacrifice serving as the wall in which the inmates are held. Incongruously, it's piled with fresh flowers. - <<case "Edo Revivalist">> - is built to look like an Edo onsen, with discreet partitions allowing citizens a modicum of privacy as they use the services here. There are baths available so they can wash themselves afterward. - <<case "Arabian Revivalist">> - is built to look like a fantastical Arabian dungeon, with the inmates kept in iron cages that hold their holes in place for use. - <<case "Chinese Revivalist">> - is set up to look like a rough bar in an ancient Chinese city, with the inmates immured in the bar itself. Rowdy citizens can drink and fuck the holes here while shouting and boasting over the slaves' heads. - <<case "Chattel Religionist">> - is well decorated with severe religious iconography, since this place is an acceptable if not respectable place for a citizen to find relief, so long as they keep the service of the slave they use here in mind. - <<case "Degradationist">> - is nothing but a system of harnesses to hold slaves in the usual posture they would hold within a normal Free Cities sex arcade. This way, no iota of their degradation here is missed. - <<case "Asset Expansionist">> - is constructed so that the slaves lie within the arcade facing up. The wall itself ends at waist height, so their breasts stick up to be groped while they are used from either end. - <<case "Repopulationist">> - is constructed so that the slaves lie within the arcade facing up. A hole is situated above them, so that their belly has room to protrude upwards as they are fucked pregnant. - <<case "Eugenics">> - is designed with built in dispensers for various prophylactics. Numerous reminders to not impregnate subhumans line the walls along with offers for patrons to join the ranks of the Elite. - <<case "Transformation Fetishist">> - reveals more of its inmates' bodies than the typical Free Cities sex arcade. There's no attempt to hide the feeding arrangements or injection lines, since transformation into a human sex toy is considered arousing here. - <<case "Gender Radicalist">> - is built to reveal most of its inmate's bellies, butts, groins, and thighs. Whatever a slave here has between her legs, it's available to be fucked, played with, or abused. - <<case "Gender Fundamentalist">> - is built to block the lower part of its inmates' butts from view and use. The slaves within are thus limited to their anuses for service here, but any slave can be disposed of in $arcadeName without offending fundamentalist sensibilities. - <<case "Physical Idealist">> - logs customers' performance for their own athletic information. It keeps track of personal bests and all-time high scores, and pays out cash prizes to customers who fuck the holes faster, harder, or for longer than the previous record holder. - <<case "Supremacist">> - is constructed so that the inmates' entire heads stick out of the mouth wall, though they're still masked and their jaws are held apart by ring gags. After all, seeing the anguish of the subhumans here is one of the main attractions. - <<case "Subjugationist">> - is constructed so that the inmates' entire heads stick out of the mouth wall, though they're still masked and their jaws are held apart by ring gags. After all, seeing the anguish of the $arcologies[0].FSSubjugationistRace slaves here is one of the main attractions. - <<case "Paternalist">> - is constructed so that nothing at all of the slaves is visible. The arcade is just a row of holes. In this way, good, paternalistic citizens can partake of a Free Cities sex arcade without being confronted with what they're doing. - <<case "Pastoralist">> - is constructed so that the slaves lie within the arcade facing up. If a slave is lactating, her breasts are kept bare and under the maximum sustainable dose of lactation drugs, so that any penetration of her holes produces amusing squirts of milk. - <<case "Maturity Preferentialist">> - is constructed so that nothing but the slaves' holes can be seen. This makes it possible to maintain the appearance of offering MILFs while using $arcadeName to get value out of useless young bitches' holes. - <<case "Youth Preferentialist">> - is constructed so that nothing but the slaves' holes can be seen. This makes it possible to maintain the appearance of offering nothing but young slaves while using $arcadeName to get value out of old bitches' holes. - <<case "Body Purist">> - is built out in such a way that much more of the slaves' rears and faces are visible than in a standard Free Cities sex arcade. This makes it much easier to check them for purity before using their holes. - <<case "Slimness Enthusiast">> - is barely distinguishable from a standard Free Cities sex arcade. The difference is a fun one, though: since the butts sticking out of the wall are much skinnier than usual, there's no padding to get in the way of hilting oneself in the holes. - <<case "Hedonistic">> - is built in such a way so that most of a slave's ass, thighs, breasts and belly are exposed for patrons to grope and fondle. Plenty of cup holders and surfaces are available to hold one's food and drink as they enjoy their hole of choice. - <<case "Intellectual Dependency">> - is barely distinguishable from a standard Free Cities sex arcade. The difference is a fun one, though: $arcadeName keeps track of the total number of orgasms each stall experiences each day and displays the current leader to encourage competition. - <<case "Slave Professionalism">> - is constructed so that nothing but the slaves' holes can be seen. No details are given about the slave within, nor are their minds allowed to perceive what is happening around them. - <<case "Petite Admiration">> - is barely distinguishable from a standard Free Cities sex arcade. The difference is remarkable, though: since it expects clientèle of all sizes, the stalls are easily ratcheted to the perfect height. - <<case "Statuesque Glorification">> - is constructed so that the slaves' holes are lined up perfectly for the taller clientèle. This makes it possible to maintain the appearance of offering nothing but tall slaves while using $arcadeName to get value out of short bitches' holes. - <<default>> - is a standard Free Cities sex arcade: a pair of hallways extend away from the entrance, lined with doorless stalls like those in a public restroom. One hallway offers mouths, the other <<if $seeDicks != 100>>vaginas and <</if>>anuses. - <</switch>> - <<if _AL > 2>> - It's busy. Customers are entering and exiting, leaving a few ¤ behind in the charge machines and loads of semen behind in the holes. - <<elseif _AL > 0>> - It's understaffed; there are lines here and there for the few holes available. - <<else>> - It's empty and quiet. - <div class="choices" style="font-style:normal"> - <<link "Decommission the arcade" "Main">> - <<set $arcade = 0, $arcadeUpgradeInjectors = 0, $arcadeUpgradeFuckdolls = 0, $arcadeUpgradeCollectors = 0>> - <<run App.Arcology.cellUpgrade($building, App.Arcology.Cell.Market, "Arcade", "Markets")>> - <</link>> - </div> - <</if>> -</p> - -<div> - It can support $arcade inmates. There <<if _AL == 1>>is<<else>>are<</if>> currently _AL slave<<if _AL != 1>>s<</if>> incarcerated in $arcadeName. -</div> -<div> - <<if $arcadeUpgradeFuckdolls == 1 && _AL > 1>> - The arcade has automatic Fuckdollification functions, and you can decide to convert your least popular slave at the end of the week. [[Activate|Arcade][$arcadeUpgradeFuckdolls = 2]] - <<elseif $arcadeUpgradeFuckdolls == 2>> - You have decided that the least popular inmate will be converted to a standard Fuckdoll this week. [[Deactivate|Arcade][$arcadeUpgradeFuckdolls = 1]] - <</if>> -</div> -<div> - <<if $arcade > _AL && $fuckdolls > 0>> - <<set _fuckdollRoom = $arcade - _AL>> - There is room in the arcade for <<print _fuckdollRoom>> menial Fuckdolls. <<if $fuckdolls > 1>>They'll be more efficient in the arcade, so you restrain them here.<<else>>Your Fuckdoll will be more efficient serving in the arcade, so you send it here.<</if>> - <</if>> -</div> -<div class="choices"> - <<set _Tmult0 = Math.trunc($arcade*1000*$upgradeMultiplierArcology)>> - [[Expand the arcade|Arcade][cashX(forceNeg(_Tmult0), "capEx"), $arcade += 10]] //Costs <<print cashFormat(_Tmult0)>> and will increase upkeep costs// -</div> -<div class="choices"> - <<if _AL > 0>> - <<includeDOM removeFacilityWorkers("arcade", "", "work a glory hole")>> - <</if>> -</div> - - -<<set _Tmult1 = Math.trunc(10000*$upgradeMultiplierArcology)>> -<div> - <<if $arcadeUpgradeInjectors == 1>> - It has been upgraded with electroshock applicators. Whether they're enjoying themselves or not is irrelevant, they are shocked to tighten their holes regardless. You may also apply aphrodisiacs to further enhance performance. [[Apply aphrodisiacs|Arcade][$arcadeUpgradeInjectors = 2]] - <<elseif $arcadeUpgradeInjectors == 2>> - It has been upgraded with aphrodisiac injection systems and electroshock applicators. If the aphrodisiacs fail to force an orgasm from an inmate, they are shocked to tighten their holes regardless. - <<elseif $arcadeUpgradeCollectors == 1>> - It has been retrofitted to milk lactating slaves<<if $seeDicks != 0>> and cockmilk slaves capable of ejaculating<</if>>, though less efficiently than a dedicated facility. - <<else>> - It is a standard arcade. It can be upgraded to either maximize the pleasure of those that visit it at the expense of the health of the inmates, or to keep them healthy (if not happy) and milk them of useful fluids. - <div class="choices"> - [[Upgrade the arcade with invasive performance-enhancing systems|Arcade][cashX(forceNeg(_Tmult1), "capEx"), $arcadeUpgradeInjectors = 1]] | [[Retrofit the arcade to collect useful fluids|Arcade][cashX(forceNeg(_Tmult1), "capEx"), $arcadeUpgradeCollectors = 1]] - <div class="note"> - Choosing either upgrade will cost <<print cashFormat(_Tmult1)>> and will increase upkeep costs. They are mutually exclusive; only one can be chosen. - </div> - </div> - <</if>> -</div> -<div> - <<if $arcadeUpgradeHealth == 2>> - It has been upgraded with curative injectors and set to maximum power. Inmates will be kept decently healthy so they can be held locked in place for as long as necessary while remaining productive throughout. - <div class="choices"> - [[Decrease power|Arcade][$arcadeUpgradeHealth = 1]] - </div> - <<elseif $arcadeUpgradeHealth == 1>> - It has been upgraded with curative injectors. Inmates will be kept alive and productive, so they may be held locked in place for as long as necessary and available for use. - <div class="choices"> - [[Increase power|Arcade][$arcadeUpgradeHealth = 2]] | [[Turn off|Arcade][$arcadeUpgradeHealth = 0]] - </div> - <<elseif $arcadeUpgradeHealth == 0>> - It has been upgraded with curative injectors, but they are currently turned off. - <div class="choices"> - [[Turn on|Arcade][$arcadeUpgradeHealth = 1]] - </div> - <<else>> - The arcade can be upgraded to include curative injectors in order to keep inmates from succumbing under the harsh treatment. You are assured the inmates won't like their time in the arcade any better, it is purely intended to keep them functional and ready for use around the clock. It comes equipped with two settings. - <div class="choices"> - [[Install curative injectors|Arcade][cashX(forceNeg(_Tmult1), "capEx"), $arcadeUpgradeHealth = 1]] - </div> - <div class="note"> - Costs <<print cashFormat(_Tmult1)>> and will increase upkeep costs - </div> - <</if>> -</div> - -<div> - _arcadeNameCaps is - <<if $arcadeUpgradeFuckdolls == 1>> - equipped to convert inmates into standard Fuckdolls. The converter can be put to work on your order. - <div class="choices"> - [[Turn on conversion|Arcade][$arcadeUpgradeFuckdolls = 2]] | [[Turn on bulk conversion|Arcade][$arcadeUpgradeFuckdolls = 3]] - </div> - <<elseif $arcadeUpgradeFuckdolls == 2>> - equipped to convert inmates into standard Fuckdolls. The converter is currently active and will convert the least popular girl at the end of the week. - <div class="choices"> - [[Turn off conversion|Arcade][$arcadeUpgradeFuckdolls = 1]] | [[Switch to bulk conversion|Arcade][$arcadeUpgradeFuckdolls = 3]] - </div> - <<elseif $arcadeUpgradeFuckdolls == 3>> - equipped to convert inmates into standard Fuckdolls. The converter is currently active and will convert underperforming girls at the end of the week. - <div class="choices"> - [[Turn off conversion|Arcade][$arcadeUpgradeFuckdolls = 1]] | [[Switch to single conversion|Arcade][$arcadeUpgradeFuckdolls = 2]] - </div> - <<else>> - <<set _Tmult2 = Math.trunc(5000*$upgradeMultiplierArcology)>> - not equipped to convert inmates into standard Fuckdolls. - <div class="choices"> - [[Upgrade the arcade to create Fuckdolls|Arcade][cashX(forceNeg(_Tmult2), "capEx"), $arcadeUpgradeFuckdolls = 1]] - <span class="note"> - Costs <<print cashFormat(_Tmult2)>> - </span> - </div> - <</if>> -</div> - -<!-- Statistics output --> -<<includeDOM App.Facilities.Arcade.Stats(true)>> - -<p> - <<includeDOM App.UI.SlaveList.listSJFacilitySlaves(App.Entity.facilities.arcade)>> -</p> - -<p> - Rename $arcadeName: <<textbox "$arcadeName" $arcadeName "Arcade">> - <span class="note"> - Use a noun or similar short phrase - </span> -</p> - -<<run App.UI.SlaveList.ScrollPosition.restore()>> diff --git a/src/uncategorized/randomNonindividualEvent.tw b/src/uncategorized/randomNonindividualEvent.tw index fd2d54b2a4bfb8ca487e5418a2a96de00ce8c4bc..20a6b70faac569ec1fb276c7573d8eb6e7570845 100644 --- a/src/uncategorized/randomNonindividualEvent.tw +++ b/src/uncategorized/randomNonindividualEvent.tw @@ -30,24 +30,6 @@ <</if>> <<set $legendaryFacility = 1>> - <<if $legendaryWhoreID != 0>> - <<set $events.push("RE legendary whore")>> - <</if>> - <<if $legendaryEntertainerID != 0>> - <<set $events.push("RE legendary entertainer")>> - <</if>> - <<if $legendaryCowID != 0>> - <<set $events.push("RE legendary cow")>> - <</if>> - <<if $legendaryBallsID != 0>> - <<set $events.push("RE legendary balls")>> - <</if>> - <<if $legendaryWombID != 0>> - <<set $events.push("RE legendary womb")>> - <</if>> - <<if $legendaryAbolitionistID != 0>> - <<set $events.push("RE former abolitionist")>> - <</if>> <<if $seeCats != 0>> <<if ($projectN.status > 4)>> <<set $events.push("RE sos assassin")>> @@ -95,66 +77,9 @@ <</if>> <</if>> - /* Relationship Events */ - - <<if $seeIncest == 1>> - - <<set _relatedSlaves = $slaves.filter(function(s) { return s.daughters > 0 || s.sisters > 0; })>> - - <<set _devMothers = _relatedSlaves.filter(function(s) { return s.daughters > 0 && s.devotion > 50 && s.anus != 0 && canWalk(s); })>> - <<for _devMothers.length > 0>> - <<set $devMother = _devMothers.pluck()>> - <<set $devDaughter = randomDaughter($devMother)>> - <<if (def $devDaughter) && ($devDaughter.devotion > 50) && ($devDaughter.anus != 0) && canWalk($devDaughter)>> - <<set $events.push("RE devoted mother daughter")>> - <<set $devMother = $devMother.ID>> - <<set $devDaughter = $devDaughter.ID>> - <<break>> - <</if>> - <</for>> - - <<set _resMothers = _relatedSlaves.filter(s => s.daughters > 0 && s.devotion < 10 && s.anus != 0 && canWalk(s))>> - <<for _resMothers.length > 0>> - <<set $motherSlave = _resMothers.pluck()>> - <<set $daughterSlave = randomDaughter($motherSlave)>> - <<if (def $daughterSlave) && ($daughterSlave.devotion < 10) && ($daughterSlave.anus != 0) && canWalk($daughterSlave)>> - <<set $events.push("RE resistant mother daughter")>> - <<set $motherSlave = $motherSlave.ID>> - <<set $daughterSlave = $daughterSlave.ID>> - <<break>> - <</if>> - <</for>> - - <<set _youngerSisters = _relatedSlaves.filter(function(s) { return s.sisters > 0 && s.origin == "$He was sold into slavery by $his older sister." && canPenetrate(s); })>> - <<for _youngerSisters.length > 0>> - <<set $youngerSister = _youngerSisters.pluck()>> - <<set $olderSister = randomSister($youngerSister)>> - <<if (def $olderSister) && ($olderSister.anus == 0) && $youngerSister.devotion > ($olderSister.devotion+20)>> - <<set $events.push("RE sibling revenge")>> - <<set $youngerSister = $youngerSister.ID>> - <<set $olderSister = $olderSister.ID>> - <<break>> - <</if>> - <</for>> - - <</if>> - /* Multislave Events */ <<set _L = App.Utils.countFacilityWorkers(["brothel", "clinic", "club", "dairy", "cellblock", "spa", "schoolroom", "servantsQuarters"])>> - <<if $dairyRestraintsSetting >= 2>> - <<set $rebelSlaves = $slaves.filter(function(s) { return s.devotion < -20 && s.assignment != "be confined in the arcade" && canWalk(s) && s.assignment != "work in the dairy"; })>> - <<else>> - <<set $rebelSlaves = $slaves.filter(function(s) { return s.devotion < -20 && s.assignment != "be confined in the arcade" && canWalk(s); })>> - <</if>> - <<if $rebelSlaves.length > 1>> - <<set $rebelSlaves = $rebelSlaves.shuffle()>> - <<set $rebelSlaves.length = 2>> - <<set $rebelSlaves[0] = $rebelSlaves[0].ID>> - <<set $rebelSlaves[1] = $rebelSlaves[1].ID>> - <<set $events.push("RE rebels")>> - <</if>> - <<if _L.brothel > 3>> <<set $events.push("RE busy brothel")>> <</if>> @@ -367,27 +292,6 @@ <<set $events.push("RE shipping container")>> <</if>> - <<if $corp.Cash > 50000>> - <<set $events.push("REM merger")>> - <</if>> - - <<if $mercenaries > 0>> - <<if (random(1,2) == 1 || ($debugMode > 0 && $debugModeEventSelection > 0))>> - <<set $events.push("RE AWOL")>> - <<else>> - <<set $events.push("RE Poker Night")>> - <</if>> - <</if>> - - <<if ($arcologies[0].prosperity >= 100 && ($rep > random(1,30000)) || _oneIfDebug)>> - <<set _milfSlaves = $slaves.filter(function(s) { return s.devotion > 20 && canTalk(s) && canWalk(s) && (s.assignment == "serve the public" || s.assignment == "serve in the club"); })>> - <<if _milfSlaves.length > 0>> - <<set $events.push("RE milf tourist")>> - <<set $milfSlaveID = _milfSlaves.random()>> - <<set $milfSlaveID = $milfSlaveID.ID>> - <</if>> - <</if>> - <<if $SF.Toggle && $SF.Active >= 1>> <<set $events.push("Trick Shot Night")>> <</if>> @@ -398,18 +302,6 @@ <</if>> <</if>> - <<set $REM = 0>> - <<if (random(1,100) > $slaveCostFactor*50)>> - <<set $REM += 1>> - <</if>> - <<if (random(1,100) < $slaveCostFactor*50)>> - <<set $REM -= 1>> - <</if>> - <<if $REM != 0>> - <<set $events.push("REM fluctuations")>> - <<set $events.push("REM fluctuations")>> - <</if>> - /* FUTURE SOCIETY EVENTS */ <<if $arcologies[0].FSBodyPurist > (random(25,100) || _oneIfDebug+24)>> diff --git a/src/uncategorized/reAWOL.tw b/src/uncategorized/reAWOL.tw deleted file mode 100644 index 42606cec1ec53c169e7b081a105c5d900d217364..0000000000000000000000000000000000000000 --- a/src/uncategorized/reAWOL.tw +++ /dev/null @@ -1,263 +0,0 @@ -:: RE AWOL [nobr] - -<<set $nextButton = "Continue", $nextLink = "RIE Eligibility Check", $returnTo = "RIE Eligibility Check">> - -<<if $pedo_mode == 1>> - <<set _minAge = 21>> -<<else>> - <<set _minAge = 38>> -<</if>> - -<<set _genParam = {minAge: _minAge, maxAge: 43, ageOverridesPedoMode: 1, race: "nonslave", disableDisability: 1}>> -<<if $seeDicks != 100>> - <<set _slave = GenerateNewSlave("XX", _genParam)>> -<<else>> - <<set _slave = GenerateNewSlave("XY", _genParam)>> -<</if>> -<<set _slave.origin = "You sentenced $him to enslavement as a punishment for dereliction of $his duty to you as a mercenary and for theft.">> -<<set _slave.career = "a soldier">> -<<set _slave.devotion = random(-75,-60)>> -<<set _slave.trust = random(-15,0)>> -<<run setHealth(_slave, jsRandom(60, 80))>> -<<set _slave.muscles = 50>> -<<set _slave.weight = random(-10,10)>> -<<run eyeSurgery(_slave, "both", "normal")>> -<<set _slave.hears = 0>> -<<set _slave.anus = 0>> -<<set _slave.skill.anal = 0>> -<<set _slave.skill.whoring = 0>> -<<set _slave.skill.combat = 1>> -<<set _slave.behavioralFlaw = "arrogant">> -<<set _slave.sexualFlaw = "hates men">> -<<set _slave.hStyle = "shaved into a mohawk">> -<<set _slave.custom.tattoo = "$He has a number of tattoos from a variety of mercenary companies.">> -<<set _slave.clothes = "a military uniform">> - -<<run App.Utils.setLocalPronouns(_slave)>> -<<setAssistantPronouns>> -<span id="art-frame"> - /* 000-250-006 */ - <<if $seeImages == 1>> - <div class="imageColumn"> - <<if $imageChoice == 1>> - <div class="imageRef lrgVector"><div class="mask"> </div><<SlaveArt _slave 3 0>></div> - <<else>> - <div class="imageRef lrgRender"><div class="mask"> </div><<SlaveArt _slave 3 0>></div> - <</if>> - <<= assistantArt(3)>> - </div> - <</if>> - /* 000-250-006 */ -</span> - -Human soldiers are superior to drones in a number of ways — they have the capability for suspicion, the ability to understand human interactions, and are impervious to the ever-present threat of cyber-warfare. That said, a crucial failing of any sentient warrior is their agency. - -<br><br> - -On this particular evening, you find your work interrupted by an urgent alert from $assistant.name<<if $seeImages == 1>>, accompanied by a recent picture<</if>>. -<<if $assistant.personality > 0>> - "<<= properMaster()>>, one of the $mercenariesTitle has gone AWOL." _HeA pauses before continuing. "$He's taken a number of weapons with $him." -<<else>> - _HeA informs you that one of the $mercenariesTitle has disappeared, seemingly taking with $him a small stash of weapons. -<</if>> - -<br><br> - -Your window of opportunity to act is closing. If you have plans for punishing this dereliction from your authority, they must be set in motion now. - -<br><br> - -<span id="result"> - -<<link "Let them go">> - <<replace "#result">> - You inform your personal assistant that you aren't planning to take any action. By the next morning, word has spread to the rest of your arcology that crossing you is apparently permissible and your @@.red;reputation has suffered@@ as a result. - <<run repX(-1000, "event", _slave)>> - <</replace>> -<</link>> - -<br> - -<<link "Let your mercenaries handle $him">> - <<replace "#art-frame">> - /* 000-250-006 */ - <<if $seeImages == 1>> - <div class="imageColumn"> - <<= assistantArt(3)>> - </div> - <</if>> - /* 000-250-006 */ - <</replace>> - <<replace "#result">> - <<if random(1,100) > 50>> - Despite the trouble $he has caused you, the culmination of this mercenary's wanton flight from the rest of the $mercenariesTitle is decidedly an anti-climax. The last you hear of the matter is a chorus of grim grunts and nods as your mercenaries file back into the arcology. The matter is done. - <<else>> - Your mercenaries return to tell you that they could not find the mutineer. It could be that $he managed to escape beyond their reach or that one among your 'loyal' retainers allowed $him to flee your judgment, but alas there is little that can be done to remedy the issue now. Still, aside from a slight grumbling within the arcology, few fault you for allowing the $mercenariesTitle to recapture one of their own — even if they failed to do so. - <</if>> - <</replace>> -<</link>> - -<br> - -<<if $SF.Toggle && $SF.Active >= 1>> - <<link "Let your $SF.Lower handle $him">> - <<replace "#result">> - You take a tablet and send <<print App.SF.SFC()>> a notice about the mutinous mercenary. When you have the majority of the pertinent details committed to text, all that remains is to decide the fate of your quarry. - <br><br> - <span id="SFresult"> - - <<link "You want $him dead">> - <<replace "#art-frame">> - /* 000-250-006 */ - <<if $seeImages == 1>> - <<set _slave.trust = 100>> - <<set _slave.devotion = 100>> - <div class="imageColumn"> - <<= assistantArt(3)>> - </div> - <</if>> - /* 000-250-006 */ - <</replace>> - <<replace "#SFresult">> - Despite the trouble $he has caused you, the culmination of this mercenary's wanton flight from the rest of the $mercenariesTitle is decidedly anti-climatic. The last you hear of $him is in the footnote of one of your daily reports, with some minute yet suitably gory pictures as an accompaniment. When the stolen weapons are returned to their rightful place in your arcology, the unfortunate matter is concluded once and for all. @@.green;Your reputation and $arcologies[0].name's prosperity improves,@@ a result of the fear crossing you will bring, in addition to showing your citizens that you are willing and able to deal with such matters in-house. - <<set $arcologies[0].prosperity += 2>> - <<run repX(5000, "event", _slave)>> - <<if $arcologies[0].prosperity > $AProsperityCap>> - <<set $arcologies[0].prosperity = $AProsperityCap>> - <</if>> - <</replace>> - <</link>> - - <br> - - <<link "You want $him alive">> - <<replace "#SFresult">> - <<replace "#art-frame">> - /* 000-250-006 */ - <<if $seeImages == 1>> - <<set _slave.clothes = "chains">> - <div class="imageColumn"> - <<if $imageChoice == 1>> - <div class="imageRef lrgVector"><div class="mask"> </div><<SlaveArt _slave 3 0>></div> - <<else>> - <div class="imageRef lrgRender"><div class="mask"> </div><<SlaveArt _slave 3 0>></div> - <</if>> - <<= assistantArt(3)>> - </div> - <</if>> - /* 000-250-006 */ - <</replace>> - It doesn't take long for a squad of $SF.Lower to track $him down. Soon you have the troublesome turncoat before you in chains. - <br><br> - <span id="alive-result"> - - <<link "Enslave $him">> - <<replace "#alive-result">> - Despite the trouble $he has caused you, you manage to complete the legalities and biometric scanning quickly and without incident. Of course, this is in large part due to the fact that the would-be mutineer is of course restrained. Based on the accounts of $his captors and the numerous injuries evident amongst them, $he is likely to be violent when $he is finally released. - <br> - <<includeDOM App.UI.newSlaveIntro(_slave)>> - <</replace>> - <</link>> - - <br> - - <<link "Flog $him in public then exile $him from the arcology">> - <<replace "#alive-result">> - An example must be made. There is a binding contract between you and your $mercenariesTitle, and this $woman attempted to undermine it for $his own selfish profit. The protesting bitch is stripped and flogged on the promenade before being escorted bleeding from the arcology. The public @@.green;approves of this harshness.@@ In addition @@.green;Arcology prosperity improves,@@ a result of showing your citizens that you are willing and able to deal with such matters in-house. - <<set $arcologies[0].prosperity += 2>> - <<run repX(5000, "event", _slave)>> - <<if $arcologies[0].prosperity > $AProsperityCap>> - <<set $arcologies[0].prosperity = $AProsperityCap>> - <</if>> - <</replace>> - <</link>> - - </span> /* closes alive-result */ - <</replace>> /* SFresult */ - <</link>> /* want $him alive */ - - </span> /* closes SFresult */ - <</replace>> /* result */ - <</link>> -<</if>> -<<if $cash < 5000>> - <br> - //You lack the necessary funds to put out a bounty.// -<<else>> /* cash >= 5000 */ - <br> - - <<link "Put out a bounty on $his head">> - <<replace "#result">> - You take a tablet and draft a bounty notice for the mutinous mercenary. When you have the majority of the pertinent details committed to text, all that remains is to decide the fate of your quarry. - <br><br> - <span id="bounty-result"> - - <<link "You want $him dead">> - <<replace "#art-frame">> - /* 000-250-006 */ - <<if $seeImages == 1>> - <div class="imageColumn"> - <<= assistantArt(3)>> - </div> - <</if>> - /* 000-250-006 */ - <</replace>> - <<replace "#bounty-result">> - Despite the trouble $he has caused you, the culmination of this mercenary's wanton flight from the rest of the $mercenariesTitle is decidedly an anti-climax. The last you hear of $him is in the footnote of one of your daily reports, with some minute yet suitably gory pictures as an accompaniment. When the stolen weapons are returned to their rightful place in your arcology, the unfortunate matter is concluded once and for all. @@.green;Your reputation improves,@@ a result of the fear of crossing you that your unpleasantness has inspired. - <<run repX(5000, "event", _slave)>> - <<run cashX(-5000, "capEx")>> - <</replace>> - <</link>> - - <br> - - <<link "You want $him alive">> - <<replace "#art-frame">> - /* 000-250-006 */ - <<if $seeImages == 1>> - <<set _slave.clothes = "chains">> - <div class="imageColumn"> - <<if $imageChoice == 1>> - <div class="imageRef lrgVector"><div class="mask"> </div><<SlaveArt _slave 3 0>></div> - <<else>> - <div class="imageRef lrgRender"><div class="mask"> </div><<SlaveArt _slave 3 0>></div> - <</if>> - <<= assistantArt(3)>> - </div> - <</if>> - /* 000-250-006 */ - <</replace>> - <<replace "#bounty-result">> - It doesn't take long for some hired guns, motivated by the bounty, to track $him down. Soon you have the troublesome turncoat before you in chains. - <br><br> - <span id="alive-result"> - - <<link "Enslave $him">> - <<replace "#alive-result">> - Despite the trouble $he has caused you, you manage to complete the legalities and biometric scanning quickly and without incident. Of course, this is in large part due to the fact that the would-be mutineer is of course restrained. Based on the accounts of $his captors and the numerous injuries evident amongst them, $he is likely to be violent when $he is finally released. - <br> - <<includeDOM App.UI.newSlaveIntro(_slave)>> - <<run cashX(-5000, "event", _slave)>> - <</replace>> - <</link>> - - <br> - - <<link "Flog $him in public then exile $him from the arcology">> - <<replace "#alive-result">> - An example must be made. There is a binding contract between you and your $mercenariesTitle, and this $woman attempted to undermine it for $his own selfish profit. The protesting bitch is stripped and flogged on the promenade before being escorted bleeding from the arcology. The public @@.green;approves of this harshness.@@ - <<run repX(5000, "event", _slave)>> - <<run cashX(-5000, "event", _slave)>> - <</replace>> - <</link>> - - </span> /* closes alive-result */ - <</replace>> /* bounty-result */ - <</link>> /* want $him alive */ - - </span> /* closes bounty-result */ - <</replace>> /* result */ - <</link>> // It will cost <<print cashFormat(5000)>> to put out a bounty on $him.// -<</if>> /* cash >= 5000 */ - -</span> /* closes result */ diff --git a/src/uncategorized/reAnalPunishment.tw b/src/uncategorized/reAnalPunishment.tw deleted file mode 100644 index dd88e4d6b80c974f1afc89c9a24516bc613055e9..0000000000000000000000000000000000000000 --- a/src/uncategorized/reAnalPunishment.tw +++ /dev/null @@ -1,78 +0,0 @@ -:: RE anal punishment [nobr] - -<<set $nextButton = "Continue", $nextLink = "AS Dump", $returnTo = "Next Week">> - -<<set $activeSlave = $eventSlave>> -<<run App.Utils.setLocalPronouns($activeSlave)>> -<<setLocalPronouns _S.HeadGirl 2>> - -<<run Enunciate($activeSlave)>> - -<<set _clothesTemp = $activeSlave.clothes, $activeSlave.clothes = "no clothing">> -<<set _clothesTemp2 = _S.HeadGirl.clothes, _S.HeadGirl.clothes = "no clothing">> -<span id="art-frame"> -/* 000-250-006 */ -<<if $seeImages == 1>> - <div class="imageColumn"> - <div class="imageRef medImg"> - <<SlaveArt _S.HeadGirl 2 0>> - </div> - <div class="imageRef medImg"> - <<SlaveArt $activeSlave 2 0>> - </div> - </div> -<</if>> -/* 000-250-006 */ -</span> -<<set $activeSlave.clothes = _clothesTemp>> -<<set _S.HeadGirl.clothes = _clothesTemp2>> - -As you're making the rounds through your penthouse, you hear _S.HeadGirl.slaveName speaking in the tones _he2 uses to castigate misbehaving slaves in the next room. When you appear in the doorway, you have little chance to survey the situation before <<= App.UI.slaveDescriptionDialog($activeSlave)>>, apparently the miscreant, flings $himself at your feet. $He clings to one of your legs convulsively, choking on tears as $he stares up at you and tries to muster an explanation. After two false starts, $he manages to start begging. "Plea<<s>>e, <<Master>>," $he wails miserably. "Plea<<s>>e don't let _him2 rape my butt." -<br><br> -You shoot an amused glance at _S.HeadGirl.slaveName, who smiles back as _he2 explains the slave's minor sin and _his2 intention to sodomize the malefactor. _He2 does not bother to keep an edge of anticipation out of _his2 voice, and $activeSlave.slaveName cries harder and clings to you with renewed force as your Head Girl pronounces _his2 intention with cruel clarity.<<if $activeSlave.boobs > 4000>> The supplicant's breasts are so huge that $his embrace of your leg has completely surrounded it in deliciously heaving breastflesh.<<elseif $activeSlave.boobs > 1000>> The weight of the supplicant's breasts is quite noticeable as $his embrace of your leg presses them against it.<</if>> You look down at $activeSlave.slaveName. $He stares back with huge wet <<= App.Desc.eyesColor($activeSlave)>>, doing $his best to implore you with $his gaze, and scooting $his rear in towards your foot in an unconscious effort to protect it from the promised assrape. $He's quite authentically terrified; $his whole body is shaking. -<br><br> -_S.HeadGirl.slaveName is very much acting within _his2 duties, and $activeSlave.slaveName has now misbehaved twice by trying to go over your Head Girl's head by appealing to you. _S.HeadGirl.slaveName is ready to carry out the sentence: <<if canPenetrate(_S.HeadGirl) && (_S.HeadGirl.dick > 2)>>_his2 cock is fully erect, and _he2's keeping it hard with one hand. _He2 slaps its head against _his2 other palm<<elseif _S.HeadGirl.dick > 0>>since _his2 dick isn't an appropriate instrument for inflicting anal pain, _he2's got an elephantine dildo ready. _He2 slaps it against _his2 palm<<else>>_He2's got an elephantine dildo ready, and _he2 slaps it against _his2 palm<</if>>, forcing a frightened moan from $activeSlave.slaveName. - -<br><br> - -<span id="result"> -<<link "Carry on">> - <<replace "#result">> - You ignore $activeSlave.slaveName — no small feat, since the poor <<if $activeSlave.physicalAge > 30>>$woman<<else>>$girl<</if>> is clinging to your leg — and tell _S.HeadGirl.slaveName to carry on. Your Head Girl @@.mediumaquamarine;puffs up a bit with pride,@@ and orders the weeping slave to present $his anus. The <<if $activeSlave.physicalAge > 30>>$woman<<else>>$girl<</if>> does not resist, but nor does $he comply. _S.HeadGirl.slaveName jabs a thumb into $activeSlave.slaveName's side, right above $his kidney, driving the wind out of the slave with a pained grunt. $He arches $his back involuntarily and $his grip on you loosens, and _S.HeadGirl.slaveName drags $him off you. _He2 jabs $him again, depriving _his2 victim of breath completely, and then takes _him2 by the ankle, dragging the slave across the floor with comic effect. The slave leaves a trail of tears across the flooring as $he vanishes into the room. As you continue making your rounds, you hear a drawn-out howl followed by rhythmic screaming. - <<set $activeSlave.counter.anal += 1>> - <<set $analTotal += 1>> - <<set _S.HeadGirl.trust += 4, _S.HeadGirl.counter.penetrative += 1>> - <<set $penetrativeTotal += 1>> - <</replace>> -<</link>> -<br><<link "Take part">> - <<replace "#result">> - You explain $activeSlave.slaveName's double crime to $him, and tell _S.HeadGirl.slaveName to get started. Your Head Girl orders the weeping slave to present $his anus. The <<if $activeSlave.physicalAge > 30>>$woman<<else>>$girl<</if>> does not resist, but nor does $he comply. _S.HeadGirl.slaveName jabs a thumb into $activeSlave.slaveName's side, right above $his kidney, driving the wind out of the slave with a pained grunt. $He arches $his back involuntarily and $his grip on you loosens, so _S.HeadGirl.slaveName drags $him off you, telling $activeSlave.slaveName that it'll hurt less if $he cooperates and assumes the proper position. $He doesn't, so _S.HeadGirl.slaveName assfucks $him lying flat on the floor, with the poor $girl sobbing loudly as _S.HeadGirl.slaveName <<if canPenetrate(_S.HeadGirl) && (_S.HeadGirl.dick > 2)>>pistons _his2 cock in and out of $his rectum<<else>>rams the massive dildo up $his butt<</if>>. - <br><br> - After enjoying the spectacle for a while, you judge that the slave's sphincter is loose enough and tell _S.HeadGirl.slaveName to flip the bitch over. @@.hotpink;_He2 obeys, chuckling,@@ sitting _himself2 down and hauling the reluctant slave onto _his2 lap by seizing a nipple and pulling it into position so the agonized slave is forced to follow. <<if canPenetrate(_S.HeadGirl) && (_S.HeadGirl.dick > 2)>>_S.HeadGirl.slaveName reinserts _his2 dick, <<else>>_S.HeadGirl.slaveName maneuvers the dildo down over _his2 own crotch, approximating the position of a natural cock and using its base to stimulate _himself2. _He2 reinserts it,<</if>> intentionally missing twice to keep the experience unpleasant despite _his2 victim's well-fucked backdoor. - <br><br> - $activeSlave.slaveName, now facing upward rather than having $his face ground into the floor, notices for the first time that <<if $PC.dick != 0>>you've got your dick out and hard<<else>>you've donned one of your punishment-sized strap-ons<</if>>. $His <<= App.Desc.eyesColor($activeSlave)>> @@.gold;fly open with horror@@ as you kneel down and smack its head against $his <<if $activeSlave.vagina > -1>>poor pussy<<else>>stretched taint<</if>>, but $he doesn't realize how comprehensively fucked $he is until you press it against the top of $his already-stretched anal sphincter. "Plea<<s>>e no, <<Master>>! It won't fit! Plea<<s>>e <<if $activeSlave.vagina > 0>>put it in my pu<<ss>>y<<else>>let me <<s>>uck it<</if>> in<<s>>tead," $he begs desperately. "I p-promi<<s>>e I'll be a g-good - <<if $girl == "girl">> - giiAAIIEEHH," - <<elseif $girl == "boy">> - boAAIIEEHH," - <<elseif $girl == "toy">> - toAAIIEEHH," - <<else>> - <<s>>laAAIIEEHH," - <</if>> - $he howls. $He gasps for air, tears streaming down $his $activeSlave.skin cheeks, and then continues: "AAAH! FUCK! TAKE IT OUUUT! N-NOOO, PLEA<<S>>E DON'T THRU<<S>>T — AAAH! AAAH! AAAH!" - <<set $activeSlave.trust -= 5, $activeSlave.counter.anal += 1>> - <<set $analTotal += 1>> - <<set _S.HeadGirl.devotion += 4, _S.HeadGirl.counter.penetrative += 1>> - <<set $penetrativeTotal += 1>> - <</replace>> -<</link>> -<br><<link "Take pity">> - <<replace "#result">> - You tell _S.HeadGirl.slaveName you've decided to be merciful, just this once. $activeSlave.slaveName holds your leg even harder, @@.mediumaquamarine;sobbing $his thanks@@ over and over until you reach down, pat $his head, and tell $him it will be all right, calming the hysterical <<if $activeSlave.physicalAge > 30>>$woman<<else>>$girl<</if>>. _S.HeadGirl.slaveName, meanwhile, stammers an apology. _He2 hurries about _his2 business, @@.gold;badly puzzled@@ and more than a little shaken. _He2 thought _he2 had the authority to anally rape misbehaving slaves, but _he2's no longer so sure of _his2 rights and responsibilities. - <<set $activeSlave.trust += 4>> - <<set _S.HeadGirl.trust -= 15>> - <</replace>> -<</link>> -</span> diff --git a/src/uncategorized/reDevotedMotherDaughter.tw b/src/uncategorized/reDevotedMotherDaughter.tw deleted file mode 100644 index 7b1f1ca9740b1d8a546ac6bf7ab842b7fa0e2d4c..0000000000000000000000000000000000000000 --- a/src/uncategorized/reDevotedMotherDaughter.tw +++ /dev/null @@ -1,68 +0,0 @@ -:: RE devoted mother daughter [nobr] - -<<set $nextButton = "Continue", $nextLink = "RIE Eligibility Check">> - -<<set $i = $slaveIndices[$devMother]>> -<<set $j = $slaveIndices[$devDaughter]>> -<<setLocalPronouns $slaves[$i]>> -<<setLocalPronouns $slaves[$j] 2>> - -<<set _clothesTemp = $slaves[$i].clothes, $slaves[$i].clothes = "no clothing">> -<<set _clothesTemp2 = $slaves[$j].clothes, $slaves[$j].clothes = "no clothing">> -<span id="art-frame"> - /* 000-250-006 */ - <<if $seeImages == 1>> - <div class="imageColumn"> - <div class="imageRef medImg"> - <<SlaveArt $slaves[$i] 2 0>> - </div> - <div class="imageRef medImg"> - <<SlaveArt $slaves[$j] 2 0>> - </div> - </div> - <</if>> - /* 000-250-006 */ -</span> -<<set $slaves[$i].clothes = _clothesTemp>> -<<set $slaves[$j].clothes = _clothesTemp2>> - -$slaves[$i].slaveName and $his _daughter2 $slaves[$j].slaveName are both good slaves, devoted and obedient. They'd probably do anything you order them to do. By happenstance they come before you for inspection one after the other. They certainly see each other stark naked frequently enough. As you finish $slaves[$i].slaveName's inspection, $his _daughter2 waits patiently for _his2 turn. It occurs to you that they probably would do //anything// you order them to do, and that they're so acclimated to sexual slavery that they might well enjoy it. - -<br><br> - -<span id="result"> -<br><<link "Spend the night sharing your bed with them, and each of them with the other">> - <<replace "#result">> - Neither of them bat an eye when you announce you're turning in early and that they'll be joining you. Since they're already naked, they get into your big soft bed before you and lie facing each other, with enough room in between them for you to take a central position. They clearly assume you'll start with one of them on each side of you, so they're quite surprised when you slide in behind $slaves[$i].slaveName instead. $slaves[$j].slaveName snuggles up to _his2 $mother happily enough, however. You extend the foreplay for hours, eventually bringing both of them to such a state of naked arousal that they begin grinding against each other as much as they do you. They get the idea, and things turn into a sort of unspoken mutual one-upmanship between them. What starts with $slaves[$j].slaveName clearly feeling very daring as _he2 sucks _his2 $mother's nipple ends with $slaves[$i].slaveName lying on $his back getting fucked by you while $he orally pleasures $slaves[$j].slaveName. You're face to face with $slaves[$j].slaveName and _he2 groans happily into your mouth as $slaves[$i].slaveName moans into _his2 fuckhole. - @@.mediumaquamarine;They have both become more trusting of you.@@ - - <<set $slaves[$i].trust += 4, $slaves[$j].trust += 4, $slaves[$i].counter.oral += 1, $slaves[$j].counter.oral += 1, $oralTotal += 2>> - - <<if canDoAnal($slaves[$i])>> - <<set $slaves[$i].counter.anal += 1>> - <<set $analTotal += 1>> - <<elseif canDoVaginal($slaves[$i])>> - <<set $slaves[$i].counter.vaginal += 1>> - <<set $vaginalTotal += 1>> - <</if>> - - <<if canDoAnal($slaves[$j])>> - <<set $slaves[$j].counter.anal += 1>> - <<set $analTotal += 1>> - <<elseif canDoVaginal($slaves[$j])>> - <<set $slaves[$j].counter.vaginal += 1>> - <<set $vaginalTotal += 1>> - <</if>> - - <</replace>> -<</link>> -<br><<link "Get them started and then keep them at it in your office">> - <<replace "#result">> - You give them orders of devastating simplicity: they are to repair to the couch in your office and are to take turns getting each other off until such time as you tell them otherwise. They're momentarily stunned, but $slaves[$i].slaveName takes the lead and draws $his _daughter2 over to the couch<<if hasAnyArms($slaves[$i]) && hasAnyArms($slaves[$j])>> by the hand<</if>>. They're both accomplished sex slaves and obey orders well, so they are quite successful in the little game, if a bit mechanical. For the rest of the day, interviewees come and go and are treated to the sight of the two of them having subdued sex on the couch. Showing off one's slaves for business interlocutors is a common Free Cities practice, but more than one perceptive person figures out what the resemblance between the two slaves and the age gap between them really means. Of course, all those who figure it out are impressed by your sheer decadence. - @@.green;Your reputation has increased considerably.@@ - <<run repX(2500, "event", $slaves[$i])>> - <<run repX(2500, "event", $slaves[$j])>> - <<set $slaves[$i].counter.oral += 5, $slaves[$j].counter.oral += 5, $oralTotal += 10>> - <</replace>> -<</link>> -</span> diff --git a/src/uncategorized/reFormerAbolitionist.tw b/src/uncategorized/reFormerAbolitionist.tw deleted file mode 100644 index 873c6fb7c4d6c5d03c067765b1290bf6a2f9f42d..0000000000000000000000000000000000000000 --- a/src/uncategorized/reFormerAbolitionist.tw +++ /dev/null @@ -1,92 +0,0 @@ -:: RE former abolitionist [nobr] - -<<set $nextButton = "Continue">> -<<set $nextLink = "AS Dump">> -<<set $returnTo = "RIE Eligibility Check">> - -<<if $legendaryFacility == 1>> - <<set $activeSlave = getSlave($legendaryAbolitionistID)>> -<<else>> - <<set $activeSlave = $eventSlave>> -<</if>> -<<run App.Utils.setLocalPronouns($activeSlave)>> - -Crime is extremely rare in $arcologies[0].name, and some would say justice rarer still, but if there's one thing that unites the citizens of $arcologies[0].name, it's a mutual outrage towards attempted abolitionists. Slaveownership is the cornerstone of the society that protects and enriches them, and they see those who would attempt to unlawfully free slaves not just as thieves of property but as anarchists trying to bring down everything they have worked to build. - -While a brutal flogging or surgical mutilation soothes their outrage, nothing warms the collective heart of $arcologies[0].name's mob like the sight of a former abolitionist well and truly broken. <<= App.UI.slaveDescriptionDialog($activeSlave)>> is one such shining example, and $his borderline worship of you is doing wonders for your reputation lately as $he becomes a local celebrity and a popular topic of discussion. - -This is a rare opportunity. While the mob is quick to pat itself on the back for withstanding attacks from abolitionists, before long they will tire of remembering those dangers and turn their attention elsewhere. It might be possible, with a serious investment of funds in publicity, to really fix $him in the public mind as a shining example of your slave-breaking prowess. - -<br><br> - -<span id="result"> -<<link "Just capitalize on $his popularity to increase your reputation">> - <<replace "#result">> - You spend the week parading $activeSlave.slaveName around in public, letting everyone get a good look at $his fawning adoration of you. A variety of public sex acts really nails the point home in the psyche of your citizens and @@.yellowgreen;increases your reputation,@@ and after a few days you start to receive a sincere golf clap from onlookers every time you cum in or on $activeSlave.slaveName. - <<run repX(1000, "event", $activeSlave)>> - <</replace>> -<</link>> -<span id="result"> -<br><<link "Just capitalize on $his popularity by renting out $his mouth">> - <<replace "#result">> - You fasten $activeSlave.slaveName in a kneeling position in the center of your club, secured by shackles around $his <<if hasAnyArms($activeSlave)>>wrist<<if hasBothArms($activeSlave)>>s<</if>><<if hasAnyLegs($activeSlave)>> and <</if>><</if>><<if hasAnyLegs($activeSlave)>>ankle<<if hasBothLegs($activeSlave)>>s<</if>><</if>> — purely decorative, since $he's so devoted $he'd perform $his role in this if you just hinted it would please you if $he did. In front of $him, you place a sign: "Fuck the mouth that preached abolitionism, <<print cashFormat(5)>>." In a few moments, the morning crowd will begin to arrive, and you have no doubt that $activeSlave.slaveName will be very, very popular. And $he is. Even with an extra dose of curatives and a check-up every night, the strain of a week of dicks and a diet of cum @@.health.dec;has taken a toll on $his health.@@ But even after you pay to have the area that $activeSlave.slaveName worked thoroughly cleaned, you have made @@.yellowgreen;a tidy profit.@@ - <<run healthDamage($activeSlave, 10)>> - <<set $activeSlave.counter.oral += random(410,440)>> - <<run cashX(2000, "event", $activeSlave)>> - <</replace>> -<</link>> -<br><<link "Invest <<print cashFormat(5000)>> in making $him locally famous">> - <<if random(1,100) > 50>> - <<replace "#result">> - You buy media coverage of $him, invest in an ad campaign, and even arrange for $him to give a speech denouncing the abolitionist movement and praising your efforts in fighting against them. Your efforts are a success. $His current extreme popularity will fade in time, but you have managed to arrange for $him a permanent place as an @@.green;example of your slave-breaking skills.@@ - <<run cashX(-5000, "event", $activeSlave)>> - <<run repX(1000, "event", $activeSlave)>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is notorious as a former abolitionist turned devoted slave.">> - <</replace>> - <<else>> - <<replace "#result">> - You buy media coverage of $him, invest in an ad campaign, and even arrange for $him to give a speech denouncing the abolitionist movement and praising your efforts in fighting against them. Unfortunately, popularity remains an art, not a science; though you do your best, the public mind's fancy eludes your grasp. As $his owner, your reputation has @@.green;increased,@@ but in a week $he'll be forgotten. - <<run cashX(-5000, "event", $activeSlave)>> - <<run repX(1000, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -<br><<link "Lavish <<print cashFormat(10000)>> on making $him locally famous">> - <<if random(1,100) > 10>> - <<replace "#result">> - You buy prime media coverage of $him, invest in a lavish ad campaign, and even arrange for $him to give a speech denouncing the abolitionist movement and praising your efforts in fighting against them that is broadcast around the world. Your efforts are a success. $His current extreme popularity will fade in time, but you have managed to arrange for $him a permanent place as an @@.green;example of your slave-breaking skills.@@ - <<run cashX(-10000, "event", $activeSlave)>> - <<run repX(2000, "event", $activeSlave)>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is notorious as a former abolitionist turned devoted slave.">> - <</replace>> - <<else>> - <<replace "#result">> - You buy prime media coverage of $him, invest in a lavish ad campaign, and even arrange for $him to give a speech denouncing the abolitionist movement and praising your efforts in fighting against them that is broadcast around the world. Unfortunately, popularity remains an art, not a science; though you do your best, the public mind's fancy eludes your grasp. As $his owner, your reputation has @@.green;increased,@@ but in a week $he'll be forgotten. - <<run cashX(-10000, "event", $activeSlave)>> - <<run repX(2000, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -</span> -<br><<link "Spend <<print cashFormat(25000)>> on an attempt to make $him world famous">> - <<if random(1,100) > 50>> - <<replace "#result">> - The world is in love with $activeSlave.slaveName. $His face graces magazine covers the world over and $his passionate arguments (ghostwritten by the best spin doctors money can buy) spark debate everywhere they're heard. $He is mentioned by name in strident denunciations about the immorality of the present day from religious leaders. $He appears on the internet with all sorts of attempts at humor superimposed on $his image. $His loving and overblown descriptions of you spark a new trend in protagonists of badly-written romance novels. When a very popular talk show host attempts to call $his bluff and receives oral sex in front of a live studio audience, @@.yellowgreen;you know for sure that $his fame has stuck.@@ - <<run cashX(-25000, "event", $activeSlave)>> - <<run repX(3000, "event", $activeSlave)>> - <<set $activeSlave.prestige = 2>> - <<set $activeSlave.prestigeDesc = "$He is world famous as an anti-abolitionist, and has told the world at length of the joys of slavery in general and slavery to you in particular.">> - <</replace>> - <<else>> - <<replace "#result">> - The world seems temporarily enamored with $activeSlave.slaveName as $he appears on talk shows and in political debates with millions of watchers, but before long $his fifteen minutes of fame peter out and the only offers coming in are from pornography magnates and local talk radio shows. Though $he achieved @@.yellowgreen;local fame@@ for appearing on the world stage, the rest of the world seems to have gotten bored with $activeSlave.slaveName. - <<run cashX(-25000, "event", $activeSlave)>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is notorious as a former abolitionist turned devoted slave.">> - <<run repX(2000, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -</span> diff --git a/src/uncategorized/reLegendaryBalls.tw b/src/uncategorized/reLegendaryBalls.tw deleted file mode 100644 index d9e00ee001f3de16561734251dcc46861def7c71..0000000000000000000000000000000000000000 --- a/src/uncategorized/reLegendaryBalls.tw +++ /dev/null @@ -1,91 +0,0 @@ -:: RE legendary balls [nobr] - -<<set $nextButton = "Continue", $nextLink = "AS Dump", $returnTo = "RIE Eligibility Check", $activeSlave = ($legendaryFacility == 1) ? getSlave($legendaryBallsID) : $eventSlave>> - -<<if (ndef $activeSlave)>> /* not found — reset variable and stop event */ - <<set $legendaryBallsID = 0>> - <<goto "RIE Eligibility Check">> -<<else>> - -<<run App.Utils.setLocalPronouns($activeSlave)>> -<<set $activeSlave.devotion += 4>> - -<span id="art-frame"> -/* 000-250-006 */ -<<if $seeImages == 1>> - <<if $imageChoice == 1>> - <div class="imageRef lrgVector"><div class="mask"> </div><<SlaveArt $activeSlave 3 0>></div> - <<else>> - <div class="imageRef lrgRender"><div class="mask"> </div><<SlaveArt $activeSlave 3 0>></div> - <</if>> -<</if>> -/* 000-250-006 */ -</span> - -<<= App.UI.slaveDescriptionDialog($activeSlave)>> is an incredible producer of cum. $He's producing in volumes that would have been unthinkable in the days when it was illegal to restrain a slave so that $he could have every drop of $his ejaculate milked out by a machine. A nascent slave stock organization will be holding a public livestock show tomorrow, and since they're aware you're experimenting with cockmilking, they've sent you an invitation to enter an especially productive slave to be judged. - -<br><br> - -This is a rare opportunity. The idea of cockmilking is new and understandably fascinating to many, so the livestock show is likely to draw some serious press. Were $activeSlave.slaveName to win, $he would probably be remembered for a long time as a special slave. - -<br><br> - -<span id="result"> -<<link "Fairly enter $him in the livestock show">> - <<if random(1,100) > 90>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then publicly cockmilked. It's likely there was some bribery behind the scenes, but $his massive junk wins the day. Against all odds $he is named best in show, and will be @@.green;remembered@@ as cock stock of the highest pedigree. As $his owner, your reputation has @@.green;also increased.@@ - <<run repX(500, "event", $activeSlave)>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is remembered for winning best in show as a cockmilker.">> - <<set $desc = "a best in show ribbon awarded to " + $activeSlave.slaveName + " for " + getPronouns($activeSlave).possessive + " balls">> - <<set $trinkets.push($desc)>> - <</replace>> - <<else>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then publicly cockmilked. It's likely there was some bribery behind the scenes, and it is fatal to $his chances of winning. Though $his junk is easily the most impressive on display, another stock owner who was more open-handed with the judges took best in show. The public is impressed with $activeSlave.slaveName's nuts anyway; as you are $his owner, your reputation has @@.green;increased@@ a little. - <<run repX(500, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -<br><<link "Spend <<print cashFormat(5000)>> bribing the judges">> - <<if random(1,100) > 50>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then publicly cockmilked. Several of the judges cannot resist giving you a wink as they look $him over. $activeSlave.slaveName is unsurprisingly named best in show, and will be @@.green;remembered@@ as cock stock of the highest pedigree. As $his owner, your reputation has @@.green;also increased.@@ - <<run cashX(-5000, "event", $activeSlave)>> - <<run repX(500, "event", $activeSlave)>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is remembered for winning best in show as a cockmilker.">> - <<set $desc = "a best in show ribbon awarded to " + $activeSlave.slaveName + " for " + getPronouns($activeSlave).possessive + " balls">> - <<set $trinkets.push($desc)>> - <</replace>> - <<else>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then publicly cockmilked. Several of the judges cannot resist giving you a wink as they look $him over, but others look disapprovingly at them; it seems some of your competitors also forwarded money to the committee. After furious wrangling, $activeSlave.slaveName loses to another milker. The public is impressed with $activeSlave.slaveName's balls anyway; as you are $his owner, your reputation has @@.green;increased@@ a little. - <<run cashX(-5000, "event", $activeSlave)>> - <<run repX(500, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -<br><<link "Spend <<print cashFormat(10000)>> bribing the judges and sabotaging the competition">> - <<if random(1,100) > 10>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then publicly cockmilked. After $he's put through $his paces, the most unfortunate series of accidents somehow befalls $his fellow cows. One is taken ill, another seems drugged, and someone seems to have slipped a finger of raw ginger up another's urethra, making them whine and squeal when cockmilked. $activeSlave.slaveName is unsurprisingly named best in show, and will be @@.green;remembered@@ as cock stock of the highest pedigree. As $his owner, your reputation has @@.green;also increased.@@ - <<run cashX(-10000, "event", $activeSlave)>> - <<run repX(500, "event", $activeSlave)>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is remembered for winning best in show as a cockmilker.">> - <<set $desc = "a best in show ribbon awarded to " + $activeSlave.slaveName + " for " + getPronouns($activeSlave).possessive + " balls">> - <<set $trinkets.push($desc)>> - <</replace>> - <<else>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then publicly cockmilked. You are surprised to see that the judging committee has been changed at the last minute. They choose another cow as best in show. There are persistent @@.red;rumors@@ after the show that there was an absolute massacre of firings at the stock organization headquarters the night before the show after it was discovered that someone, widely thought to be you, had been corrupting the judges. - <<run cashX(-10000, "event", $activeSlave)>> - <<run repX(-100, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -</span> - -<</if>> /* closes validity check */ diff --git a/src/uncategorized/reLegendaryCow.tw b/src/uncategorized/reLegendaryCow.tw deleted file mode 100644 index e0ad0cdc8ed47b8fd4ff54395d32f8d929627fe0..0000000000000000000000000000000000000000 --- a/src/uncategorized/reLegendaryCow.tw +++ /dev/null @@ -1,91 +0,0 @@ -:: RE legendary cow [nobr] - -<<set $nextButton = "Continue", $nextLink = "AS Dump", $returnTo = "RIE Eligibility Check", $activeSlave = ($legendaryFacility == 1) ? getSlave($legendaryCowID) : $eventSlave>> - -<<if (ndef $activeSlave)>> /* not found — reset variable and stop event */ - <<set $legendaryCowID = 0>> - <<goto "RIE Eligibility Check">> -<<else>> - -<<run App.Utils.setLocalPronouns($activeSlave)>> -<<set $activeSlave.devotion += 4>> - -<span id="art-frame"> -/* 000-250-006 */ -<<if $seeImages == 1>> - <<if $imageChoice == 1>> - <div class="imageRef lrgVector"><div class="mask"> </div><<SlaveArt $activeSlave 3 0>></div> - <<else>> - <div class="imageRef lrgRender"><div class="mask"> </div><<SlaveArt $activeSlave 3 0>></div> - <</if>> -<</if>> -/* 000-250-006 */ -</span> - -<<= App.UI.slaveDescriptionDialog($activeSlave)>> is an incredible producer of milk. $He's lactating in volumes that would have been unthinkable in the days when drug treatments were limited by consent. A nascent slave dairy trade organization will be holding a public stock show tomorrow, and since they're aware you keep cows, they've sent you an invitation to enter stock to be judged. - -<br><br> - -This is a rare opportunity. The idea of human dairy is new and understandably fascinating to many, so the stock show is likely to draw some serious press. Were $activeSlave.slaveName to win, $he would probably be remembered for a long time as a special cow. - -<br><br> - -<span id="result"> -<<link "Fairly enter $him in the stock show">> - <<if random(1,100) > 90>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then publicly milked. It's likely there was some bribery behind the scenes, but $his massive tits win the day. Against all odds $he is named best in show, and will be @@.green;remembered@@ as dairy stock of the highest pedigree. As $his owner, your reputation has @@.green;also increased.@@ - <<run repX(500, "event", $activeSlave)>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is remembered for winning best in show as a dairy cow.">> - <<set $desc = "a best in show ribbon awarded to " + $activeSlave.slaveName + " as a milk cow">> - <<set $trinkets.push($desc)>> - <</replace>> - <<else>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then publicly milked. It's likely there was some bribery behind the scenes, and it is fatal to $his chances of winning. Though $his tits are easily the most impressive on display, another stock owner who was more open-handed with the judges took best in show. The public is impressed with $activeSlave.slaveName's tits anyway; as you are $his owner, your reputation has @@.green;increased@@ a little. - <<run repX(500, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -<br><<link "Spend <<print cashFormat(5000)>> bribing the judges">> - <<if random(1,100) > 50>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then publicly milked. Several of the judges cannot resist giving you a wink as they look $him over. $activeSlave.slaveName is unsurprisingly named best in show, and will be @@.green;remembered@@ as dairy stock of the highest pedigree. As $his owner, your reputation has @@.green;also increased.@@ - <<run cashX(-5000, "event", $activeSlave)>> - <<run repX(500, "event", $activeSlave)>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is remembered for winning best in show as a dairy cow.">> - <<set $desc = "a best in show ribbon awarded to " + $activeSlave.slaveName + " as a milk cow">> - <<set $trinkets.push($desc)>> - <</replace>> - <<else>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then publicly milked. Several of the judges cannot resist giving you a wink as they look $him over, but others look disapprovingly at them; it seems some of your competitors also forwarded money to the committee. After furious wrangling, $activeSlave.slaveName loses to another cow. The public is impressed with $activeSlave.slaveName's tits anyway; as you are $his owner, your reputation has @@.green;increased@@ a little. - <<run cashX(-5000, "event", $activeSlave)>> - <<run repX(500, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -<br><<link "Spend <<print cashFormat(10000)>> bribing the judges and sabotaging the competition">> - <<if random(1,100) > 10>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then publicly milked. After $he's put through $his paces, the most unfortunate series of accidents somehow befalls $his fellow cows. One is taken ill, another seems drugged, and someone seems to have slipped a finger of raw ginger up another's ass, making them whine and squeal constantly. $activeSlave.slaveName is unsurprisingly named best in show, and will be @@.green;remembered@@ as dairy stock of the highest pedigree. As $his owner, your reputation has @@.green;also increased.@@ - <<run cashX(-10000, "event", $activeSlave)>> - <<run repX(500, "event", $activeSlave)>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is remembered for winning best in show as a dairy cow.">> - <<set $desc = "a best in show ribbon awarded to " + $activeSlave.slaveName + " as a milk cow">> - <<set $trinkets.push($desc)>> - <</replace>> - <<else>> - <<replace "#result">> - $activeSlave.slaveName is shown in public, closely inspected by the judging committee, and then publicly milked. You are surprised to see that the judging committee has been changed at the last minute. They choose another cow as best in show. There are persistent @@.red;rumors@@ after the show that there was an absolute massacre of firings at the dairy organization headquarters the night before the show after it was discovered that someone, widely thought to be you, had been corrupting the judges. - <<run cashX(-10000, "event", $activeSlave)>> - <<run repX(-100, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -</span> - -<</if>> /* closes validity check */ diff --git a/src/uncategorized/reLegendaryEntertainer.tw b/src/uncategorized/reLegendaryEntertainer.tw deleted file mode 100644 index 7e3c672f60cb2b5ebdb488b81300baa595be3c27..0000000000000000000000000000000000000000 --- a/src/uncategorized/reLegendaryEntertainer.tw +++ /dev/null @@ -1,84 +0,0 @@ -:: RE legendary entertainer [nobr] - -<<set $nextButton = "Continue", $nextLink = "AS Dump", $returnTo = "RIE Eligibility Check", $activeSlave = ($legendaryFacility == 1) ? getSlave($legendaryEntertainerID) : $eventSlave>> - -<<if (ndef $activeSlave)>> /* not found — reset variable and stop event */ - <<set $legendaryEntertainerID = 0>> - <<goto "RIE Eligibility Check">> -<<else>> - -<<run App.Utils.setLocalPronouns($activeSlave)>> -<<set $activeSlave.devotion += 4>> - -<span id="art-frame"> -/* 000-250-006 */ -<<if $seeImages == 1>> - <<if $imageChoice == 1>> - <div class="imageRef lrgVector"><div class="mask"> </div><<SlaveArt $activeSlave 3 0>></div> - <<else>> - <div class="imageRef lrgRender"><div class="mask"> </div><<SlaveArt $activeSlave 3 0>></div> - <</if>> -<</if>> -/* 000-250-006 */ -</span> - -The Free Cities fashion scene extends to slave bodies, of course; stopping at mere clothes and behaviors is an old world conceit. This week, <<= App.UI.slaveDescriptionDialog($activeSlave)>> is in vogue. Such a crowd of gawkers and hangers-on follows $him around the club that the fine citizens who have a chance at an hour of $his time must shoulder their way through the throng. - -<br><br> - -This is a rare opportunity. Such popularity and fame is here today, and gone tomorrow. It might be possible, with a serious investment of funds in publicity, to really fix $him in the public mind as a courtesan of note. There's no guarantee of success, but if you are successful, $his value will increase a great deal. - -<br><br> - -<span id="result"> -<<link "Just capitalize on $his popularity as it is">> - <<replace "#result">> - You decide to limit your advantage on $his temporary popularity to a little publicity and some advertising. You've gained a little @@.green;notoriety.@@ - <<run repX(1000, "event", $activeSlave)>> - <</replace>> -<</link>> -<br><<link "Invest <<print cashFormat(5000)>> in $his image">> - <<if random(1,100) > 50>> - <<replace "#result">> - You buy media coverage of $him, invest in an ad campaign, and even arrange for persons of influence and taste to sample and review $his gentle caresses. Your efforts are a success. $His current extreme popularity will fade in time, but you have managed to arrange for $him a permanent place as a @@.green;respected and famous courtesan.@@ As $his owner, your reputation has @@.green;also increased.@@ - <<run cashX(-5000, "event", $activeSlave)>> - <<run repX(1000, "event", $activeSlave)>> - <<if $activeSlave.prestige <= 1>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is a famed Free Cities slut, and can please anyone.">> - <</if>> - <<set $desc = "a framed article written about " + $activeSlave.slaveName + " when " + getPronouns($activeSlave).pronoun + " debuted as a famous courtesan">> - <<set $trinkets.push($desc)>> - <</replace>> - <<else>> - <<replace "#result">> - You buy media coverage of $him, invest in an ad campaign, and even arrange for persons of influence and taste to sample and review $his gentle caresses. Unfortunately, popularity remains an art, not a science; though you do your best, the public mind's fancy eludes your grasp. As $his owner, your reputation has @@.green;increased,@@ but in a week $he'll be forgotten. - <<run cashX(-5000, "event", $activeSlave)>> - <<run repX(1000, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -<br><<link "Lavish <<print cashFormat(10000)>> on $his fame">> - <<if random(1,100) > 10>> - <<replace "#result">> - You buy prime media coverage of $him, invest in a lavish ad campaign, and even arrange for persons of great influence and fine taste to sample and review $his gentle caresses. Your efforts are a success. $His current extreme popularity will fade in time, but you have managed to arrange for $him a permanent place as a @@.green;respected and famous courtesan.@@ As $his owner, your reputation has @@.green;also increased.@@ - <<run cashX(-10000, "event", $activeSlave)>> - <<run repX(2000, "event", $activeSlave)>> - <<if $activeSlave.prestige <= 1>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is a famed Free Cities slut, and can please anyone.">> - <</if>> - <<set $desc = "a framed article written about " + $activeSlave.slaveName + " when " + getPronouns($activeSlave).pronoun + " debuted as a famous courtesan">> - <<set $trinkets.push($desc)>> - <</replace>> - <<else>> - <<replace "#result">> - You buy prime media coverage of $him, invest in a lavish ad campaign, and even arrange for persons of great influence and fine taste to sample and review $his gentle caresses. Unfortunately, popularity remains an art, not a science; though you do your best, the public mind's fancy eludes your grasp. As $his owner, your reputation has @@.green;increased,@@ but in a week $he'll be forgotten. - <<run cashX(-10000, "event", $activeSlave)>> - <<run repX(2000, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -</span> - -<</if>> /* closes validity check */ diff --git a/src/uncategorized/reLegendaryWhore.tw b/src/uncategorized/reLegendaryWhore.tw deleted file mode 100644 index 19beb4f31d27ea0d667379dd7b0ecb8d9bebcfb9..0000000000000000000000000000000000000000 --- a/src/uncategorized/reLegendaryWhore.tw +++ /dev/null @@ -1,81 +0,0 @@ -:: RE legendary whore [nobr] - -<<set $nextButton = "Continue", $nextLink = "AS Dump", $returnTo = "RIE Eligibility Check", $activeSlave = ($legendaryFacility == 1) ? getSlave($legendaryWhoreID) : $eventSlave>> - -<<if (ndef $activeSlave)>> /* not found — reset variable and stop event */ - <<set $legendaryWhoreID = 0>> - <<goto "RIE Eligibility Check">> -<<else>> - -<<run App.Utils.setLocalPronouns($activeSlave)>> -<<set $activeSlave.devotion += 4>> - -<span id="art-frame"> -/* 000-250-006 */ -<<if $seeImages == 1>> - <<if $imageChoice == 1>> - <div class="imageRef lrgVector"><div class="mask"> </div><<SlaveArt $activeSlave 3 0>></div> - <<else>> - <div class="imageRef lrgRender"><div class="mask"> </div><<SlaveArt $activeSlave 3 0>></div> - <</if>> -<</if>> -/* 000-250-006 */ -</span> - -The Free Cities red light areas are so overcharged with cheap and easy sex that the fashion in whores is comically unstable. This week, <<= App.UI.slaveDescriptionDialog($activeSlave)>> is in vogue. So many customers are interested in renting $his body that it's necessary to assign other whores to take some of the load off $him by diverting less important customers away from $him. - -<br><br> - -This is a rare opportunity. Such popularity and fame is here today, and gone tomorrow. It might be possible, with a serious investment of funds in publicity, to really fix $him in the public mind as a whore of note. There's no guarantee of success, but if you are successful, $his value will increase a great deal. - -<br><br> - -<span id="result"> -<<link "Just capitalize on $his popularity as it is">> - <<replace "#result">> - You decide to limit your advantage on $his temporary popularity to a little marketing and some minor price increases. You've made some unexpected @@.yellowgreen;profits,@@ and gained a little @@.green;notoriety.@@ - <<run cashX(1000, "event", $activeSlave)>> - <<run repX(500, "event", $activeSlave)>> - <</replace>> -<</link>> -<br><<link "Invest <<print cashFormat(5000)>> in $his notoriety">> - <<if random(1,100) > 50>> - <<replace "#result">> - You buy media coverage of $him, invest in an ad campaign, and even arrange for persons of influence and taste to sample and review $his many delights. Your efforts are a success. $His current extreme popularity will fade in time, but you have managed to arrange for $him a permanent place as a @@.green;notorious and very popular prostitute.@@ As $his owner, your reputation has @@.green;also increased.@@ - <<run cashX(-5000, "event", $activeSlave)>> - <<run repX(500, "event", $activeSlave)>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is a famed Free Cities whore, and commands top prices.">> - <<set $desc = "a framed pornographic advertisement for " + $activeSlave.slaveName + " from the week " + getPronouns($activeSlave).pronoun + " became a famous whore">> - <<set $trinkets.push($desc)>> - <</replace>> - <<else>> - <<replace "#result">> - You buy media coverage of $him, invest in an ad campaign, and even arrange for persons of influence and taste to sample and review $his many delights. Unfortunately, popularity remains an art, not a science; though you do your best, the public mind's fancy eludes your grasp. As $his owner, your reputation has @@.green;increased,@@ but in a week $he'll be forgotten. - <<run cashX(-5000, "event", $activeSlave)>> - <<run repX(500, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -<br><<link "Lavish <<print cashFormat(10000)>> on $his fame">> - <<if random(1,100) > 10>> - <<replace "#result">> - You buy prime media coverage of $him, invest in a lavish ad campaign, and even arrange for persons of great influence and fine taste to sample and review $his many delights. Your efforts are a success. $His current extreme popularity will fade in time, but you have managed to arrange for $him a permanent place as a @@.green;notorious and very popular prostitute.@@ As $his owner, your reputation has @@.green;also increased.@@ - <<run cashX(-10000, "event", $activeSlave)>> - <<run repX(1000, "event", $activeSlave)>> - <<set $activeSlave.prestige = 1>> - <<set $activeSlave.prestigeDesc = "$He is a famed Free Cities whore, and commands top prices.">> - <<set $desc = "a framed pornographic advertisement for " + $activeSlave.slaveName + " from the week " + getPronouns($activeSlave).pronoun + " became a famous whore">> - <<set $trinkets.push($desc)>> - <</replace>> - <<else>> - <<replace "#result">> - You buy prime media coverage of $him, invest in a lavish ad campaign, and even arrange for persons of great influence and fine taste to sample and review $his many delights. Unfortunately, popularity remains an art, not a science; though you do your best, the public mind's fancy eludes your grasp. As $his owner, your reputation has @@.green;increased,@@ but in a week $he'll be forgotten. - <<run cashX(-10000, "event", $activeSlave)>> - <<run repX(1000, "event", $activeSlave)>> - <</replace>> - <</if>> -<</link>> -</span> - -<</if>> /* closes validity check */ diff --git a/src/uncategorized/reMilfTourist.tw b/src/uncategorized/reMilfTourist.tw deleted file mode 100644 index 029b474fa5eb58f32707b4d776c9b853fac5c66e..0000000000000000000000000000000000000000 --- a/src/uncategorized/reMilfTourist.tw +++ /dev/null @@ -1,170 +0,0 @@ -:: RE milf tourist [nobr] - -<<set $nextButton = "Continue", $nextLink = "RIE Eligibility Check", $returnTo = "RIE Eligibility Check">> - -<<set _milfed = $slaveIndices[$milfSlaveID]>> -<<set _milfSlave = $slaves[_milfed]>> -<<run Enunciate(_milfSlave)>> - -<<set _slave = GenerateNewSlave("XX", {minAge: 36, maxAge: 42, ageOverridesPedoMode: 1, race: "nonslave", disableDisability: 1})>> -<<set _slave.origin = "$He came to your arcology as a tourist and found $himself enslaved.">> -<<set _slave.devotion = random(-70,-55)>> -<<set _slave.trust = random(-45,-25)>> -<<run setHealth(_slave, jsRandom(10, 20), undefined, undefined, undefined, 5)>> -<<set _slave.vagina++>> -<<set _slave.hips = 2>> -<<set _slave.butt = random(4,6)>> -<<set _slave.boobs = 100*random(10,18)>> -<<set _slave.weight = random(60,140)>> -<<set _slave.behavioralQuirk = "none">> -<<set _slave.sexualQuirk = "none">> -<<set _slave.canRecruit = 0>> -<<set _slave.clothes = "nice business attire">> - -<span id="art-frame"> - /* 000-250-006 */ - <<if $seeImages == 1>> - <div class="imageColumn"> - <div class="imageRef medImg"> - <<SlaveArt _slave 2 0>> - </div> - <div class="imageRef medImg"> - <<SlaveArt _milfSlave 2 0>> - </div> - </div> - <</if>> - /* 000-250-006 */ -</span> - -<<setLocalPronouns _milfSlave>> -<<setLocalPronouns _slave 2>> -<<setAssistantPronouns>> - -<<if $assistant.personality == 1>> - <<= capFirstChar($assistant.name)>>'s - <<if $assistant.appearance == "normal">> - symbol - <<else>> - $assistant.appearance avatar - <</if>> - appears on your desk in the middle of the day. "Something unusual for you, <<= properTitle()>>," _heA says. "_milfSlave.slaveName is out doing public service. A tourist from the old world accosted $him. _milfSlave.slaveName thought _he2 was a rich citizen who wanted to fuck $him, but it turns out _he2 just wanted a tour guide. It was a reasonable mistake; _he2 seems wealthy. $He has been showing _him2 around for the last half hour. Now _he2's asked $him if _he2 can meet you." _HeA displays a video feed showing _milfSlave.slaveName standing with the tourist in question out on the main plaza. _He2's just into middle age, and extremely plush, wearing Capri pants over _his2 motherly hips and a cashmere sweater that understates _his2 generous bust. _He2's blushing as _he2 asks your slave a discreet question about public sex in the arcology, brought on by the sight of a couple of citizens spitroasting a slave. Your personal assistant's avatar - <<switch $assistant.appearance>> - <<case "monstergirl">> - bares _hisA fangs and makes pinching gestures at nipple height. - <<case "shemale">> - gives a wolf whistle and makes exaggerated gestures over _hisA own boobs. - <<case "amazon">> - brandishes a club suggestively. - <<case "businesswoman">> - looks the tourist up and down over the tops of _hisA glasses. - <<case "schoolgirl">> - stares openly at the tourist's ass. - <<case "fairy" "pregnant fairy">> - zips around the tourist, giving _him2 a good look-over. - <<case "hypergoddess" "goddess">> - eyes _his2 fertile hips. - <<case "loli" "preggololi">> - stares longingly at _his2 huge tits. - <<case "angel">> - blushes at the sight of _his2 obvious curves. - <<case "cherub">> - makes exaggerated movements over _hisA own tits. - <<case "incubus">> - is sporting an absolutely enormous erection. _HeA seems to be enjoying the show. - <<case "succubus">> - turns to face you; _hisA breasts huge armfuls, butt jiggling non-stop and a pair of hips to rival any cow. "My curves are better." - <<case "imp">> - makes pinching gestures at nipple height then turns and slaps _hisA own ass. - <<case "witch">> - blushes at the sight of those lovely curves. - <<case "ERROR_1606_APPEARANCE_FILE_CORRUPT">> - swells _himselfA to resemble _his2 figure before twisting _hisA arm into a cock and ramming it straight up _hisA cunt. - <<default>> - reforms into an exaggerated female form before going back to _hisA normal symbol shape. - <</switch>> -<<else>> - <<= capFirstChar($assistant.name)>> gets your attention the middle of the day. "A minor matter for you, <<= properTitle()>>," _heA says. "_milfSlave.slaveName is currently performing public service. A tourist from the old world accosted $him. _milfSlave.slaveName thought _he2 was a rich citizen who wanted to have sex with $him, but it seems _he2 just wanted a tour guide. It was a reasonable mistake; the tourist appears wealthy. $He has been acting as _his2 guide for the last half hour. The tourist has asked $him if _he2 can meet you." _HeA displays a video feed showing _milfSlave.slaveName standing with the tourist in question out on the main plaza. _He2's just into middle age, and extremely plush, wearing Capri pants over _his2 motherly hips and a cashmere sweater that understates _his2 generous bust. _He2's blushing as _he2 asks your slave a discreet question about public sex in the arcology, brought on by the sight of a couple of citizens spitroasting a slave. -<</if>> - -<br><br> - -<span id="result"> -<<link "Decline politely">> - <<replace "#result">> - <<setSpokenLocalPronouns _milfSlave _slave>> - You have $assistant.name instruct _milfSlave.slaveName to pass on your regrets, and add a message for _milfSlave.slaveName expressing confidence in $him to represent you and the arcology perfectly well without you. $He's @@.mediumaquamarine;affirmed@@ by your trust in $him. "<<Master>>," $he reports the next time you see $him, "that touri<<s>>t wa<<s>> really nice. Al<<s>>o, I got _him2 to have <<s>>e<<x>> with me, after all. <<He 2>> wa<<s>> all he<<s>>itant and blu<<sh>>y about doing it in public, but <<he 2>> got better after the fir<<s>>t time I ate _him2 out." $He looks pleased with $himself. "I bet <<he 2>> @@.green;tell<<s>> all <<his 2>> friend<<s>>@@ back home how much fun it i<<s>> here." - <<run repX(500, "event")>> - <<set $slaves[_milfed].trust += 4, $slaves[_milfed].counter.oral++>> - <<set $oralTotal++>> - <</replace>> -<</link>> -<br><<link "Share some Free Cities life with _him2">> - <<replace "#result">> - <<run Enunciate(_slave)>> - You have _milfSlave.slaveName bring the tourist up to meet you. _He2's full of questions about what it's like to be an arcology owner, and you finally tell _him2 that you can give _him2 a pretty good idea. Eagerly, _he2 asks you how, and you point at _milfSlave.slaveName, telling the tourist _he2 ought to bend the slave over the couch if _he2 wants to know what it's really like to be an oversexed oligarch. "I'm, um, not really a le<<s>>bian," the tourist responds hesitantly. - <<run Enunciate(_milfSlave)>> - <<if _milfSlave.dick > 0>> - "You don't have to be," $he purrs. "I have a cock." $He slides in, just close enough to prove it. "Plea<<s>>e, - <<else>> - "Having <<s>>e<<x>> with <<s>>lave<<s>> doe<<s>> not make you a le<<s>>bian," $he purrs. "It'<<s>> different here. Plea<<s>>e, - <</if>> - fuck me. It'll be fun!" The tourist turns to stare at _him2, and _he2 offers just the right kind of plaintive expression. "O-okay," the tourist says in a tiny voice, and _milfSlave.slaveName giggles, hugging _him2 from behind. $He cups one of the tourist's breasts, and snakes $his other hand down the front of _his2 pants. "Here!?" the tourist gasps, staring straight at you and blushing even harder. You tell _him2 that that's how you do things in the Free Cities: enjoying a slave is nothing to be ashamed of. _He2 looks doubtful, but _he2 doesn't try to escape from _milfSlave.slaveName's roving hand<<if hasBothArms(_milfSlave)>>s<</if>>, either. Your presence continues to bother _him2 until _milfSlave.slaveName distracts _him2 by getting _him2 to cuddle on the couch and make out, providing enough of a distraction that _he2 gets over _his2 inhibitions and orgasms rather immodestly. - <br><br> - You offer _him2 some liquid courage as _he2 recovers, but _he2's rapidly getting over _his2 hesitation. As the alcohol suffuses _him2, _he2 starts stealing glances at _milfSlave.slaveName, who for $his part is being as seductive as humanly possible. Finally, the tourist mouths 'fuck it' silently, reaches over, and openly gropes the slave's ass. _milfSlave.slaveName giggles and shifts lewdly, ensuring that the tourist's hand makes a thorough tour of everything the slave has. The tourist tentatively sinks a couple of fingers into $him, and the slave shamelessly slides $himself onto the invading digits, begging to be fucked. You make a party of it, with the various slaves who come and go over the course of the evening treated to the sight of $him getting fucked by the tourist. _He2 drunkenly promises you to @@.green;tell all _his2 friends@@ how awesome your arcology is at one point, though _he2 has to take _his2 mouth off one of _milfSlave.slaveName's nipples to do so. - <<set $slaves[_milfed].trust += 4, $slaves[_milfed].counter.oral += 3, $slaves[_milfed].counter.anal += 3>> - <<set $oralTotal += 3, $analTotal += 3>> - <<run repX(500, "event")>> - <<set $desc = "a thank-you note from a MILF tourist whom you made feel welcome in the arcology">> - <<set $trinkets.push($desc)>> - <</replace>> -<</link>> -<br><<link "Encourage _him2 to enjoy the slave with your compliments">> - <<replace "#result">> - <<run Enunciate(_slave)>> - You have _milfSlave.slaveName bring the tourist up to meet you, and exchange some minor pleasantries. You tell _him2 that if _he2 really wants to experience Free Cities life, though, _he2 really should enjoy _milfSlave.slaveName, pointing at the slave hovering behind _him2. _He2 blushes furiously, but before _he2 can stammer a refusal, the slave whispers something into _his2 ear. "I'm, um, not really a le<<s>>bian," the tourist responds hesitantly. - <<run Enunciate(_milfSlave)>> - <<if _milfSlave.dick > 0>> - "You don't have to be," $he purrs. "I have a cock." $He slides in, just close enough to prove it. "Plea<<s>>e, - <<else>> - "Having <<s>>e<<x>> with <<s>>lave<<s>> doe<<s>> not make you a le<<s>>bian," $he purrs. "It'<<s>> different here. Plea<<s>>e, - <</if>> - give me a try." The tourist turns to stare at $him, and _he2 offers just the right kind of plaintive expression. "O-okay," the tourist says in a tiny voice, and _milfSlave.slaveName giggles, hugging _him2 from behind. $He takes the tourist's hand, and they leave your office together. - <br><br> - <<setSpokenLocalPronouns _milfSlave _slave>> - "<<Master>>," $he reports the next time you see $him, "that touri<<s>>t was really nice. Al<<s>>o, I got _him2 to have <<s>>e<<x>> with me, after all. <<He 2>> wa<<s>> going to take me back to <<his 2>> hotel but I got _him2 to do me on the way. <<He 2>> wa<<s>> all he<<s>>itant and blu<<sh>>y about doing it in public, but <<he 2>> got better after the fir<<s>>t time I ate _him2 out." $He looks pleased with $himself. "I bet <<he 2>> @@.green;tell<<s>> all <<his 2>> friend<<s>>@@ back home how much fun it i<<s>> here." - <<set $slaves[_milfed].trust += 4, $slaves[_milfed].counter.oral++>> - <<set $oralTotal++>> - <<run repX(500, "event")>> - <<set $desc = "a thank-you note from a MILF tourist whom you made feel welcome in the arcology">> - <<set $trinkets.push($desc)>> - <</replace>> -<</link>> -<<if $cash > 20000>> - <br><<link "Enslave _him2">> - <<set _slave.clothes = "no clothing">> - <<replace "#art-frame">> - /* 000-250-006 */ - <<if $seeImages == 1>> - <div class="imageColumn"> - <div class="imageRef medImg"> - <<SlaveArt _slave 2 0>> - </div> - <div class="imageRef medImg"> - <<SlaveArt _milfSlave 2 0>> - </div> - </div> - <</if>> - /* 000-250-006 */ - <</replace>> - <<replace "#result">> - <<run Enunciate(_slave)>> - When your new slave comes to, _his2 weight is hanging from _his2 wrists, bound over _his2 head. _He2's not exactly thin, making the position uncomfortable for _his2 arms, so _he2 groggily stands, finding _himself2 in a pool of light in the middle of a cell. _He2's nursing a tremendous hangover, and though _he2 does not realize it, _he2's drugged. You're present, though not visible, witnessing _his2 first conscious moment of slavery from your desk. Realization is slow. _He2's no innocent, so _he2 recognizes the sensations of waking up the morning after a night of drinking interspersed with vigorous vaginal, oral, and anal intercourse, but _he2 does not remember the specifics. After a few minutes, _he2 understands that no one is coming, and speaks up hesitantly: "I<<s>> anyone there?" Getting no immediate answer, _he2 slumps against _his2 wrist restraints again, and begins to cry to _himself2. "W-why would a-anyone do thi<<s>>." - <br> - <<run cashX(-20000, "event", _slave)>> - <<includeDOM App.UI.newSlaveIntro(_slave)>> - <</replace>> - <</link>> //This will require an unprofitable <<print cashFormat(20000)>>, since _he2 is wealthy and obfuscating _his2 fate will require considerable spending// -<<else>> - //You cannot afford the <<print cashFormat(20000)>> enslaving _him2 would require, since _he2 is wealthy and obfuscating _his2 fate would necessitate considerable spending// -<</if>> -</span> diff --git a/src/uncategorized/rePokerNight.tw b/src/uncategorized/rePokerNight.tw deleted file mode 100644 index 2a6245ed63249279772d1c07958846c202702f17..0000000000000000000000000000000000000000 --- a/src/uncategorized/rePokerNight.tw +++ /dev/null @@ -1,148 +0,0 @@ -:: RE Poker Night [nobr] - -<<set $nextButton = "Continue", $nextLink = "RIE Eligibility Check", $returnTo = "RIE Eligibility Check">> - -<<setAssistantPronouns>> - -<span id="art-frame"> -</span> - -Despite their persistent presence in your arcology, interaction with your mercenaries is relatively scarce. Aside from mutually exchanged nods on the street and the occasional briefing, your $mercenariesTitle enjoy a degree of autonomy. - -<br><br> - -On a particularly lackadaisical evening, you find yourself alerted to a message alert by $assistant.name. -<<if $assistant.personality > 0>> - "<<= properMaster()>>, a message from your $mercenariesTitle." _HeA pauses before continuing. "It seems they're asking if you'd like to join their poker night." -<<else>> - _HeA informs you that the $mercenariesTitle have sent a message asking you to join them at their poker night. -<</if>> - -<br><br> - -<span id="result"> - -<<link "Politely decline">> - <<replace "#result">> - You inform $assistant.name that you aren't planning to attend. A short while later, you receive a message from the $mercenariesTitle stating that the invitation is an open one and that you're welcome to join in another night. - <</replace>> -<</link>> - -<br> - -<<if $cash < 5000>> - //You lack the necessary funds to attend a high stakes poker game.// -<<else>> /* cash >= 5000 */ - <br> - <<link "Attend the poker night">> - <<replace "#result">> - You instruct $assistant.name to inform your $mercenariesTitle that you will be attending their poker night, and after settling your affairs in the penthouse you head down to the barracks. Unsurprisingly the atmosphere in the barracks is casual, especially in comparison to the high stakes games commonplace in arcology high society, though your mercenaries still maintain some measure of decorum towards you as their employer. Eventually, you settle in at the table with a handful of $mercenariesTitle officers and cash in your <<print cashFormat(5000)>> into chips. All that remains is to decide your strategy for the night. - <br><br> - <span id="bounty-result"> - <<link "Play it safe">> - <<replace "#bounty-result">> - <<if random(1,100) > 50>> - Despite your attempts to mitigate risk and play the safest hands possible, it seems lady luck has conspired against you this evening. However, even when your last chip is spent, your mercenaries pitch you a few chips to keep you in the game for the rest of the night. You may have lost most of your ¤, but it seems you've @@.green;made some friends.@@ - <<run repX(5000, "event")>> - <<run cashX(-2500, "event")>> - <<else>> - While a careful eye for risk has buoyed you through the evening, ultimately lady luck is the decider in handing you the win in a number of close hands. Unfortunately your meticulous play limited your chance at a larger payout, and you only come away from the evening with <<print cashFormat(1000)>> more than you arrived with and @@.green;the respect of your mercenaries.@@ - <<run repX(500, "event")>> - <<run cashX(1000, "event")>> - <</if>> - <</replace>> - <</link>> - <br> - <<link "Up the ante">> - <<set _genParam = {minAge: 38, maxAge: 43, ageOverridesPedoMode: 1, race: "nonslave", disableDisability: 1}>> - <<if $seeDicks != 100>> - <<set _slave = GenerateNewSlave("XX", _genParam)>> - <<else>> - <<set _slave = GenerateNewSlave("XY", _genParam)>> - <</if>> - <<set _slave.origin = "$He put $himself up as collateral at a poker game, and lost.">> - <<set _slave.career = "a soldier">> - <<set _slave.indentureRestrictions = 2>> - <<set _slave.indenture = 52>> - <<set _slave.devotion = random(25,40)>> - <<set _slave.trust = random(35,45)>> - <<run setHealth(_slave, jsRandom(60, 80), 0, undefined, 0, 10)>> - <<set _slave.muscles = 50>> - <<if _slave.weight > 130>> - <<set _slave.weight -= 100>> - <<set _slave.waist = random(-10,50)>> - <</if>> - <<set _slave.anus = 0>> - <<set _slave.skill.anal = 0>> - <<set _slave.skill.whoring = 0>> - <<set _slave.skill.combat = 1>> - <<set _slave.accent = random(0,1)>> - <<set _slave.behavioralFlaw = "arrogant">> - <<set _slave.hLength = 1>> - <<set _slave.hStyle = "shaved into a mohawk">> - <<set _slave.custom.tattoo = "$He has a number of tattoos from a variety of mercenary companies.">> - <<set _slave.clothes = "a military uniform">> - <<run App.Utils.setLocalPronouns(_slave)>> - <<replace "#art-frame">> - /* 000-250-006 */ - <<if $seeImages == 1>> - <<if $imageChoice == 1>> - <div class="imageRef lrgVector"><div class="mask"> </div><<SlaveArt _slave 3 0>></div> - <<else>> - <div class="imageRef lrgRender"><div class="mask"> </div><<SlaveArt _slave 3 0>></div> - <</if>> - <</if>> - /* 000-250-006 */ - <</replace>> - <<replace "#bounty-result">> - Some aggressive play and an eye for riling up your fellow players has resulted in an immense payout, and all but one of your adversaries have folded as the situation has escalated. The only player still in contention is a wily old mercenary, the veteran of $his fair share of battles on the battlefield and at the poker table. $He's short on chips, however, and $he'll have to buy in with something else as collateral. - <br><br> - <span id="alive-result"> - <<set _slave.clothes = "no clothing">> - <<link "A year of servitude">> - <<replace "#alive-result">> - <<if random(1,100) > 50>> - For all your skillful maneuvering to reach this position, ultimately the win comes down to chance. This time, however, luck was not on your side. As the victor sweeps up $his spoils, the other mercenaries clap you on the back and offer their condolences for your defeat. Though you may have lost your ¤, it seems you've @@.green;made some friends.@@ - <<run repX(5000, "event")>> - <<run cashX(-5000, "event")>> - <<else>> - <<replace "#art-frame">> - /* 000-250-006 */ - <<if $seeImages == 1>> - <<if $imageChoice == 1>> - <div class="imageRef lrgVector"><div class="mask"> </div><<SlaveArt _slave 3 0>></div> - <<else>> - <div class="imageRef lrgRender"><div class="mask"> </div><<SlaveArt _slave 3 0>></div> - <</if>> - <</if>> - /* 000-250-006 */ - <</replace>> - For all your skillful maneuvering to reach this position, ultimately the win comes down to chance. This time, however, luck has rendered you the victor. A silence falls over the room as the result is declared, but after some time your opponent breaks the hush by joking that life as your slave is probably easier than fighting for $arcologies[0].name. After some awkward laughter the night continues, and at the end your former mercenary joins you on your trip back to the penthouse to submit to processing and to begin $his new life as your sexual servant. $He's not young, but $he's tough and not distrusting of you due to $his service in the $mercenariesTitle. - <br> - <<includeDOM App.UI.newSlaveIntro(_slave)>> - <</if>> - <</replace>> - <</link>> - <br> - <<link "Dock $his wages">> - <<replace "#alive-result">> - <<if random(1,100) > 50>> - For all your skillful maneuvering to reach this position, ultimately the win comes down to chance. This time, however, luck was not on your side. As the victor sweeps up $his spoils, the other mercenaries clap you on the back and offer their condolences for your defeat. Though you may have lost your ¤, it seems you've @@.green;made some friends.@@ - <<run repX(5000, "event")>> - <<run cashX(-5000, "event")>> - <<else>> - For all your skillful maneuvering to reach this position, ultimately the win comes down to chance. This time, however, luck has rendered you the victor. Your opponent accepts $his defeat with grace and jokes to $his comrades that $he'll be fighting in $his underwear for the next few months, and their uproar of laughter fills the room. Though you take the lion's share of the ¤, your mercenaries also @@.green;had a good time fraternizing with you.@@ - <<run repX(1000, "event")>> - <<run cashX(5000, "event")>> - <</if>> - <</replace>> - <</link>> - </span> - <</replace>> - <</link>> - </span> - <</replace>> - <</link>> // It will cost <<print cashFormat(5000)>> to participate in the poker night.// -<</if>> - -</span> diff --git a/src/uncategorized/reRebels.tw b/src/uncategorized/reRebels.tw deleted file mode 100644 index 4145ee85b3c66e5532bdda1794f261e8b37cd869..0000000000000000000000000000000000000000 --- a/src/uncategorized/reRebels.tw +++ /dev/null @@ -1,115 +0,0 @@ -:: RE rebels [nobr] - -<<set $nextButton = "Continue">> -<<set $nextLink = "RIE Eligibility Check">> - -<<set _i = $slaveIndices[$rebelSlaves[0]]>> -<<set _j = $slaveIndices[$rebelSlaves[1]]>> -<<setLocalPronouns $slaves[_i]>> -<<setLocalPronouns $slaves[_j] 2>> - -<<set _clothesTemp = $slaves[_i].clothes, $slaves[_i].clothes = "no clothing">> -<<set _clothesTemp2 = $slaves[_j].clothes, $slaves[_j].clothes = "no clothing">> -<span id="art-frame"> -/* 000-250-006 */ -<<if $seeImages == 1>> - <div class="imageColumn"> - <div class="imageRef medImg"> - <<SlaveArt $slaves[_i] 2 0>> - </div> - <div class="imageRef medImg"> - <<SlaveArt $slaves[_j] 2 0>> - </div> - </div> -<</if>> -/* 000-250-006 */ -</span> -<<set $slaves[_i].clothes = _clothesTemp>> -<<set $slaves[_j].clothes = _clothesTemp2>> - -You have a rebel problem. <<= App.UI.slaveDescriptionDialog($slaves[_i])>> and <<= App.UI.slaveDescriptionDialog($slaves[_j])>> are both unbroken, and they seem to draw strength from each other. They're discreet about it, but the arcology's always-vigilant systems occasionally catch them nodding to one another after one of them is punished, or giving each other quiet words of encouragement when they think no one is listening. This is extremely dangerous and should be addressed promptly. - -<br><br> - -<span id="result"> -<<link "Set them against each other, in public">> - <<replace "#result">> - You haul your little rebel bitches out in public, one by one, bound, with bags over their heads. They find themselves chained in a low position so their mouths are publicly available. Then, you whisper to each of them that whichever slut sucks off the most passersby gets to rest tomorrow — and whichever sucks least gets a beating. It doesn't take long before @@.hotpink;they forget their friendship@@ and try to outdo each other, and their desperate efforts @@.green; are certainly appreciated by the citizens getting free blowjobs.@@ It's childishly easy to declare the contest over when they happen to be tied, and announce that no one will be punished or rewarded. They hate you less and each other more. - <<set $slaves[_i].devotion += 4>> - <<set $slaves[_j].devotion += 4>> - <<set $slaves[_j].counter.oral += 6>> - <<set $slaves[_i].counter.oral += 6>> - <<set $oralTotal += 12>> - <<run repX(250, "event", $slaves[_i])>> - <<run repX(250, "event", $slaves[_j])>> - <</replace>> -<</link>> -<br><<link "Set them against each other, in private">> - <<replace "#result">> - Back in the old world, the saying went that turnabout was fair play. In the Free Cities, turnabout is often a cast-iron bitch. Whenever you have an idle moment, all week, you set them against one another in some degrading or painful contest. They are made to spank each other, with the slave who hits lightest getting a spanking from you. They are made to compete to see who can suck other slaves off quickest, with the loser forced to orally service the winner. So on, and so on; by the end of the week @@.gold;they forget their friendship@@ and try to outdo each other to avoid punishment. - <<set $slaves[_i].trust -= 5>> - <<set $slaves[_j].trust -= 5>> - <<set $slaves[_j].counter.oral += 6>> - <<set $slaves[_i].counter.oral += 6>> - <<set $oralTotal += 12>> - <</replace>> -<</link>> -<<if $seeExtreme == 1 && $slaves[_j].vagina > 0 && $slaves[_i].vagina > 0>> - <br><<link "Let them compete against each other to decide who lives">> - <<replace "#result">> - You haul your bound little rebel bitches into one of the deepest, most out of the way rooms of your penthouse with bags over their heads. When you pull them off, they are met with <<if canSee($slaves[_j]) && canSee($slaves[_i])>>the sight of <</if>>a gallows, complete with a pair of nooses. You haul them, one at a time up onto a stool and loop the rope around their necks. They scream and beg the whole time for you to reconsider, before turning on each other to try and avoid their fate. It won't be that easy for them. You hold up a pair of spoons and explain the rules of the game. They'll hold them in their pussies, and whoever loses their grip and drops it first, dies. - <br><br> - <<if $slaves[_i].vagina > 3>> - You start with $slaves[_i].slaveName and no sooner than you turn to $slaves[_j].slaveName do you hear the telltale clatter of the spoon hitting the floor. With a simple kick, the unfortunately loose $slaves[_i].slaveName is left struggling in the air. $slaves[_j].slaveName <<if canSee($slaves[_j])>>watches<<elseif canHear($slaves[_j])>>listens<<else>>stares blankly<</if>> in horror as the life drains from _his2 former accomplice. @@.gold;_He2 promises to never cross you again.@@ - <<set $slaves[_j].trust -= 20>> - <<run removeSlave($slaves[_i])>> - <<elseif $slaves[_j].vagina > 3>> - You start with $slaves[_i].slaveName before moving to $slaves[_j].slaveName as $he holds $his life between $his netherlips. Setting the spoon inside $slaves[_j].slaveName, you prepare to kick the stools out from under them; but the telltale clatter of the spoon hitting the floor saves you the trouble. With a simple kick, the unfortunately loose $slaves[_j].slaveName is left struggling in the air. $slaves[_i].slaveName <<if canSee($slaves[_i])>>watches<<elseif canHear($slaves[_i])>>listens<<else>>stares blankly<</if>> in horror as the life drains from $his former accomplice. @@.gold;$He promises to never cross you again.@@ - <<set $slaves[_i].trust -= 20>> - <<run removeSlave($slaves[_j])>> - <<elseif random(1,100) == 69>> - You start with $slaves[_i].slaveName before moving to $slaves[_j].slaveName as $he holds $his life between $his netherlips. Once both spoons are inserted, you sit back and watch them squirm at the cold metal in their most sensitive recesses. They are both desperate to survive and clamp down as hard as they can, but it can't go on forever as the sounds of a spoon clattering to the floor fills the room. Both slaves freeze as they realize the other has lost their grip on the silverware, uncertain of what comes next. You answer the question by knocking the stools out from under them, allowing them both to hang. They came into this together and they are going out together. - <<run removeSlave($slaves[_i])>> - <<run removeSlave($slaves[_j])>> - <<elseif $slaves[_i].vagina == $slaves[_j].vagina && random(1,100) > 50>> - You start with $slaves[_i].slaveName before moving to $slaves[_j].slaveName as $he holds $his life between $his netherlips. Once both spoons are inserted, you sit back and watch them squirm at the cold metal in their most sensitive recesses. They are both <<if $slaves[_i].vagina == 1>>quite tight, so it's no surprise when they put up a good show.<<else>>not the tightest slaves, so it's a surprise they manage to hold on as long as they do<</if>>. But it can't go on forever as the sound of the spoon clattering to the floor fills the room. - <<if random(1,100) <= 50>> - You kick the stool out from under $slaves[_j].slaveName and let _him2 hang. $slaves[_i].slaveName <<if canSee($slaves[_i])>>watches<<elseif canHear($slaves[_i])>>listens<<else>>stares blankly<</if>> in horror as the life drains from $his former accomplice, @@.gold;terrified that you'd so callously toy with their lives.@@ The ordeal @@.red;leaves $him behaving strangely.@@ - <<set $slaves[_i].trust -= -20, $slaves[_i].behavioralFlaw = "odd">> - <<run removeSlave($slaves[_j])>> - <<else>> - You kick the stool out from under $slaves[_i].slaveName and let $him hang. $slaves[_j].slaveName <<if canSee($slaves[_j])>>watches<<elseif canHear($slaves[_j])>>listens<<else>>stares blankly<</if>> in horror as the life drains from _his2 former accomplice, @@.gold;terrified that you'd so callously toy with their lives.@@ The ordeal @@.red;leaves _him2 behaving strangely.@@ - <<set $slaves[_j].trust -= -20, $slaves[_j].behavioralFlaw = "odd">> - <<run removeSlave($slaves[_i])>> - <</if>> - <<elseif $slaves[_j].vagina > $slaves[_i].vagina && random(1,100) > 50>> - You start with $slaves[_i].slaveName before moving to $slaves[_j].slaveName as $he holds $his life between $his netherlips. Once both spoons are inserted, you sit back and watch them squirm at the cold metal in their most sensitive recesses. $slaves[_i].slaveName is the clear favorite in this game, but the looser $slaves[_j].slaveName refuses to give in, using _his2 experience to clamp down as hard as _he2 can. But it can't go on forever as the sound of the spoon clattering to the floor fills the room. - <<if random(1,100) <= 90>> - You kick the stool out from under $slaves[_j].slaveName and let _him2 hang. $slaves[_i].slaveName <<if canSee($slaves[_i])>>watches<<elseif canHear($slaves[_i])>>listens<<else>>stares blankly<</if>> in horror as the life drains from $his former accomplice, @@.gold;terrified that you'd so callously toy with their lives.@@ The ordeal @@.red;leaves $him behaving strangely.@@ - <<set $slaves[_i].trust -= -20, $slaves[_i].behavioralFlaw = "odd">> - <<run removeSlave($slaves[_j])>> - <<else>> - You kick the stool out from under $slaves[_i].slaveName and let $him hang. $slaves[_j].slaveName <<if canSee($slaves[_j])>>watches<<elseif canHear($slaves[_j])>>listens<<else>>stares blankly<</if>> in horror as the life drains from _his2 former accomplice, @@.gold;terrified that you'd so callously toy with their lives.@@ The ordeal @@.red;leaves _him2 behaving strangely.@@ <<if $slaves[_j].vagina >= 3>>You can't say you expected this outcome, but it was amusing all the same to discover the blown out whore has some talent<<else>>You're glad no bets were riding on this<</if>>. - <<set $slaves[_j].trust -= -20, $slaves[_j].behavioralFlaw = "odd">> - <<run removeSlave($slaves[_i])>> - <</if>> - <<else>> - You start with $slaves[_i].slaveName before moving to $slaves[_j].slaveName as $he holds $his life between $his netherlips. Once both spoons are inserted, you sit back and watch them squirm at the cold metal in their most sensitive recesses. In a show of underhandedness, $slaves[_j].slaveName kicks $slaves[_i].slaveName, knocking $him off balance and sending $him hanging. $slaves[_j].slaveName <<if canSee($slaves[_j])>>watches<<elseif canHear($slaves[_j])>>listens<<else>>stares blankly<</if>> as the life drains from _his2 accomplice, @@.gold;horrified at what _he2 just did.@@ The ordeal @@.red;leaves _him2 behaving strangely.@@ - <<set $slaves[_j].trust = -100, $slaves[_j].behavioralFlaw = "odd">> - <<run removeSlave($slaves[_i])>> - <</if>> - <</replace>> - <</link>> -<</if>> -<<if $arcade > 0>> - <br><<link "Sentence them to a month in the arcade">> - <<replace "#result">> - They scream and beg when they realize what their punishment is to be, but you are obdurate. Each tries to inform on the other to avoid such a fate, but to no avail. After they're properly confined, the only sign of their discomfiture is a slight movement of their butts as they wriggle desperately against their restraints. - <<= assignJob($slaves[_j], "be confined in the arcade")>> - <<set $slaves[_j].sentence = 4>> - <<= assignJob($slaves[_i], "be confined in the arcade")>> - <<set $slaves[_i].sentence = 4>> - <</replace>> - <</link>> -<</if>> -</span> diff --git a/src/uncategorized/reRelationshipAdvice.tw b/src/uncategorized/reRelationshipAdvice.tw deleted file mode 100644 index a37305a64a1706cf2f9ebbd69d0448756919ac7b..0000000000000000000000000000000000000000 --- a/src/uncategorized/reRelationshipAdvice.tw +++ /dev/null @@ -1,151 +0,0 @@ -:: RE relationship advice [nobr] - -<<set $nextButton = "Continue", $nextLink = "AS Dump", $returnTo = "Next Week", $activeSlave = $eventSlave>> -<<run Enunciate($activeSlave)>> -<<run App.Utils.setLocalPronouns($activeSlave)>> - -<<set _i = $slaveIndices[$activeSlave.relationshipTarget]>> -<<set $subSlave = $slaves[_i]>> -<<setLocalPronouns $subSlave 2>> - -<<set _clothesTemp = $activeSlave.clothes, $activeSlave.clothes = "no clothing">> -<span id="art-frame"> -/* 000-250-006 */ -<<if $seeImages == 1>> - <div class="imageColumn"> - <div class="imageRef medImg"> - <<SlaveArt $activeSlave 2 0>> - </div> - <div class="imageRef medImg"> - <<SlaveArt $subSlave 2 0>> - </div> - </div> -<</if>> -/* 000-250-006 */ -</span> -<<set $activeSlave.clothes = _clothesTemp>> - -<<= App.UI.slaveDescriptionDialog($activeSlave)>> is standing for an inspection. $He's a good $girl, and is cooperating, but $he seems preoccupied. After ignoring it for a while, you give in to curiosity and flatly ask $him what's going on. "I'm <<s>>orry, <<Master>>," $he <<if SlaveStatsChecker.checkForLisp($activeSlave)>>lisp<<else>>mutter<</if>>s, biting $his lip. "It'<<s>> <<= App.UI.slaveDescriptionDialog($subSlave)>>." -$He hesitates, so you prompt $him, asking if $he's having trouble with $his -<<if $activeSlave.relationship == 2>> - friend. -<<elseif $activeSlave.relationship == 3>> - friend with benefits. -<<elseif $activeSlave.relationship == 4>> - lover. -<</if>> -$He quickly shakes $his head no. "N-no, <<Master>>, it's ju<<s>>t —" $He subsides into silence again, blushing and staring <<if !canSee($activeSlave)>>blankly <</if>><<if hasBothLegs($activeSlave)>>at $his feet<<else>>downwards<</if>>. Comprehension dawning, you ask $him if -<<if $activeSlave.relationship == 2>> - $he wants to be more than friends with $subSlave.slaveName. -<<elseif $activeSlave.relationship == 3>> - $he's wanting to bring emotions into relationship with $subSlave.slaveName, rather than keep it friendly and sexual. -<<elseif $activeSlave.relationship == 4>> - $he wants to make an honest _woman2 out of $subSlave.slaveName. -<</if>> -$He nods $his head quickly, still staring <<if !canSee($activeSlave)>>blankly <</if>><<if hasBothLegs($activeSlave)>>at $his feet<<else>>downwards<</if>>. $He shuts $his eyes tight and waits for you to weigh in on the situation. - -<span id="result"> -<br><<link "Break them up">> - <<replace "#result">> - <br><br> - In a cold tone of voice, you admit your irritation with this school<<= $girl>> nonsense, and tell $him $he's to stop spending time with $subSlave.slaveName. $He's unable to prevent $his eyes from flicking up at you in @@.mediumorchid;shock and horror,@@ but $he instantly lowers them again, the tears coming fast. You dismiss $him, and $he turns to go, but is so discombobulated by anguish that $he trips over $his own feet and falls with a slap of naked $activeSlave.skin flesh against the floor. Their relationship @@.lightsalmon;is over.@@ - - <<set $activeSlave.devotion -= 5>> - <<set $activeSlave.relationship = 0>> - <<set $activeSlave.relationshipTarget = 0>> - <<set $slaves[_i].relationship = 0>> - <<set $slaves[_i].relationshipTarget = 0>> - <</replace>> -<</link>> -<br><<link "Build $his confidence">> - <<replace "#result">> - <br><br> - In a warm tone of voice, you tell $him you approve of $his relationship with $subSlave.slaveName. $He raises $his chin and looks at you with @@.hotpink;growing adoration@@ as you point out how lucky $subSlave.slaveName is to have $him. You tell $him that you're not planning to intervene personally, but that you think $he really ought to pursue the relationship, that they're good for each other, and that you're confident $subSlave.slaveName feels the same way. $He thanks you prettily and leaves at a flat run, in a hurry to tell $his - <<if $activeSlave.relationship == 2>> - sexy friend - <<elseif $activeSlave.relationship == 3>> - friend with benefits - <<elseif $activeSlave.relationship == 4>> - dear lover - <</if>> - how $he feels about _him2. - <<if $activeSlave.relationship == 2>> - The next time you see them together, they're looking like they've been getting a little less sleep lately, but @@.lightgreen;can't seem to keep their hands off each other.@@ $activeSlave.slaveName mouths a silent thanks to you when $subSlave.slaveName isn't looking. - <<elseif $activeSlave.relationship == 3>> - The next time you see them together, they're @@.lightgreen;holding hands at breakfast,@@ looking almost ashamed of themselves, but not letting go. $activeSlave.slaveName mouths a silent thanks to you when $subSlave.slaveName isn't looking. - <<elseif $activeSlave.relationship == 4>> - $He comes running right back, a happy $subSlave.slaveName <<if canWalk($subSlave)>>running in with $him<<else>>being helped in by _his2 lover<</if>>. You @@.lightgreen;marry them@@ solemnly, and they embrace tightly, hugging each other close. $activeSlave.slaveName comes to face you over $his _wife2's shoulder, and $he mouths a silent, tearful thanks to you. - <</if>> - - <<set $activeSlave.devotion += 5>> - <<set $activeSlave.relationship += 1>> - <<set $slaves[_i].relationship += 1>> - <</replace>> -<</link>> -<br><<link "Bring the other _girl2 in">> - <<replace "#result">> - <br><br> - You tell $activeSlave.slaveName to wait, and page $subSlave.slaveName up to your office. $activeSlave.slaveName looks terrified, but tries to conceal $his emotions behind a happy greeting for $his - <<if $activeSlave.relationship == 2>> - friend - <<elseif $activeSlave.relationship == 3>> - friend with benefits - <<elseif $activeSlave.relationship == 4>> - lover - <</if>> - when _he2 comes in. $subSlave.slaveName knows $him well enough to detect $his inner turmoil, and asks $him what's wrong. $activeSlave.slaveName flinches and looks to you in desperation, but you just nod at $him to spit it out. After two false starts, $he manages to say, - "$subSlave.slaveName, I really want - <<if $activeSlave.relationship == 2>> - <<if ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "buttslut")>> - to fuck your butt." $subSlave.slaveName looks relieved that that's all it is, and <<if ($subSlave.voice != 0)>>says, "Okay!"<<else>>nods.<</if>> _He2 kisses $activeSlave.slaveName and then grinds _his2 ass against $activeSlave.slaveName's crotch. - <<elseif ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "cumslut")>> - to <<if ($subSlave.vagina != -1)>>eat you out<<else>>blow you<</if>>." $subSlave.slaveName looks relieved that that's all it is, and <<if ($subSlave.voice != 0)>>says, "Okay!"<<else>>nods.<</if>> _He2 <<if ($subSlave.vagina != -1)>>offers _his2 pussy<<else>>flops _his2 dick at $activeSlave.slaveName<</if>> comically. - <<elseif ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "humiliation")>> - to fuck you in public." $subSlave.slaveName looks relieved that that's all it is, and <<if ($subSlave.voice != 0)>>says, "Okay!"<<else>>nods.<</if>> - <<elseif ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "masochist")>> - you to hurt me. Like, really hurt me." $subSlave.slaveName looks relieved that that's all it is, and <<if ($subSlave.voice != 0)>>says, "Okay!"<<else>>nods.<</if>> _He2 pinches one of $activeSlave.slaveName's nipples experimentally. - <<elseif ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "sadist")>> - to hold you down." $subSlave.slaveName looks relieved that that's all it is, and <<if ($subSlave.voice != 0)>>says, "Okay!"<<else>>nods.<</if>> _He2 steps in close to $activeSlave.slaveName, takes $activeSlave.slaveName's hand<<if hasBothArms($activeSlave)>>s<</if>>, and places them around _his2 own throat. - <<elseif ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "dom")>> - to be your top." $subSlave.slaveName looks relieved that that's all it is, and <<if ($subSlave.voice != 0)>>says, "Okay!"<<else>>nods.<</if>> _He2 sidles up to $activeSlave.slaveName, looking up at $him submissively. - <<elseif ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "submissive")>> - to be your bottom." $subSlave.slaveName looks relieved that that's all it is, and says, <<if ($subSlave.voice != 0)>>says, "Okay!"<<else>>nods.<</if>> _He2 takes $activeSlave.slaveName's face in _his2 hand<<if hasBothArms($subSlave)>>s<</if>> and kisses $him dominantly. - <<elseif ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "boobs")>> - to fuck your boob<<s>>." $subSlave.slaveName looks relieved that that's all it is, and says, <<if ($subSlave.voice != 0)>>says, "Okay!"<<else>>nods.<</if>> _He2 takes $activeSlave.slaveName's <<if hasBothArms($activeSlave)>>hands and places them<<else>>hand and places it<</if>> right on _his2 breasts. - <<else>> - to fuck you." $subSlave.slaveName looks relieved that that's all it is, and <<if ($subSlave.voice != 0)>>says, "Okay!"<<else>>nods.<</if>> _He2 takes $activeSlave.slaveName's <<if hasBothArms($activeSlave)>>hands and places them<<else>>hand and places it<</if>> right on _his2 breasts. - <</if>> - $activeSlave.slaveName bursts out laughing. They're now @@.lightgreen;friends with benefits.@@ - <<elseif $activeSlave.relationship == 3>> - t-to b-be your <<= $girl>>friend." $He takes a deep breath. "It'<<s>> fun, ju<<s>>t - <<if ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "buttslut")>> - fucking your butt. - <<elseif ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "cumslut")>> - to <<if ($subSlave.vagina != -1)>>eating you out<<else>>blowing you<</if>>. - <<elseif ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "humiliation")>> - fucking you in public. - <<elseif ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "masochist")>> - having you hurt me. - <<elseif ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "sadist")>> - holding you down. - <<elseif ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "dom")>> - topping you. - <<elseif ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "submissive")>> - being your bottom. - <<elseif ($activeSlave.fetishKnown == 1) && ($activeSlave.fetish == "boobs")>> - fucking your boob<<s>>. - <<else>> - having <<s>>e<<x>> with you. - <</if>> - But I — I really like you." $subSlave.slaveName looks relieved, and <<if $subSlave.voice != 0>>says, "I really like you too. And you're really cute! I'd love to be your <<= _girl2>>friend." _He2<<else>>lovingly<</if>> takes $activeSlave.slaveName's hands in _hers2, and then kisses $him on the cheek. $activeSlave.slaveName crushes $subSlave.slaveName in a hug, pressing a squeak out of _him2. They're now @@.lightgreen;lovers.@@ - <<elseif $activeSlave.relationship == 4>> - - " $He stops $himself. "No, I want to do thi<<s>> right." $He takes $subSlave.slaveName's hand, and then drops to one knee. After a moment of uncomprehending shock, $subSlave.slaveName begins to cry. "Will you marry me?" $subSlave.slaveName turns to you and<<if !canTalk($subSlave)>> wordlessly<</if>> asks if it's all right with you; you nod, and _he2 turns back to $activeSlave.slaveName. <<if !canTalk($subSlave)>>_He2 gestures distractedly that $activeSlave.slaveName is being silly, and of course _he2'll marry $him, because _he2 loves $him.<<else>><<run Enunciate($subSlave)>>"O-of cour<<s>>e I'll m-marry you, <<s>>illy $girl. I love you."<</if>> $activeSlave.slaveName jumps up and crushes $subSlave.slaveName in a hug, kissing _him2 frantically through $his tears. You @@.lightgreen;marry them@@ solemnly, and they embrace tightly, hugging each other close. $activeSlave.slaveName comes to face you over $his _wife2's shoulder, and $he mouths a silent thanks to you. - <</if>> - If $activeSlave.slaveName had doubts about you, @@.mediumaquamarine;they've been addressed.@@ - - <<set $activeSlave.trust += 10>> - <<set $activeSlave.relationship += 1>> - <<set $slaves[_i].relationship += 1>> - <</replace>> -<</link>> -</span> diff --git a/src/uncategorized/reShowerPunishment.tw b/src/uncategorized/reShowerPunishment.tw deleted file mode 100644 index aa02ad62a514e356ac327363ac41db4fcaa93551..0000000000000000000000000000000000000000 --- a/src/uncategorized/reShowerPunishment.tw +++ /dev/null @@ -1,112 +0,0 @@ -:: RE shower punishment [nobr] - -<<set $nextButton = "Continue", $nextLink = "AS Dump", $returnTo = "Next Week">> - -<<set $activeSlave = $eventSlave>> -<<run App.Utils.setLocalPronouns($activeSlave)>> -<<setLocalPronouns _S.HeadGirl 2>> -<<setPlayerPronouns>> -<<run Enunciate(_S.HeadGirl)>> - -<<set _clothesTemp = $activeSlave.clothes, $activeSlave.clothes = "no clothing">> -<<set _clothesTemp2 = _S.HeadGirl.clothes, _S.HeadGirl.clothes = "no clothing">> -<span id="art-frame"> -/* 000-250-006 */ -<<if $seeImages == 1>> - <div class="imageColumn"> - <div class="imageRef medImg"> - <<SlaveArt _S.HeadGirl 2 0>> - </div> - <div class="imageRef medImg"> - <<SlaveArt $activeSlave 2 0>> - </div> - </div> -<</if>> -/* 000-250-006 */ -</span> -<<set $activeSlave.clothes = _clothesTemp>> -<<set _S.HeadGirl.clothes = _clothesTemp2>> - -<<if $HGSuite == 1>> - Looking in on your Head Girl in _his2 suite, you hear _his2 private shower running and head that way. Through the thick steam the shower makes on its hottest setting, you see -<<else>> - Passing by the showers, you see, through the steam of a very hot shower, -<</if>> -a <<if $activeSlave.height > 180>>tall, <<elseif $activeSlave.height < 150>>tiny, <</if>>$activeSlave.skin form moving busily around a _S.HeadGirl.skin figure, which is standing confidently in the middle of the warm, moist space. As you draw nearer, you identify the stationary slave as your Head Girl, <<= App.UI.slaveDescriptionDialog(_S.HeadGirl)>>. _His2 attendant is <<= contextualIntro(_S.HeadGirl, $activeSlave, true)>>, and $he's washing $his superior with a big sponge. -<<if $HGSeverity > 0>> - By virtue of not being rape, this is an unusually mild punishment by your Head Girl, if indeed that's what it is. But perhaps _he2's saving that for later. And to go by the cringing, frightened mien of the busy little bath bitch, that's probably it. -<<elseif $HGSeverity == 0>> - Your Head Girl does _his2 best to fit the punishment to the crime, so $activeSlave.slaveName's failure was likely minor. With _S.HeadGirl.slaveName's penchant for poetic justice, probably some little deficiency of personal cleanliness. -<<else>> - This is the sort of mild punishment that your regime of respect and dignity requires _him2 to use for all but the most egregious fault. Thus restricted, _he2 does _his2 best to come up with novel little degradations to keep _his2 charges on their toes. -<</if>> -<br><br> -$activeSlave.slaveName is being very thorough. When you first appeared, $he was working $his way up _S.HeadGirl.slaveName's <<if _S.HeadGirl.muscles > 30>>muscle-corded<<elseif _S.HeadGirl.weight > 10>>soft<<elseif _S.HeadGirl.vagina > -1>>feminine<<else>>pretty<</if>> thighs, having obviously started at the bottom. $He skips over _S.HeadGirl.slaveName's crotch, probably under instructions to leave it for last. It's late in your Head Girl's busy day, and you hear _his2 groan of relaxation over the running water when the stiff sponge begins to scrub back and forth across _his2 <<if _S.HeadGirl.belly >= 60000>>enormously <<if _S.HeadGirl.preg > 0>>pregnant<<else>>rounded<</if>> belly<<elseif _S.HeadGirl.weight > 190>>massively fat gut<<elseif _S.HeadGirl.belly >= 10000>>hugely <<if _S.HeadGirl.preg > 0>>pregnant<<else>>rounded<</if>> belly<<elseif _S.HeadGirl.weight > 95>>big soft belly<<elseif _S.HeadGirl.belly >= 5000>><<if _S.HeadGirl.preg > 0>>pregnant<<else>>round<</if>> belly<<elseif _S.HeadGirl.weight > 30>>soft belly<<elseif _S.HeadGirl.belly >= 1500>>bloated belly<<elseif _S.HeadGirl.muscles > 30>>shredded abs<<elseif _S.HeadGirl.weight > 10>>plush belly<<elseif _S.HeadGirl.navelPiercing > 0>>pierced belly button<<elseif _S.HeadGirl.waist < -10>><<if _S.HeadGirl.waist < -95>>absurdly <</if>>narrow waist<<else>>belly<</if>>. - -<br><br> - -<span id="result"> -<<link "Just spectate">> - <<replace "#result">> - You could strip off your suit, walk into the steam, and enjoy your slaves' ministrations, but sometimes the artistry of tastefully nude bodies is a welcome change of pace. You lean against the wall, far enough away that they remain unaware of your presence, and take in the sight. _S.HeadGirl.slaveName makes the penitent $girl do the job with Brahmanical thoroughness, cleaning $his superior's _S.HeadGirl.race body down to its very last pore. As $activeSlave.slaveName circles the Head Girl laboriously, doing $his best to ingratiate $himself by diligence, the pair of naked <<if $girl == _girl2>>$women<<else>>slaves<</if>> present a fascinating contrast. They are unclothed alike, the water streaming off their bodies without any distinction, but even an old world fool could not mistake the immense gulf between them. - <br><br> - When $activeSlave.slaveName is finally done, _S.HeadGirl.slaveName's - <<if $HGSeverity > 0>> - hands seize $him by the ears and pull $his head in for a kiss that is dominance distilled into the form of a loving gesture. Then _he2 pokes _his2 bitch in the side, forcing the slave to collapse in just the right way. - <<elseif $HGSeverity == 0>> - arms encircle $him in an embrace that is simultaneously controlling, comforting, and sexually insistent. The slave does not resist, allowing the Head Girl to run _his2 hands over the warm, wet sex slave. - <<else>> - arousal is obvious. Though the respectful regime you require secures $him from the fear of being used, $activeSlave.slaveName nonverbally offers $his superior oral, out of obvious gratitude that whatever $he did is being treated so leniently, and perhaps out of a desire to be in _S.HeadGirl.slaveName's good graces. - <</if>> - In no time at all, $activeSlave.slaveName's $activeSlave.hColor head descends to obscure _S.HeadGirl.slaveName's groin. The <<if _S.HeadGirl.face > 95>>heartrendingly gorgeous<<elseif _S.HeadGirl.face <= 95>>wonderfully pretty<<elseif _S.HeadGirl.face <= 40>>approachably lovely<<elseif _S.HeadGirl.face <= 10>>not unattractive<<else>>homely<</if>> <<if _S.HeadGirl.physicalAge > 25>>_woman2's<<else>>_girl2's<</if>> head cranes back with orgasm before long; that diligent scrub must have been quite stimulating. - <br><br> - $activeSlave.slaveName stays in the shower to clean $himself, so _S.HeadGirl.slaveName exits to see you watching the denouement. _He2 @@.hotpink;smiles,@@ murmuring a greeting, and hurries over to give you a peck on the cheek, leaning in as best _he2 can to keep _his2 moist body away from your suit. "Thi<<s>> i<<s>> the life, <<Master>>," _he2 whispers. - <<set $activeSlave.counter.oral += 1>> - <<set $oralTotal += 1>> - <<set _S.HeadGirl.devotion += 4>> - <<set _S.HeadGirl.counter.penetrative += 1>> - <<set $penetrativeTotal += 1>> - <</replace>> -<</link>> -<br><<link "Get a scrub down too">> - <<replace "#result">> - You strip off your suit and enter the shower. By the time you get in, _S.HeadGirl.slaveName's sponge scrub is almost done. _He2 turns to greet you with half-lidded eyes, well pleased with _his2 thorough scrubbing. _His2 _S.HeadGirl.skin skin shines with wet cleanliness, and _his2 _S.HeadGirl.nipples nipples begin to <<if _S.HeadGirl.nipples == "fuckable">>swell with arousal<<else>>stiffen<</if>> as _he2 sees your gaze take in _his2 nude body. _He2 brusquely orders $activeSlave.slaveName to scrub you, too, anticipating your intention. The rough, exfoliating sensation of the sponge is indeed delightful, and you close your eyes to savor the feeling as the slave rubs it up and down your calves and then the backs of your knees. - <br><br> - <<if $HGSeverity > 0>> - You detect tremors of fear in the slave<<if hasAnyArms($activeSlave)>>'s hand<<if hasBothArms($activeSlave)>>s<</if>><</if>>; $he knows that $he hasn't extirpated $his misbehavior, whatever it was, just yet. You let your Head Girl manage that, however, and _he2 does. When $activeSlave.slaveName is stuck in one position for a short time by the need to wash your thighs, you hear a gasp and open your eyes to the sight of your Head Girl crouched behind $him, giving $him an anal fingerfuck. When $activeSlave.slaveName is done washing you, your Head Girl holds the slave's head to your - <<else>> - When the washing reaches your shoulders, it becomes clumsier, and $activeSlave.slaveName's wet body begins to bump gently against your torso. Opening your eyes, you see that your Head Girl is taking $him as $he finishes your bath. $activeSlave.slaveName is doing $his best to do a good job as $he's fucked, and $he manages it reasonably well. When $he's done, _S.HeadGirl.slaveName pushes $his head down towards your - <</if>> - <<if $PC.dick != 0>>groin so $he can suck you off<<if $PC.vagina != -1>> and stroke your cunt<</if>><<else>>cunt so $he can eat you out<</if>>. $activeSlave.slaveName complies, and afterward, $he seems to feel that @@.mediumaquamarine;$he came off reasonably well;@@ it could have been worse. - <<set $activeSlave.counter.anal += 1>> - <<set $analTotal += 1>> - <<= knockMeUp($activeSlave, 10, 1, $HeadGirlID)>> - <<set $activeSlave.counter.oral += 1>> - <<set $oralTotal += 1>> - <<set $activeSlave.trust += 4>> - <<set _S.HeadGirl.counter.penetrative += 1>> - <<set $penetrativeTotal += 1>> - <</replace>> -<</link>> -<br><<link "Focus on your Head Girl">> - <<replace "#result">> - You strip off your suit and walk into the steam, producing a surprised but welcoming greeting from your Head Girl and a muffled, submissive noise from $activeSlave.slaveName. _S.HeadGirl.slaveName is held more or less stationary by the slave _he2's straddling, so you step in, hook a dominant arm around _his2 waist, and kiss _him2. There's precisely one person in this arcology who's allowed to treat _him2 as _hersP, and it's you. _He2 relaxes into you with gratitude as you shoulder the burden of being the leader in this little area of your empire, lifting it from _his2 shoulders for now. - <br><br> - You run a hand up the side of _his2 neck, bringing it to rest with your fingers cupping _him2 under the ear and your thumb running up along _his2 temple. _He2 shivers, unable to concentrate despite all _his2 poise, the ongoing oral service blending into your intense closeness. Right now, _he2's the <<if _S.HeadGirl.physicalAge > 25>>_woman2<<else>>_girl2<</if>> for you, so you snap your fingers next to the ear of the slave <<if _S.HeadGirl.vagina > -1>>eating _him2 out<<else>>blowing _him2<</if>>, point at the dropped sponge, and then point at yourself. The oral stops as $activeSlave.slaveName hurries to scrub you, starting at your feet, but your Head Girl doesn't care. You're kissing _him2. - <br><br> - _He2 gently strokes your <<if $PC.dick != 0>>rapidly hardening member, smiling into your mouth at the speed with which it stiffens<<if $PC.vagina != -1>>, and teases your pussylips with mischievous fingers<</if>><<else>>flushed cunt, smiling into your mouth at the moisture that instantly coats _his2 fingertips<</if>>. You reach out in turn, - <<if _S.HeadGirl.vagina > -1>> - caressing _his2 pussylips before slowly inserting a digit inside _his2 warmth while nuzzling _his2 clit with the knuckle of your thumb. At the first real brush against _his2 clitoris, the overstimulated _S.HeadGirl.slaveName climaxes, pulling _his2 mouth away from you to shout your name and then sobbing thanks into your ear. - <<else>> - hooking your fingers up underneath _his2 taint to grope _his2 anus. After teasing _his2 asspussy for a moment you bring your hand slowly across _his2 perineum<<if _S.HeadGirl.scrotum > 0>> until _his2 ballsack rests against your wrist<</if>>. The overstimulated _S.HeadGirl.slaveName cums the instant the butt of your hand touches the base of _his2 cock. _He2 screams your name. - <</if>> - <br><br> - _He2 isn't terribly affected by loving shower sex with you; after all, it isn't exactly novel for _him2. $activeSlave.slaveName was there to bear witness, though, scrubbing your back as _S.HeadGirl.slaveName clung to it with orgasm. $He can't help but be @@.hotpink;impressed.@@ Maybe, just maybe, that could be $him someday. $He seems distinctly uncomfortable. - <<set $activeSlave.counter.oral += 1>> - <<set $oralTotal += 1>> - <<set $activeSlave.devotion += 4>> - <<set _S.HeadGirl.counter.oral += 1>> - <<set $oralTotal += 1>> - <</replace>> -<</link>> -</span> diff --git a/src/uncategorized/reSiblingRevenge.tw b/src/uncategorized/reSiblingRevenge.tw deleted file mode 100644 index d5c97ea6c740eb7428734d1cf41cd11aa5292d97..0000000000000000000000000000000000000000 --- a/src/uncategorized/reSiblingRevenge.tw +++ /dev/null @@ -1,82 +0,0 @@ -:: RE sibling revenge [nobr] - -<<set $nextButton = "Continue", $nextLink = "RIE Eligibility Check">> - -<<set $i = $slaveIndices[$youngerSister]>> -<<set $j = $slaveIndices[$olderSister]>> -<<setLocalPronouns $slaves[$i]>> -<<setLocalPronouns $slaves[$j] 2>> - -<<set _clothesTemp = $slaves[$i].clothes, $slaves[$i].clothes = "no clothing">> -<<set _clothesTemp2 = $slaves[$j].clothes, $slaves[$j].clothes = "no clothing">> -<span id="art-frame"> -/* 000-250-006 */ -<<if $seeImages == 1>> - <div class="imageColumn"> - <div class="imageRef medImg"> - <<SlaveArt $slaves[$i] 2 0>> - </div> - <div class="imageRef medImg"> - <<SlaveArt $slaves[$j] 2 0>> - </div> - </div> -<</if>> -/* 000-250-006 */ -</span> -<<set $slaves[$i].clothes = _clothesTemp>> -<<set $slaves[$j].clothes = _clothesTemp2>> - -$slaves[$i].slaveName, whose older _sister2 tried to sell $him to you, is up for inspection. As usual, you pepper your inspection with questions about $his duties, $his feelings about $his physical condition, and experiences. More information about one's property is never a bad thing. When the inspection reaches $slaves[$i].slaveName's asshole, you ask whether $he enjoyed having $his older _sister2 sell $his butt. - -"No, <<Master $slaves[$i]>>," $he says. - -<br><br> - -<span id="result"> -<br><<link "Turnabout is fair play">> - <<replace "#result">> - $slaves[$j].slaveName is brought in. You gag _him2, throw the resisting bitch down on the couch, and hold _him2 there. Then, you peremptorily order the wide-eyed $slaves[$i].slaveName to <<if canDoAnal($slaves[$j])>>sodomize<<else>>facefuck<</if>> $his _sister2. $He stares open mouthed for a moment, but comes over obediently. $His face is a strange mix of vengeful eagerness, revulsion, and even a little lust. $He shoves $himself into the frantically struggling _girl2's <<if canDoAnal($slaves[$j])>>butt<<else>>jaw<</if>> without mercy. $His cock is <<if $slaves[$i].dick < 3>>pathetically small<<elseif $slaves[$i].dick < 5>>nothing out of the ordinary<<elseif $slaves[$i].dick < 7>>admittedly nothing to scoff at<<else>>a source of great envy amongst your slaves<</if>>, but by how $slaves[$j].slaveName reacts it might as well be a baseball bat. $slaves[$i].slaveName rarely gets to penetrate anything, mostly serving as an oral slut<<if canDoAnal($slaves[$i])>> and anal cocksleeve<</if>>, so $he comes in no time and takes a turn holding $slaves[$j].slaveName down <<if canDoAnal($slaves[$j])>>so you can claim sloppy seconds on _his2 spasming butthole<</if>>. - @@.hotpink;$slaves[$i].slaveName has become more devoted to you,@@ while $slaves[$j].slaveName @@.mediumorchid;hates you@@ and has become @@.gold;more afraid of you,@@<<if canDoAnal($slaves[$j])>> and @@.lime;$slaves[$j].slaveName has lost _his2 anal virginity.@@<<else>>.<</if>> - <<set $slaves[$i].devotion += 4>> - <<set $slaves[$i].counter.penetrative += 1>> - <<set $penetrativeTotal += 1>> - - <<set $slaves[$j].trust -= 5>> - <<set $slaves[$j].devotion -= 4>> - <<if canDoAnal($slaves[$j])>> - <<set $slaves[$j].anus = 1>> - <<set $slaves[$j].counter.anal += 1>> - <<set $analTotal += 1>> - <<else>> - <<set $slaves[$j].counter.oral += 1>> - <<set $oralTotal += 1>> - <</if>> - <</replace>> -<</link>> -<br><<link "Let $him have $his revenge, but remind $him of $his place">> - <<replace "#result">> - $slaves[$j].slaveName is brought in. You gag _him2, throw the resisting bitch down on the couch, and hold _him2 there. Then, you peremptorily order the wide-eyed $slaves[$i].slaveName to put $his cock <<if canDoAnal($slaves[$j])>>up $his _sister2's ass<<else>>in $his _sister2's mouth<</if>>, and then hold it there. $He stares open mouthed for a moment, but comes over obediently. $His face is a strange mix of vengeful eagerness, revulsion, and even a little lust. $He shoves $himself into the frantically struggling _girl2's <<if canDoAnal($slaves[$j])>>butt<<else>>jaw<</if>> without mercy. $His cock is <<if $slaves[$i].dick < 3>>pathetically small<<elseif $slaves[$i].dick < 5>>nothing out of the ordinary<<elseif $slaves[$i].dick < 7>>admittedly nothing to scoff at<<else>>a source of great envy amongst your slaves<</if>>, but by how $slaves[$j].slaveName reacts it might as well be a baseball bat. $slaves[$i].slaveName obeys your orders and holds still after inserting $himself. You<<if $PC.dick == 0>> don a strap-on,<</if>> move around <<if canDoAnal($slaves[$i])>>behind $him and start ass<<else>>in front of $him and start face-<</if>>fucking $him in turn, slowly permitting $him to find a rhythm where $he can fuck and get fucked at the same time. $He's getting it much harder than $he's giving it but $he's experienced enough that $he comes quickly. - @@.hotpink;$slaves[$i].slaveName has become more devoted to you,@@ while @@.mediumorchid;$slaves[$j].slaveName has become more rebellious,@@<<if canDoAnal($slaves[$j])>> and @@.lime;$slaves[$j].slaveName has lost _his2 anal virginity.@@<<else>>.<</if>> - <<set $slaves[$i].devotion += 4>> - <<if canDoAnal($slaves[$i])>> - <<set $slaves[$i].counter.anal += 1>> - <<set $analTotal += 1>> - <<else>> - <<set $slaves[$i].counter.oral += 1>> - <<set $oralTotal += 1>> - <</if>> - <<set $slaves[$i].counter.penetrative += 1>> - <<set $penetrativeTotal += 1>> - - <<set $slaves[$j].devotion -= 5>> - <<if canDoAnal($slaves[$j])>> - <<set $slaves[$j].anus = 1>> - <<set $slaves[$j].counter.anal += 2>> - <<set $analTotal += 2>> - <<else>> - <<set $slaves[$j].counter.oral += 2>> - <<set $oralTotal += 2>> - <</if>> - <</replace>> -<</link>> -</span> diff --git a/src/uncategorized/reSlaveMarriage.tw b/src/uncategorized/reSlaveMarriage.tw deleted file mode 100644 index eff7e4b8e6837518ecf80811515ef00c9c9a61e5..0000000000000000000000000000000000000000 --- a/src/uncategorized/reSlaveMarriage.tw +++ /dev/null @@ -1,152 +0,0 @@ -:: RE slave marriage [nobr] - -<<set $nextButton = "Continue", $nextLink = "Next Week">> - -<<set _groomSlave = $eventSlave>> -<<run Enunciate(_groomSlave)>> -<<setLocalPronouns _groomSlave>> - -<<set _brideSlave = getSlave(_groomSlave.relationshipTarget)>> -<<setLocalPronouns _brideSlave 2>> - - -<span id="art-frame"> -/* 000-250-006 */ -<<if $seeImages == 1>> - <div class="imageColumn"> - <div class="imageRef medImg"> - <<SlaveArt _groomSlave 2 0>> - </div> - <div class="imageRef medImg"> - <<SlaveArt _brideSlave 2 0>> - </div> - </div> -<</if>> -/* 000-250-006 */ -</span> - -<<= App.UI.slaveDescriptionDialog(_groomSlave)>> and <<= App.UI.slaveDescriptionDialog(_brideSlave)>> come into your office -<<if hasAnyArms(_groomSlave) && hasAnyArms(_brideSlave)>>holding hands<<else>>doing their best to stay close to one another despite their physical limitations<</if>>. _brideSlave.slaveName looks at _groomSlave.slaveName expectantly, but _he2's terribly nervous and makes several false starts before beginning. Finally _groomSlave.slaveName musters $his courage and <<if !canTalk(_groomSlave)>>asks you with simple gestures to grant the two of them a slave marriage.<<else>>asks with $his voice cracking, "<<Master>>, would you plea<<s>>e grant u<<s>> a <<s>>lave marriage?"<</if>> - -<br><br> - -<span id="result"> -<<link "Of course">> - <<replace "#result">> - You inquire as to whether they understand the Free Cities slave marriage ceremony, and they nod, not trusting themselves to do anything more. You give them a few minutes to get dressed in special outfits you make available. When they come back, they're wearing lacy lingerie designed to resemble old world wedding dresses, but without concealing anything. - - <br><br> - <<if (_groomSlave.vagina == 0)>> - _groomSlave.slaveName is a virgin, so $he's wearing white - <<elseif (_groomSlave.pregKnown == 1)>> - _groomSlave.slaveName is pregnant, so $he's wearing light pink - <<elseif (_groomSlave.vagina < 0)>> - _groomSlave.slaveName is a sissy slave, so $he's wearing light blue - <<else>> - _groomSlave.slaveName is an experienced sex slave, so $he's wearing light pink - <</if>> - against $his _groomSlave.skin skin. - <<if (_groomSlave.chastityPenis)>> - $He has a little bow on $his chastity cage. - <<elseif canAchieveErection(_groomSlave)>> - The <<if canSee(_groomSlave)>>sight of _brideSlave.slaveName<<else>>anticipation<</if>> has $him stiffly erect, and $he's wearing a little bow around $his cockhead. - <<elseif (_groomSlave.dick > 0)>> - $He's impotent, but $he's wearing a little bow around $his useless cockhead. - <<elseif (_groomSlave.clit > 0)>> - $His prominent clit is engorged, and $he's wearing a tiny bow on it. - <<else>> - $He's wearing a demure little bow just over $his pussy. - <</if>> - <<if (_groomSlave.anus > 1)>> - $His lacy panties are designed to spread $his buttocks a little and display $his big butthole. - <<elseif (_groomSlave.anus == 0)>> - $His lacy panties cover $his virgin anus, for once. - <</if>> - <<if (_groomSlave.boobs > 1000)>> - The bra makes no attempt to cover or even support $his huge breasts, simply letting them through holes in the lace to jut proudly out. - <<elseif (_groomSlave.boobs > 500)>> - The bra supports and presents $his big breasts, leaving $his stiffening nipples bare. - <<else>> - The bra supports and presents $his breasts, giving $him more cleavage than $he usually displays. - <</if>> - <<if _groomSlave.belly >= 1500>> - $His - <<if _groomSlave.preg > 0>> - growing pregnancy - <<else>> - rounded middle - <</if>> - prominently bulges from the gap between $his lingerie. - <</if>> - - <br><br> - <<if (_brideSlave.vagina == 0)>> - _brideSlave.slaveName is a virgin, so _he2's wearing white - <<elseif (_brideSlave.pregKnown == 1)>> - _brideSlave.slaveName is pregnant, so _he2's wearing light pink - <<elseif (_brideSlave.vagina < 0)>> - _brideSlave.slaveName is a sissy slave, so _he2's wearing light blue - <<else>> - _brideSlave.slaveName is an experienced sex slave, so _he2's wearing light pink - <</if>> - against _his2 _brideSlave.skin skin. - <<if (_brideSlave.chastityPenis)>> - _He2 has a little bow on _his2 chastity cage. - <<elseif canAchieveErection(_brideSlave)>> - The <<if canSee(_brideSlave)>>sight of _groomSlave.slaveName<<else>>anticipation<</if>> has _him2 stiffly erect, and _he2's wearing a little bow around _his2 cockhead. - <<elseif (_brideSlave.dick > 0)>> - $He's impotent, but _he2's wearing a little bow around _his2 useless cockhead. - <<elseif (_brideSlave.clit > 0)>> - _His2 prominent clit is engorged, and _he2's wearing a tiny bow on it. - <<else>> - _He2's wearing a demure little bow just over _his2 pussy. - <</if>> - <<if (_brideSlave.anus > 1)>> - _His2 lacy panties are designed to spread _his2 buttocks a little and display _his2 big butthole. - <<elseif (_brideSlave.anus == 0)>> - _His2 lacy panties cover _his2 virgin anus, for once. - <</if>> - <<if (_brideSlave.boobs > 1000)>> - The bra makes no attempt to cover or even support _his2 huge breasts, simply letting them through holes in the lace to jut proudly out. - <<elseif (_brideSlave.boobs > 500)>> - The bra supports and presents _his2 big breasts, leaving _his2 stiffening nipples bare. - <<else>> - The bra supports and presents _his2 breasts, giving _him2 more cleavage than _he2 usually displays. - <</if>> - <<if _brideSlave.belly >= 1500>> - _His2 - <<if _brideSlave.preg > 0>> - growing pregnancy - <<else>> - rounded middle - <</if>> - prominently bulges from the gap between _his2 lingerie. - <</if>> - - <br><br>The procedure is simple. The two of them prostrate themselves on the ground and beg your indulgence. You state that you grant it, and hand each of them a simple gold band to be worn on the little finger in advertisement of the inferiority of their union. In turn, each of them gives the other their ring, and they kiss. You pronounce them slave spouses, and offer them the couch for their honeymoon; they @@.mediumaquamarine;thank you profusely@@ through their building tears. It's always touching to see <<if _groomSlave.bellyPreg >= 5000 && _brideSlave.bellyPreg >= 5000>>two pregnant slaves <<if hasAnyArms(_brideSlave) && hasAnyArms(_groomSlave)>>fingering<<else>>fucking<</if>> each other<<else>>a 69<</if>> in which both participants are @@.hotpink;softly crying with happiness.@@ - <<if _groomSlave.pregSource == _brideSlave.ID && _brideSlave.pregSource == _groomSlave.ID>> - When _groomSlave.slaveName and _brideSlave.slaveName tire, they rest, shoulder to shoulder, with a hand upon each other's bulging belly. Gently, they caress their growing pregnancies, knowing that they carry the other's love child. - <<elseif _brideSlave.pregSource == _groomSlave.ID>> - When they tire, _groomSlave.slaveName rests $his head upon _brideSlave.slaveName's lap and gently kisses $his lover's belly, knowing the child of their love is growing within. - <<elseif _groomSlave.pregSource == _brideSlave.ID>> - When they tire, _brideSlave.slaveName rests _his2 head upon _groomSlave.slaveName's lap and gently kisses _his2 lover's belly, knowing the child of their love is growing within. - <</if>> - <<set _groomSlave.devotion += 4>> - <<set _brideSlave.devotion += 4>> - <<set _groomSlave.trust += 4>> - <<set _brideSlave.trust += 4>> - <<set _groomSlave.counter.oral += 1>> - <<set _brideSlave.counter.oral += 1>> - <<set _groomSlave.relationship = 5>> - <<set _brideSlave.relationship = 5>> - <<set $oralTotal += 2>> - <<set $slaves[$slaveIndices[_brideSlave.ID]] = _brideSlave>> - <<set $slaves[$slaveIndices[_groomSlave.ID]] = _groomSlave>> - <</replace>> -<</link>> -<br><<link "No">> - <<replace "#result">> - You decline gently, telling them that their relationship is acceptable to you as it is. They are disappointed, but not surprised, and accept your will without a murmur. They leave as they entered, holding hands. - <</replace>> -<</link>> -</span> diff --git a/src/uncategorized/remFluctuations.tw b/src/uncategorized/remFluctuations.tw deleted file mode 100644 index 2f7b903629ff1144aa6c3ebb84d390ee812a4524..0000000000000000000000000000000000000000 --- a/src/uncategorized/remFluctuations.tw +++ /dev/null @@ -1,127 +0,0 @@ -:: REM fluctuations [nobr] - -<<set $nextButton = "Continue", $nextLink = "RIE Eligibility Check">> - -<<if $REM == 1>> - <<set $REM = either("antislavery terrorism", "medical breakthrough", "new free city", "revel", "speculation", "tainted drugs")>> -<<elseif $REM == -1>> - <<set $REM = either("anti-slavery coup", "arcology change", "bankruptcy", "empty prisons", "hostilities ended", "refugee boat", "unemployment", "war")>> -<</if>> - -<<setAssistantPronouns>> -<p> - <<if $assistant.personality > 0>> - <<if $assistant.market>> - The market assistant's avatar appears on a wallscreen as you're going about your business. - <<switch $assistant.appearance>> - <<case "monstergirl">>The regular monster<<= _girlA>> stands behind and prods the human _girlM forward. - <<case "shemale">>You recognize _hisM function by _hisM glasses and because _hisM bimbo cock softens, halfway, while _heM addresses you on economic matters. - <<case "amazon">>_HeM illustrates a small group of gossiping tribeswomen that fades away as _heM leaves them and approaches you. - <<case "businesswoman">>The junior business<<= _womanM>> adopts a shy posture when addressing you directly, as if unsuccessfully concealing a workplace crush. - <<case "goddess">>The demigoddess portrait arrives in a glittery cloud of dust, wearing winged shoes. - <<case "schoolgirl">>Both <<if _girlA == _girlM>>school<<= _girlA>><<else>>student<</if>>s are sitting knee to knee; the nerdy one hands the other a folded note. "Pass it on," _heM stage whispers. <<if $assistant.name == "your personal assistant">>Your regular assistant<<else>>$assistant.name<</if>> rolls _hisA eyes. - <<case "hypergoddess">>The demigoddess portrait arrives in a glittery cloud of dust, wearing winged shoes and a noticeable roundness in _hisM middle. - <<case "loli">>The chubby, glasses-wearing _loliM arrives holding a neatly folded note addressed to you. - <<case "preggololi">>The chubby, glasses-wearing _loliM arrives holding a hastily written note addressed to you. _HeM seems kind of winded, with a suspicious stain in _hisM panties under _hisM pussy. - <<case "fairy" "pregnant fairy">>The older fairy flutters into view before, curtseys, and holds out a rolled piece of parchment addressed to you. - <<case "normal">>_HisM symbol lights up in regular green pulses while _heM waits for your attention. - <<case "angel">>The short haired angel lands before you, a rolled piece of parchment under _hisM arm. - <<case "cherub">>The short haired cherub flutters before you holding a rolled piece of parchment in _hisM hands. - <<case "incubus">>The regular incubus stands behind and prods the human _girlM forward with _hisA dick. - <<case "succubus">>The regular succubus stands behind and pushes the human _girlM forward. - <<case "imp">>The short haired imp flaps before you holding a rolled piece of parchment in _hisM hands. - <<case "witch">>The apprentice's apprentice arrives before you; a message begins playing the moment _heM opens _hisM mouth. - <<case "ERROR_1606_APPEARANCE_FILE_CORRUPT">>The creature finishes forcing eggs into the human _girlM, leaving _himM to stagger towards you clutching a crumpled letter in one hand and struggling to hold back the eggs with the other. - <</switch>> - <<else>> - <<= capFirstChar($assistant.name)>> appears on a wallscreen as you're going about your business. - <<switch $assistant.appearance>> - <<case "monstergirl">>_HeA's looking unusually businesslike, with _hisA tentacle hair restrained in a bun. - <<case "loli">>_HeA's looking unusually businesslike, withdrawn deep in thought. - <<case "preggololi">>_HeA's looking unusually businesslike, withdrawn deep in thought. - <<case "shemale">>_HeA's looking unusually businesslike, with _hisA perpetually erect dick going untended, for once. - <<case "amazon">>_HeA's looking unusually businesslike, and is doing sums on a primitive little abacus. - <<case "businesswoman">>_HeA has a clipboard pressed against _hisA generous bosom, and peers at you over the tops of _hisA spectacles. - <<case "fairy">>_HeA's looking unusually businesslike, wearing a tiny business suit with an opening in the back for _hisA wings to come out. - <<case "pregnant fairy">>_HeA's looking unusually businesslike, wearing a tiny business suit open in the front to let _hisA swollen belly out and another opening in the back for _hisA wings to come out. - <<case "goddess" "hypergoddess">>_HeA's looking unusually businesslike, with _hisA hands clasped behind _hisA back and pivoting one foot. - <<case "schoolgirl">>_HeA's looking unusually businesslike, and has a scribbled note in _hisA hand. - <<case "angel">>_HeA's looking unusually businesslike; deep in thought with _hisA hands together in front of _himA. - <<case "cherub">>_HeA's looking unusually businesslike, reading a newspaper titled "Heaven's Post". - <<case "incubus">>_HeA's looking unusually businesslike, with _hisA typically erect dick flaccid for once. - <<case "succubus">>_HeA's looking unusually businesslike, wearing a slutty business suit, glasses and _hisA hair in a tight bun. A slight buzzing can be heard from under _hisA skirt. - <<case "imp">>_HeA's looking unusually businesslike, reading a list titled "Hell's Holes". - <<case "witch">>_HeA's looking unusually businesslike, nose first in an a book title "Economics and You". - <<case "ERROR_1606_APPEARANCE_FILE_CORRUPT">>_HeA's looking unusually businesslike, wearing an ill-fitted business suit. _HisA blouse buttons pop off as _hisA belly swells grotesquely, before the object within _himA begins steadily moving upwards. - <<default>>_HisA symbol spins for attention. - <</switch>> - "<<= properTitle()>>, I have a news item that may be of business interest," _heA - <<switch $assistant.appearance>> - <<case "monstergirl" "normal">>informs you. - <<case "shemale">>says seriously. - <<case "amazon">>says warmly. - <<case "businesswoman">>says diffidently. - <<case "goddess">>announces. - <<case "schoolgirl">>reads aloud. - <<case "hypergoddess">>announces between _hisA children's kicking. - <<case "loli" "preggololi">>says cutely. - <<case "fairy" "pregnant fairy">>says excitedly. - <<case "angel">>calmly states. - <<case "cherub" "imp">>says enthusiastically. - <<case "incubus">>starts, pauses to play with _himselfA, and continues. - <<case "succubus">>says between overly loud moans. - <<case "witch">>states, finishes the page, and snaps _hisA fingers. _HeA grunts, reaches up _hisA skirt and pulls out a message for you. Seems it didn't arrive as planned. - <<case "ERROR_1606_APPEARANCE_FILE_CORRUPT">>says, _hisA throat bulging as the egg containing the message passes out _hisA mouth. - <</switch>> - <</if>> - <<else>> - Your <<if $assistant.market>>market<<else>>personal<</if>> assistant's symbol appears on a wallscreen as you're going about your business. _HeA spins for your attention. "<<= properTitle()>>, I have a news item that may be of business interest," _heA says. - <</if>> -</p> - -/* The events reducing slave prices are all supply sided. Without events reducing demand this is a little unbalanced. A minor issue */ -<<if $REM == "revel">> - Something is happening in one of the Free Cities' richest arcologies. It's not clear what, exactly, it is, since its owner is making skillful use of the arcology's advanced surveillance and media systems to keep its internal affairs quite secret. The truth will get out eventually, and it's probably not going to do much for old world opinions of the Free Cities. After all, cheap slaves go into that arcology at a prodigious rate, and they don't seem to ever come out again. The unexpected demand for slaves, any slaves, has produced a temporary tightening of the entire slave market. Projections suggest price increases of up to five percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a great time to sell stock, and a bad time to buy. <span class="noteworthy">The market price of slaves has increased.</span> - <<set $menialDemandFactor += 12000>> -<<elseif $REM == "tainted drugs">> - The Free Cities are anarcho-capitalist paradises — or 'paradises,' depending on one's station and assets. You can't complain personally, as one of the Free Cities' richest citizens, master of your own arcology and owner of sexual slaves. Unfortunately quite a few slaves in the markets are in a position to complain today, as are their owners. Many slave markets use long-lasting stimulants to pep their wares up for auction; dull-eyed slaves earn low bids. Corner-cutting at one of the major suppliers of these stimulants led to a number of slaves being prepared for auction being damaged today. Relatively few were permanently lost, but slaves are going to be a little scarce for a while, which will drive up the going rate. Projections suggest increases of up to five percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a great time to sell stock, and a bad time to buy. <span class="noteworthy">The market price of slaves has increased.</span> - <<set $menialSupplyFactor -= 12000>> -<<elseif $REM == "antislavery terrorism">> - Antislavery activism in the old world has grown to match the spread of slavery in the Free Cities. Unfortunately for the activists, they are confronted with a fundamental problem: the independence of the Free Cities. There is very little they can do without resorting to violence, and so, predictably, they often do. A major slave induction center in one of the more open Free Cities has just suffered a suicide bombing. The actual damage was slight, but a wave of increased import security is sweeping the Free Cities in reaction to the incident. Slave prices will be driven up by the cost of checking imported merchandise for explosive devices until the market adjusts. Projections suggest price increases of up to five percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a great time to sell stock, and a bad time to buy. <span class="noteworthy">The market price of slaves has increased.</span> - <<set $menialSupplyFactor -= 12000>> -<<elseif $REM == "new free city">> - New Free Cities arise unpredictably. They require either carving out a slice of the old world, emancipating it from whichever inattentive or corrupt country previously owned the land, or reclaiming new land from barren or uninhabitable areas, efforts which are often kept secret. The unpredictable happened today; the world has a new Free City. As usual, immigration rights are being offered cheaply to deserving persons. Many of the remaining rich and talented of the old world are staking claims in the new city, and they'll be buying slaves when they get to their new home. It's a sellers' market out there; projections show the price of slaves rising as much as ten percent in the short term. There will be no immediate impact on you or your slaves, but the coming weeks will be a great time to sell stock, and a bad time to buy. <span class="noteworthy">The market price of slaves has increased.</span> - <<set $menialDemandFactor += 20000>> -<<elseif $REM == "speculation">> - The Free Cities are almost totally unregulated. Prices and interest rates can spike and plummet with speeds not seen since the South Sea Bubble, and for the most silly or corrupt of reasons. Today, it's the latter. A massive attempt to rig the slave market was uncovered this morning. Ultimately, the culprits were caught and much of the damage reversed, but confidence in the marketplace has been shaken. Many great slave vendors are holding onto their stock until they're sure the water's calm again. It's a sellers' market out there; projections show the price of slaves rising as much as ten percent in the short term. There will be no immediate impact on you or your slaves, but the coming weeks will be a great time to sell stock, and a bad time to buy. <span class="noteworthy">The market price of slaves has increased.</span> - <<set $menialSupplyFactor -= 20000>> -<<elseif $REM == "medical breakthrough">> - There has been a breakthrough in gene therapy. More accurately, there was a breakthrough in gene therapy several years ago — you already knew all about it, and some of the more advanced slave medical upgrades available to you use the technology. However, it's finally gotten out of the prototype stage, and is becoming available to the Free Cities middle class, citizens with one or two slaves. The average citizen is more able today than he was yesterday to turn his chattel housekeeper into the girl he's always dreamed of. Aspirational stuff like this always causes a major price shock. It's a sellers' market out there; projections show the price of slaves rising as much as ten percent in the short term. There will be no immediate impact on you or your slaves, but the coming weeks will be a great time to sell stock, and a bad time to buy. <span class="noteworthy">The market price of slaves has increased.</span> - <<set $menialDemandFactor += 20000>> -<<elseif $REM == "bankruptcy">> - The economy of the Free Cities is a rough-and-tumble place. The absence of old world regulations and institutions, and the often gold-rush atmosphere of the new cities, lead to fortunes being made and lost overnight. Last night, one of the Free Cities' greatest fortunes was lost. A great slave trading house unexpectedly went bankrupt, and its huge stable of slaves are being sold at fire-sale prices. The unforeseen sell off is driving down the market price of slaves all across the Free Cities. Projections show a short-term price drop of up to five percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span> - <<set $menialSupplyFactor += 12000>> -<<elseif $REM == "refugee boat">> - Periodic refugee crises sweep the old world, and sometimes the human flotsam shaken loose from its moorings in the old world is brought up on the shores of the Free Cities. This week, that was no metaphor. A floating Free City has been inundated by refugees in boats. Naturally, the boats have been discarded and the refugees enslaved. It is unclear whether they somehow did not know that this was their inevitable fate, or their lot in the old world was so desperate that they were willing to accept it. Projections show a short-term slave price drop of up to five percent as the market digests the influx. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span> - <<set $menialSupplyFactor += 12000>> -<<elseif $REM == "arcology change">> - All across the Free Cities, arcology owners are experimenting with new society models and new ways of enforcing them. A nearby arcology has just undergone a major internal struggle as its owner forced through a radical program of changes and harsh measures to enforce them. All but a handful of its inhabitants have been enslaved and placed under the control of a chosen few. With harems of hundreds and little experience or infrastructure to manage them, the new overlords are selling off stock to raise funds to make the transition. Projections show a short-term price drop of up to five percent as they flood the market with mediocre slaves. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span> - <<set $menialSupplyFactor += 12000>> -<<elseif $REM == "war">> - The old world outside the Free Cities took another step towards its final decline today. A relatively prosperous third world city fell to a regional warlord, and it seems the remaining great powers lack either the money or the will to do anything about it. The victors seem to be following the standard procedure for modern conquerors. Anything valuable, they steal. Among the population, they recruit the willing, shoot the unwilling, and enslave everyone else. The slave markets are going to be glutted with new stock soon. Projections show a short-term price drop of up to ten percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span> - <<set $menialSupplyFactor += 20000>> -<<elseif $REM == "empty prisons">> - A small, impoverished old world country defaulted on its currency today. Its beleaguered government is taking every available step to raise funds. Among other things, it has sold every inmate in its prisons who would fetch a price worth the trouble of sale into Free Cities slavery. Though most of the influx is going to be of abominably low quality, the sudden addition of so much new meat is going to have a big impact on the slave economy. Projections show a short-term price drop of up to ten percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span> - <<set $menialSupplyFactor += 20000>> -<<elseif $REM == "unemployment">> - A leading old world nation has just suffered a major economic downturn. Old world nations suffer economic downturns all the time, of course, but to those with interests in the slave market, news like this can be very important. Slave market shocks from catastrophes get all the headlines, but a change that affects millions will often be more impactful. As unemployment in the old world rises, the number of people faced with the choice between starvation and voluntary enslavement rises. Social safety nets just aren't what they used to be. Projections show a short-term slave price drop of up to ten percent due to the sharp increase in desperate people immigrating to the Free Cities for enslavement. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span> - <<set $menialSupplyFactor += 20000>> -<<elseif $REM == "anti-slavery coup">> - For months there were strong indications that an old world nation was quietly taking steps towards legalizing slavery. The market began to anticipate a serious increase in the demand for slaves in earnest but this week a month of protests against the country's leaders ended in a violent coup. The new government, claiming to only follow the will of the people, has made several promises, including a very vocal rebuke of even the slightest possibility of legal slavery within their borders. The slave market was shocked to find the previous government to be so weak and even more shocked at how unwilling the new one is to accept the times we live in. The panicked market quickly adjusted to greatly lowered slave demand and projections show a short-term price drop of up to ten percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span> - <<set $menialDemandFactor -= 20000>> -<<elseif $REM == "hostilities ended">> - The Free Cities make a real effort to avoid armed conflict, especially amongst themselves, as such endeavors almost never have any real winners. But tensions grew so high in their trade conflict that the likelihood of a full blown war between two Free Cities became not just a possibility but a near certainty for months. As skirmishes commenced and slave armies were quickly drilled for action on both sides, the slave market anticipated a boost to demand as soon as the fighting intensified. Miraculously, cooler heads prevailed and the Free Cities agreed to disband their armies. While many people sighed with relief the slave market was forced into a shock adjustment, projections show a short-term price drop of up to five percent. There will be no immediate impact on you or your slaves, but the coming weeks will be a fine time to buy new stock, and a terrible time to sell. <span class="noteworthy">The market price of slaves has dropped.</span> - <<set $menialDemandFactor -= 12000>> -<</if>> -<<set $menialDemandFactor = Math.clamp($menialDemandFactor, -50000, 50000)>> -<<set $slaveCostFactor = menialSlaveCost()/1000>> diff --git a/src/uncategorized/remMerger.tw b/src/uncategorized/remMerger.tw deleted file mode 100644 index 18c661363199229391d8f0ed7fc3ff3b3bccb4a3..0000000000000000000000000000000000000000 --- a/src/uncategorized/remMerger.tw +++ /dev/null @@ -1,61 +0,0 @@ -:: REM merger [nobr] - -<<set $nextButton = "Continue">> -<<set $nextLink = "RIE Eligibility Check">> - -<<set _slaveCompany = App.Corporate.divisionList - .filter(div => div.founded && div.hasMergers) - .map (div => div.mergerChoices.map((merger, index) => ({merger, index, division:div}))) - .flat ()>> -<<set _maxCompanies = Math.trunc(Math.log2(App.Corporate.divisionList.filter(div => div.founded).length)) + 1>> -<<set _numCompanies = random(1, _maxCompanies)>> - -<<set _companies = []>> -<<for _index = 0; _index < _numCompanies; ++_index>> - <<run _companies.push(_slaveCompany.pluck())>> -<</for>> -<<set _assistant = $assistant.market ? "your market assistant" : $assistant.name>> - -<p><<= capFirstChar(_assistant)>> constantly combs business records, tax receipts and the media for leads on opportunities for your corporation to take advantage of. Small businesses go under all the time, and with a large amount of cash on hand, your corporation can afford to step in and acquire them. This week, _assistant has found <<= numberWithPlural(_numCompanies, "troubled organization") >> you could easily fold into your corporation.</p> - -<<if _companies.length == 1>> - <<set _company = _companies[0]>> - <div class="majorText">This week you come across <<= _company.merger.text.trouble >></div> -<<else>> - <<for _index, _company range _companies>> - <div class="majorText">The <<= ordinalSuffixWords(_index + 1)>> is <<= _company.merger.text.trouble >></div> - <</for>> -<</if>> -<div id="result"> -<<for _company range _companies>> - <<capture _company>> - <div> - <<set _absorbName = "Absorb the " + _company.merger.name>> - <<link _absorbName>> - <<replace "#result">> - You quickly acquire the <<= _company.merger.name>><<= _company.merger.text.acquire >> - <<set _devCount = _company.merger.result.development, - _slaveCount = _company.merger.result.slaves>> - <<if _devCount != null>> - <<set _company.division.developmentCount += _devCount>> - <</if>> - <<if _slaveCount != null>> - <<set _company.division.activeSlaves += _slaveCount>> - <</if>> - <<set _cost = (_company.merger.cost || 50) * 1000 >> - <<if _devCount != null && _slaveCount != null>> - <<set App.Corporate.chargeAsset(_cost / 2, "development")>> - <<set App.Corporate.chargeAsset(_cost / 2, "slaves")>> - <<elseif _devCount != null>> - <<set App.Corporate.chargeAsset(_cost, "development")>> - <<elseif _slaveCount != null>> - <<set App.Corporate.chargeAsset(_cost, "slaves")>> - <<else>> - @@.red;ERROR! No changes to the corporation are made!@@ - <</if>> - <</replace>> - <</link>> - </div> - <</capture>> -<</for>> -</div>