diff --git a/src/interaction/prostheticConfig.tw b/src/interaction/prostheticConfig.tw index 7a732cfbff4c4bc42de8a75e58878723887f004d..6ab665cbe8c1c61220bbcbdd69ddfdd56ad0e4c9 100644 --- a/src/interaction/prostheticConfig.tw +++ b/src/interaction/prostheticConfig.tw @@ -148,67 +148,7 @@ This room is lined with shelves and cabinets, it could be easily mistaken for a <</if>> <</if>> -<<if $activeSlave.readyProsthetics.length > 0>> - <br><br> - <<if $activeSlave.fuckdoll != 0>> - // A Fuckdoll can't use prosthetic limbs. // - <<elseif hasAnyNaturalLimbs($activeSlave)>> - // $He must be a quadruple amputee to attach prosthetic limbs. // - <<elseif $activeSlave.PLimb == 0>> - // $He must have a prosthetic interface installed to attach prosthetic limbs. // - <<else>> - /* Currently prosthetics are all or nothing; will be changed */ - <<if getLeftArmID($activeSlave) > 1>> - //$He currently has - <<switch getLeftArmID($activeSlave)>> - <<case 2>> <<= addA(setup.prosthetics.basicL.name)>> - <<case 3>> <<= addA(setup.prosthetics.sexL.name)>> - <<case 4>> <<= addA(setup.prosthetics.beautyL.name)>> - <<case 5>> <<= addA(setup.prosthetics.combatL.name)>> - <<case 6>> <<= addA(setup.prosthetics.cyberneticL.name)>> - <</switch>> - installed.//<br> - <<link "Detach <<= $his>> limbs" "Prosthetics Configuration">> - <<set removeLimbs($activeSlave, "all"), $prostheticsConfig = "removeLimbs">> - <</link>> - <br><br> - <</if>> - /* TODO save .legsTat and .armsTat / link them to prosthetic*/ - <<if getLeftArmID($activeSlave) !== 2 && $activeSlave.readyProsthetics.findIndex(function(p) {return p.id == "basicL"}) != -1>> - <<link "Attach <<= addA(setup.prosthetics.basicL.name)>>" "Prosthetics Configuration">> - <<set removeLimbs($activeSlave, "all"), attachLimbs($activeSlave, "all", 2), $prostheticsConfig = "basicPLimbs">> - <</link>> - <br> - <</if>> - <<if getLeftArmID($activeSlave) !== 3 && $activeSlave.readyProsthetics.findIndex(function(p) {return p.id == "sexL"}) != -1>> - <<link "Attach <<= addA(setup.prosthetics.sexL.name)>>" "Prosthetics Configuration">> - <<set removeLimbs($activeSlave, "all"), attachLimbs($activeSlave, "all", 3), $prostheticsConfig = "sexPLimbs">> - <</link>> - <br> - <</if>> - <<if getLeftArmID($activeSlave) !== 4 && $activeSlave.readyProsthetics.findIndex(function(p) {return p.id == "beautyL"}) != -1>> - <<link "Attach <<= addA(setup.prosthetics.beautyL.name)>>" "Prosthetics Configuration">> - <<set removeLimbs($activeSlave, "all"), attachLimbs($activeSlave, "all", 4), $prostheticsConfig = "beautyPLimbs">> - <</link>> - <br> - <</if>> - <<if getLeftArmID($activeSlave) !== 5 && $activeSlave.readyProsthetics.findIndex(function(p) {return p.id == "combatL"}) != -1>> - <<link "Attach <<= addA(setup.prosthetics.combatL.name)>>" "Prosthetics Configuration">> - <<set removeLimbs($activeSlave, "all"), attachLimbs($activeSlave, "all", 5), $prostheticsConfig = "combatPLimbs">> - <</link>> - <br> - <</if>> - <<if getLeftArmID($activeSlave) !== 6 && $activeSlave.readyProsthetics.findIndex(function(p) {return p.id == "cyberneticL"}) != -1>> - <<if $activeSlave.PLimb == 2>> - <<link "Attach <<= addA(setup.prosthetics.cyberneticL.name)>>" "Prosthetics Configuration">> - <<set removeLimbs($activeSlave, "all"), attachLimbs($activeSlave, "all", 6), $prostheticsConfig = "cyberPLimbs">> - <</link>> - <<else>> - // $He must have <<= addA(setup.prosthetics.interfaceP2.name)>> installed to attach <<= addA(setup.prosthetics.cyberneticL.name)>>. // - <</if>> - <</if>> - <</if>> -<</if>> +<<= App.Desc.limbChange().selector($activeSlave, App.Desc.limbChange().currentLimbs($activeSlave))>> <<if $activeSlave.PTail == 1>><br><br> $He has a neural tail interface installed. You can assign and adjust $his tail here. @@ -342,6 +282,12 @@ Fit prosthetics to $him: $He has a panicked expression when $his vision suddenly goes out. <</if>> +<<case "limbs">> + <<set $prostheticsConfig = "main", $nextButton = "Continue", $nextLink = "Prosthetics Configuration">> + <<= App.Desc.limbChange().reaction($activeSlave, $oldLimbs)>> + <<unset $oldLimbs>> + +/* <<case "basicPLimbs">> <<set $prostheticsConfig = "main", $nextButton = "Continue", $nextLink = "Prosthetics Configuration">> Attaching $his limbs is a simple procedure, you simply push a connector on each limb into the socket in $his implants until the lock engages.<<if $activeSlave.PLimb == 2>> $He jumps a bit as limbs connect to $his nerves.<</if>> @@ -416,6 +362,7 @@ Fit prosthetics to $him: <<else>> You order $him to lie down on the table and proceed to remove $his limbs. $He <<if canSee($activeSlave)>>watches<<elseif canHear($activeSlave)>>listens<<else>>waits<</if>> with a bitter expression as you work. <</if>> +*/ <<case "hearing">> <<set $prostheticsConfig = "main", $nextButton = "Continue", $nextLink = "Prosthetics Configuration">> @@ -459,11 +406,12 @@ Fit prosthetics to $him: <<else>>admires $his new tail. <</if>> +/* <<case "interface">> <span id="attach"> <<set _first = 1>> /*TODO save .legsTat and .armsTat / link them to prosthetic*/ - <<if getLeftArmID($activeSlave) !== 2 && $activeSlave.readyProsthetics.findIndex(function(p) {return p.id == "basicL"}) != -1>> +/* <<if getLeftArmID($activeSlave) !== 2 && $activeSlave.readyProsthetics.findIndex(function(p) {return p.id == "basicL"}) != -1>> <<if _first>> <br><br>Since you already have prepared limbs for $him you might as well attach them while you are working on $him:<br> <<set _first = 0>> @@ -520,5 +468,5 @@ Fit prosthetics to $him: <</if>> <</if>> </span> - +*/ <</switch>> diff --git a/src/js/itemAvailability.js b/src/js/itemAvailability.js index 745ab63bda8def3556d0ce4fe20131075b0d6cc2..36923b4fe5a7c570b4acf37d16c9efc76058d301 100644 --- a/src/js/itemAvailability.js +++ b/src/js/itemAvailability.js @@ -169,3 +169,7 @@ window.isItemAccessible = function(string) { return true; } }; + +window.isProstheticAvailable = function(slave, prosthetic) { + return slave.readyProsthetics.findIndex(function(p) { return p.id === prosthetic; }) !== -1; +}; diff --git a/src/js/slaveStatsChecker.js b/src/js/slaveStatsChecker.js index 06f253d191daa9d06af349157ad6fac6d00eca77..0e52cc0a74f98ed23accf0a747991072f924acdb 100644 --- a/src/js/slaveStatsChecker.js +++ b/src/js/slaveStatsChecker.js @@ -1262,7 +1262,3 @@ window.armsAndLegs = function(slave, arms = "arms", arm = "arm", legs = "legs", return r; }; - -window.isProstheticAvailable = function(slave, prosthetic) { - return slave.readyProsthetics.findIndex(function(p) { return p.id === prosthetic; }) !== -1; -}; diff --git a/src/npc/descriptions/limbs.js b/src/npc/descriptions/limbs.js new file mode 100644 index 0000000000000000000000000000000000000000..798c9ec42a1e5cbb7afe2b990e82da78990f8b99 --- /dev/null +++ b/src/npc/descriptions/limbs.js @@ -0,0 +1,258 @@ +App.Desc.limbChange = function() { + return { + currentLimbs: currentLimbs, + amputate: amputate, + prosthetic: prosthetic, + selector: selector, + applySelector: applySelector, + reaction: reaction + }; + + /** + * Generates an object usable with the standard limb check functions. + * @param {App.Entity.SlaveState} slave + * @returns {{}} + */ + function currentLimbs(slave) { + let s = {arm: {left: {type: 1}, right: {type: 1}}, leg: {left: {type: 1}, right: {type: 1}}, PLimb: 0}; + if (hasLeftArm(slave)) { + s.arm.left.type = getLeftArmID(slave); + } else { + s.arm.left = null; + } + if (hasRightArm(slave)) { + s.arm.right.type = getRightArmID(slave); + } else { + s.arm.right = null; + } + if (hasLeftLeg(slave)) { + s.leg.left.type = getLeftLegID(slave); + } else { + s.leg.left = null; + } + if (hasRightLeg(slave)) { + s.leg.right.type = getRightLegID(slave); + } else { + s.leg.right = null; + } + s.PLimb = slave.PLimb; + return s; + } + + /** + * @param {App.Entity.SlaveState} slave + * @param {{}} oldLimbs + * @param {string} returnTo + * @returns {string} + */ + function amputate(slave, oldLimbs, returnTo) { + const {his} = getPronouns(slave); + let implant = false; + let r = ""; + + if (slave.PLimb < 1 && isProstheticAvailable(slave, "interfaceP1")) { + implant = true; + r += `<<link "Install basic interface">>` + + `<<set $activeSlave.PLimb = 1, $activeSlave.health -= 10>>` + + `<<replace "#amputate">><<= App.Desc.limbChange().prosthetic($activeSlave, ${JSON.stringify(oldLimbs)}, "${returnTo}")>><</replace>>` + + `<</link>>`; + } + if (slave.PLimb < 2 && isProstheticAvailable(slave, "interfaceP2")) { + if (implant) { + r += "<br>"; + } + implant = true; + r += `<<link "Install advanced interface">>` + + `<<set $activeSlave.PLimb = 2, $activeSlave.health -= 10>>` + + `<<replace "#amputate">><<= App.Desc.limbChange().prosthetic($activeSlave, ${JSON.stringify(oldLimbs)}, "${returnTo}")>><</replace>>` + + `<</link>>`; + } + + if (implant) { + return `<span id="amputate"> + 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} + <<link "Do not install">> + <<replace "#amputate">><<= App.Desc.limbChange().reaction($activeSlave, ${JSON.stringify(oldLimbs)}, "${returnTo}")>><</replace>> + <</link>> + </span>`; + } + + if (slave.PLimb > 0) { + return prosthetic(slave, oldLimbs, returnTo); + } + return reaction(slave, oldLimbs, returnTo); + } + + /** + * @param {App.Entity.SlaveState} slave + * @param {{}} oldLimbs + * @param {string} returnTo + * @returns {string} + */ + function prosthetic(slave, oldLimbs, returnTo) { + if (!(isProstheticAvailable(slave, "basicL") || isProstheticAvailable(slave, "sexL") + || isProstheticAvailable(slave, "beautyL") || isProstheticAvailable(slave, "combatL") + || (isProstheticAvailable(slave, "cyberneticL") && slave.PLimb > 1))) { + return reaction(slave, oldLimbs, returnTo); + } + const {him} = getPronouns(slave); + + let r = `<br>Since you already have limbs prepared for ${him} you might as well attach them while you are working on ${him}:` + + selector(slave, oldLimbs, returnTo); + + return `<span id="selector">${r}</span>`; + } + + /** + * Displays a selector for prosthetic limbs of $activeSlave + * @param {App.Entity.SlaveState} slave + * @param {{}} oldLimbs + * @param {string} [returnTo] + * @returns {string} + */ + function selector(slave, oldLimbs, returnTo = "") { + if (hasAllNaturalLimbs((slave))) { + return "//You must amputate your slaves limbs before you can attach prosthetics.//"; + } + if (slave.PLimb < 1) { + return "//You must install a prosthetic interface before you can attach prosthetics.//"; + } + const state = currentState(slave); + + /** + * Generates an array with the current limbs of a slave. + * @param {App.Entity.SlaveState} slave + * @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; + } + + /** + * @param {number} pos + * @param {number} id + * @returns {string} + */ + function entry(pos, id) { + if (state[pos] === 1) { + return "<div></div>"; + } + return `<div><<radiobutton "_newState[${pos}]" ${id}${state[pos] === id ? " checked" : ""}>></div>`; + } + + /** + * @param {string} title + * @param {number} id + * @returns {string} + */ + function row(title, id) { + return `<div>${title}</div>${entry(0, id)}${entry(1, id)}${entry(2, id)}${entry(3, id)}`; + } + + let r = "<div></div><div>Left Arm</div><div>Right Arm</div><div>Left Leg</div><div>Right Leg</div>"; + + 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='cyber' style='text-align: center;'>//Install an advanced interface to attach cybernetic limbs.//</div>"; + } + } + + r = `<br><br><<set _newState = [${state}]>>` + + "<style> .selector{display: grid; grid-template-columns: 200px 100px 100px 100px 100px;}" + + ".cyber {grid-column-start: 1; grid-column-end: 6;</style>" + + `<div class='selector'>${r}</div>${apply()}`; + + return r; + + function apply() { + let s; + if (!returnTo) { + s = `<<set $prostheticsConfig = "limbs", $oldLimbs = ${JSON.stringify(oldLimbs)}>>` + + '<<goto "Prosthetics Configuration">>'; + } else { + s = `<<replace "#selector">><<= App.Desc.limbChange().reaction($activeSlave, ${JSON.stringify(oldLimbs)}, "${returnTo}")>><</replace>>`; + } + + return `<<link "Apply">><<run App.Desc.limbChange().applySelector($activeSlave, _newState)>>${s}<</link>>`; + } + } + + /** + * + * @param {App.Entity.SlaveState} slave + * @param {[number]} newState + */ + function applySelector(slave, newState) { + if (getLeftArmID(slave) !== newState[0]) { + if (getLeftArmID(slave) > 1) { + removeLimbs(slave, "left arm"); + } + if (newState[0] > 1) { + attachLimbs(slave, "left arm", newState[0]); + } + } + if (getRightArmID(slave) !== newState[1]) { + if (getRightArmID(slave) > 1) { + removeLimbs(slave, "right arm"); + } + if (newState[1] > 1) { + attachLimbs(slave, "right arm", newState[1]); + } + } + if (getLeftLegID(slave) !== newState[2]) { + if (getLeftLegID(slave) > 1) { + removeLimbs(slave, "left leg"); + } + if (newState[2] > 1) { + attachLimbs(slave, "left leg", newState[2]); + } + } + if (getRightLegID(slave) !== newState[3]) { + if (getRightLegID(slave) > 1) { + removeLimbs(slave, "right leg"); + } + if (newState[3] > 1) { + attachLimbs(slave, "right leg", newState[3]); + } + } + } + + /** + * @param {App.Entity.SlaveState} slave + * @param {{}} oldLimbs + * @param {string} returnTo + * @returns {string} + */ + function reaction(slave, oldLimbs, returnTo = "") { + let r = "//Slave's reaction//"; + // TODO + // reaction based on limb change & devotion/trust + if (returnTo) { + r = `<br><br>${r}<br>[[Continue|${returnTo}]]`; + } + return r; + } +}; diff --git a/src/uncategorized/remoteSurgery.tw b/src/uncategorized/remoteSurgery.tw index 870d6ea06c218c2ab4f665a0bf6e35a8e41828a8..8a87314d014c1cdac7ea965898980321ee821eaa 100644 --- a/src/uncategorized/remoteSurgery.tw +++ b/src/uncategorized/remoteSurgery.tw @@ -1750,6 +1750,8 @@ Work on $him structurally: <<link "Amputate limb(s)">> <<set _atleastOne = 0>> + /* temporary story variable */ + <<set $oldLimbs = App.Desc.limbChange().currentLimbs($activeSlave)>> <<if _LA === 1>> <<run removeLimbs($activeSlave, "left arm")>> <<set _atleastOne++>> @@ -1771,26 +1773,24 @@ Work on $him structurally: <<if !hasAnyArms($activeSlave)>> <<set $activeSlave.releaseRules = "restrictive">> <</if>> - <<if !hasAnyNaturalLimbs($activeSlave) && (isProstheticAvailable($activeSlave, "interfaceP1") || isProstheticAvailable($activeSlave, "interfaceP2"))>> - <<set $surgeryType = "amp1">> - <<else>> - <<set $surgeryType = "amp">> - <</if>> + <<set $surgeryType = "amp">> <<goto "Surgery Degradation">> + <<else>> + <<unset $oldLimbs>> <</if>> <</link>> //This will greatly restrict $him.// <br> <</if>> /* extreme toggle */ -<<if isAmputee($activeSlave) && $activeSlave.PLimb == 0>> - <<if $activeSlave.readyProsthetics.findIndex(function(p) {return p.id == "interfaceP1"}) != -1>> | - [[Install basic prosthetic interface|Surgery Degradation][$activeSlave.PLimb = 1, cashX(forceNeg($surgeryCost), "slaveSurgery", $activeSlave), $activeSlave.health -= 20, $surgeryType = "PLimb interface1"]] +<<if !hasAllNaturalLimbs($activeSlave) && $activeSlave.PLimb == 0>> + <<if isProstheticAvailable($activeSlave, "interfaceP1")>> + [[Install basic prosthetic interface|Surgery Degradation][$oldLimbs = App.Desc.limbChange().currentLimbs($activeSlave), $activeSlave.PLimb = 1, cashX(forceNeg($surgeryCost), "slaveSurgery", $activeSlave), $activeSlave.health -= 20, $surgeryType = "PLimb interface"]] <</if>> - <<if $activeSlave.readyProsthetics.findIndex(function(p) {return p.id == "interfaceP2"}) != -1>> | - [[Install advanced prosthetic interface|Surgery Degradation][$activeSlave.PLimb = 2, cashX(forceNeg($surgeryCost), "slaveSurgery", $activeSlave), $activeSlave.health -= 20, $surgeryType = "PLimb interface2"]] + <<if isProstheticAvailable($activeSlave, "interfaceP2")>> | + [[Install advanced prosthetic interface|Surgery Degradation][$oldLimbs = App.Desc.limbChange().currentLimbs($activeSlave), $activeSlave.PLimb = 2, cashX(forceNeg($surgeryCost), "slaveSurgery", $activeSlave), $activeSlave.health -= 20, $surgeryType = "PLimb interface"]] <</if>> -<<elseif isAmputee($activeSlave) && $activeSlave.PLimb == 1 && $activeSlave.readyProsthetics.findIndex(function(p) {return p.id == "interfaceP2"}) != -1>> | - [[Upgrade advanced prosthetic interface|Surgery Degradation][$activeSlave.PLimb = 2, cashX(forceNeg($surgeryCost), "slaveSurgery", $activeSlave), $activeSlave.health -= 5, $surgeryType = "PLimb interface3"]] +<<elseif $activeSlave.PLimb == 1 && isProstheticAvailable($activeSlave, "interfaceP2")>> + [[Upgrade to advanced prosthetic interface|Surgery Degradation][$oldLimbs = App.Desc.limbChange().currentLimbs($activeSlave), $activeSlave.PLimb = 2, cashX(forceNeg($surgeryCost), "slaveSurgery", $activeSlave), $activeSlave.health -= 5, $surgeryType = "PLimb interface"]] <</if>> <br> diff --git a/src/uncategorized/surgeryDegradation.tw b/src/uncategorized/surgeryDegradation.tw index 8820520c09674f3c5862b3ccdd3ca6e1189d8e01..7b746d054ba044a05412f967a2334d060116864d 100644 --- a/src/uncategorized/surgeryDegradation.tw +++ b/src/uncategorized/surgeryDegradation.tw @@ -1842,6 +1842,17 @@ As the remote surgery's long recovery cycle completes, <</if>> <<case "amp">> + <<set $nextButton = " ">> + <<= App.Desc.limbChange().amputate($activeSlave, $oldLimbs, "Remote Surgery")>> + <<unset $oldLimbs>> + +<<case "PLimb interface">> + <<set $nextButton = " ">> + <<= App.Desc.limbChange().prosthetic($activeSlave, $oldLimbs, "Remote Surgery")>> + <<unset $oldLimbs>> + + /* +<<case "bla">> <<if $activeSlave.fetish == "mindbroken">> Of course, $he could not walk out of the surgery; you carried $him. $He squirms the entire time, trying to move the arms and legs $he now lacks. Since the surgery was invasive, @@.red;$his health has been greatly affected.@@ <<elseif ($activeSlave.devotion > 50)>> @@ -1882,6 +1893,7 @@ As the remote surgery's long recovery cycle completes, <<include "Prosthetics Configuration">> <<set $nextLink = "Remote Surgery">> + */ <<case "PLimb interface1">> When $he is carried out of surgery $he <<if canSee($activeSlave)>>cranes $his neck to better see the ports<<else>>wiggles $his stumps trying to feel the ports<</if>> installed in $his stumps. Recovery will be @@.red;significant,@@ since the surgical implantation of anchor points for the limbs themselves and the installation of nerve impulse detectors constituted major surgery.