diff --git a/js/003-data/slaveProstheticsData.js b/js/003-data/slaveProstheticsData.js index bc6709b76e961daf4ba592983a3d3d3590480e8d..a212d2ce48625aba23a24b1882e493fb6867198b 100644 --- a/js/003-data/slaveProstheticsData.js +++ b/js/003-data/slaveProstheticsData.js @@ -159,3 +159,46 @@ App.Data.modTails = new Map([ ["risu", {animal: "Squirrel", desc: "a large squirrel tail"}], ["uma", {animal: "Horse", desc: "a long horse tail"}] ]); + +/** + * TODO expand with beauty stats and similar + * + * @type {Map<number, {minimumInterface: number, prostheticKey: string, short: string}>} + */ +App.Data.limbs = new Map([ + /* TODO think about how to include these + [0, { + short: "None", + isProsthetic: false, + }], + [0, { + short: "Human", + isProsthetic: false, + }], + */ + [2, { + short: "basic prosthetic", + prostheticKey: "basicL", + minimumInterface: 1, + }], + [3, { + short: "advanced sex", + prostheticKey: "sexL", + minimumInterface: 1, + }], + [4, { + short: "advanced beauty", + prostheticKey: "beautyL", + minimumInterface: 1, + }], + [5, { + short: "advanced combat", + prostheticKey: "combatL", + minimumInterface: 1, + }], + [6, { + short: "cybernetic", + prostheticKey: "cyberneticL", + minimumInterface: 2, + }], +]); diff --git a/src/facilities/surgery/remoteSurgery.tw b/src/facilities/surgery/remoteSurgery.tw index f4627e8e7a2c70b0f11367e2faafb6c8b6367dc3..10eb2b11eaa4ec8482d3d216ff8c068a8b8d039c 100644 --- a/src/facilities/surgery/remoteSurgery.tw +++ b/src/facilities/surgery/remoteSurgery.tw @@ -897,7 +897,7 @@ <<link "Amputate limb(s)">> <<set _atleastOne = 0>> /* temporary story variable */ - <<set $oldLimbs = App.Desc.limbChange().currentLimbs(getSlave($AS))>> + <<set $oldLimbs = App.Medicine.Prosthetics.currentLimbs(getSlave($AS))>> <<if _LA === 1>> <<run removeLimbs(getSlave($AS), "left arm")>> <<set _atleastOne++>> @@ -931,13 +931,13 @@ <div> <<if !hasAllNaturalLimbs(getSlave($AS)) && getSlave($AS).PLimb == 0>> <<if isProstheticAvailable(getSlave($AS), "interfaceP1")>> - [[Install basic prosthetic interface|Surgery Degradation][$oldLimbs = App.Desc.limbChange().currentLimbs(getSlave($AS)), getSlave($AS).PLimb = 1, cashX(forceNeg($surgeryCost), "slaveSurgery", getSlave($AS)), surgeryDamage(getSlave($AS),20), $surgeryType = "PLimb interface"]] + [[Install basic prosthetic interface|Surgery Degradation][$oldLimbs = App.Medicine.Prosthetics.currentLimbs(getSlave($AS)), getSlave($AS).PLimb = 1, cashX(forceNeg($surgeryCost), "slaveSurgery", getSlave($AS)), surgeryDamage(getSlave($AS),20), $surgeryType = "PLimb interface"]] <</if>> <<if isProstheticAvailable(getSlave($AS), "interfaceP2")>> | - [[Install advanced prosthetic interface|Surgery Degradation][$oldLimbs = App.Desc.limbChange().currentLimbs(getSlave($AS)), getSlave($AS).PLimb = 2, cashX(forceNeg($surgeryCost), "slaveSurgery", getSlave($AS)), surgeryDamage(getSlave($AS),20), $surgeryType = "PLimb interface"]] + [[Install advanced prosthetic interface|Surgery Degradation][$oldLimbs = App.Medicine.Prosthetics.currentLimbs(getSlave($AS)), getSlave($AS).PLimb = 2, cashX(forceNeg($surgeryCost), "slaveSurgery", getSlave($AS)), surgeryDamage(getSlave($AS),20), $surgeryType = "PLimb interface"]] <</if>> <<elseif getSlave($AS).PLimb == 1 && isProstheticAvailable(getSlave($AS), "interfaceP2")>> - [[Upgrade to advanced prosthetic interface|Surgery Degradation][$oldLimbs = App.Desc.limbChange().currentLimbs(getSlave($AS)), getSlave($AS).PLimb = 2, cashX(forceNeg($surgeryCost), "slaveSurgery", getSlave($AS)), surgeryDamage(getSlave($AS),5), $surgeryType = "PLimb interface"]] + [[Upgrade to advanced prosthetic interface|Surgery Degradation][$oldLimbs = App.Medicine.Prosthetics.currentLimbs(getSlave($AS)), getSlave($AS).PLimb = 2, cashX(forceNeg($surgeryCost), "slaveSurgery", getSlave($AS)), surgeryDamage(getSlave($AS),5), $surgeryType = "PLimb interface"]] <</if>> </div> diff --git a/src/interaction/prostheticConfig.js b/src/interaction/prostheticConfig.js index 60026c83001d49b492d1a074368ecdf38419ff11..91fc869e063102e65a6be10f6964c5c71d935639 100644 --- a/src/interaction/prostheticConfig.js +++ b/src/interaction/prostheticConfig.js @@ -239,10 +239,7 @@ App.UI.prostheticsConfig = function(slave) { const f = document.createDocumentFragment(); App.UI.DOM.appendNewElement("h2", f, "Limbs"); - const p = document.createElement("p"); - p.classList.add("choices"); - jQuery(p).wiki(App.Desc.limbChange().selector(slave, App.Desc.limbChange().currentLimbs(slave))); - f.append(p); + App.UI.DOM.appendNewElement("p", f, App.Medicine.Prosthetics.selector(slave, App.Medicine.Prosthetics.currentLimbs(slave)), "choices"); return f; } diff --git a/src/interaction/prostheticConfig.tw b/src/interaction/prostheticConfig.tw index 869778cc426365dce8b3b4ee04997cf7f8947879..c26fc69341fc707febae20b65be828080cd36ecf 100644 --- a/src/interaction/prostheticConfig.tw +++ b/src/interaction/prostheticConfig.tw @@ -23,7 +23,7 @@ <<case "limbs">> <<set $prostheticsConfig = "main", $nextButton = "Continue", $nextLink = "Prosthetics Configuration">> - <<= App.Desc.limbChange().reaction(getSlave($AS), $oldLimbs)>> + <<includeDOM App.Medicine.Prosthetics.reaction(getSlave($AS), $oldLimbs)>> <<unset $oldLimbs>> /* diff --git a/src/npc/descriptions/limbs.js b/src/npc/descriptions/limbs.js index 8cc98f12efed0c9870497f79b8f3ac257e6f2a2a..3ed278edafea2863b396b554bd3ed2d454ecfb7b 100644 --- a/src/npc/descriptions/limbs.js +++ b/src/npc/descriptions/limbs.js @@ -1,4 +1,4 @@ -App.Desc.limbChange = function() { +App.Medicine.Prosthetics = (function() { return { currentLimbs: currentLimbs, amputate: amputate, @@ -11,7 +11,7 @@ App.Desc.limbChange = function() { /** * Generates an object usable with the standard limb check functions. * @param {App.Entity.SlaveState} slave - * @returns {{}} + * @returns {FC.LimbsState} */ function currentLimbs(slave) { let s = {arm: {left: {type: 1}, right: {type: 1}}, leg: {left: {type: 1}, right: {type: 1}}, PLimb: 0}; @@ -43,42 +43,48 @@ App.Desc.limbChange = function() { * @param {App.Entity.SlaveState} slave * @param {FC.LimbsState} oldLimbs * @param {string} returnTo - * @returns {string} + * @returns {Element|DocumentFragment} */ function amputate(slave, oldLimbs, returnTo) { const {his} = getPronouns(slave); - /** - * @param {number} id - */ - function install(id) { - slave.PLimb = id; - surgeryDamage(slave, 10); - App.UI.replace("#amputate", App.Desc.limbChange().prosthetic(slave, oldLimbs, returnTo)); - } - - function noInstall() { - App.UI.replace("#amputate", App.Desc.limbChange().reaction(slave, oldLimbs, returnTo)); - } + const r = []; let implant = false; - let r = ""; - if (slave.PLimb < 1 && isProstheticAvailable(slave, "interfaceP1")) { implant = true; - r += `<div>${App.UI.link("Install basic interface", install, [1])}</div>`; + r.push(App.UI.DOM.makeElement("div", App.UI.DOM.link("Install basic interface", () => install(1)))); } if (slave.PLimb < 2 && isProstheticAvailable(slave, "interfaceP2")) { implant = true; - r += `<div>${App.UI.link("Install advanced interface", install, [2])}</div>`; + r.push(App.UI.DOM.makeElement("div", App.UI.DOM.link("Install advanced interface", () => install(2)))); } + // check if we can install a limb interface and if yes, give player the option to do so. if (implant) { - return "<span id='amputate'>" + - `<div>Since you already have a prosthetic interface prepared for this slave, you can install it during the operation. The procedure will put additional strain on ${his} health but less so than if you were to perform the procedures separately.</div>` + - `${r}<div>${App.UI.link("Do not install", noInstall)}</div></span>`; + const outerDiv = document.createElement("div"); + outerDiv.id = "amputate"; + outerDiv.append( + App.UI.DOM.makeElement("div", `Since you already have a prosthetic interface prepared for this slave, you can install it during the operation. The procedure will put additional strain on ${his} health but less so than if you were to perform the procedures separately.`), + ...r, + App.UI.DOM.makeElement("div", App.UI.DOM.link("Do not install", noInstall))); + return outerDiv; } + /** + * @param {number} id + */ + function install(id) { + slave.PLimb = id; + surgeryDamage(slave, 10); + App.UI.DOM.replace("#amputate", App.Medicine.Prosthetics.prosthetic(slave, oldLimbs, returnTo)); + } + + function noInstall() { + App.UI.DOM.replace("#amputate", App.Medicine.Prosthetics.reaction(slave, oldLimbs, returnTo)); + } + + // check if there is a limb interface installed already, if there is show limb selection screen if (slave.PLimb > 0) { return prosthetic(slave, oldLimbs, returnTo); } @@ -89,7 +95,7 @@ App.Desc.limbChange = function() { * @param {App.Entity.SlaveState} slave * @param {FC.LimbsState} oldLimbs * @param {string} returnTo - * @returns {string} + * @returns {DocumentFragment|HTMLDivElement} */ function prosthetic(slave, oldLimbs, returnTo) { if (!(isProstheticAvailable(slave, "basicL") || isProstheticAvailable(slave, "sexL") @@ -99,28 +105,76 @@ App.Desc.limbChange = function() { } const {him} = getPronouns(slave); - let r = `<div>Since you already have limbs prepared for ${him} you might as well attach them while you are working on ${him}:</div>` + - selector(slave, oldLimbs, returnTo); + const div = document.createElement("div"); + div.id = "selector"; + + App.UI.DOM.appendNewElement("div", div, `Since you already have limbs prepared for ${him} you might as well attach them while you are working on ${him}:`); + div.append(selector(slave, oldLimbs, returnTo)); - return `<span id="selector">${r}</span>`; + return div; } /** * Displays a selector for prosthetic limbs of getSlave(V.AS) * @param {App.Entity.SlaveState} slave - * @param {{}} oldLimbs - * @param {string} [returnTo] - * @returns {string} + * @param {FC.LimbsState} oldLimbs + * @param {string} [returnTo=""] + * @returns {HTMLSpanElement|DocumentFragment} */ function selector(slave, oldLimbs, returnTo = "") { const {her} = getPronouns(slave); if (hasAllNaturalLimbs(slave)) { - return `<span class='detail'>You must amputate ${her} limbs before you can attach prosthetics.</span>`; + return App.UI.DOM.makeElement("span", `You must amputate ${her} limbs before you can attach prosthetics.`, "detail"); } if (slave.PLimb < 1) { - return "<span class='detail'>You must install a prosthetic interface before you can attach prosthetics.</span>"; + return App.UI.DOM.makeElement("span", `You must install a prosthetic interface before you can attach prosthetics.`, "detail"); + } + + const {his} = getPronouns(slave); + const newState = currentState(slave); + + const f = document.createDocumentFragment(); + + const limbSelector = document.createElement("div"); + limbSelector.classList.add("limb-selector"); + + App.UI.DOM.appendNewElement("div", limbSelector, ""); + App.UI.DOM.appendNewElement("div", limbSelector, "Left Arm"); + App.UI.DOM.appendNewElement("div", limbSelector, "Right Arm"); + App.UI.DOM.appendNewElement("div", limbSelector, "Left Leg"); + App.UI.DOM.appendNewElement("div", limbSelector, "Right Leg"); + + limbSelector.append(row("None", 0)); + App.Data.limbs.forEach((limb, key) => { + if (isProstheticAvailable(slave, limb.prostheticKey)) { + if (limb.minimumInterface <= slave.PLimb) { + limbSelector.append(row(capFirstChar(limb.short), key)); + } else { + App.UI.DOM.appendNewElement("div", limbSelector, + `You need to upgrade ${his} prosthetic interface to attach ${limb.short} limbs.`, ["full", "detail"]); + } + } + }); + + f.append(limbSelector); + f.append(apply()); + + return f; + + function apply() { + V.AS = slave.ID; + + return App.UI.DOM.link("Apply", () => { + App.Medicine.Prosthetics.applySelector(slave, newState); + if (returnTo) { + App.UI.DOM.replace("#selector", reaction(slave, oldLimbs, returnTo)); + } else { + V.prostheticsConfig = "limbs"; + V.oldLimbs = oldLimbs; + Engine.play("Prosthetics Configuration"); + } + }); } - const state = currentState(slave); /** * Generates an array with the current limbs of a slave. @@ -128,71 +182,48 @@ App.Desc.limbChange = function() { * @returns {number[]} */ function currentState(slave) { - let a = []; - a[0] = getLeftArmID(slave); - a[1] = getRightArmID(slave); - a[2] = getLeftLegID(slave); - a[3] = getRightLegID(slave); - return a; + return [getLeftArmID(slave), getRightArmID(slave), getLeftLegID(slave), getRightLegID(slave)]; } /** - * @param {number} pos + * @param {number} limb * @param {number} id - * @returns {string} + * @returns {HTMLDivElement} */ - function entry(pos, id) { - if (state[pos] === 1) { - return "<div></div>"; + function radio(limb, id) { + const div = document.createElement("div"); + + if (newState[limb] !== 1) { + const radio = document.createElement("input"); + radio.type = "radio"; + radio.name = "limb" + limb; + if (newState[limb] === id) { + radio.checked = true; + } + radio.onclick = () => { + newState[limb] = id; + }; + div.append(radio); } - return `<div><<radiobutton "_newState[${pos}]" ${id}${state[pos] === id ? " checked" : ""}>></div>`; + + return div; } /** * @param {string} title * @param {number} id - * @returns {string} + * @returns {DocumentFragment} */ function row(title, id) { - return `<div>${title}</div>${entry(0, id)}${entry(1, id)}${entry(2, id)}${entry(3, id)}`; - } + const f = document.createDocumentFragment(); - let r = "<div></div><div>Left Arm</div><div>Right Arm</div><div>Left Leg</div><div>Right Leg</div>"; + App.UI.DOM.appendNewElement("div", f, title); - r += row("None", 0); - if (isProstheticAvailable(slave, "basicL")) { - r += row("Basic prosthetic", 2); - } - if (isProstheticAvailable(slave, "sexL")) { - r += row("Advanced sex limb", 3); - } - if (isProstheticAvailable(slave, "beautyL")) { - r += row("Advanced beauty limb", 4); - } - if (isProstheticAvailable(slave, "combatL")) { - r += row("Advanced combat limb", 5); - } - if (isProstheticAvailable(slave, "cyberneticL")) { - if (slave.PLimb > 1) { - r += row("Cybernetic limb", 6); - } else { - r += "<div class='full'><span class='detail'>Install an advanced interface to attach cybernetic limbs.</span></div>"; + for (let i = 0; i < newState.length; i++) { + f.append(radio(i, id)); } - } - - return `<<set _newState = [${state}]>><div class='limb-selector'>${r}</div>${apply()}`; - function apply() { - let s; - V.AS = slave.ID; - if (!returnTo) { - s = `<<set $prostheticsConfig = "limbs", $oldLimbs = ${JSON.stringify(oldLimbs)}>>` + - '<<goto "Prosthetics Configuration">>'; - } else { - s = `<<replace "#selector">><<= App.Desc.limbChange().reaction(getSlave(${slave.ID}), ${JSON.stringify(oldLimbs)}, "${returnTo}")>><</replace>>`; - } - - return `<<link "Apply">><<run App.Desc.limbChange().applySelector(getSlave(${slave.ID}), _newState)>>${s}<</link>>`; + return f; } } @@ -240,7 +271,7 @@ App.Desc.limbChange = function() { * @param {App.Entity.SlaveState} slave * @param {FC.LimbsState} oldLimbs * @param {string} returnTo - * @returns {string} + * @returns {DocumentFragment} */ function reaction(slave, oldLimbs, returnTo = "") { let r = ""; @@ -260,14 +291,15 @@ App.Desc.limbChange = function() { r += `Right leg was ${idToDescription(getRightLegID(oldLimbs))} and is now ${idToDescription(getRightLegID(slave))}. `; } - r += "<br>"; + const f = document.createDocumentFragment(); + + App.UI.DOM.appendNewElement("p", f, r,); + App.UI.DOM.appendNewElement("p", f, "Slave's reaction", "note"); - r += "<span style='font-style: italic'>Slave's reaction</span>"; - // TODO - // reaction based on limb change & devotion/trust if (returnTo) { - r = `<br><br>${r}<br>[[Continue|${returnTo}]]`; + f.append(App.UI.DOM.passageLink("Continue", returnTo)); } - return r; + + return f; } -}; +})(); diff --git a/src/npc/surgery/surgeryDegradation.js b/src/npc/surgery/surgeryDegradation.js index 5c61c85c3f0d200043eb182324d02d38b513004b..4e3bc2bf43f1066d3dc759d496441dcde29c12a7 100644 --- a/src/npc/surgery/surgeryDegradation.js +++ b/src/npc/surgery/surgeryDegradation.js @@ -3485,16 +3485,12 @@ App.UI.SlaveInteract.surgeryDegradation = function(slave) { break; case "amp": V.nextButton = " "; - const ampFrag = jQuery(document.createDocumentFragment()); - ampFrag.wiki(App.Desc.limbChange().amputate(slave, V.oldLimbs, "Remote Surgery")); - r.push(ampFrag); + r.push(App.Medicine.Prosthetics.amputate(slave, V.oldLimbs, "Remote Surgery")); delete V.oldLimbs; break; case "PLimb interface": V.nextButton = " "; - const prosthFrag = jQuery(document.createDocumentFragment()); - prosthFrag.wiki(App.Desc.limbChange().prosthetic(slave, V.oldLimbs, "Remote Surgery")); - r.push(prosthFrag); + r.push(App.Medicine.Prosthetics.prosthetic(slave, V.oldLimbs, "Remote Surgery")); delete V.oldLimbs; break; /* diff --git a/src/uncategorized/multiImplant.tw b/src/uncategorized/multiImplant.tw index efea5291c3ccd01f0287538b5602b6aeeccc1c9c..2ecb17b0c920f3f006c67ab4841257494a8c51a4 100644 --- a/src/uncategorized/multiImplant.tw +++ b/src/uncategorized/multiImplant.tw @@ -139,38 +139,38 @@ that are ready be sent down. //Since $he must have a prosthetic interface installed to attach prosthetic limbs the <<= App.Data.prosthetics[_p.id].name>> will be put into storage.// <<else>> <<if _p.id == "basicL">> - <<set _state = App.Desc.limbChange().currentLimbs(getSlave($AS)), _change = upgradeLimbs(getSlave($AS), 2)>> + <<set _state = App.Medicine.Prosthetics.currentLimbs(getSlave($AS)), _change = upgradeLimbs(getSlave($AS), 2)>> <<if _change>> - <<= App.Desc.limbChange().reaction(getSlave($AS), _state)>> + <<includeDOM App.Medicine.Prosthetics.reaction(getSlave($AS), _state)>> <<else>> //Since $he already has more advanced prosthetic limbs attached the <<= App.Data.prosthetics.basicL.name>> will be put into storage.// <</if>> <<elseif _p.id == "sexL">> - <<set _state = App.Desc.limbChange().currentLimbs(getSlave($AS)), _change = upgradeLimbs(getSlave($AS), 3)>> + <<set _state = App.Medicine.Prosthetics.currentLimbs(getSlave($AS)), _change = upgradeLimbs(getSlave($AS), 3)>> <<if _change>> - <<= App.Desc.limbChange().reaction(getSlave($AS), _state)>> + <<includeDOM App.Medicine.Prosthetics.reaction(getSlave($AS), _state)>> <<else>> //Since $he already has advanced prosthetic limbs attached the <<= App.Data.prosthetics.sexL.name>> will be put into storage.// <</if>> <<elseif _p.id == "beautyL">> - <<set _state = App.Desc.limbChange().currentLimbs(getSlave($AS)), _change = upgradeLimbs(getSlave($AS), 4)>> + <<set _state = App.Medicine.Prosthetics.currentLimbs(getSlave($AS)), _change = upgradeLimbs(getSlave($AS), 4)>> <<if _change>> - <<= App.Desc.limbChange().reaction(getSlave($AS), _state)>> + <<includeDOM App.Medicine.Prosthetics.reaction(getSlave($AS), _state)>> <<else>> //Since $he already has advanced prosthetic limbs attached the <<= App.Data.prosthetics.beautyL.name>> will be put into storage.// <</if>> <<elseif _p.id == "combatL">> - <<set _state = App.Desc.limbChange().currentLimbs(getSlave($AS)), _change = upgradeLimbs(getSlave($AS), 5)>> + <<set _state = App.Medicine.Prosthetics.currentLimbs(getSlave($AS)), _change = upgradeLimbs(getSlave($AS), 5)>> <<if _change>> - <<= App.Desc.limbChange().reaction(getSlave($AS), _state)>> + <<includeDOM App.Medicine.Prosthetics.reaction(getSlave($AS), _state)>> <<else>> //Since $he already has advanced prosthetic limbs attached the <<= App.Data.prosthetics.combatL.name>> will be put into storage.// <</if>> <<else>> <<if getSlave($AS).PLimb == 2>> - <<set _state = App.Desc.limbChange().currentLimbs(getSlave($AS)), _change = upgradeLimbs(getSlave($AS), 2)>> + <<set _state = App.Medicine.Prosthetics.currentLimbs(getSlave($AS)), _change = upgradeLimbs(getSlave($AS), 2)>> <<if _change>> - <<= App.Desc.limbChange().reaction(getSlave($AS), _state)>> + <<includeDOM App.Medicine.Prosthetics.reaction(getSlave($AS), _state)>> <</if>> <<else>> //Since $he must have <<= addA(App.Data.prosthetics.interfaceP2.name)>> installed to attach cybernetic limbs the <<= App.Data.prosthetics.cyberneticL.name>> will be put into storage.//