From 65854fcb019c94a2442acc71a30afec389c794dc Mon Sep 17 00:00:00 2001
From: lowercasedonkey <lowercasedonkey@gmail.com>
Date: Mon, 30 Nov 2020 15:02:00 -0500
Subject: [PATCH] brand and scar work

---
 .../bodyModification/bodyModification.js      | 305 +++++++++++++++++-
 .../bodyModification/createBrand.js           |  16 +-
 2 files changed, 311 insertions(+), 10 deletions(-)

diff --git a/src/facilities/bodyModification/bodyModification.js b/src/facilities/bodyModification/bodyModification.js
index 0a5bf22625c..f2497a4c0da 100644
--- a/src/facilities/bodyModification/bodyModification.js
+++ b/src/facilities/bodyModification/bodyModification.js
@@ -14,7 +14,6 @@ App.UI.bodyModification = function(slave, cheat = false) {
 	let piercingLevel;
 	let modReaction;
 	let scarApplied;
-	let brandApplied;
 	let tattooChoice;
 
 	container.append(createPage());
@@ -31,6 +30,8 @@ App.UI.bodyModification = function(slave, cheat = false) {
 		}
 		el.append(piercings());
 		el.append(tattoos());
+		el.append(branding());
+		el.append(scar());
 		return el;
 	}
 
@@ -44,7 +45,7 @@ App.UI.bodyModification = function(slave, cheat = false) {
 	function reaction() {
 		const el = new DocumentFragment();
 		let r = [];
-		if (brandApplied || V.degradation || scarApplied || modReaction) {
+		if (V.brandApplied || V.degradation || scarApplied || modReaction) {
 			if (slave.fuckdoll === 0) {
 				if (canSee(slave)) {
 					r.push(`There's a mirror on the ceiling, so ${he} can see`);
@@ -58,10 +59,10 @@ App.UI.bodyModification = function(slave, cheat = false) {
 				}
 				r.push(`${his} new appearance.`);
 			}
-			if (brandApplied) {
+			if (V.brandApplied) {
 				r.push(`The smell of burnt flesh hangs in the air. Being branded <span class="health.dec">has hurt ${his} health a little.</span>`);
 				healthDamage(slave, 10);
-				brandApplied = false;
+				V.brandApplied = 0;
 			}
 			if (scarApplied) {
 				if (V.scarTarget.local === "entire body") {
@@ -554,6 +555,302 @@ App.UI.bodyModification = function(slave, cheat = false) {
 		}
 	}
 
+	function branding() {
+		const el = new DocumentFragment();
+		App.UI.DOM.appendNewElement("h2", el, "Branding");
+		const selection = document.createElement("span");
+		selection.id = "brand-selection";
+		selection.append(App.Medicine.Modification.Select.brand(slave, cheat));
+		el.append(selection);
+
+		if (slave.breedingMark === 1 && (V.propOutcome === 0 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) {
+			const r = [];
+			r.push(`${He} has an intricate tattoo on ${his} lower belly that suggests ${he} was made to be bred.`);
+			r.push(
+				App.UI.DOM.link(
+					"Remove it",
+					() => {
+						slave.breedingMark = 0;
+						refresh();
+					}
+				)
+			);
+			App.Events.addNode(el, r, "div");
+		}
+		return el;
+	}
+
+	function scar() {
+		const el = new DocumentFragment();
+		App.UI.DOM.appendNewElement("h2", el, "Scars");
+		let r = [];
+
+		for (const _scarName in slave.scar) {
+			const scarDiv = document.createElement("div");
+			scarDiv.append(`${His} ${_scarName} is marked with ${App.Desc.expandScarString(slave, _scarName)}: `);
+			scarDiv.append(
+				App.UI.DOM.link(
+					"Remove Scar",
+					() => {
+						scarApplied = 0;
+						delete slave.scar[_scarName];
+						cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave);
+						V.degradation -= 10;
+						refresh();
+					}
+				)
+			);
+			r.push(scarDiv);
+		}
+		if (r.length > 0) {
+			App.Events.addNode(el, r, "div");
+		} else {
+			App.UI.DOM.appendNewElement("div", el, `${His} skin is not scarred.`);
+		}
+
+
+		r = [];
+		r.push(`Use <strong>${V.scarDesign.local}</strong> or choose another scar:`);
+		const scarTypes = new Set([
+			"whip",
+			"burn",
+			"surgical",
+			"menacing",
+			"exotic"
+		]); // Other common scars might be battle scars or c-Section but it makes little sense to include them here
+		let linkArray = [];
+		for (const scarType of scarTypes) {
+			linkArray.push(
+				App.UI.DOM.link(
+					capFirstChar(scarType),
+					() => {
+						V.scarDesign.local = scarType;
+					}
+				)
+			);
+		}
+		r.push(App.UI.DOM.generateLinksStrip(linkArray));
+		App.Events.addNode(el, r, "div");
+
+		r = [];
+		r.push(`Or design your own:`);
+		r.push(
+			App.UI.DOM.makeTextBox(
+				V.scarDesign.local,
+				(v) => {
+					V.scarDesign.local = v;
+					refresh();
+				}
+			)
+		);
+		App.Events.addNode(el, r, "div");
+
+		r = [];
+		r.push(`Choose a site for scaring:`);
+
+		let scarLocations = new Map();
+
+		if (["exotic", "menacing"].includes(V.scarDesign.local)) {
+			scarLocations.set("Cheeks", "cheek");
+		} else {
+			// Sorted head to toe
+			scarLocations.set("Entire body", "entire body");
+
+			// Head
+			if (slave.earShape !== "none") {
+				scarLocations.set("Ears", "ear");
+			}
+			scarLocations.set("Cheeks", "cheek");
+			scarLocations.set("Neck", "neck");
+
+			// Torso
+			scarLocations.set("Chest", "chest");
+			scarLocations.set("Breasts", "breast");
+			scarLocations.set("Back", "back");
+			scarLocations.set("Lower Back", "lower back");
+			scarLocations.set("Belly", "belly");
+			scarLocations.set("Pubic Mound", "pubic mound");
+
+			if (slave.dick > 0) {
+				scarLocations.set("Penis", "penis");
+			}
+			if (slave.balls > 0 && slave.scrotum > 0) {
+				scarLocations.set("Testicles", "testicle");
+			}
+
+			// Arms
+			scarLocations.set("Shoulders", "shoulder");
+			if (hasAnyNaturalArms(slave)) {
+				scarLocations.set("Arm, upper", "upper arm");
+				scarLocations.set("Arm, lower", "lower arm");
+				scarLocations.set("Wrists", "wrist");
+				scarLocations.set("Hands", "hand");
+			}
+
+			// Legs
+			scarLocations.set("Buttocks", "buttock");
+			if (hasAnyNaturalLegs(slave)) {
+				scarLocations.set("Thighs", "thigh");
+				scarLocations.set("Calves", "calf");
+				scarLocations.set("Ankles", "ankle");
+				scarLocations.set("Feet", "foot");
+			}
+		}
+
+		linkArray = [];
+		for (const [text, value] of scarLocations) {
+			linkArray.push(
+				App.UI.DOM.link(
+					text,
+					() => {
+						V.scarTarget.local = value;
+						refresh();
+					}
+				)
+			);
+		}
+		r.push(App.UI.DOM.generateLinksStrip(linkArray));
+		App.Events.addNode(el, r, "div");
+
+		r = [];
+		r.push(`Or a custom site:`);
+		r.push(
+			App.UI.DOM.makeTextBox(
+				V.scarTarget.local,
+				(v) => {
+					V.scarTarget.local = v;
+					refresh();
+				}
+			)
+		);
+		App.Events.addNode(el, r, "div");
+
+		// Correct some "bad" choices"
+		if (["exotic", "menacing"].includes(V.scarDesign.local)) {
+			if (V.scarTarget.local !== "cheek") {
+				V.scarTarget.local = "cheek";
+			}
+		}
+
+		r = [];
+
+		if (["ankle", "breast", "buttock", "calf", "cheek", "ear", "foot", "hand", "lower arm", "shoulder", "testicle", "thigh", "upper arm", "wrist"].includes(V.scarTarget.local)) {
+			const _leftTarget = ("left " + V.scarTarget.local);
+			const _rightTarget = ("right " + V.scarTarget.local);
+			if (slave.scar[_leftTarget]) {
+				r.push(`${His}${_leftTarget} is already marked with ${App.Desc.expandScarString(slave, _leftTarget)}.`);
+			}
+			if (slave.scar[_rightTarget]) {
+				r.push(`${His}${_rightTarget} is already marked with ${App.Desc.expandScarString(slave, _rightTarget)}.`);
+			}
+			r.push(`Scar ${him} now with ''${V.scarDesign.local}'' on the`);
+			let _left = 0, _right = 0;
+			// overwrite brand
+
+			if (!(["upper arm", "lower arm", "wrist", "hand"].includes(V.scarTarget.local) && getLeftArmID(slave) !== 1) && !(["thigh", "calf", "ankle", "foot"].includes(V.scarTarget.local) && getLeftLegID(slave) !== 1)) {
+				_left = 1;
+				// make next checks easier
+				r.push(
+					App.UI.DOM.link(
+						"left",
+						() => {
+							V.scarTarget.local = _leftTarget;
+							scarApplied = 1;
+							App.Medicine.Modification.addScar(slave, _leftTarget, V.scarDesign.local);
+							cashX(forceNeg(V.modCost), "slaveMod", slave);
+							V.degradation += 10;
+							refresh();
+						}
+					)
+				);
+			}
+			if (!(["upper arm", "lower arm", "wrist", "hand"].includes(V.scarTarget.local) && getRightArmID(slave) !== 1) && !(["thigh", "calf", "ankle", "foot"].includes(V.scarTarget.local) && getRightLegID(slave) !== 1)) {
+				_right = 1;
+				// make next checks easier
+			}
+			if (_left && _right) {
+				r.push(`${V.scarTarget.local}, or the`);
+			}
+			if (_right) {
+				r.push(
+					App.UI.DOM.link(
+						"right",
+						() => {
+							V.scarTarget.local = _rightTarget;
+							scarApplied = 1;
+							App.Medicine.Modification.addScar(slave, _rightTarget, V.scarDesign.local);
+							cashX(forceNeg(V.modCost), "slaveMod", slave);
+							V.degradation += 10;
+							refresh();
+						}
+					)
+				);
+			}
+			if (!_left || !_right) {
+				r.push(`${V.scarTarget.local}?`);
+			}
+		} else {
+			if (slave.scar.hasOwnProperty(V.scarTarget.local)) {
+				if (slave.scar[V.scarTarget.local][V.scarDesign.local]) {
+					r.push(`${He} already has ${V.scarDesign.local} scars on ${his} V.scarTarget.local. You can make it worse.`);
+				} else {
+					// check how much scarring is on this part
+					const _scarTotalValue = (Object.values(slave.scar[V.scarTarget.local])).reduce((a, b) => a + b, 0);
+					if (_scarTotalValue) {
+						r.push(`That would be a new kind of scar to add to the growing collection on ${his} ${V.scarTarget.local}. Life can always be worse for a slave.`);
+					}
+				}
+			}
+			r.push(
+				App.UI.DOM.link(
+					"Scar",
+					() => {
+						let _scarArray;
+						if (V.scarTarget.local === "entire body" && V.scarDesign.local.includes("whip")) {
+							// Special case for whipping scene, produces two kinds of scars
+							App.Medicine.Modification.addScourged(slave);
+						} else {
+							// Normal entire body scarring
+							if (V.scarTarget.local === "entire body") {
+								_scarArray = ["left breast", "right breast", "back", "lower back", "left buttock", "right buttock"];
+								if (getLeftArmID(slave) === 0) {
+									_scarArray.push("left upper arm");
+								}
+								if (getRightArmID(slave) === 0) {
+									_scarArray.push("right upper arm");
+								}
+								if (getLeftLegID(slave) === 0) {
+									_scarArray.push("left thigh");
+								}
+								if (getRightLegID(slave) === 0) {
+									_scarArray.push("right thigh");
+								}
+							} else { // Single scar
+								_scarArray = [V.scarTarget.local];
+							}
+							for (const scar of _scarArray) {
+								App.Medicine.Modification.addScar(slave, scar, V.scarDesign.local);
+								V.degradation += 10;
+							}
+						}
+						cashX(forceNeg(V.modCost), "slaveMod", slave);
+						scarApplied = 1;
+						V.degradation += 10;
+						refresh();
+					}
+				)
+			);
+			r.push(`with ${V.scarDesign.local} on the V.scarTarget.local`);
+			if (slave.scar[V.scarTarget.local]) {
+				r.push(`, adding to the scars that are already there?`);
+			} else {
+				r.push(`.`);
+			}
+		}
+
+		return el;
+	}
+
 	function refresh() {
 		jQuery("#body-modification").empty().append(createPage());
 	}
diff --git a/src/facilities/bodyModification/createBrand.js b/src/facilities/bodyModification/createBrand.js
index 25c6930b16f..7e91b9630f2 100644
--- a/src/facilities/bodyModification/createBrand.js
+++ b/src/facilities/bodyModification/createBrand.js
@@ -33,7 +33,7 @@ App.Medicine.Modification.Select.brand = function(slave, cheat = false) {
 					"Remove Brand",
 					() => {
 						delete slave.brand[brandPlace];
-						App.Medicine.Modification.Select.brand(slave, cheat); // Refresh display
+						refresh();
 					},
 				)
 			);
@@ -76,7 +76,7 @@ App.Medicine.Modification.Select.brand = function(slave, cheat = false) {
 			V.brandDesign.local,
 			v => {
 				V.brandDesign.local = v;
-				App.Medicine.Modification.Select.brand(slave, cheat); // Refresh display
+				refresh();
 			},
 		)
 	);
@@ -100,7 +100,7 @@ App.Medicine.Modification.Select.brand = function(slave, cheat = false) {
 			V.brandTarget.local,
 			v => {
 				V.brandTarget.local = v;
-				App.Medicine.Modification.Select.brand(slave, cheat); // Refresh display
+				refresh();
 			},
 		)
 	);
@@ -228,7 +228,7 @@ App.Medicine.Modification.Select.brand = function(slave, cheat = false) {
 		}
 	}
 	el.append(p);
-	return jQuery('#brand-selection').empty().append(el);
+	return el;
 
 	function symbolBlock(brandList) {
 		const div = document.createElement('div');
@@ -256,7 +256,7 @@ App.Medicine.Modification.Select.brand = function(slave, cheat = false) {
 					list[brand].displayName,
 					() => {
 						V.brandDesign.local = check(brand);
-						App.Medicine.Modification.Select.brand(slave, cheat); // Refresh display
+						refresh();
 					}
 				)
 			);
@@ -325,7 +325,7 @@ App.Medicine.Modification.Select.brand = function(slave, cheat = false) {
 					bodyPartObj[bp],
 					() => {
 						V.brandTarget.local = check(bp);
-						App.Medicine.Modification.Select.brand(slave, cheat); // Refresh display
+						refresh();
 					}
 				)
 			);
@@ -342,4 +342,8 @@ App.Medicine.Modification.Select.brand = function(slave, cheat = false) {
 				return brand;
 		}
 	}
+
+	function refresh() {
+		jQuery('#brand-selection').empty().append(App.Medicine.Modification.Select.brand(slave, cheat));
+	}
 };
-- 
GitLab