From bbb97f28ea90625ebc4984e1e87dd9971d4a4d88 Mon Sep 17 00:00:00 2001 From: Svornost <11434-svornost@users.noreply.gitgud.io> Date: Tue, 13 Apr 2021 03:55:20 -0700 Subject: [PATCH] Time-gated plot event controller --- js/003-data/gameVariableData.js | 1 + src/002-config/fc-version.js | 2 +- .../backwardsCompatibility.js | 4 + src/events/nonRandom/arcologyNaming.js | 3 - src/events/nonRandom/daughters/pBombing.tw | 1 - .../daughters/pCollaborationChoice.tw | 2 +- .../nonRandom/daughters/pCoupAftermath.tw | 2 +- .../nonRandom/daughters/pCoupAttempt.tw | 2 +- .../nonRandom/daughters/pCoupBetrayal.tw | 2 +- .../nonRandom/daughters/pHackerSupport.tw | 2 +- .../nonRandom/daughters/pTraitorMessage.tw | 2 +- .../daughters/pUndergroundRailroad.tw | 15 +-- .../nonRandom/mercs/pCitizensAndCivilians.tw | 2 +- src/events/nonRandom/mercs/pMercenaries.tw | 2 +- src/events/nonRandom/mercs/pRaidInvitation.tw | 2 +- src/events/nonRandom/mercs/pSnatchAndGrab.tw | 1 - src/events/nonRandom/militia.js | 20 +--- src/events/nonRandom/pDefenseFears.tw | 2 +- src/events/nonRandom/pInvasion.tw | 2 +- src/events/nonRandom/shootInvitation.js | 8 -- src/events/nonRandom/slaveFood.js | 8 -- src/events/nonRandom/stripClubAftermath.js | 8 -- src/events/nonRandom/stripClubClosing.js | 8 -- src/events/nonRandomEvent.js | 47 +--------- src/events/timeGatedPlotEvent.js | 92 +++++++++++++++++++ src/uncategorized/seNicaeaAnnouncement.tw | 1 - src/uncategorized/seNicaeaPreperation.tw | 1 - 27 files changed, 123 insertions(+), 119 deletions(-) create mode 100644 src/events/timeGatedPlotEvent.js diff --git a/js/003-data/gameVariableData.js b/js/003-data/gameVariableData.js index 2db7bf14ea4..0e20f0d3645 100644 --- a/js/003-data/gameVariableData.js +++ b/js/003-data/gameVariableData.js @@ -371,6 +371,7 @@ App.Data.resetOnNGPlus = { targetArcology: {fs: "New"}, plot: 1, + plotEventWeek: 0, assignmentRecords: {}, marrying: [], // array of slave being married this week organs: [], diff --git a/src/002-config/fc-version.js b/src/002-config/fc-version.js index bd99c90adf1..fac73455af3 100644 --- a/src/002-config/fc-version.js +++ b/src/002-config/fc-version.js @@ -2,5 +2,5 @@ App.Version = { base: "0.10.7.1", // The vanilla version the mod is based off of, this should never be changed. pmod: "3.9.6", commitHash: null, - release: 1123 // When getting close to 2000, please remove the check located within the onLoad() function defined at line five of src/js/eventHandlers.js. + release: 1124 // When getting close to 2000, please remove the check located within the onLoad() function defined at line five of src/js/eventHandlers.js. }; diff --git a/src/data/backwardsCompatibility/backwardsCompatibility.js b/src/data/backwardsCompatibility/backwardsCompatibility.js index f0f3d216e2d..b27815d8936 100644 --- a/src/data/backwardsCompatibility/backwardsCompatibility.js +++ b/src/data/backwardsCompatibility/backwardsCompatibility.js @@ -2238,6 +2238,10 @@ App.Update.oldVersions = function(node) { if (V.releaseID <= 1116 && V.pregnancyMonitoringUpgrade === 3) { V.pregnancyMonitoringUpgrade = 1; } + // assume we're caught up on plot events if we were running the old plot event system + if (V.releaseID <= 1123) { + V.plotEventWeek = App.Events.effectiveWeek(); + } node.append(`Done!`); }; diff --git a/src/events/nonRandom/arcologyNaming.js b/src/events/nonRandom/arcologyNaming.js index bb078d00220..18f2734818c 100644 --- a/src/events/nonRandom/arcologyNaming.js +++ b/src/events/nonRandom/arcologyNaming.js @@ -5,9 +5,7 @@ App.Events.PArcologyNaming = class PArcologyNaming extends App.Events.BaseEvent eventPrerequisites() { return [ - () => App.Events.effectiveWeek() === 4, () => V.arcologies[0].name.indexOf("Arcology ") !== -1, - () => V.plotEventWeek !== 4 ]; } @@ -17,7 +15,6 @@ App.Events.PArcologyNaming = class PArcologyNaming extends App.Events.BaseEvent execute(node) { let r = []; - V.plotEventWeek = 4; r.push(`As a society free of the encumbrance of governmental oversight, the arcologies of the Free Cities are places where societal evolution and corporate expansion can occur rapidly. Even so, the incredible speed with which the arcology has improved under your tenure as compared to that of your predecessor, after you obtained ownership through`); if (V.PC.rumor === "wealth") { r.push(`a leveraged buyout,`); diff --git a/src/events/nonRandom/daughters/pBombing.tw b/src/events/nonRandom/daughters/pBombing.tw index 85e5ed231cc..79379414173 100644 --- a/src/events/nonRandom/daughters/pBombing.tw +++ b/src/events/nonRandom/daughters/pBombing.tw @@ -1,7 +1,6 @@ :: P bombing [nobr] <<set $nextButton = "Continue">> -<<set $nextLink = "Random Nonindividual Event">> <<if _S.Bodyguard>> <<setLocalPronouns _S.Bodyguard>> diff --git a/src/events/nonRandom/daughters/pCollaborationChoice.tw b/src/events/nonRandom/daughters/pCollaborationChoice.tw index 6018eb635b9..2f23d92e3c6 100644 --- a/src/events/nonRandom/daughters/pCollaborationChoice.tw +++ b/src/events/nonRandom/daughters/pCollaborationChoice.tw @@ -1,6 +1,6 @@ :: P collaboration choice [nobr] -<<set $nextButton = "Continue", $nextLink = "Random Nonindividual Event">> +<<set $nextButton = "Continue">> <<setLocalPronouns $traitor>> <<run Enunciate($traitor)>> diff --git a/src/events/nonRandom/daughters/pCoupAftermath.tw b/src/events/nonRandom/daughters/pCoupAftermath.tw index 3d1d3baabbd..9e3f8c86d22 100644 --- a/src/events/nonRandom/daughters/pCoupAftermath.tw +++ b/src/events/nonRandom/daughters/pCoupAftermath.tw @@ -1,6 +1,6 @@ :: P coup aftermath [nobr] -<<set $nextButton = " ", $nextLink = "Random Nonindividual Event", $rivalOwner = 0, $rivalryPower = 0, _num = random(0,99)>> /* hide button until user makes a selection */ +<<set $nextButton = " ", $rivalOwner = 0, $rivalryPower = 0, _num = random(0,99)>> /* hide button until user makes a selection */ <<if _num <= $seeDicks>> <<set $rivalGender = 2>> <<else>> diff --git a/src/events/nonRandom/daughters/pCoupAttempt.tw b/src/events/nonRandom/daughters/pCoupAttempt.tw index 59092130f43..9f6ee502652 100644 --- a/src/events/nonRandom/daughters/pCoupAttempt.tw +++ b/src/events/nonRandom/daughters/pCoupAttempt.tw @@ -1,6 +1,6 @@ :: P coup attempt [nobr] -<<set $nextButton = "Continue", $nextLink = "Random Nonindividual Event", $daughtersVictory = 1>> +<<set $nextButton = "Continue", $daughtersVictory = 1>> <<if $traitor != 0>> <<set _weeks = $traitorWeeks-1, _pregWeeks = $traitorWeeks-1, $traitorWeeks = 0>> diff --git a/src/events/nonRandom/daughters/pCoupBetrayal.tw b/src/events/nonRandom/daughters/pCoupBetrayal.tw index b909a046674..71b41cac5bc 100644 --- a/src/events/nonRandom/daughters/pCoupBetrayal.tw +++ b/src/events/nonRandom/daughters/pCoupBetrayal.tw @@ -1,6 +1,6 @@ :: P coup betrayal [nobr] -<<set $nextButton = "Continue", $nextLink = "Random Nonindividual Event", $daughtersVictory = 1>> +<<set $nextButton = "Continue", $daughtersVictory = 1>> <<set _weeks = $traitorWeeks-1, _pregWeeks = $traitorWeeks-1, $traitorWeeks = 0>> diff --git a/src/events/nonRandom/daughters/pHackerSupport.tw b/src/events/nonRandom/daughters/pHackerSupport.tw index 86ad08e8016..3a368ef36f2 100644 --- a/src/events/nonRandom/daughters/pHackerSupport.tw +++ b/src/events/nonRandom/daughters/pHackerSupport.tw @@ -1,6 +1,6 @@ :: P hacker support [nobr] -<<set $nextButton = "End Call", $nextLink = "Random Nonindividual Event", $hackerSupport = 0>> +<<set $nextButton = "End Call", $hackerSupport = 0>> <<setAssistantPronouns>> <<set $fcnn.push("...the Daughters of Liberty as 'cyberterrorists', after an attempted...")>> diff --git a/src/events/nonRandom/daughters/pTraitorMessage.tw b/src/events/nonRandom/daughters/pTraitorMessage.tw index f4cb04d78a0..c3b72d9864a 100644 --- a/src/events/nonRandom/daughters/pTraitorMessage.tw +++ b/src/events/nonRandom/daughters/pTraitorMessage.tw @@ -1,6 +1,6 @@ :: P traitor message [nobr] -<<set $nextButton = "Continue", $nextLink = "Random Nonindividual Event">> +<<set $nextButton = "Continue">> <<set _weeks = $traitorWeeks-1, _pregWeeks = $traitorWeeks-1, $traitorWeeks = 1>> <<setLocalPronouns $traitor>> diff --git a/src/events/nonRandom/daughters/pUndergroundRailroad.tw b/src/events/nonRandom/daughters/pUndergroundRailroad.tw index adab61e47ca..49e8c7df6b7 100644 --- a/src/events/nonRandom/daughters/pUndergroundRailroad.tw +++ b/src/events/nonRandom/daughters/pUndergroundRailroad.tw @@ -1,6 +1,9 @@ :: P underground railroad [nobr] -<<set $nextButton = " ", $nextLink = "Random Nonindividual Event">> /* hide button until user makes a selection */ +<<set $nextButton = " ">> /* hide button until user makes a selection */ +<<set $returnTo = $nextLink>> /* we might have to call AS Dump, so make sure it goes back to wherever we were going next */ + +<<set $collaboration = 0, $traitor = 0, $hackerSupport = 0>> <<set $activeSlave = $slaves.filter(function(s) { return s.fuckdoll == 0 && s.fetish != "mindbroken" && canWalk(s) && s.devotion < 75 && s.trust < 75 && s.indenture == -1 && canWalk(s) && canTalk(s) && canSee(s) && ["serve in the club", "serve the public", "whore", "work in the brothel"].includes(s.assignment); }).random()>> <<if (ndef $activeSlave)>> /* search again without assignments limitation */ @@ -190,7 +193,7 @@ This is disturbing, to say the least. After close investigation, it appears some <</replace>> <</link>> <br><<link "Tell $him to ignore the Daughters in the future">> - <<set $nextButton = "Continue", $nextLink = "AS Dump", $returnTo = "Random Nonindividual Event">><<run App.Utils.updateUserButton()>> /* unlock Continue button */ + <<set $nextButton = "Continue">><<run App.Utils.updateUserButton()>> /* unlock Continue button */ <<replace "#result">> $activeSlave.slaveName nods $his head in acceptance. There is too much at stake to take such a risk. All attempts to use your monitoring systems to find the citizens who contacted $him fail; it seems their ability to corrupt your systems is considerable. $He keeps $his lips shut tight in an effort to prevent rumors from spreading, but @@.mediumorchid;whispers of freedom@@ still manage to run through your chattel. <<run $slaves.forEach(function(s) { s.devotion -= 5; })>> @@ -324,7 +327,7 @@ This is disturbing, to say the least. After close investigation, it appears some <<run removeSlave($activeSlave)>> <</link>> <br><<link "Tell $him to ignore the Daughters in the future">> - <<set $nextButton = "Continue", $nextLink = "AS Dump", $returnTo = "Random Nonindividual Event">><<run App.Utils.updateUserButton()>> /* unlock Continue button */ + <<set $nextButton = "Continue", $nextLink = "AS Dump">><<run App.Utils.updateUserButton()>> /* unlock Continue button */ <<replace "#result">> <<if $traitorType != "defiant">> $activeSlave.slaveName almost @@.mediumorchid;faints with relief@@ when it becomes apparent you aren't going to punish $him for speaking of freedom. @@ -337,7 +340,7 @@ This is disturbing, to say the least. After close investigation, it appears some <</replace>> <</link>> <br><<link "Publicly flog $him for treasonous conversation">> - <<set $nextButton = "Continue", $nextLink = "AS Dump", $returnTo = "Random Nonindividual Event">><<run App.Utils.updateUserButton()>> /* unlock Continue button */ + <<set $nextButton = "Continue", $nextLink = "AS Dump">><<run App.Utils.updateUserButton()>> /* unlock Continue button */ <<replace "#result">> You announce that a treasonous slave will be publicly flogged. Treason is understood in the Free Cities to be activity that tends to undermine slavery, and public interest is considerable when $activeSlave.slaveName is dragged out into a public atrium and secured to a post. You do your duty; the one that passes the sentence should swing the lash. The ordeal is long and bloody. The populace understand the necessity of the punishment, though they are @@.red;disturbed@@ that such a thing could happen in your penthouse of all places. The effect on $activeSlave.slaveName's health @@.health.dec;is serious,@@ and $he is @@.gold;terrified of failing you again.@@ <<set $activeSlave.trust -= 15>> @@ -345,7 +348,7 @@ This is disturbing, to say the least. After close investigation, it appears some <</replace>> <</link>> <br><<link "Chemically lobotomize $him to extirpate any record of the incident">> - <<set $nextButton = "Continue", $nextLink = "AS Dump", $returnTo = "Random Nonindividual Event">><<run App.Utils.updateUserButton()>> /* unlock Continue button */ + <<set $nextButton = "Continue", $nextLink = "AS Dump">><<run App.Utils.updateUserButton()>> /* unlock Continue button */ <<replace "#result">> You inform $activeSlave.slaveName that $he is to return to $his duties, which $he does, mystified. Later in the day $he finds $himself scheduled for surgery, and meekly goes. As $he feels the cool touch of the injector, loaded with powerful chemical lobotomizing agents, $he looks up at the camera above the autosurgery with a hint of <<if $traitorType != "defiant">>resigned apology<<else>>regret<</if>> in $his eyes. When $he is released from the surgery's care a few hours later, the hint is gone. @@.red;As is everything.@@ <<set $activeSlave.fetish = "mindbroken">> @@ -353,7 +356,7 @@ This is disturbing, to say the least. After close investigation, it appears some <</link>> <<if $arcologies[0].FSPaternalist == "unset" && $seeExtreme == 1>> <br><<link "Publicly execute $him">> - <<set $nextButton = "Continue", $returnTo = "Random Nonindividual Event">><<run App.Utils.updateUserButton()>> /* unlock Continue button */ + <<set $nextButton = "Continue">><<run App.Utils.updateUserButton()>> /* unlock Continue button */ <<replace "#result">> You announce that a treasonous slave will be publicly executed. Treason is understood in the Free Cities to be activity that tends to undermine slavery, and public interest is considerable when $activeSlave.slaveName is dragged out into a public atrium and <<if $arcologies[0].FSAztecRevivalist !== "unset">>has $his heart cut out of $his living body<<elseif $arcologies[0].FSEdoRevivalist !== "unset">>is boiled alive<<elseif $arcologies[0].FSRomanRevivalist !== "unset">>is crucified and left hanging until $he perishes<<else>>is summarily hanged<</if>>. The populace understands the necessity of the punishment, though they are @@.red;disturbed@@ that such a thing could happen in your penthouse of all places. The surviving slaves are @@.gold;terrified@@ at the display, but at least you can be sure they will remember the price of failing you. <<run repX(-500, "event", $activeSlave)>> diff --git a/src/events/nonRandom/mercs/pCitizensAndCivilians.tw b/src/events/nonRandom/mercs/pCitizensAndCivilians.tw index b5018beaeae..f2ee9db5c05 100644 --- a/src/events/nonRandom/mercs/pCitizensAndCivilians.tw +++ b/src/events/nonRandom/mercs/pCitizensAndCivilians.tw @@ -7,7 +7,7 @@ <</if>> <<setAssistantPronouns>> -<<set $nextButton = "Continue", $nextLink = "Random Nonindividual Event">> +<<set $nextButton = "Continue">> <<if $assistant.personality > 0>> While working at your desk, you are accompanied by the luscious sound of $assistant.name humming to _himselfA, which _heA does to indicate _heA's working on a difficult task. After this goes on for a while, diff --git a/src/events/nonRandom/mercs/pMercenaries.tw b/src/events/nonRandom/mercs/pMercenaries.tw index c00dcffc947..93733b26a4c 100644 --- a/src/events/nonRandom/mercs/pMercenaries.tw +++ b/src/events/nonRandom/mercs/pMercenaries.tw @@ -1,6 +1,6 @@ :: P mercenaries [nobr] -<<set $nextButton = "Continue", $nextLink = "Random Nonindividual Event", $mercenaries = 0, $mercenariesTitle = "mercenaries">> +<<set $nextButton = "Continue", $mercenaries = 0, $mercenariesTitle = "mercenaries">> <<if ($PC.skill.warfare >= 100)>> <<set _price = 2500>> diff --git a/src/events/nonRandom/mercs/pRaidInvitation.tw b/src/events/nonRandom/mercs/pRaidInvitation.tw index 4af7af86981..df14811aef9 100644 --- a/src/events/nonRandom/mercs/pRaidInvitation.tw +++ b/src/events/nonRandom/mercs/pRaidInvitation.tw @@ -1,6 +1,6 @@ :: P raid invitation [nobr] -<<set $nextButton = "Continue", $nextLink = "Random Nonindividual Event">> +<<set $nextButton = "Continue">> <<set $eventResults.raid = 0, $eventResults.raidTarget = 0>> diff --git a/src/events/nonRandom/mercs/pSnatchAndGrab.tw b/src/events/nonRandom/mercs/pSnatchAndGrab.tw index 4e9bb2b484f..df7f2b0f841 100644 --- a/src/events/nonRandom/mercs/pSnatchAndGrab.tw +++ b/src/events/nonRandom/mercs/pSnatchAndGrab.tw @@ -1,7 +1,6 @@ :: P snatch and grab [nobr] <<set $nextButton = "Continue">> -<<set $nextLink = "Random Nonindividual Event">> <<set $eventResults.snatch = 0>> <<setAssistantPronouns>> diff --git a/src/events/nonRandom/militia.js b/src/events/nonRandom/militia.js index c2334216904..a44f4ecb2c0 100644 --- a/src/events/nonRandom/militia.js +++ b/src/events/nonRandom/militia.js @@ -3,19 +3,11 @@ App.Events.PMilitia = class PMilitia extends App.Events.BaseEvent { super(actors, params); } - eventPrerequisites() { - return [ - () => App.Events.effectiveWeek() === 24, - () => V.plotEventWeek !== 24 - ]; - } - get eventName() { return "Militia"; } execute(node) { - V.plotEventWeek = 24; let r = []; const dronesTooCost = 5000; const selfAloneCost = 2000; @@ -41,37 +33,31 @@ App.Events.PMilitia = class PMilitia extends App.Events.BaseEvent { App.Events.addResponses(node, responses); function armDrones() { - const el = new DocumentFragment(); let r = []; r.push(`In a time of uncertainty, the public adores people who protect them. So, in addition to publicly procuring yourself the latest weapons and armor, you update the arcology's drone systems. The security drones' riot cannons can be replaced for easy maintenance, so it's rather easy to provide them with alternate, lethal weaponry that they can switch to if it becomes necessary. ${V.arcologies[0].name} becomes known as one of the best-protected in the Free Cities. <span class="green">Your reputation has greatly improved.</span>`); unlock(); repX(4000, "event"); cashX(-dronesTooCost, "event"); V.personalArms = 3; - App.Events.addParagraph(node, r); - return el; + return r; } function armOnlySelf() { - const el = new DocumentFragment(); let r = []; r.push(`In a time of uncertainty, the public looks up to people who project strength. So, you purchase yourself some of the latest armor and weapons, and make sure they are visible in a glass-walled cabinet in your office. Many of your wealthier tenants follow suit. A few of them even emulate your example and practice using these implements once a week. <span class="green">Your reputation has improved.</span>`); unlock(); repX(1500, "event"); cashX(-selfAloneCost, "event"); V.personalArms = 1; - App.Events.addParagraph(node, r); - return el; + return r; } function ignore() { - const el = new DocumentFragment(); let r = []; r.push(`No doubt this panicky fad will pass. You ignore the controversy. In a few days, the subject of a militia passes from the public mind.`); unlock(); V.personalArms = 0; - App.Events.addParagraph(node, r); - return el; + return r; } function unlock() { diff --git a/src/events/nonRandom/pDefenseFears.tw b/src/events/nonRandom/pDefenseFears.tw index b5cb4572216..c27a1edb710 100644 --- a/src/events/nonRandom/pDefenseFears.tw +++ b/src/events/nonRandom/pDefenseFears.tw @@ -1,6 +1,6 @@ :: P defense fears [nobr] -<<set $nextButton = " ", $nextLink = "Random Nonindividual Event">> /* hide button until user makes a selection */ +<<set $nextButton = " ">> /* hide button until user makes a selection */ <<set $fcnn.push("...hiring mercenaries to act as a defensive force against the old world...")>> A deputation of slaveowning citizens comes to see you. Though they haven't experienced anything so disturbing as your dealings with the Daughters of Liberty, rumors of unrest and revolution are running through the Free Cities. They are upset with the lack of troops to protect the arcology. This is quite a development in the young history of Free Cities society; only a few months ago, the idea of collective defense would have been a bitterly controversial one. It's still an employer's market for mercenaries; you could easily hire some. Alternatively, your citizens would probably agree to fund them by subscription — the word "taxes" would be impolitic. diff --git a/src/events/nonRandom/pInvasion.tw b/src/events/nonRandom/pInvasion.tw index c7bf19ce67a..d2d31484a55 100644 --- a/src/events/nonRandom/pInvasion.tw +++ b/src/events/nonRandom/pInvasion.tw @@ -1,6 +1,6 @@ :: P invasion [nobr] -<<set $nextButton = "Continue", $nextLink = "Random Nonindividual Event">> +<<set $nextButton = "Continue">> <<set $invasionVictory = 1, $peacekeepers = 0>> <<setAssistantPronouns>> diff --git a/src/events/nonRandom/shootInvitation.js b/src/events/nonRandom/shootInvitation.js index df329419379..0fea7a533a6 100644 --- a/src/events/nonRandom/shootInvitation.js +++ b/src/events/nonRandom/shootInvitation.js @@ -3,19 +3,11 @@ App.Events.PShootInvitation = class PShootInvitation extends App.Events.BaseEven super(actors, params); } - eventPrerequisites() { - return [ - () => App.Events.effectiveWeek() === 17, - () => V.plotEventWeek !== 17 - ]; - } - get eventName() { return "Shoot Invitation"; } execute(node) { - V.plotEventWeek = 17; let r = []; r.push(`${capFirstChar(V.assistant.name)} usually delays message delivery when you're relieving your sexual needs with your property, but messages from other arcology owners have a special priority. This one is a brief but rather well-spoken audio invitation from one of your more notoriously wealthy peers.`); App.Events.addParagraph(node, r); diff --git a/src/events/nonRandom/slaveFood.js b/src/events/nonRandom/slaveFood.js index e31fa22eb01..5ec7dd08f41 100644 --- a/src/events/nonRandom/slaveFood.js +++ b/src/events/nonRandom/slaveFood.js @@ -3,19 +3,11 @@ App.Events.PSlaveFood = class PSlaveFood extends App.Events.BaseEvent { super(actors, params); } - eventPrerequisites() { - return [ - () => App.Events.effectiveWeek() === 20, - () => V.plotEventWeek !== 20 - ]; - } - get eventName() { return "Slave Food"; } execute(node) { - V.plotEventWeek = 20; let r = []; const { HeA, HisA, diff --git a/src/events/nonRandom/stripClubAftermath.js b/src/events/nonRandom/stripClubAftermath.js index f7c6d904cf5..6e4e8db6727 100644 --- a/src/events/nonRandom/stripClubAftermath.js +++ b/src/events/nonRandom/stripClubAftermath.js @@ -3,19 +3,11 @@ App.Events.PStripClubAftermath = class PStripClubAftermath extends App.Events.Ba super(actors, params); } - eventPrerequisites() { - return [ - () => App.Events.effectiveWeek() === 8, - () => V.plotEventWeek !== 8 - ]; - } - get eventName() { return "Strip Club Aftermath"; } execute(node) { - V.plotEventWeek = 8; let r = []; let contractCost = 1000; let cost; diff --git a/src/events/nonRandom/stripClubClosing.js b/src/events/nonRandom/stripClubClosing.js index 88ae831bd67..59171e5b467 100644 --- a/src/events/nonRandom/stripClubClosing.js +++ b/src/events/nonRandom/stripClubClosing.js @@ -3,19 +3,11 @@ App.Events.PStripClubClosing = class PStripClubClosing extends App.Events.BaseEv super(actors, params); } - eventPrerequisites() { - return [ - () => App.Events.effectiveWeek() === 6, - () => V.plotEventWeek !== 6 - ]; - } - get eventName() { return "Strip Club Closing"; } execute(node) { - V.plotEventWeek = 6; let r = []; V.eventResults.strip = 1; r.push(`It's been a good few weeks, getting settled in as owner of ${V.arcologies[0].name}. The power of being overlord of this great building and everyone in it is incredible, but so is the responsibility. It's a good thing you have ample opportunities for stress relief. You're going to need them after today. There's a nasty disturbance on a business level of the arcology. Normally, the arcology's public safety drones would suppress this kind of nonsense, but ${V.assistant.name} program is suggesting that you resolve the dispute.`); diff --git a/src/events/nonRandomEvent.js b/src/events/nonRandomEvent.js index 49157292c9e..be4b3d37cc3 100644 --- a/src/events/nonRandomEvent.js +++ b/src/events/nonRandomEvent.js @@ -45,6 +45,7 @@ App.Events.getNonrandomEvents = function() { new App.Events.SEDeath(), new App.Events.SEBirth(), new App.Events.SEfctv(), + new App.Events.TimeGatedPlotEvent(), new App.Events.assistantAwakens(), new App.Events.assistantSP(), new App.Events.assistantFS(), @@ -55,13 +56,7 @@ App.Events.getNonrandomEvents = function() { new App.Events.pBadBreasts(), new App.Events.pAidInvitation(), new App.Events.pAidResult(), - new App.Events.PStripClubClosing(), - new App.Events.PStripClubAftermath(), - new App.Events.PMilitia(), - new App.Events.PShootInvitation(), new App.Events.PShootResult(), - new App.Events.PArcologyNaming(), - new App.Events.PSlaveFood(), new App.Events.TwineEvent().wrapPassage([ () => V.RecruiterID !== 0, () => V.recruiterProgress >= (13 + (V.recruiterEugenics === 1 ? policies.countEugenicsSMRs() * 6 : 0)) @@ -237,13 +232,7 @@ globalThis.nonRandomEvent = function() { V.assholeKnight = 1; V.imperialEventWeek = effectiveWeek; setTimeout(() => Engine.play("SE assholeknight"), Engine.minDomActionDelay); - } else if (effectiveWeek === 31 && V.mercenaries === 0) { - setTimeout(() => Engine.play("P mercenaries"), Engine.minDomActionDelay); - } else if (effectiveWeek === 35 && V.mercenaries > 0) { - setTimeout(() => Engine.play("P snatch and grab"), Engine.minDomActionDelay); - } else if (effectiveWeek === 43) { - setTimeout(() => Engine.play("P invasion"), Engine.minDomActionDelay); - } else if ((effectiveWeek === 44) && (V.mercenaries > 0) && V.mercRomeo !== 1) { + } else if ((effectiveWeek >= 44) && (V.mercenaries > 0) && V.mercRomeo !== 1) { const valid = V.slaves.find(function(s) { return (["serve the public", "serve in the club", "whore", "work in the brothel"].includes(s.assignment) || s.counter.publicUse >= 50) && s.fetish !== "mindbroken" && s.fuckdoll === 0; }); V.mercRomeo = 1; if (valid) { @@ -251,8 +240,6 @@ globalThis.nonRandomEvent = function() { } else { setTimeout(() => Engine.play("Nonrandom Event"), Engine.minDomActionDelay); } - } else if (effectiveWeek === 46 && V.mercenaries > 0) { - setTimeout(() => Engine.play("P raid invitation"), Engine.minDomActionDelay); } else if (effectiveWeek === 48 && V.experimental.food === 1) { V.foodCrisis = 1; setTimeout(() => Engine.play("P food crisis"), Engine.minDomActionDelay); @@ -261,39 +248,9 @@ globalThis.nonRandomEvent = function() { setTimeout(() => Engine.play("P food crisis"), Engine.minDomActionDelay); } else if (effectiveWeek === 54 && (V.peacekeepers) && V.peacekeepers.attitude >= 0) { setTimeout(() => Engine.play("P peacekeepers deficit"), Engine.minDomActionDelay); - } else if (effectiveWeek === 56) { - V.collaboration = 0; - V.traitor = 0; - V.hackerSupport = 0; - setTimeout(() => Engine.play("P underground railroad"), Engine.minDomActionDelay); - } else if (effectiveWeek === 58 && V.traitor === 0) { - setTimeout(() => Engine.play("P bombing"), Engine.minDomActionDelay); } else if (effectiveWeek === 60 && V.rations > 0) { V.foodCrisis = 3; setTimeout(() => Engine.play("P food crisis"), Engine.minDomActionDelay); - } else if (effectiveWeek === 61 && V.traitor !== 0) { - setTimeout(() => Engine.play("P traitor message"), Engine.minDomActionDelay); - } else if (effectiveWeek === 62 && V.mercenaries < 3) { - setTimeout(() => Engine.play("P defense fears"), Engine.minDomActionDelay); - } else if (effectiveWeek === 65 && V.mercenaries >= 3) { - setTimeout(() => Engine.play("P citizens and civilians"), Engine.minDomActionDelay); - } else if (effectiveWeek === 67 && V.traitor !== 0) { - setTimeout(() => Engine.play("P collaboration choice"), Engine.minDomActionDelay); - } else if (effectiveWeek === 69) { - setTimeout(() => Engine.play("P hacker support"), Engine.minDomActionDelay); - } else if (effectiveWeek === 70 && V.collaboration === 1 && V.traitorType !== "trapper") { - setTimeout(() => Engine.play("P coup collaboration"), Engine.minDomActionDelay); - } else if (effectiveWeek === 71) { - const doubleAgent = (V.traitorType !== "agent" && V.traitorType !== "trapper") ? 0 : 1; - if (V.traitorType === "trapper") { - setTimeout(() => Engine.play("P coup betrayal"), Engine.minDomActionDelay); - } else if (V.mercenaries + V.personalArms + V.hackerSupport + doubleAgent < 5) { - setTimeout(() => Engine.play("P coup loss"), Engine.minDomActionDelay); - } else { - setTimeout(() => Engine.play("P coup attempt"), Engine.minDomActionDelay); - } - } else if (effectiveWeek === 72) { - setTimeout(() => Engine.play("P coup aftermath"), Engine.minDomActionDelay); } else if (V.SF.Toggle && V.SF.Active === -1 && effectiveWeek >= 72) { setTimeout(() => Engine.play("Security Force Proposal"), Engine.minDomActionDelay); } else if (V.arcologies[0].FSRestart !== "unset" && V.failedElite > 300 && V.eugenicsFullControl !== 1) { diff --git a/src/events/timeGatedPlotEvent.js b/src/events/timeGatedPlotEvent.js new file mode 100644 index 00000000000..86100e04520 --- /dev/null +++ b/src/events/timeGatedPlotEvent.js @@ -0,0 +1,92 @@ +/** This event serves as a controller for the "main" plot event chain, which is designed to advance the plot based ONLY on the current (effective) week. + * These events don't have to keep their own gating code or results variables, because this chain controller tracks when they should be executed. */ +App.Events.TimeGatedPlotEvent = class TimeGatedPlotEvent extends App.Events.BaseEvent { + constructor(actors, params) { + super(actors, params); + + // sparse array, indexed by effective week + // maybe mercs should be a separate chain? Oh well, they're here for now. + this.events = []; + this.events[4] = new App.Events.PArcologyNaming(); + this.events[6] = new App.Events.PStripClubClosing(); + this.events[8] = new App.Events.PStripClubAftermath(); + this.events[17] = new App.Events.PShootInvitation(); + this.events[20] = new App.Events.PSlaveFood(); + this.events[24] = new App.Events.PMilitia(); + this.events[31] = new App.Events.TwineEvent().wrapPassage([ + () => V.mercenaries === 0 + ], "P mercenaries"); + this.events[35] = new App.Events.TwineEvent().wrapPassage([ + () => V.mercenaries > 0 + ], "P snatch and grab"); + this.events[43] = new App.Events.TwineEvent().wrapPassage([], "P invasion"); + this.events[46] = new App.Events.TwineEvent().wrapPassage([ + () => V.mercenaries > 0 + ], "P raid invitation"); + this.events[54] = new App.Events.TwineEvent().wrapPassage([], "P underground railroad"); + this.events[58] = new App.Events.TwineEvent().wrapPassage([ + () => V.traitor === 0 + ], "P bombing"); + this.events[61] = new App.Events.TwineEvent().wrapPassage([ + () => V.traitor !== 0 + ], "P traitor message"); + this.events[62] = new App.Events.TwineEvent().wrapPassage([ + () => V.mercenaries < 3 + ], "P defense fears"); + this.events[65] = new App.Events.TwineEvent().wrapPassage([ + () => V.mercenaries >= 3 + ], "P citizens and civilians"); + this.events[67] = new App.Events.TwineEvent().wrapPassage([ + () => V.traitor !== 0 + ], "P collaboration choice"); + this.events[69] = new App.Events.TwineEvent().wrapPassage([], "P hacker support"); + this.events[70] = new App.Events.TwineEvent().wrapPassage([ + () => V.collaboration === 1, + () => V.traitorType !== "trapper" + ], "P coup collaboration"); + // week 71 plot event is one of three possibilities, depending on game state + const doubleAgent = (V.traitorType !== "agent" && V.traitorType !== "trapper") ? 0 : 1; + if (V.traitorType === "trapper") { + this.events[71] = new App.Events.TwineEvent().wrapPassage([], "P coup betrayal"); + } else if (V.mercenaries + V.personalArms + V.hackerSupport + doubleAgent < 5) { + this.events[71] = new App.Events.TwineEvent().wrapPassage([], "P coup loss"); + } else { + this.events[71] = new App.Events.TwineEvent().wrapPassage([], "P coup attempt"); + } + this.events[72] = new App.Events.TwineEvent().wrapPassage([], "P coup aftermath"); + + // events with complex prerequisites don't belong here...they're just normal scheduled events and need their own chain controller or result flags + for (let week = 0; week < this.events.length; ++week) { + const event = this.events[week]; + if (event.actorPrerequisites().length > 0) { + throw new Error(`Time-gated plot events are not permitted to cast actors. Check event: ${event.eventName}`); + } + if (V.debugMode !== 0 && event.eventPrerequisites().length > 0) { + // sometimes this is intentional, but it could also be a mistake...unlike ordinary nonrandom events, events in the plot chain only get ONE chance to execute, so you have to be very careful with prereqs + console.log(`Time-gated plot event ${event.eventName} imposes prerequisites and WILL BE SKIPPED ENTIRELY if the prerequisites are not met on week ${week}!`); + } + } + } + + eventPrerequisites() { + if (V.plot === 1) { + const effectiveWeek = App.Events.effectiveWeek(); + // choose the earliest event that we need to run, within the window between the last event we ran and the current week, and run it + // this means that effectiveWeek can jump ahead and we still won't skip any events...we'll just run whatever was missed until we catch up + // but we also won't ever repeat any events, or play any new ones that should have occurred before the last event we played + for (let week = V.plotEventWeek + 1; week <= effectiveWeek; ++week) { + if (this.events[week]) { + this.params.event = this.events[week]; + this.params.week = week; + break; + } + } + } + return [() => !!this.params.event]; + } + + execute(node) { + V.plotEventWeek = this.params.eventWeek; + this.params.event.execute(node); + } +}; diff --git a/src/uncategorized/seNicaeaAnnouncement.tw b/src/uncategorized/seNicaeaAnnouncement.tw index 4a4199989bf..530a0a29f42 100644 --- a/src/uncategorized/seNicaeaAnnouncement.tw +++ b/src/uncategorized/seNicaeaAnnouncement.tw @@ -1,6 +1,5 @@ :: SE nicaea announcement [nobr] -<<if $plot == 1>><<set $nextLink = "Nonrandom Event">><<else>><<set $nextLink = "Random Nonindividual Event">><</if>> <<set $nextButton = "Continue">> <<set $nicaea.announced = 1, $nicaea.preparation = 1, $nicaea.involvement = 0, $nicaea.power = 1, $nicaea.eventWeek = $week>> <<set $nicaea.name = "Council of " + App.Data.ArcologyNames.ChattelReligionist.random()>> diff --git a/src/uncategorized/seNicaeaPreperation.tw b/src/uncategorized/seNicaeaPreperation.tw index aff6a5af9b0..4f726f4b279 100644 --- a/src/uncategorized/seNicaeaPreperation.tw +++ b/src/uncategorized/seNicaeaPreperation.tw @@ -1,6 +1,5 @@ :: SE nicaea preparation [nobr] -<<if $plot == 1>><<set $nextLink = "Nonrandom Event">><<else>><<set $nextLink = "Random Nonindividual Event">><</if>> <<set $nextButton = "Continue">> <<set $nicaea.preparation = 0, $nicaea.eventWeek = $week>> -- GitLab