From adeb6461c25621798c7a481e56de44da7d059ca1 Mon Sep 17 00:00:00 2001 From: Blank_Alt <12406-Blank_Alt@users.noreply.gitgud.io> Date: Sat, 3 Jul 2021 10:51:01 +0000 Subject: [PATCH] SecExp-Fixes/Cleanup --- .../SecExp/buildings/riotControlCenter.tw | 1 + src/Mods/SecExp/edicts.tw | 1 + src/Mods/SecExp/events/attackReport.js | 232 ++++++++---------- src/Mods/SecExp/events/rebellionReport.js | 2 +- src/endWeek/economics/neighborsDevelopment.js | 8 +- src/endWeek/economics/persBusiness.js | 8 +- src/events/RE/reArcologyInspection.js | 2 +- src/events/scheduled/sePCBirthday.js | 8 +- src/gui/storyCaption.js | 2 +- 9 files changed, 122 insertions(+), 142 deletions(-) diff --git a/src/Mods/SecExp/buildings/riotControlCenter.tw b/src/Mods/SecExp/buildings/riotControlCenter.tw index 6ab03a6c31d..5f875d557e0 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/edicts.tw b/src/Mods/SecExp/edicts.tw index 810c785926a..41fcdf1a6da 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/attackReport.js b/src/Mods/SecExp/events/attackReport.js index ef06c5fb6fa..659aa823efe 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,93 +986,54 @@ App.Events.attackReport = function() { function unitsBattleReport() { const el = document.createElement("div"); - if (V.SecExp.war.losses === 0) { - 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, type) { - for (const unit of units) { - if (App.SecExp.unit.isDeployed(unit)) { - const r = [`${type !== 'bots' ? `${unit.platoonName}` : `Security Drones`} : no casualties.`]; - if (type !== "bots") { - 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"); - } - } - }; - for (const unitClass of App.SecExp.unit.list()) { - if (App.SecExp.battle.deployedUnits(unitClass) >= 1) { - if (unitClass !== 'bots') { - noCasualties(V.SecExp.units[unitClass].squads, unitClass); + 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 { - noCasualties([V.SecExp.units.bots], unitClass); + losses -= assignedLosses; } + lossesList.push(assignedLosses); } - } - } 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; + if (losses > 0) { + lossesList[random(lossesList.length - 1)] += losses; } - lossesList.push(assignedLosses); - } - if (losses > 0) { - lossesList[random(lossesList.length - 1)] += losses; - } - lossesList.shuffle(); + 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; + // 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]; + } + 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); } - 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); } - // assigns the losses and notify the player 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"); + App.UI.DOM.appendNewElement("div", el, `${num(V.SF.ArmySize)} soldiers from ${V.SF.Lower} joined the battle: casualtiesReport(type, loss)`); + } for (const unitClass of App.SecExp.unit.list()) { if (App.SecExp.battle.deployedUnits(unitClass) >= 1) { @@ -1018,62 +1042,12 @@ App.Events.attackReport = function() { } 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, type) { - for (const unit of units) { - if (App.SecExp.unit.isDeployed(unit)) { - let loss = lossesList.pluck(); - loss = Math.clamp(loss, 0, unit.troops); - if (type !== "bots") { - unit.battlesFought++; - } else { - unit.troops -= loss; - } - const r = [`${type !== "bots" ? `${unit.platoonName}` : `Security drones`}:`]; - 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.`); - if (type !== "bots") { - 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 && 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; - if (type !== "bots") { - 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 { - 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. It will take quite the investment to rebuild them.`); - } - } 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/rebellionReport.js b/src/Mods/SecExp/events/rebellionReport.js index 14e108cc7c0..663cea8f7f5 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/endWeek/economics/neighborsDevelopment.js b/src/endWeek/economics/neighborsDevelopment.js index ccbc6650db4..e7c56e72c9d 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 7adcd0e5f95..cd8e407a987 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/events/RE/reArcologyInspection.js b/src/events/RE/reArcologyInspection.js index 1f87c964457..66907be72d6 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/scheduled/sePCBirthday.js b/src/events/scheduled/sePCBirthday.js index 4e4231efde9..5af0807e12d 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/gui/storyCaption.js b/src/gui/storyCaption.js index a2ff2f9a9a8..0b39cf7d009 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)); -- GitLab