diff --git a/src/004-base/basePitFight.js b/src/004-base/basePitFight.js index 168863b3b8ed4fa3c8cc8f0a252b9183439bc84a..169cd9c6cd0e0be3d5d10a4485df7f54f67f875c 100644 --- a/src/004-base/basePitFight.js +++ b/src/004-base/basePitFight.js @@ -48,6 +48,14 @@ App.Facilities.Pit.Fights.BaseFight = class BaseFight { return 1; } + /** + * If the fight can be queued from the pit screen + * @returns {boolean} + */ + get selectable() { + return true; + } + /** * @typedef {object} fightOption * @property {string} name @@ -155,10 +163,6 @@ App.Facilities.Pit.Fights.TestFight = class extends App.Facilities.Pit.Fights.Ba return "test"; } - fightPrerequisites() { - return []; - } - actorPrerequisites() { return [ [], // actor one, no requirements diff --git a/src/events/scheduled/pitFight.js b/src/events/scheduled/pitFight.js index 29da1c29796a46eb16980424eb107b921e38ec06..afaae1b37134366abfbc7f531152fd79a2b6dbc4 100644 --- a/src/events/scheduled/pitFight.js +++ b/src/events/scheduled/pitFight.js @@ -38,8 +38,11 @@ App.Events.SEPitFight = class SEPitFight extends App.Events.BaseEvent { for (let i = 0; i < fights.length; i++) { if (fights[i].fightPrerequisites().every(p => p()) && fights[i].castActors()) { App.UI.DOM.appendNewElement("span", node, `The ${ordinalSuffixWords(i + 1)} fight this day: ` + fights[i].uiDescription + ": ", "bold"); - const impact = fights[i].execute(node) * fights[i].impact; - node.append(eventImpact(impact)); + const success = fights[i].execute(node); + const impact = success * fights[i].impact; + const p = document.createElement("p"); + p.append(fightSuccess(success), " ", eventImpact(impact)); + node.append(p); totalSuccess += impact; } else if (V.cheatMode || V.debugMode) { node.append("Unable to run fight: ", fights[i].key); @@ -55,31 +58,54 @@ App.Events.SEPitFight = class SEPitFight extends App.Events.BaseEvent { cashX(4000 * totalSuccess, "pit"); } + /** + * @param {number} success + * @returns {DocumentFragment} + */ + function fightSuccess(success) { + const f = new DocumentFragment(); + + if (success < 0) { + f.append("The fight was an embarrassment."); + } else if (success === 0) { + f.append("The fight had no success."); + } else if (success < 0.2) { + f.append("The fight had little success."); + } else if (success < 0.8) { + f.append("The fight had normal success."); + } else if (success <= 1) { + f.append("The fight had good success."); + } else { + f.append("The fight had unexpectedly high success."); + } + + return f; + } + /** * @param {number} impact - * @returns {HTMLParagraphElement} + * @returns {DocumentFragment} */ function eventImpact(impact) { - const p = document.createElement("p"); + const f = new DocumentFragment(); impact = Math.abs(impact); if (impact === 0) { - p.append("The fight had no impact on the total event."); + f.append("The fight had no impact on the total event."); } else if (impact < 0.2) { - p.append("The fight had little impact on the total event."); + f.append("The fight had little impact on the total event."); } else if (impact < 0.8) { - p.append("The fight had normal impact on the total event."); - } else if (impact < 1.2) { - p.append("The fight had high impact on the total event."); - } else if (impact < 5) { - p.append("The fight had extreme impact on the total event."); + f.append("The fight had normal impact on the total event."); + } else if (impact < 2) { + f.append("The fight had high impact on the total event."); + } else { + f.append("The fight had extreme impact on the total event."); } - return p; + return f; } - /** * @param {number} success * @returns {HTMLParagraphElement} @@ -87,17 +113,17 @@ App.Events.SEPitFight = class SEPitFight extends App.Events.BaseEvent { function eventSuccess(success) { const p = document.createElement("p"); - if (success === 0) { - p.append("The event had no success."); - } else if (success < 0) { + if (success < 0) { p.append("The event was an embarrassment."); + } else if (success === 0) { + p.append("The event had no success."); } else if (success < 0.2) { p.append("The event had little success."); } else if (success < 0.8) { p.append("The event had normal success."); - } else if (success < 1.2) { + } else if (success < 1.1) { p.append("The event had high success."); - } else if (success < 5) { + } else { p.append("The event had extremely high success."); } diff --git a/src/facilities/pit/fights/0_lethalRandom.js b/src/facilities/pit/fights/0_lethalRandom.js index 1780ab9472f4e023621c08ed8366123d887fa568..b36ebc218fbfe1518a1ff438a11ffb028a3b350d 100644 --- a/src/facilities/pit/fights/0_lethalRandom.js +++ b/src/facilities/pit/fights/0_lethalRandom.js @@ -16,10 +16,6 @@ App.Facilities.Pit.Fights.LR1v1 = class extends App.Facilities.Pit.Fights.BaseFi return 5; } - fightPrerequisites() { - return []; - } - actorPrerequisites() { return [ [canWalk], diff --git a/src/facilities/pit/fights/0_nonLethalRandom.js b/src/facilities/pit/fights/0_nonLethalRandom.js index 3a1340276d2b9aa80d942f22ae8c618d870194dd..ddf28976313bad2874d45e7aff1ac14ec6bee466 100644 --- a/src/facilities/pit/fights/0_nonLethalRandom.js +++ b/src/facilities/pit/fights/0_nonLethalRandom.js @@ -20,10 +20,6 @@ App.Facilities.Pit.Fights.NlR1v1 = class extends App.Facilities.Pit.Fights.BaseF }]; } - fightPrerequisites() { - return []; - } - actorPrerequisites() { return [ [canWalk], diff --git a/src/facilities/pit/fights/2_lethalScheduledBG.js b/src/facilities/pit/fights/2_lethalScheduledBG.js new file mode 100644 index 0000000000000000000000000000000000000000..195f75a4866d26476fae31e777b03648a52410f7 --- /dev/null +++ b/src/facilities/pit/fights/2_lethalScheduledBG.js @@ -0,0 +1,41 @@ +/** Lethal 1v1 between the BG and a random slave. */ +App.Facilities.Pit.Fights.LSchBg1v1 = class extends App.Facilities.Pit.Fights.LBg1v1 { + get uiDescription() { + return "Scheduled 1-vs-1 between your bodyguard and a set slave"; + } + + get key() { + return "l sch bg 1v1"; + } + + get selectable() { + return false; + } + + get options() { + return [{ + name: "Slave", key: "slaveID", default: null, values: [] + }]; + } + + fightPrerequisites() { + return [() => !!getSlave(this.params.slaveID), ...super.fightPrerequisites()]; + } + + actorPrerequisites() { + return []; + } + + execute(node) { + this.actors = [this.params.slaveID, ...this.actors]; + App.Facilities.Pit.unqueueFight(this.key); + return super.execute(node); + } + + introCombatants(slave1, slave2) { + const {his1} = getPronouns(slave1).appendSuffix("1"); + return [`In this scheduled fight your bodyguard`, App.UI.DOM.slaveDescriptionDialog(slave1), + `will demonstrate ${his1} combat prowess on`, + App.UI.DOM.combineNodes(contextualIntro(slave1, slave2, true), ".")]; + } +}; diff --git a/src/facilities/pit/pit.js b/src/facilities/pit/pit.js index 06ab426a71f94f012e9bea6435f53581a71f8fd7..77a3b9928ac631f1201b6d2d46fcb395bbb018e4 100644 --- a/src/facilities/pit/pit.js +++ b/src/facilities/pit/pit.js @@ -30,7 +30,6 @@ App.Facilities.Pit.pit = function() { const endWeekFrag = new DocumentFragment(); App.UI.DOM.appendNewElement("div", endWeekFrag, arenaRules(), ['margin-bottom']); - // App.UI.DOM.appendNewElement("div", endWeekFrag, pitScheduled(), ['margin-bottom']); App.UI.DOM.appendNewElement("div", endWeekFrag, arenaFights(), ['margin-bottom']); tabs.addTab("Fights", "ew_fights", endWeekFrag); @@ -210,7 +209,9 @@ App.Facilities.Pit.pit = function() { const el = new DocumentFragment(); const fights = App.Facilities.Pit.getFightsMap(); for (const f of fights.values()) { - el.append(arenaFight(f)); + if (f.selectable || App.Facilities.Pit.fightIsQueued(f.key)) { + el.append(arenaFight(f)); + } } return el; } @@ -233,20 +234,29 @@ App.Facilities.Pit.pit = function() { const group = new App.UI.OptionsGroup(); const isActive = App.Facilities.Pit.fightIsQueued(fight.key); - group.addOption("Active", "isActive", {isActive}) - .addValue("Yes", true).on().addCallback(() => App.Facilities.Pit.queueFight(fight.key)) - .addValue("No", false).off().addCallback(() => App.Facilities.Pit.unqueueFight(fight.key)); + if (fight.selectable) { + group.addOption("Active", "isActive", {isActive}) + .addValue("Yes", true).on().addCallback(() => App.Facilities.Pit.queueFight(fight.key)) + .addValue("No", false).off().addCallback(() => App.Facilities.Pit.unqueueFight(fight.key)); + } else { + group.addOption("", "isActive", {isActive}) + .addValue("Cancel", false).addCallback(() => App.Facilities.Pit.unqueueFight(fight.key)); + } if (isActive) { const options = fight.options; if (options.length > 0) { const params = App.Facilities.Pit.getFightOptions(fight.key); for (const o of options) { - const go = group.addOption(o.name, o.key, params); - for (const v of o.values) { - go.addValue(v.name, v.value); + if (o.key === "slaveID") { + group.addComment("You assigned " + getSlave(params.slaveID).slaveName + " to this fight"); + } else { + const go = group.addOption(o.name, o.key, params); + for (const v of o.values) { + go.addValue(v.name, v.value); + } + go.addCallbackToEach(() => App.Facilities.Pit.setFightOptions(fight.key, params)); } - go.addCallbackToEach(() => App.Facilities.Pit.setFightOptions(fight.key, params)); } } } @@ -274,26 +284,6 @@ App.Facilities.Pit.pit = function() { } } - function pitScheduled() { - const el = document.createDocumentFragment(); - - if (V.pit.slaveFightingAnimal || V.pit.slaveFightingBodyguard) { - const animal = V.pit.slaveFightingAnimal; - const bodyguard = V.pit.slaveFightingBodyguard; - - el.append(`You have scheduled ${getSlave(animal || bodyguard).slaveName} to fight ${V.pit.slaveFightingAnimal ? `an animal` : `your bodyguard`} to the death this week.`); - - App.UI.DOM.appendNewElement("div", el, App.UI.DOM.link(`Cancel it`, () => { - V.pit.slaveFightingAnimal = null; - V.pit.slaveFightingBodyguard = null; - - App.UI.reload(); - }), ['indent']); - } - - return el; - } - function arenaSlaves() { const el = document.createDocumentFragment(); diff --git a/src/facilities/pit/pitFightList.js b/src/facilities/pit/pitFightList.js index 9fc8b0d8ed8b815bb88e7e214b6b701b4013a816..a7bea02f03ace7c70eeb4af33490b7e253c90fcf 100644 --- a/src/facilities/pit/pitFightList.js +++ b/src/facilities/pit/pitFightList.js @@ -12,6 +12,7 @@ App.Facilities.Pit.getFights = function() { new App.Facilities.Pit.Fights.NlBg1v1(), new App.Facilities.Pit.Fights.LR1v1(), new App.Facilities.Pit.Fights.LBg1v1(), + new App.Facilities.Pit.Fights.LSchBg1v1(), ]; }; /** diff --git a/src/npc/interaction/killSlave.js b/src/npc/interaction/killSlave.js index a891216f4af44f6beb64e3b105295cf662f1afcd..88c5d2f24f574b5a6ff44af270861677a0534e57 100644 --- a/src/npc/interaction/killSlave.js +++ b/src/npc/interaction/killSlave.js @@ -36,7 +36,7 @@ App.UI.SlaveInteract.killSlave = function(slave) { frag.appendChild(intro()); - if (V.pit && V.pit.slaveFightingBodyguard) { + if (App.Facilities.Pit.fightIsQueued((new App.Facilities.Pit.Fights.LSchBg1v1()).key)) { frag.appendChild(plannedFight()); } else { frag.appendChild(links()); @@ -196,10 +196,11 @@ App.UI.SlaveInteract.killSlave = function(slave) { function plannedFight() { const plannedFightsDiv = document.createElement("div"); - plannedFightsDiv.append(`${!slave.fuckdoll && slave.fetish !== Fetish.MINDBROKEN ? `You abruptly cut ${his} begging short once you` : `You change your mind as you suddenly`} remember ${getSlave(V.pit.slaveFightingBodyguard).slaveName} is already fighting your bodyguard ${S.Bodyguard.slaveName} for ${his} life this week.`); + const slave = getSlave(App.Facilities.Pit.getFightOptions((new App.Facilities.Pit.Fights.LSchBg1v1()).key).slaveID); + plannedFightsDiv.append(`${!slave.fuckdoll && slave.fetish !== Fetish.MINDBROKEN ? `You abruptly cut ${his} begging short once you` : `You change your mind as you suddenly`} remember ${slave.slaveName} is already fighting your bodyguard ${S.Bodyguard.slaveName} for ${his} life this week.`); App.UI.DOM.appendNewElement("div", plannedFightsDiv, App.UI.DOM.passageLink(`Cancel the fight`, V.returnTo, () => { - V.pit.slaveFightingBodyguard = null; + App.Facilities.Pit.unqueueFight((new App.Facilities.Pit.Fights.LSchBg1v1()).key); }), ['margin-top']); return plannedFightsDiv; @@ -237,7 +238,7 @@ App.UI.SlaveInteract.killSlave = function(slave) { function getDisabledReasons() { const arr = []; - if (V.pit && V.pit.slaveFightingBodyguard) { + if (App.Facilities.Pit.fightIsQueued((new App.Facilities.Pit.Fights.LSchBg1v1()).key)) { arr.push(`You already have a slave fighting your bodyguard this week.`); } @@ -774,89 +775,21 @@ App.UI.SlaveInteract.killSlave = function(slave) { reactionText = `${He} nods ${his} head and straightens up, as though mentally preparing ${himself} for the fight for ${his} life.`; } - if (V.animals.canine.length || V.animals.hooved.length || V.animals.feline.length) { - combatDiv.append(animals()); - } else { - combatDiv.append(bodyguard()); - } + combatDiv.append(bodyguard()); return combatDiv; - function animals() { - const subDiv = document.createElement("div"); - const linksDiv = App.UI.DOM.makeElement("div", null, ['kill-slave-options']); - - const links = []; - - const moreThanOneAnimal = V.active.canine && V.active.hooved || - V.active.canine && V.active.feline || - V.active.hooved && V.active.feline; - - let activeAnimal; - - if (!moreThanOneAnimal) { - if (V.active.canine) { - activeAnimal = V.active.canine; - } else if (V.active.hooved) { - activeAnimal = V.active.hooved; - } else { - activeAnimal = V.active.feline; - } - } - - subDiv.append(`You tell ${him} you'll give ${him} the chance to win ${his} life in combat – if ${he} wants to live, ${he} can either fight your bodyguard or one of your beasts.`); - - links.push(App.UI.DOM.link(`Have ${him} fight ${S.Bodyguard.slaveName}`, () => { - V.pit.slaveFightingBodyguard = slave.ID; - V.pit.slaveFightingAnimal = null; - V.pit.lethal = true; - V.pit.animal = null; - - App.UI.DOM.replace(linksDiv, `It's decided. ${He} will fight your bodyguard, ${S.Bodyguard.slaveName}. ${reactionText}`); - })); - - if (V.active.canine && getAnimal(V.active.canine).species === "dog" && !V.active.hooved && !V.active.feline) { - links.push(App.UI.DOM.disabledLink(`Have ${him} fight one of your animals`, [`A dog isn't a proper challenge.`])); - } else if (V.active.feline && getAnimal(V.active.feline).species === "cat" && !V.active.hooved && !V.active.canine) { - links.push(App.UI.DOM.disabledLink(`Have ${him} fight one of your animals`, [`Housecats are much too small to fight.`])); - } else { - links.push(App.UI.DOM.link(`Have ${him} fight one of your animals`, () => { - const animalOptions = []; - - if (V.active.canine && getAnimal(V.active.canine).species !== "dog") { - animalOptions.push(V.active.canine); - } - if (V.active.hooved) { - animalOptions.push(V.active.hooved); - } - if (V.active.feline && getAnimal(V.active.feline).species !== "cat") { - animalOptions.push(V.active.feline); - } - - V.pit.slaveFightingAnimal = slave.ID; - V.pit.slaveFightingBodyguard = null; - V.pit.lethal = true; - V.pit.animal = animalOptions.random(); - - App.UI.DOM.replace(linksDiv, `It's decided. ${He} will fight ${moreThanOneAnimal ? ` one of your animals.` : ` your ${activeAnimal.species}.`} ${reactionText}`); - })); - } - - App.UI.DOM.appendNewElement("div", linksDiv, App.UI.DOM.generateLinksStrip(links)); - - subDiv.append(linksDiv); - - return subDiv; - } - function bodyguard() { const subDiv = document.createElement("div"); subDiv.append(`You tell ${him} you'll let your bodyguard decide ${his} fate — if ${he} wants to live, ${he}'ll have to beat ${S.Bodyguard.slaveName} in hand-to-hand combat in ${V.pit.name}. `, reactionText); - V.pit.slaveFightingBodyguard = slave.ID; - V.pit.lethal = true; - V.pit.animal = null; + const key = (new App.Facilities.Pit.Fights.LSchBg1v1()).key; + + App.Facilities.Pit.queueFight(key); + const options = App.Facilities.Pit.getFightOptions(key); + options.slaveID = slave.ID; + App.Facilities.Pit.setFightOptions(key, options); return subDiv; }