From bcb153e74b1fc0602ca27729d641da028f640635 Mon Sep 17 00:00:00 2001 From: Arkerthan <arkerthan@mailbox.org> Date: Wed, 15 Feb 2023 21:25:41 +0100 Subject: [PATCH] Create settings for pit fights --- devTools/types/FC/facilities.d.ts | 35 +-- src/004-base/basePitFight.js | 24 ++ src/data/backwardsCompatibility/pitBC.js | 67 ++++-- src/events/scheduled/pitFight.js | 2 +- .../pit/fights/0_nonLethalRandom.js | 24 +- src/facilities/pit/pit.js | 205 +++++------------- src/facilities/pit/pitFightList.js | 89 ++++++++ src/facilities/pit/pitUtils.js | 9 +- 8 files changed, 243 insertions(+), 212 deletions(-) diff --git a/devTools/types/FC/facilities.d.ts b/devTools/types/FC/facilities.d.ts index 36c3bbd4d02..6069050493c 100644 --- a/devTools/types/FC/facilities.d.ts +++ b/devTools/types/FC/facilities.d.ts @@ -182,40 +182,23 @@ declare namespace FC { trainingIDs: number[]; // Pit section - /** The animal fighting a slave if not null. */ - animal: string | "random"; /** The type of audience the Pit has. */ audience: "none" | "free" | "paid"; - /** Whether or not the bodyguard is fighting this week. */ - bodyguardFights: boolean; /** The type of decoration the Pit is using. */ decoration: FC.FutureSocietyDeco; - /** - * Who is fighting this week. - * - * | Value | Description | - * |------:|:---------------------------| - * | 0 | Two random slaves | - * | 1 | Random slave and bodyguard | - * | 2 | Random slave and animal | - * | 3 | True random | - * | 4 | Two specific slaves | - */ - fighters: number; /** An array of the IDs of slaves assigned to the Pit. */ fighterIDs: number[]; /** Whether or not a fight has taken place during the week. */ fought: boolean; - /** Whether or not the fights in the Pit are lethal. */ - lethal: boolean; - /** The ID of the slave fighting the bodyguard for their life. */ - slaveFightingBodyguard: number; - /** The ID of the slave fighting one of your beasts for their life. */ - slaveFightingAnimal: number; - /** The IDs of the two slaves chosen to fight this week. */ - slavesFighting: number[]; - /** The virginities of the loser not allowed to be taken. */ - virginities: "neither" | "vaginal" | "anal" | "all" + /** + * Active fights run every week. + */ + activeFights: Array<ActiveFight>; + } + + interface ActiveFight { + key: string + options: Record<string, any> } } } diff --git a/src/004-base/basePitFight.js b/src/004-base/basePitFight.js index 42c939bdb91..20f10b2d21e 100644 --- a/src/004-base/basePitFight.js +++ b/src/004-base/basePitFight.js @@ -39,6 +39,30 @@ App.Facilities.Pit.Fights.BaseFight = class BaseFight { return false; } + /** + * @typedef {object} fightOption + * @property {string} name + * @property {string} value + */ + /** + * @typedef {object} fightOptions + * @property {string} name + * @property {string} key + * @property {Array<fightOption>} values + * @property {*} default + */ + + /** + * Options for the fight. For every option there is an array with valid values and a name and key for each one. + * The selection for the options are supplied to {@link App.Facilities.Pit.Fights.BaseFight#param the param member} + * as an object as key/value pairs before calling {@link App.Facilities.Pit.Fights.BaseFight#execute execute}. + * A value must be passed for every option + * @returns {Array<fightOptions>} + */ + get options() { + return []; + } + /** Fight predicates determine whether the fight can be shown/executed * @callback pitFightPredicate * @returns {boolean} diff --git a/src/data/backwardsCompatibility/pitBC.js b/src/data/backwardsCompatibility/pitBC.js index 877af4c22c5..5666e94f593 100644 --- a/src/data/backwardsCompatibility/pitBC.js +++ b/src/data/backwardsCompatibility/pitBC.js @@ -6,39 +6,58 @@ App.Facilities.Pit.BC = function() { } if (V.pit) { - V.pit.name = V.pit.name || V.pitName || "the Pit"; - V.pit.virginities = V.pit.virginities || V.pitVirginities || "neither"; + if (V.releaseID <= 1185) { + V.pit.name = V.pit.name || V.pitName || "the Pit"; + V.pit.virginities = V.pit.virginities || V.pitVirginities || "neither"; - if (typeof V.pit.virginities !== "string") { - const virginities = ["neither", "vaginal", "anal", "all"]; + if (typeof V.pit.virginities !== "string") { + const virginities = ["neither", "vaginal", "anal", "all"]; - V.pit.virginities = virginities[V.pit.virginities]; - } + V.pit.virginities = virginities[V.pit.virginities]; + } - V.pit.bodyguardFights = V.pit.bodyguardFights || V.pitBG || false; - V.pit.fighterIDs = V.pit.fighterIDs || V.fighterIDs || []; - V.pit.fighters = V.pit.fighters || 0; + V.pit.bodyguardFights = V.pit.bodyguardFights || V.pitBG || false; + V.pit.fighterIDs = V.pit.fighterIDs || V.fighterIDs || []; + V.pit.fighters = V.pit.fighters || 0; - if (V.pit.bodyguardFights && V.pit.fighterIDs.includes(V.BodyguardID)) { - V.pit.fighterIDs.delete(V.BodyguardID); - } + if (V.pit.bodyguardFights && V.pit.fighterIDs.includes(V.BodyguardID)) { + V.pit.fighterIDs.delete(V.BodyguardID); + } - if (V.farmyard) { - V.pit.animal = V.pit.animal || V.pitAnimalType || null; - } + if (V.farmyard) { + V.pit.animal = V.pit.animal || V.pitAnimalType || null; + } - V.pit.trainingIDs = V.pit.trainingIDs || []; + V.pit.trainingIDs = V.pit.trainingIDs || []; - V.pit.audience = V.pit.audience || V.pitAudience || "none"; - V.pit.lethal = V.pit.lethal || V.pitLethal || false; - V.pit.fought = V.pit.fought || V.pitFought || false; + V.pit.audience = V.pit.audience || V.pitAudience || "none"; + V.pit.lethal = V.pit.lethal || V.pitLethal || false; + V.pit.fought = V.pit.fought || V.pitFought || false; - V.pit.slavesFighting = V.pit.slavesFighting || []; - V.pit.decoration = V.pit.decoration || "standard"; - } + V.pit.slavesFighting = V.pit.slavesFighting || []; + V.pit.decoration = V.pit.decoration || "standard"; - if (V.slaveFightingBG && V.pit) { - V.pit.slaveFightingBodyguard = V.slaveFightingBG; + if (V.slaveFightingBG) { + V.pit.slaveFightingBodyguard = V.slaveFightingBG; + } + } + + V.pit.activeFights = V.pit.activeFights || []; + + if (V.pit.hasOwnProperty("lethal")) { + if (V.pit.lethal) { + V.pit.activeFights.push("l r 1v1"); + } else { + V.pit.activeFights.push("nl r 1v1"); + } + } + delete V.pit.lethal; + delete V.pit.animal; + delete V.pit.bodyguardFights; + delete V.pit.slaveFightingAnimal; + delete V.pit.slaveFightingBodyguard; + delete V.pit.slavesFighting; + delete V.pit.virginities; } if (V.pit && V.pit.trainingIDs) { diff --git a/src/events/scheduled/pitFight.js b/src/events/scheduled/pitFight.js index 467a54588c5..1f83e282291 100644 --- a/src/events/scheduled/pitFight.js +++ b/src/events/scheduled/pitFight.js @@ -32,7 +32,7 @@ App.Events.SEPitFight = class SEPitFight extends App.Events.BaseEvent { App.Events.addParagraph(node, r); - const fights = App.Facilities.Pit.getFights(); + const fights = App.Facilities.Pit.activeFights(); 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"); diff --git a/src/facilities/pit/fights/0_nonLethalRandom.js b/src/facilities/pit/fights/0_nonLethalRandom.js index 24cf41a9152..fdcdb0bc8d8 100644 --- a/src/facilities/pit/fights/0_nonLethalRandom.js +++ b/src/facilities/pit/fights/0_nonLethalRandom.js @@ -8,6 +8,18 @@ App.Facilities.Pit.Fights.NlR1v1 = class extends App.Facilities.Pit.Fights.BaseF return "nl r 1v1"; } + get options() { + return [{ + name: "Respect virginities", + key: "virginities", + values: [ + {name: "None", value: "neither"}, {name: "Vaginal", value: "vaginal"}, + {name: "Anal", value: "anal"}, {name: "All", value: "all"} + ], + default: "all" + }]; + } + fightPrerequisites() { return []; } @@ -45,7 +57,7 @@ App.Facilities.Pit.Fights.NlR1v1 = class extends App.Facilities.Pit.Fights.BaseF r.push(`You review the rules — the combatants are wearing light gloves, and the fight will be nonlethal, with you as the judge. The winner will have the right to do anything they wish to the loser,`); - switch (V.pit.virginities) { + switch (that.params.virginities) { case "all": r.push(`except take their virginity,`); break; @@ -59,7 +71,7 @@ App.Facilities.Pit.Fights.NlR1v1 = class extends App.Facilities.Pit.Fights.BaseF r.push(`even take virginities,`); break; default: - throw new Error(`Unexpected V.pit.virginities value of '${V.pit.virginities}' found`); + throw new Error(`Unexpected V.pit.virginities value of '${that.params.virginities}' found`); } r.push(`and earn two complete days of rest. You take a moment to look over your fighters before giving the word.`); @@ -610,7 +622,7 @@ App.Facilities.Pit.Fights.NlR1v1 = class extends App.Facilities.Pit.Fights.BaseF const winnerPenetrates = orifice => `${He} pushes ${loser.slaveName}'s back down onto the mat, forces ${his2} ${hasBothLegs(loser) ? `legs apart` : !hasAnyLegs(loser) ? `hips steady` : `leg aside`}, and penetrates the loser's ${orifice}.`; const loserProtest = `${canTalk(loser) ? `${loser.slaveName} starts to scream a protest to stop ${winner.slaveName} raping ${him2} pregnant, but ${winner.slaveName} grinds ${his2} face into the mat to shut ${him2} up` - : `${loser.slaveName} tries to gesture a protest before ${winner.slaveName} fills ${his2} fertile ${loser.mpreg && V.pit.virginities !== anal ? `asspussy` : `pussy`} with cum, but ${winner.slaveName} grabs ${his2} ${hasBothArms(loser) ? `hands and pins them` : hasAnyArms(loser) ? `hand and pins it` : `neck firmly`} to keep ${him2} from complaining`}.`; + : `${loser.slaveName} tries to gesture a protest before ${winner.slaveName} fills ${his2} fertile ${loser.mpreg && that.params.virginities !== anal ? `asspussy` : `pussy`} with cum, but ${winner.slaveName} grabs ${his2} ${hasBothArms(loser) ? `hands and pins them` : hasAnyArms(loser) ? `hand and pins it` : `neck firmly`} to keep ${him2} from complaining`}.`; const virginitySpan = App.UI.DOM.makeElement("span", ``, ["virginity", "loss"]); @@ -626,7 +638,7 @@ App.Facilities.Pit.Fights.NlR1v1 = class extends App.Facilities.Pit.Fights.BaseF r.push(`${He} needs it, since ${his} soft dick won't be raping anything.`); } - if (V.pit.virginities === "all") { + if (that.params.virginities === "all") { if (loser.vagina === 0 && canDoVaginal(loser) && loser.anus === 0 && canDoAnal(loser)) { r.push(`${He} respects ${loser.slaveName}'s virgin holes, and hauls the loser to ${his2} knees for a facefuck.`); @@ -688,7 +700,7 @@ App.Facilities.Pit.Fights.NlR1v1 = class extends App.Facilities.Pit.Fights.BaseF actX(loser, oral); } - } else if (V.pit.virginities === "anal") { + } else if (that.params.virginities === "anal") { if (loser.vagina === 0 && canDoVaginal(loser)) { r.push(`${He} pushes ${loser.slaveName}'s back down onto the mat, forces ${his2} ${hasBothLegs(loser) ? `legs apart` : !hasAnyLegs(loser) ? `hips steady` : `leg aside`},`); @@ -756,7 +768,7 @@ App.Facilities.Pit.Fights.NlR1v1 = class extends App.Facilities.Pit.Fights.BaseF actX(loser, oral); } - } else if (V.pit.virginities === "vaginal") { + } else if (that.params.virginities === "vaginal") { if (loser.vagina === 0 && canDoVaginal(loser)) { r.push(`${He} pushes ${loser.slaveName}'s back down onto the mat, forces ${his2} ${hasBothLegs(loser) ? `legs apart` : !hasAnyLegs(loser) ? `hips steady` : `leg aside`},`); diff --git a/src/facilities/pit/pit.js b/src/facilities/pit/pit.js index 67e650cb1f0..46cd60a825f 100644 --- a/src/facilities/pit/pit.js +++ b/src/facilities/pit/pit.js @@ -5,11 +5,6 @@ App.Facilities.Pit.pit = function() { const pit = App.Entity.facilities.pit; - if (V.pit.slavesFighting.length !== 2) { - V.pit.slavesFighting = []; - V.pit.fighters = V.pit.fighters !== 4 ? V.pit.fighters : 0; - } - const container = document.createElement("div"); container.append(assemble()); return container; @@ -35,7 +30,8 @@ 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, pitScheduled(), ['margin-bottom']); + App.UI.DOM.appendNewElement("div", endWeekFrag, arenaFights(), ['margin-bottom']); tabs.addTab("Fights", "ew_fights", endWeekFrag); frag.append(tabs.render()); @@ -191,151 +187,66 @@ App.Facilities.Pit.pit = function() { function arenaRules() { const el = document.createDocumentFragment(); - const animal = V.active.canine || V.active.hooved || V.active.feline; - /** @type {FC.Facilities.Rule[]} */ - const rules = !V.pit.slaveFightingAnimal && !V.pit.slaveFightingBodyguard// only display if a fight has not been scheduled - ? [{ - property: "audience", prereqs: [], options: [{ - get text() { - return `Fights here are strictly private.`; - }, link: `Closed`, value: 'none', - }, { - get text() { - return `Fights here are free and open to the public.`; - }, link: `Free`, value: 'free', - }, { - get text() { - return `Admission is charged to the fights here.`; - }, link: `Paid`, value: 'paid', - }, ], object: V.pit, - }, { - property: "fighters", prereqs: [], options: [{ - get text() { - return `Two fighters will be selected from the pool at random.`; - }, link: `Slaves`, value: 0, - }, { - get text() { - return `Your bodyguard ${S.Bodyguard.slaveName} will fight a slave selected from the pool at random.`; - }, link: `Bodyguard`, value: 1, prereqs: [!!S.Bodyguard, ], - }, { - get text() { - return `A random slave will fight an animal.`; - }, link: `Animal`, value: 2, prereqs: [!!animal, ], handler: () => { - if (!V.pit.animal) { - V.pit.animal = animal; - } - }, - }, { - get text() { - return `A random slave will fight another slave${S.Bodyguard && !animal ? ` or your bodyguard` : S.Bodyguard ? `, your bodyguard` : ``}${animal ? ` or an animal` : ``}.`; - }, link: `Random`, value: 3, prereqs: [!!S.Bodyguard || !!animal, ], - }, { - get text() { - return `${V.pit.slavesFighting.length > 1 ? `${SlaveFullName(getSlave(V.pit.slavesFighting[0]))} will fight ${SlaveFullName(getSlave(V.pit.slavesFighting[1]))} this week.` : `Two chosen slaves will fight.`}`; - }, link: `Choose slaves`, value: 4, handler: () => { - Engine.play("Pit Workaround"); - - V.pit.slavesFighting = []; - }, - }, ], object: V.pit, - }, { - property: "animal", prereqs: [V.pit.fighters === 2 || V.pit.fighters === 3, !!animal, ], options: [{ - get text() { - return `Your slave will fight ${getAnimal(V.active.canine).articleAn} ${V.active.canine}.`; - }, - get link() { - return capFirstChar(V.active.canine); - }, - value: V.active.canine, - prereqs: [!!V.active.canine, - !["beagle", "French bulldog", "poodle", "Yorkshire terrier"].includes(V.active.canine), ], - }, { - get text() { - return `Your slave will fight ${getAnimal(V.active.hooved).articleAn} ${V.active.hooved}.`; - }, get link() { - return capFirstChar(V.active.hooved); - }, value: V.active.hooved, prereqs: [!!V.active.hooved, ], - }, { - get text() { - return `Your slave will fight ${getAnimal(V.active.feline).articleAn} ${V.active.feline}.`; - }, - get link() { - return capFirstChar(V.active.feline); - }, - value: V.active.feline, - prereqs: [!!V.active.feline, getAnimal(V.active.feline)?.species !== "cat", ], - }, { - get text() { - return `Your slave will fight one of your animals at random.`; - }, - link: `Random`, - value: 'random', - prereqs: [(!!V.active.canine && !!V.active.hooved) || (!!V.active.canine && !!V.active.feline) || (!!V.active.hooved && !!V.active.feline), ], - }, ], object: V.pit, - }, { - property: "lethal", prereqs: [], options: [{ - get text() { - return V.pit.fighters === 2 ? `The fighter will be armed with a sword and will fight to the death.` : `Fighters will be armed with swords, and fights will be to the death.`; - }, link: `Lethal`, value: true, - }, { - get text() { - return V.pit.fighters === 2 ? `The slave will be restrained and will try to avoid becoming the animal's plaything.` : `Fighters will use their fists and feet, and fights will be to submission.`; - }, link: `Nonlethal`, value: false, - }, ], object: V.pit, - }, { - property: "virginities", prereqs: [V.pit.fighters !== 2, !V.pit.lethal, ], options: [{ - get text() { - return `No virginities of the loser will be respected.`; - }, link: `Neither`, value: 'neither', - }, { - get text() { - return `Vaginal virginity of the loser will be respected.`; - }, link: `Vaginal`, value: 'vaginal', - }, { - get text() { - return `Anal virginity of the loser will be respected.`; - }, link: `Anal`, value: 'anal', - }, { - get text() { - return `All virginities of the loser will be respected.`; - }, link: `All`, value: 'all', - }, ], object: V.pit, - }, ] : []; - - if (rules.length > 0 && rules.some(rule => rule.prereqs.every(prereq => prereq === true))) { - App.UI.DOM.appendNewElement("h2", el, `Rules`); - - rules.forEach(rule => { - if (rule.prereqs.every(prereq => prereq === true)) { - const options = new App.UI.OptionsGroup(); - const option = options.addOption(null, rule.property, rule.object || V); - - rule.options.forEach(o => { - if (!o.prereqs || o.prereqs.every(prereq => prereq === true)) { - option.addValue(o.link, o.value); - if (o.handler) { - option.addCallback(o.handler); - } - if (o.note) { - option.addComment(o.note); - } - - if ((rule.object && _.isEqual(rule.object[rule.property], o.value)) || _.isEqual(V[rule.property], o.value)) { - App.UI.DOM.appendNewElement("div", el, o.text); - } - } - }); - - App.UI.DOM.appendNewElement("div", el, options.render(), ['margin-bottom']); - } + const options = new App.UI.OptionsGroup(); + + let option = options.addOption(null, "audience", V.pit) + .addValue("Closed", "none") + .addValue("Free", "free") + .addValue("Paid", "paid"); + if (V.pit.audience === "none") { + option.addComment(`Fights here are strictly private.`); + } else if (V.pit.audience === "free") { + option.addComment(`Fights here are free and open to the public.`); + } else if (V.pit.audience === "paid") { + option.addComment(`Admission is charged to the fights here.`); + } + + App.UI.DOM.appendNewElement("div", el, options.render(), ['margin-bottom']); - if (rule.nodes) { - App.Events.addNode(el, rule.nodes); + return el; + } + + function arenaFights() { + const el = new DocumentFragment(); + const fights = App.Facilities.Pit.getFightsMap(); + for (const f of fights.values()) { + el.append(arenaFight(f)); + } + return el; + } + + /** + * @param {App.Facilities.Pit.Fights.BaseFight} fight + * @returns {HTMLParagraphElement} + */ + function arenaFight(fight) { + const p = document.createElement("p"); + p.append(fight.uiDescription); + + 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 (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); + } + go.addCallbackToEach(() => App.Facilities.Pit.setFightOptions(fight.key, params)); } - }); + } } - return el; + p.append(group.render()); + + return p; } function pitScheduled() { diff --git a/src/facilities/pit/pitFightList.js b/src/facilities/pit/pitFightList.js index 5dc0afee13d..5856881600d 100644 --- a/src/facilities/pit/pitFightList.js +++ b/src/facilities/pit/pitFightList.js @@ -4,6 +4,8 @@ */ App.Facilities.Pit.getFights = function() { return [ + // order is important, it will be played in the same order during end week! + // new App.Facilities.Pit.Fights.TestFight(), new App.Facilities.Pit.Fights.NlR1v1(), new App.Facilities.Pit.Fights.NlBg1v1(), @@ -11,3 +13,90 @@ App.Facilities.Pit.getFights = function() { new App.Facilities.Pit.Fights.LBg1v1(), ]; }; +/** + * Gives all pit fights as a Mmap + * @returns {Map<string, App.Facilities.Pit.Fights.BaseFight>} + */ +App.Facilities.Pit.getFightsMap = function() { + const m = new Map(); + for (const f of App.Facilities.Pit.getFights()) { + m.set(f.key, f); + } + return m; +}; + +/** + * @returns {Array<App.Facilities.Pit.Fights.BaseFight>} + */ +App.Facilities.Pit.activeFights = function() { + const allFights = App.Facilities.Pit.getFightsMap(); + const fights = /** @type {Array<App.Facilities.Pit.Fights.BaseFight>} */ []; + for (const f of V.pit.activeFights) { + const fight = allFights.get(f.key); + deepAssign(fight.params, f.options); + fights.push(fight); + } + return fights; +}; + + +/** + * @param {string} key + */ +App.Facilities.Pit.queueFight = function(key) { + const fight = App.Facilities.Pit.getFightsMap().get(key); + if (!fight) { + throw new Error("Trying to queue fight which does not exist."); + } + const options = {}; + for (const o of fight.options) { + options[o.key] = o.default; + } + V.pit.activeFights.push({key: key, options: options}); +}; + +/** + * @param {string} key + */ +App.Facilities.Pit.unqueueFight = function(key) { + V.pit.activeFights.deleteWith(v => v.key === key); +}; + +/** + * @param {string} key + */ +App.Facilities.Pit.fightIsQueued = function(key) { + for (const f of V.pit.activeFights) { + if (f.key === key) { + return true; + } + } + return false; +}; + +/** + * @param {string} key + * @param {Object.<string, *>} options + */ +App.Facilities.Pit.setFightOptions = function(key, options) { + for (const f of V.pit.activeFights) { + if (f.key === key) { + f.options = options; + return; + } + } + throw new Error("Trying to set options for un-queued fight."); +}; + +/** + * @param {string} key + * @returns {Object.<string, *>} + */ +App.Facilities.Pit.getFightOptions = function(key) { + for (const f of V.pit.activeFights) { + if (f.key === key) { + return f.options; + } + } + throw new Error("Trying to get options for un-queued fight."); +}; diff --git a/src/facilities/pit/pitUtils.js b/src/facilities/pit/pitUtils.js index fc3fe4d9d47..3717b25910a 100644 --- a/src/facilities/pit/pitUtils.js +++ b/src/facilities/pit/pitUtils.js @@ -6,17 +6,10 @@ App.Facilities.Pit.init = function() { trainingIDs: [], // Pit section - animal: null, audience: "free", - bodyguardFights: false, decoration: "standard", - fighters: 0, fighterIDs: [], fought: false, - lethal: false, - slaveFightingAnimal: null, - slaveFightingBodyguard: null, - slavesFighting: [], - virginities: "neither", + activeFights: [], }; }; -- GitLab