From bdd7d146e912fc37c46142e5c6e5e2b1f26204ee Mon Sep 17 00:00:00 2001
From: Arkerthan <arkerthan@mailbox.org>
Date: Mon, 20 Feb 2023 00:08:24 +0100
Subject: [PATCH] Add more settings and descriptions for them to the pit

---
 devTools/types/FC/facilities.d.ts             |  4 ++
 src/004-base/basePitFight.js                  | 16 ++++-
 src/events/scheduled/pitFight.js              | 72 ++++++++++++++++---
 src/facilities/pit/fights/0_lethalRandom.js   |  4 +-
 .../pit/fights/0_nonLethalRandom.js           |  4 +-
 src/facilities/pit/pitUtils.js                |  3 +-
 6 files changed, 89 insertions(+), 14 deletions(-)

diff --git a/devTools/types/FC/facilities.d.ts b/devTools/types/FC/facilities.d.ts
index 18e7f5857ab..9b5ac1fb6fd 100644
--- a/devTools/types/FC/facilities.d.ts
+++ b/devTools/types/FC/facilities.d.ts
@@ -209,6 +209,10 @@ declare namespace FC {
 			 * Which virginities will be respected
 			 */
 			virginities: "none" | "vaginal" | "anal" | "all"
+			/**
+			 * Whether slaves fighting must be in somewhat fair health and generally able to do combat.
+			 */
+			minimumHealth: boolean
 		}
 	}
 }
diff --git a/src/004-base/basePitFight.js b/src/004-base/basePitFight.js
index 19c95439149..a7e805f306c 100644
--- a/src/004-base/basePitFight.js
+++ b/src/004-base/basePitFight.js
@@ -166,13 +166,27 @@ App.Facilities.Pit.Fights.BaseFight = class BaseFight {
 	 * @private
 	 */
 	_selectActor(prereqs, ...ids) {
-		const qualified = ids.filter(si => !this.actors.includes(si) && prereqs.every(p => p(getSlave(si))));
+		const qualified = ids
+			.filter(si => !this.actors.includes(si) && prereqs.every(p => p(getSlave(si))) && this._validActor(si));
 		if (qualified.length === 0) {
 			return false; // a required actor was not found
 		}
 		this.actors.push(qualified.pluck());
 		return true;
 	}
+
+	/**
+	 * @param {number} si - Slave ID
+	 * @returns {boolean} True, if the slave is allowed to fight
+	 * @private
+	 */
+	_validActor(si) {
+		if (!V.pit.minimumHealth) {
+			return true;
+		}
+		const slave = getSlave(si);
+		return canWalk(slave) && slave.health.condition >= -20;
+	}
 };
 
 /** This is a trivial fight for use as an example. */
diff --git a/src/events/scheduled/pitFight.js b/src/events/scheduled/pitFight.js
index 7f9241ebad7..483ef1086d3 100644
--- a/src/events/scheduled/pitFight.js
+++ b/src/events/scheduled/pitFight.js
@@ -16,6 +16,7 @@ App.Events.SEPitFight = class SEPitFight extends App.Events.BaseEvent {
 		const maxFights = 3 + (V.pit.fightsBase * 2);
 		let completedFights = 0;
 		let totalSuccess = 0;
+		let lethalFights = 0;
 
 		const fighterMap = new App.Facilities.Pit.Fights.FighterMap();
 
@@ -62,6 +63,9 @@ App.Events.SEPitFight = class SEPitFight extends App.Events.BaseEvent {
 				}
 				f.append(div);
 			}
+			if (availableFights.length === 0) {
+				App.UI.DOM.appendNewElement("div", f, "No fights available");
+			}
 			App.UI.DOM.appendNewElement("div", f, App.UI.DOM.link("Select different fighters", () => refreshInteractionSpan(selectFight())));
 			App.UI.DOM.appendNewElement("div", f, App.UI.DOM.link("Head back to the penthouse and cancel all the remaining fights", () => refreshInteractionSpan(finishEvent())));
 			App.Events.addResponses(f, choices);
@@ -109,7 +113,10 @@ App.Events.SEPitFight = class SEPitFight extends App.Events.BaseEvent {
 			p.append(fightSuccess(success), " ", fightImpact(impact));
 			f.append(p);
 			totalSuccess += impact;
-			completedFights += 1;
+			completedFights++;
+			if (fight.lethal) {
+				lethalFights++;
+			}
 
 			if (completedFights < maxFights) {
 				f.append(selectFight());
@@ -196,16 +203,20 @@ App.Events.SEPitFight = class SEPitFight extends App.Events.BaseEvent {
 		}
 
 		function intro() {
-			const f = new DocumentFragment();
 			let r = [];
 			if (V.pit.audience === "none") {
 				r.push(`You are alone above the pit, left to watch them square off in private.`);
+				return r[0];
 			} else if (V.pit.audience === "free") {
 				r.push(`Your guests line the rim of the pit, joking and betting.`);
 			} else {
 				r.push(`The attendees line the rim of the pit, betting and arguing.`);
 			}
 
+			if (V.pit.lethal === 1) {
+				r.push("They expect to see a mix of lethal and nonlethal fights.");
+			}
+
 			if (V.arcologies[0].FSRomanRevivalist !== "unset") {
 				r.push(`They `, App.UI.DOM.makeElement("span", 'strongly approve', ["reputation",
 					"inc"]), ` of your hosting combat between slaves; this advances ideas from antiquity about what public events should be.`);
@@ -214,27 +225,70 @@ App.Events.SEPitFight = class SEPitFight extends App.Events.BaseEvent {
 				V.arcologies[0].FSRomanRevivalist += (0.2 * V.FSSingleSlaveRep);
 			}
 
+			if (V.pit.minimumHealth) {
+				if (V.arcologies[0].FSPaternalist !== "unset") {
+					r.push(`They `, App.UI.DOM.makeElement("span", 'strongly approve', ["reputation",
+						"inc"]), ` of restricting fights to healthy slaves; this advances ideas about slave well-being.`);
+
+					repX(10 * V.FSSingleSlaveRep * (V.arcologies[0].FSPaternalist / V.FSLockinLevel), "pit");
+					V.arcologies[0].FSPaternalist += (0.2 * V.FSSingleSlaveRep);
+				} else if (V.arcologies[0].FSDegradationist !== "unset") {
+					r.push(`They `, App.UI.DOM.makeElement("span", 'strongly disapprove', ["reputation",
+						"dec"]), ` of restricting fights to healthy slaves; this hampers ideas about slave degradation.`);
+
+					repX(-10 * V.FSSingleSlaveRep * (V.arcologies[0].FSDegradationist / V.FSLockinLevel), "pit");
+					V.arcologies[0].FSDegradationist -= (0.2 * V.FSSingleSlaveRep);
+				}
+			} else {
+				if (V.arcologies[0].FSPaternalist !== "unset") {
+					r.push(`They `, App.UI.DOM.makeElement("span", 'strongly disapprove', ["reputation",
+						"dec"]), ` of allowing ill slaves to fight; this hampers ideas about slave well-being.`);
+
+					repX(-10 * V.FSSingleSlaveRep * (V.arcologies[0].FSPaternalist / V.FSLockinLevel), "pit");
+					V.arcologies[0].FSPaternalist -= (0.2 * V.FSSingleSlaveRep);
+				} else if (V.arcologies[0].FSDegradationist !== "unset") {
+					r.push(`They `, App.UI.DOM.makeElement("span", 'strongly approve', ["reputation",
+						"inc"]), ` of allowing ill slaves to fight; this advances ideas about slave degradation.`);
+
+					repX(10 * V.FSSingleSlaveRep * (V.arcologies[0].FSDegradationist / V.FSLockinLevel), "pit");
+					V.arcologies[0].FSDegradationist += (0.2 * V.FSSingleSlaveRep);
+				}
+			}
+
+			const f = new DocumentFragment();
 			App.Events.addParagraph(f, r);
 			return f;
 		}
 
 		function finishEvent() {
-			const f = new DocumentFragment();
+			const r = [];
 			V.nextButton = "Continue";
 
 			if (completedFights === 0) {
-				f.append("Opening the arena without hosting fights hurt your reputation.");
+				r.push("Opening the arena without hosting fights hurt your reputation.");
 				repX(-100 * maxFights, "pit");
+				const f = new DocumentFragment();
+				App.Events.addParagraph(f, r);
 				return f;
 			}
 
 			if (completedFights < maxFights) {
-				f.append("The audience is disappointed in the few fights this week.");
+				r.push("The audience is disappointed in the few fights this week.");
 				totalSuccess -= (maxFights - completedFights) * 0.2;
 			}
 
+			if (V.pit.lethal === 1) {
+				if (lethalFights === 0) {
+					r.push("The audience expected to see blood and did not get any.");
+					totalSuccess *= 0.9;
+				} else if (lethalFights === completedFights) {
+					r.push("The audience only saw blood today and is missing some other outcomes.");
+					totalSuccess *= 0.9;
+				}
+			}
+
 			const averageSuccess = totalSuccess / maxFights;
-			f.append(eventSuccess(averageSuccess));
+			r.push(eventSuccess(averageSuccess));
 
 			totalSuccess *= 1 + 0.5 * V.pit.seats;
 
@@ -242,15 +296,17 @@ App.Events.SEPitFight = class SEPitFight extends App.Events.BaseEvent {
 				const repGain = 100 * totalSuccess;
 				repX(repGain, "pit");
 				if (V.cheatMode || V.debugMode) {
-					f.append(" rep: " + repGain);
+					r.push("rep:" + repGain);
 				}
 			} else if (V.pit.audience === "paid") {
 				const cashGain = 2000 * totalSuccess;
 				cashX(cashGain, "pit");
 				if (V.cheatMode || V.debugMode) {
-					f.append(" cash: " + cashGain);
+					r.push("cash:" + cashGain);
 				}
 			}
+			const f = new DocumentFragment();
+			App.Events.addParagraph(f, r);
 			return f;
 		}
 	}
diff --git a/src/facilities/pit/fights/0_lethalRandom.js b/src/facilities/pit/fights/0_lethalRandom.js
index 0b807b5b0db..39cc2acb73f 100644
--- a/src/facilities/pit/fights/0_lethalRandom.js
+++ b/src/facilities/pit/fights/0_lethalRandom.js
@@ -25,8 +25,8 @@ App.Facilities.Pit.Fights.LR1v1 = class extends App.Facilities.Pit.Fights.BaseFi
 
 	actorPrerequisites() {
 		return [
-			[canWalk],
-			[canWalk]
+			[],
+			[]
 		];
 	}
 
diff --git a/src/facilities/pit/fights/0_nonLethalRandom.js b/src/facilities/pit/fights/0_nonLethalRandom.js
index 6d06f676d46..0fbac628e6b 100644
--- a/src/facilities/pit/fights/0_nonLethalRandom.js
+++ b/src/facilities/pit/fights/0_nonLethalRandom.js
@@ -29,8 +29,8 @@ App.Facilities.Pit.Fights.NlR1v1 = class extends App.Facilities.Pit.Fights.BaseF
 
 	actorPrerequisites() {
 		return [
-			[canWalk],
-			[canWalk]
+			[],
+			[]
 		];
 	}
 
diff --git a/src/facilities/pit/pitUtils.js b/src/facilities/pit/pitUtils.js
index ee0d9646ce0..964c1ea06b2 100644
--- a/src/facilities/pit/pitUtils.js
+++ b/src/facilities/pit/pitUtils.js
@@ -13,6 +13,7 @@ App.Facilities.Pit.init = function() {
 		fightsBase: 0,
 		seats: 0,
 		lethal: 0,
-		virginities: "all"
+		virginities: "all",
+		minimumHealth: true,
 	};
 };
-- 
GitLab