diff --git a/devNotes/jsEventCreationGuide.md b/devNotes/jsEventCreationGuide.md index 1f5b9da3a6a2ea8b1d0730b5e62b42e4f6f143a1..a9bb5483d32fc85bb6846d5bf730dc574f3c512c 100644 --- a/devNotes/jsEventCreationGuide.md +++ b/devNotes/jsEventCreationGuide.md @@ -1,5 +1,7 @@ # Creating your event +It would be useful to have the [JS functions Documentation](devNotes/usefulJSFunctionDocumentation.txt) open and in particular the "Core Slave Functions" section. + First decide your events name e.g. MyEvent ``` App.Events.MyEvent = class MyEvent extends App.Events.BaseEvent { @@ -9,7 +11,7 @@ App.Events.MyEvent = class MyEvent extends App.Events.BaseEvent { return [ () => V.plot === 1 ]; - + // empty example return []; } @@ -25,7 +27,7 @@ App.Events.MyEvent = class MyEvent extends App.Events.BaseEvent { s => s.trust <= 20 ] ]; - + // Dual slave return [ [ // here's the first actor, just like above @@ -41,7 +43,7 @@ App.Events.MyEvent = class MyEvent extends App.Events.BaseEvent { // Wants one actor, but "any slave will do" return [[]]; - + // Empty (no actors at all) return []; } @@ -55,7 +57,7 @@ App.Events.MyEvent = class MyEvent extends App.Events.BaseEvent { const { HeU, heU, hisU, himU, himselfU } = getNonlocalPronouns(V.seeDicks).appendSuffix('U'); - + // V.nextButton is shown to the user on the side bar, e.g. V.nextButton = "Continue"; // V.nextLink is the next passge that will be executed, e.g. V.nextLink = "Economics"; @@ -63,9 +65,9 @@ App.Events.MyEvent = class MyEvent extends App.Events.BaseEvent { App.Events.drawEventArt(node, eventSlave, "no clothing"); let t = []; - + t.push(`Event info text goes here`) - + App.Events.addParagraph(node, t); // Event branches @@ -89,11 +91,18 @@ App.Events.MyEvent = class MyEvent extends App.Events.BaseEvent { } }; ``` +# Dealling with lisping + +`Enunciate($activeSlave)/getWrittenTitle($activeSlave)/<<say>>s/that'<<s>>/<<Master>>` +Can be converted to +`const {say, title: Master} = getEnunciation(eventSlave);` +Master can just be template literalled into spoken() and it'll convert it itself. + # Adding your event to the pool Now that your event has been created it needs to be added to the pool of possible events for it's type which for most - events, as well as for our example, is random individual event. -This pool can be found at src/events/randomEvent.js. + events, as well as for our example, is random individual event. +This pool can be found at src/events/randomEvent.js. Simply add your event to the array in App.Events.getIndividualEvents. # Testing @@ -103,7 +112,7 @@ Then go to the Debug & cheating tab and enable CheatMode. Once you get to "Random Individual Event" select any slave and at the bottom under DEBUG: there should be a input box with "Check Prerequisites and Casting" link next to it. Per the example under it, place your event's full name into it e.g. App.Events.myEvent and then hit said link. -If everything works as intended you should see output +If everything works as intended you should see output ## Examples diff --git a/devNotes/usefulJSFunctionDocumentation.txt b/devNotes/usefulJSFunctionDocumentation.txt index 0108b253a8c74b72104c2048239bafb36f69aab1..9e00375521730b94605af2ee9c2e5bfced42d092 100644 --- a/devNotes/usefulJSFunctionDocumentation.txt +++ b/devNotes/usefulJSFunctionDocumentation.txt @@ -160,6 +160,12 @@ properTitle() - Returns the player's proper title. (customTitle, Sir, Ma'am) properMaster() - Returns the slave's title for Master when WrittenMaster() is inappropriate. (customTitle, Master, Mistress) +WrittenMaster(slave) - Returns a slave's title for the player and sets lisping. Returns $activeSlave if not given an argument. + +Enunciate(slave) - Syncs lisp widgets with slave. + +Spoken(slave, speech) - Returns speech with lisp if slave lisps. Replaces `<<say>>s` with Spoken(slave, "says"). + SlaveFullName(slave) - Returns the slave's full name. PlayerName() - Returns the player's full name. @@ -248,9 +254,7 @@ getSlave(ID) - Returns the slave object with the matching ID. getPronouns(slave) - Returns an object containing a slave's pronouns. -WrittenMaster(slave) - Returns a slave's title for the player and sets lisping. Returns $activeSlave if not given an argument. - -Enunciate(slave) - Syncs lisp widgets with slave. +generatePronouns(slave) - Sets slave's pronouns. fetishChangeChance(slave) - Returns an int between 0,100 as the chance of a slave's fetish shifting to a new one. @@ -272,8 +276,6 @@ removeActiveSlave() - Removes $activeSlave from $slaves. Do not use without care SetBellySize(slave) - Sets slave's belly size.(pregnancy+inflation+implant) -generatePronouns(slave) - Sets slave's pronouns. - SoftenBehavioralFlaw(slave) - Replaces the slave's behavioral flaw with the corresponding quirk. SoftenSexualFlaw(slave) - Replaces the slave's sexual flaw with the corresponding quirk. diff --git a/devTools/types/FC/SecExp.d.ts b/devTools/types/FC/SecExp.d.ts index f49f3d622968e7e2df6d93c9d05adfd2da93962b..1aae726cbe26de6d4b0f56ce125fa068276950ed 100644 --- a/devTools/types/FC/SecExp.d.ts +++ b/devTools/types/FC/SecExp.d.ts @@ -20,10 +20,11 @@ declare namespace FC { cyber: number, medics: number, SF: number, - commissars: number + commissars: number, + battlesFought: number, } - type PlayerHumanUnitType = "bots" | "citizens" | "mercenary" | "slave" | "SF"; + type PlayerHumanUnitType = "bots" | "slaves" | "militia" | "mercs" | "SF"; type EnemyUnitType = "raiders" | "free city" | "old world" | "freedom fighters"; } } diff --git a/src/Mods/SecExp/js/Unit.js b/src/Mods/SecExp/js/Unit.js index 3c2eac9a7659955da1d2790fd7be6bbef1db5ec4..dcc0198149dd7d94e8e24418ea77dccb309eeae5 100644 --- a/src/Mods/SecExp/js/Unit.js +++ b/src/Mods/SecExp/js/Unit.js @@ -10,36 +10,9 @@ App.SecExp.unit = (function() { humanSquads, genID, replenish + // unitFree - helper function }; - function base(string, operation = 'print', value = 0) { - let target, x = string.toLowerCase(); - - if (x === "slaves") { - target = V.menials; - } else if (x === "militia") { - target = V.SecExp.units.militia.free; - } else if (x === "mercs") { - target = V.SecExp.units.mercs.free; - } - - if (operation === 'print') { - return target; - } else if (operation === 'add') { - return target += value; - } else if (operation === 'remove') { - return target -= value; - } else if (operation === 'set') { - return target = value; - } else if (operation === 'can upgrade') { - if (string === 'bots') { - return V.cash >= 500; - } else { - return target > 0; - } - } - } - /** Lists all potential military units as an array. * */ @@ -56,15 +29,12 @@ App.SecExp.unit = (function() { let el = document.createElement("a"); function upgradeUnit(x) { + x.equip = 3; Object.assign(x, { - maxTroops: 50, equip: 3, commissars: 2, + maxTroops: 50, commissars: 2, cyber: 1, medics: 1 }); - if (V.SF.Active >= 1) { - x.SF = 1; - } else { - x.SF = 0; - } + x.SF = (V.SF.Toggle && V.SF.Active >= 1 ? 1 : 0); } function getCost(x) { @@ -73,9 +43,7 @@ App.SecExp.unit = (function() { if (x.maxTroops < 50) { cost -= 5000 + (((50 - x.maxTroops) /10) * equipUpgradeCost * (x.equip + x.commissars + x.cyber + x.SF)); } - if (x.equip < 3) { - cost -= (equipUpgradeCost * x.maxTroops + 1000) * (3 - x.equip); - } + if (x.commissars < 2) { cost -= (equipUpgradeCost * x.maxTroops + 1000) * (2 - x.commissars); } @@ -88,6 +56,9 @@ App.SecExp.unit = (function() { if (V.SF.Toggle && V.SF.Active >= 1 && x.SF === 0) { cost -= equipUpgradeCost * x.maxTroops + 5000; } + if (x.equip < 3) { + cost -= (equipUpgradeCost * x.maxTroops + 1000) * (3 - x.equip); + } return Math.ceil(cost * 1.1); } @@ -133,12 +104,13 @@ App.SecExp.unit = (function() { ID: -1, equip: 0, active: 1, isDeployed: 0, maxTroops: 30, troops: 30 }; if (type !== "bots") { + V.SecExp.units[type].created++; Object.assign(newUnit, { training: 0, cyber: 0, medics: 0, SF: 0, commissars: 0, battlesFought: 0, loyalty: jsRandom(40, 60), ID: genID(), - platoonName: `${ordinalSuffix(++V.SecExp.units[type].created)} ` + V.SecExp.units[type].defaultName + platoonName: `${ordinalSuffix(V.SecExp.units[type].created)} ${V.SecExp.units[type].defaultName}` }); if (type === "slaves") { @@ -152,6 +124,10 @@ App.SecExp.unit = (function() { return newUnit; } + /** Prints a list of upgrades that can be applied to the passed human unit. + * @param {FC.SecExp.PlayerHumanUnitData} input the human unit to be checked. + * @returns {HTMLDivElement} + */ function humanUpgradeList(input) { const equipUpgradeCost = 250; let el = document.createElement("div"), options = document.createElement("div"); @@ -266,7 +242,7 @@ App.SecExp.unit = (function() { for (const unit of list().slice(1)) { for (const squad of V.SecExp.units[unit].squads) { - if (!woundedUnit.contains(unit) && squad.troops < squad.maxTroops && base(unit, 'can upgrade')) { + if (!woundedUnit.contains(unit) && squad.troops < squad.maxTroops && unitFree(unit, 'can upgrade')) { woundedUnit.push(unit); } } @@ -274,14 +250,11 @@ App.SecExp.unit = (function() { if (woundedUnit.length > 0) { el.append(App.UI.DOM.link("Replenish all units", () => { - for (const unit of woundedUnit) { - if (unit === 'bots') { - cashX(-((V.SecExp.units.bots.maxTroops - V.SecExp.units.bots.troops) * 500), "securityExpansion"); - V.SecExp.units.bots.troops = V.SecExp.units.bots.maxTroops; + for (const u of woundedUnit) { + if (u === 'bots') { + replenish(V.SecExp.units.bots, u); } else { - for (const squad of V.SecExp.units[unit].squads) { - replenish(squad, unit); - } + V.SecExp.units[u].squads.forEach(s => replenish(s, u)); } } App.UI.reload(); @@ -298,7 +271,10 @@ App.SecExp.unit = (function() { } /** - * @param {FC.SecExp.PlayerUnitData} input + * @param {FC.SecExp.PlayerHumanUnitData} input + * @param {FC.SecExp.PlayerHumanUnitType} unitType + * @param {boolean} inBattle - if true appends a deply/recall link to the description, allowing for [input] to be deployed/recalled. + * @returns {HTMLDivElement} */ function describe(input, unitType, inBattle = false) { const brief = V.SecExp.settings.unitDescriptions; @@ -475,9 +451,6 @@ App.SecExp.unit = (function() { return el; } - /** Prints a list of upgrades that can be applied to the passed human unit. - * @param {FC.SecExp.PlayerHumanUnitData} input the human unit to be checked. - */ function humanSquads() { let array = []; for (const unit of list().slice(1)) { @@ -497,32 +470,70 @@ App.SecExp.unit = (function() { ) + 1; } + /** Replenishes a unit if needed + * @param {FC.SecExp.PlayerHumanUnitData} squad. + * @param {FC.SecExp.PlayerHumanUnitType} type + */ function replenish(squad, type) { const oldTroops = squad.troops; - if (base(type) >= squad.maxTroops - squad.troops) { - if (type === "slaves") { - V.menials -= (squad.maxTroops - squad.troops); - } else if (type === "militia") { - V.SecExp.units.militia.free -= (squad.maxTroops - squad.troops); - } else if (type === "mercs") { - V.SecExp.units.mercs.free -= (squad.maxTroops - squad.troops); + if (type !== "bots") { + if (unitFree(type) >= squad.maxTroops - squad.troops) { + unitFree(type, 'remove', (squad.maxTroops - squad.troops)); + squad.troops = squad.maxTroops; + } else { + squad.troops += unitFree(type); + unitFree(type, 'set'); } - squad.troops = squad.maxTroops; + const expLoss = (squad.troops - oldTroops) / squad.troops; + squad.training -= squad.training * expLoss; } else { - if (type === "slaves") { - squad.troops += V.menials; - V.menials = 0; - } else if (type === "militia") { - squad.troops += V.SecExp.units.militia.free; - V.SecExp.units.militia.free = 0; - } else if (type === "mercs") { - squad.troops += V.SecExp.units.mercs.free; - V.SecExp.units.mercs.free = 0; - } + cashX(-((squad.maxTroops - squad.troops) * 500), "securityExpansion"); + squad.troops = squad.maxTroops; + } + } + + /** performs operations on a unit + * helper function, not callable externally + * @param {FC.SecExp.PlayerHumanUnitType} type + * @param {string} [operation] action to perform + * @param {number} [value] amount to add/substract + */ + function unitFree(type, operation = 'print', value = 0) { + switch(type) { + case "bots": + if (operation === "can upgrade") { + return V.cash >= 500; + } + break; + case "slaves": + if (operation === 'add') { + V.menials += value; + } else if (operation === 'remove') { + V.menials -= value; + } else if (operation === 'set') { + V.menials = value; + } else if (operation === 'can upgrade') { + return V.menials > 0; + } else { + return V.menials; + } + break; + case "militia": + case "mercs": + if (operation === 'add') { + V.SecExp.units[type].free += value; + } else if (operation === 'remove') { + V.SecExp.units[type].free -= value; + } else if (operation === 'set') { + V.SecExp.units[type].free = value; + } else if (operation === 'can upgrade') { + return V.SecExp.units[type].free > 0; + } else { + return V.SecExp.units[type].free; + } + break; } - const expLoss = (squad.troops - oldTroops) / squad.troops; - squad.training -= squad.training * expLoss; } })();