From 19968b1167a194a16cbaf3110c877f8644d953ec Mon Sep 17 00:00:00 2001 From: CloudyCoffee <megieboy@gmail.com> Date: Sat, 4 Sep 2021 23:59:18 +0200 Subject: [PATCH] - New qaudruped interface and changes. - Quadrupedal limbs are locked behind a prosthetic lab upgrade. - fixes --- .../slave variables documentation.md | 1 + devTools/types/FC/gameState.d.ts | 1 + devTools/types/FC/human.d.ts | 2 +- devTools/types/FC/medicine.d.ts | 4 +- js/003-data/slaveProstheticsData.js | 44 +++---- .../backwardsCompatibility.js | 2 +- src/events/REFS/refsWarhound.js | 2 +- src/facilities/penthouse/penthousePassage.js | 10 +- src/interaction/prostheticConfig.js | 18 +-- src/interaction/prostheticLab.js | 9 +- src/interaction/prostheticLabPassage.js | 46 ++++--- src/js/SlaveState.js | 6 +- src/js/statsChecker/limbChecker.js | 31 +++-- src/js/statsChecker/statsChecker.js | 2 +- src/npc/children/ChildState.js | 114 ++++++++++-------- src/npc/descriptions/descriptionWidgets.js | 58 +++++---- src/npc/descriptions/ears.js | 8 +- src/npc/descriptions/limbs.js | 14 ++- src/npc/startingGirls/startingGirls.js | 13 +- src/player/js/PlayerState.js | 1 + 20 files changed, 197 insertions(+), 189 deletions(-) diff --git a/devNotes/legacy files/slave variables documentation.md b/devNotes/legacy files/slave variables documentation.md index 4daddafe301..669b2081a5b 100644 --- a/devNotes/legacy files/slave variables documentation.md +++ b/devNotes/legacy files/slave variables documentation.md @@ -2119,6 +2119,7 @@ What level of prosthetic interface she has installed 0 - no interface 1 - basic interface 2 - advanced interface +3 - quadruped interface heels: diff --git a/devTools/types/FC/gameState.d.ts b/devTools/types/FC/gameState.d.ts index 4037fdb6bf6..370812e47dd 100644 --- a/devTools/types/FC/gameState.d.ts +++ b/devTools/types/FC/gameState.d.ts @@ -140,5 +140,6 @@ declare namespace FC { export interface GameVariables extends DefaultGameStateVariables, ResetOnNGPVariables, DeprecatedGameVariables, TemporaryVariablesInTheGameState { + oldLimbs: any; } } diff --git a/devTools/types/FC/human.d.ts b/devTools/types/FC/human.d.ts index 739cc96e85b..9c0ad1d005b 100644 --- a/devTools/types/FC/human.d.ts +++ b/devTools/types/FC/human.d.ts @@ -258,7 +258,7 @@ declare global { type EarWear = WithNone<"hearing aids" | "muffling ear plugs" | "deafening ear plugs">; type EarShape = WithNone<"damaged" | "normal" | "pointy" | "elven" | "cow" | "robot" | "orcish" | "sheep" | "deer" | "gazelle" | "bird" | "dragon">; - type EarT = WithNone<"normal" | "cat" | "leopard" | "tiger" | "jaguar" | "lion" | "dog" | "wolf" | "jackal" | "fox" | "raccoon" | "rabbit" | "squirrel"| "horse">; + type EarTopType = WithNone<"normal" | "cat" | "leopard" | "tiger" | "jaguar" | "lion" | "dog" | "wolf" | "jackal" | "fox" | "raccoon" | "rabbit" | "squirrel"| "horse">; type EyebrowStyle = "bald" | "curved" | "elongated" | "high-arched" | "natural" | "rounded" | "shaved" | "shortened" | "slanted inwards" | "slanted outwards" | "straight"; type EyebrowThickness = "pencil-thin" | "thin" | "threaded" | "natural" | "tapered" | "thick" | "bushy"; diff --git a/devTools/types/FC/medicine.d.ts b/devTools/types/FC/medicine.d.ts index aa7abc61dda..62fe597b017 100644 --- a/devTools/types/FC/medicine.d.ts +++ b/devTools/types/FC/medicine.d.ts @@ -1,9 +1,9 @@ declare namespace FC { - type prostheticID = "interfaceP1" | "interfaceP2" | "basicL" | "sexL" | "beautyL" | "combatL" | "felidaeL" | "canidaeL" | "felidaeCL" | "canidaeCL" | "cyberneticL" + type prostheticID = "interfaceP1" | "interfaceP2" | "interfaceP3" | "basicL" | "sexL" | "beautyL" | "combatL" | "felidaeL" | "canidaeL" | "felidaeCL" | "canidaeCL" | "cyberneticL" | "ocular" | "cochlear" | "electrolarynx" | "interfaceTail" | "modT" | "sexT" | "combatT" | "combatT2" |/* "erectile" |*/ "interfaceBack" | "modW" | "flightW" | "sexA" | "combatW" | "combatA1" | "combatA2"; - type prostheticName = "basic prosthetic interface" | "advanced prosthetic interface" | "set of basic prosthetic limbs" | "set of advanced sex limbs" + type prostheticName = "basic prosthetic interface" | "advanced prosthetic interface" | "advanced quadrupedal prosthetic interface" | "set of basic prosthetic limbs" | "set of advanced sex limbs" | "set of advanced beauty limbs" | "set of advanced combat limbs" | "set of quadruped feline limbs" | "set of quadruped canine limbs" | "set of feline combat limbs" | "set of canine combat limbs" | "set of cybernetic limbs" | "ocular implant" | "cochlear implant" | "electrolarynx" | "prosthetic tail interface" | "modular tail" | "pleasure tail" | "combat tail" | `combat tail, type "Stinger"` | "prosthetic back interface" | "modular pair of wings" | "pair of flight capable wings" diff --git a/js/003-data/slaveProstheticsData.js b/js/003-data/slaveProstheticsData.js index b105b00f4b5..f73fb6b58ac 100644 --- a/js/003-data/slaveProstheticsData.js +++ b/js/003-data/slaveProstheticsData.js @@ -4,7 +4,7 @@ * @type {FC.prostheticID[]} */ App.Data.prostheticIDs = - ["interfaceP1", "interfaceP2", "basicL", "sexL", "beautyL", "combatL", "felidaeL", "canidaeL", "felidaeCL", "canidaeCL", "cyberneticL", "ocular", "cochlear", + ["interfaceP1", "interfaceP2", "interfaceP3", "basicL", "sexL", "beautyL", "combatL", "felidaeL", "canidaeL", "felidaeCL", "canidaeCL", "cyberneticL", "ocular", "cochlear", "electrolarynx", "interfaceTail", "modT", "sexT", "combatT", "combatT2", /* "erectile",*/"interfaceBack", "modW", "flightW", "sexA", "combatW", "combatA1", "combatA2"]; /** * @typedef {object} prosthetics @@ -18,7 +18,7 @@ App.Data.prostheticIDs = * For all time values: 10 = 1 week without upgrades */ -/** +/** * @type {Object<FC.prostheticID, prosthetics>} */ App.Data.prosthetics = { @@ -38,6 +38,14 @@ App.Data.prosthetics = { level: 2, costs: 10000 }, + interfaceP3: { + name: "advanced quadrupedal prosthetic interface", + adjust: 60, + craft: 60, + research: 140, + level: 4, + costs: 10000 + }, basicL: { name: "set of basic prosthetic limbs", adjust: 40, @@ -75,7 +83,7 @@ App.Data.prosthetics = { adjust: 60, craft: 70, research: 140, - level: 2, + level: 4, costs: 20000 }, canidaeL: { @@ -83,7 +91,7 @@ App.Data.prosthetics = { adjust: 60, craft: 80, research: 140, - level: 2, + level: 4, costs: 15000 }, felidaeCL: { @@ -91,7 +99,7 @@ App.Data.prosthetics = { adjust: 100, craft: 80, research: 180, - level: 2, + level: 4, costs: 15000 }, canidaeCL: { @@ -99,7 +107,7 @@ App.Data.prosthetics = { adjust: 100, craft: 80, research: 180, - level: 2, + level: 4, costs: 20000 }, cyberneticL: { @@ -271,22 +279,6 @@ App.Data.modTails = new Map([ ["succubus", {animal: "Succubus", desc: "a long, slender succubus tail"}], ["dragon", {animal: "Dragon", desc: "a long, thick dragon tail"}] ]); - -App.Data.modWings = new Map([ - ["angel", {animal: "Angel", desc: "a pair of elegant angelic wings"}], - ["seraph", {animal: "Seraph", desc: "three pairs of majestic-looking angels wings"}], - ["demon", {animal: "Demon", desc: "a pair of sexy and sleek demonic wings"}], - ["dragon", {animal: "Dragon", desc: "a pair of imposing draconic wings"}], - ["phoenix", {animal: "Phoenix", desc: "a pair of magnificent, luminiscent phoenix wings"}], - ["bird", {animal: "Bird", desc: "a pair of feathered wings"}], - ["fairy", {animal: "Fairy", desc: "a pair of translucent, leaf-like fairy wings"}], - ["butterfly", {animal: "Butterfly", desc: "a pair of beautiful butterfly wings"}], - ["moth", {animal: "Moth", desc: "a pair of soft moth wings"}], - ["insect", {animal: "Insect", desc: "a pair of transparent insect wings"}], - ["evil", {animal: "Fiend", desc: "a pair of fiendish wings"}] - - -]); /** * @type {Map<FC.WingsShape, {animal: string, desc: string}>} */ @@ -345,22 +337,22 @@ App.Data.prostheticLimbs = new Map([ [7, { short: "quadruped feline", prostheticKey: "felidaeL", - minimumInterface: 1, + minimumInterface: 3, }], [8, { short: "quadruped canine", prostheticKey: "canidaeL", - minimumInterface: 1, + minimumInterface: 3, }], [9, { short: "feline combat", prostheticKey: "felidaeCL", - minimumInterface: 1, + minimumInterface: 3, }], [10, { short: "canine combat", prostheticKey: "canidaeCL", - minimumInterface: 1, + minimumInterface: 3, }], ]); diff --git a/src/data/backwardsCompatibility/backwardsCompatibility.js b/src/data/backwardsCompatibility/backwardsCompatibility.js index c2572868890..46ec9a8e7e3 100644 --- a/src/data/backwardsCompatibility/backwardsCompatibility.js +++ b/src/data/backwardsCompatibility/backwardsCompatibility.js @@ -1554,7 +1554,6 @@ App.Update.oldVersions = function(node) { /* unify cybermod & vanilla */ /* limbs */ if (V.releaseID < 1045) { - if (V.adjustProsthetics === "undefined") { V.adjustProsthetics = []; } if (typeof V.limbs !== "undefined") { V.adjustProsthetics = []; V.limbs.forEach((l) => { @@ -1826,6 +1825,7 @@ App.Update.oldVersions = function(node) { delete V.researchLab.erectileImplant; } } + if (V.adjustProsthetics === "undefined") { V.adjustProsthetics = []; } } if (V.releaseID < 1047) { if (V.loliGrow > 0) { diff --git a/src/events/REFS/refsWarhound.js b/src/events/REFS/refsWarhound.js index 2af988fc23c..1909a15a4b6 100644 --- a/src/events/REFS/refsWarhound.js +++ b/src/events/REFS/refsWarhound.js @@ -68,7 +68,7 @@ App.Events.refsWarhound = class refsWarhound extends App.Events.BaseEvent { slave.preg = -1; slave.collar = "tight steel"; slave.canRecruit = 0; - slave.custom.tattoo = `${He} has the Imperial symbol of your arcology tattooed on ${his} neck above a barcode.`; + slave.custom.tattoo = `$He has the Imperial symbol of your arcology tattooed above a barcode on $his neck.`; setHealth(slave, jsRandom(30, 60), 0, 0, 0, 0); App.Events.drawEventArt(node, slave); diff --git a/src/facilities/penthouse/penthousePassage.js b/src/facilities/penthouse/penthousePassage.js index b75b18b876c..1ab227c6bbe 100644 --- a/src/facilities/penthouse/penthousePassage.js +++ b/src/facilities/penthouse/penthousePassage.js @@ -291,7 +291,15 @@ App.UI.managePenthouse = function() { } break; case 3: - r.push(`You have basic equipment for attaching and maintenance of prosthetics and a contract to guarantee the availability of high-tech prosthetics.`); + r.push(`You have advanced equipment for attaching and maintenance of prosthetics and a contract to guarantee the availability of high-tech prosthetics.`); + if (V.rep > 18000) { + r.push(makeLink("Buy a contract for quadruped prosthetics", () => { V.prostheticsUpgrade = 4; }, 100000)); + } else { + r.push(App.UI.DOM.makeElement("span", "You lack the reputation to get a contract for qaudruped prosthetics.", "note")); + } + break; + case 4: + r.push(`You have advanced equipment for attaching and maintenance of prosthetics and a contract to guarantee the availability of qaudruped prosthetics.`); } App.Events.addNode(el, r, "div"); diff --git a/src/interaction/prostheticConfig.js b/src/interaction/prostheticConfig.js index cc3cd847252..6b562cd8ced 100644 --- a/src/interaction/prostheticConfig.js +++ b/src/interaction/prostheticConfig.js @@ -659,23 +659,11 @@ App.UI.prostheticsConfigPassage = function() { V.nextLink = "Prosthetics Configuration"; App.UI.DOM.appendNewElement("div", node, `Attaching ${his} tail is a simple procedure, you simply push the connector into a socket, right where ${his} tailbone ends, until the lock engages.`); r.push(`When you are done, ${he} looks back and`); - if (slave.tailShape === "cat") { + if (slave.tailShape === "cat" || slave.tailShape === "leopard" || slave.tailShape === "tiger" || slave.tailShape === "jaguar" || slave.tailShape === "lion") { r.push(`sways ${his} tail side to side enigmatically.`); - } else if (slave.tailShape === "leopard") { - r.push(`sways ${his} tail side to side enigmatically.`); - } else if (slave.tailShape === "tiger") { - r.push(`sways ${his} tail side to side enigmatically.`); - } else if (slave.tailShape === "jaguar") { - r.push(`sways ${his} tail side to side enigmatically.`); - } else if (slave.tailShape === "Lion") { - r.push(`sways ${his} tail side to side enigmatically.`); - } else if (slave.tailShape === "dog") { - r.push(`wags ${his} tail side to side energetically.`); - } else if (slave.tailShape === "wolf") { - r.push(`wags ${his} tail side to side energetically.`); - } else if (slave.tailShape === "jackal") { + } else if (slave.tailShape === "dog" || slave.tailShape === "wolf" || slave.tailShape === "jackal") { r.push(`wags ${his} tail side to side energetically.`); - } else if (slave.tailShape === "fox") { + }else if (slave.tailShape === "fox") { r.push(`slowly sways ${his} tail feeling the soft fur brush against ${his} skin.`); } else if (slave.tailShape === "kitsune") { r.push(`slowly sways ${his} tails luxuriating in the incredibly soft, fluffy fur brushing against ${his} skin.`); diff --git a/src/interaction/prostheticLab.js b/src/interaction/prostheticLab.js index 9613a4573c0..f083e24b6e6 100644 --- a/src/interaction/prostheticLab.js +++ b/src/interaction/prostheticLab.js @@ -3,9 +3,10 @@ */ globalThis.getProstheticsStockpile = function() { - return `<div>Prosthetics interfaces: ${num(V.prosthetics.interfaceP1.amount + V.prosthetics.interfaceP2.amount)}</div>` + + return `<div>Prosthetics interfaces: ${num(V.prosthetics.interfaceP1.amount + V.prosthetics.interfaceP2.amount + V.prosthetics.interfaceP3.amount)}</div>` + `<div class="choices">Basic: ${V.prosthetics.interfaceP1.amount}</div>` + `<div class="choices">Advanced: ${V.prosthetics.interfaceP2.amount}</div>` + + `<div class="choices">Quadruped: ${V.prosthetics.interfaceP3.amount}</div>` + `<div>Limbs: ${num(V.prosthetics.basicL.amount + V.prosthetics.sexL.amount + V.prosthetics.beautyL.amount + V.prosthetics.combatL.amount + V.prosthetics.cyberneticL.amount + V.prosthetics.felidaeL.amount + V.prosthetics.canidaeL.amount + V.prosthetics.felidaeCL.amount + V.prosthetics.canidaeCL.amount)}</div>` + `<div class="choices">Basic: ${V.prosthetics.basicL.amount}</div>` + @@ -30,9 +31,9 @@ globalThis.getProstheticsStockpile = function() { `<div class="choices">Combat Tail, "Stinger": ${V.prosthetics.combatT2.amount}</div>` + `<div>Back interface: ${V.prosthetics.interfaceBack.amount}</div>` + `<div>Appedages: ${num(V.prosthetics.modW.amount + V.prosthetics.flightW.amount + V.prosthetics.sexA.amount + V.prosthetics.combatW.amount + V.prosthetics.combatA1.amount + V.prosthetics.combatA2.amount)}</div>` + - `<div class="choices">ModularWings: ${V.prosthetics.modW.amount}</div>` + - `<div class="choices">AerialWings: ${V.prosthetics.flightW.amount}</div>` + - `<div class="choices">PleasureAppendages: ${V.prosthetics.sexA.amount}</div>` + + `<div class="choices">Modular Wings: ${V.prosthetics.modW.amount}</div>` + + `<div class="choices">Aerial Wings: ${V.prosthetics.flightW.amount}</div>` + + `<div class="choices">Pleasure Appendages: ${V.prosthetics.sexA.amount}</div>` + `<div class="choices">Combat Wings, "Falcon": ${V.prosthetics.combatW.amount}</div>` + `<div class="choices">Combat Appendages, "Arachnid": ${V.prosthetics.combatA1.amount}</div>` + `<div class="choices">Combat Appendages, "Kraken": ${V.prosthetics.combatA2.amount}</div>`; diff --git a/src/interaction/prostheticLabPassage.js b/src/interaction/prostheticLabPassage.js index bc3b76f0ee5..1733e9a84b0 100644 --- a/src/interaction/prostheticLabPassage.js +++ b/src/interaction/prostheticLabPassage.js @@ -237,22 +237,20 @@ App.UI.prostheticLab = function() { App.UI.DOM.appendNewElement("div", node, `Available research projects:`); for (let p of App.Data.prostheticIDs) { if (V.prosthetics[p].research === 0) { - if (p !== "erectile") { /* excludes erectile */ - // <div class="indent"> - if (App.Data.prosthetics[p].level <= V.prostheticsUpgrade) { - App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link( - `Reverse engineer ${addA(App.Data.prosthetics[p].name)}`, - () => { - cashX(forceNeg(App.Data.prosthetics[p].costs), "labResearch"); - V.prosthetics[p].research = -1; - V.researchLab.tasks.push({type: "research", id: p, workLeft: App.Data.prosthetics[p].research}); - App.UI.reload(); - }, [], "", - `Costs ${cashFormat(App.Data.prosthetics[p].costs)} of initial investment.` - ), "indent"); - } else { - App.UI.DOM.appendNewElement("div", node, `You need better contracts to get the required research material for reverse engineering ${addA(App.Data.prosthetics[p].name)}.`, "note"); - } + // <div class="indent"> + if (App.Data.prosthetics[p].level <= V.prostheticsUpgrade) { + App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link( + `Reverse engineer ${addA(App.Data.prosthetics[p].name)}`, + () => { + cashX(forceNeg(App.Data.prosthetics[p].costs), "labResearch"); + V.prosthetics[p].research = -1; + V.researchLab.tasks.push({type: "research", id: p, workLeft: App.Data.prosthetics[p].research}); + App.UI.reload(); + }, [], "", + `Costs ${cashFormat(App.Data.prosthetics[p].costs)} of initial investment.` + ), "indent"); + } else { + App.UI.DOM.appendNewElement("div", node, `You need better contracts to get the required research material for reverse engineering ${addA(App.Data.prosthetics[p].name)}.`, "note"); } } } @@ -262,15 +260,13 @@ App.UI.prostheticLab = function() { r.push(`Available building projects:`); for (let p of App.Data.prostheticIDs) { if (V.prosthetics[p].research === 1) { - if (p !== "erectile") { /* excludes erectile*/ - App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link( - `Build ${addA(App.Data.prosthetics[p].name)}`, - () => { - V.researchLab.tasks.push({type: "craft", id: p, workLeft: App.Data.prosthetics[p].craft}); - App.UI.reload(); - } - ), "indent"); - } + App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link( + `Build ${addA(App.Data.prosthetics[p].name)}`, + () => { + V.researchLab.tasks.push({type: "craft", id: p, workLeft: App.Data.prosthetics[p].craft}); + App.UI.reload(); + } + ), "indent"); } } diff --git a/src/js/SlaveState.js b/src/js/SlaveState.js index 324e7bfe06c..035efa33c1f 100644 --- a/src/js/SlaveState.js +++ b/src/js/SlaveState.js @@ -728,9 +728,9 @@ App.Entity.SlaveState = class SlaveState { * @type {FC.EarShape} */ this.earShape = "normal"; /** type of top ears if any - * @type {FC.EarT}*/ + * @type {FC.EarTopType}*/ this.earT = "none"; - /** kemonomimi ear color + /** top ear color * "hairless" */ this.earTColor = "hairless"; /** sense of smell @@ -746,7 +746,6 @@ App.Entity.SlaveState = class SlaveState { /** horn color */ this.hornColor = "none"; /** type of tail installed - * "none", "mod", "combat", "sex" * @type {FC.TailType}*/ this.tail = "none"; /** @@ -840,6 +839,7 @@ App.Entity.SlaveState = class SlaveState { * * 0: no interface * * 1: basic interface * * 2: advanced interface + * * 3: quadruped interface */ this.PLimb = 0; /* diff --git a/src/js/statsChecker/limbChecker.js b/src/js/statsChecker/limbChecker.js index 5c4cfdf7ff6..a323dad04b7 100644 --- a/src/js/statsChecker/limbChecker.js +++ b/src/js/statsChecker/limbChecker.js @@ -360,13 +360,13 @@ globalThis.idToDescription = function(id) { case 6: return "highly advanced cybernetic"; case 7: - return "advanced, quadruped feline prosthetic"; + return "feline prosthetic"; case 8: - return "advanced, quadruped canine prosthetic"; + return "canine prosthetic"; case 9: - return "advanced, feline combat-adapted prosthetic"; + return "feline combat-adapted prosthetic"; case 10: - return "advanced, canine combat-adapted prosthetic"; + return "canine combat-adapted prosthetic"; default: return "unknown id: " + id; } @@ -380,7 +380,7 @@ globalThis.idToDescription = function(id) { * * 3: sex * * 4: beauty * * 5: combat - * *6: cybernetic + * * 6: cybernetic * * 7: felidaeL * * 8: canidaeL * * 9: felidaeCL @@ -392,10 +392,9 @@ globalThis.idToDescription = function(id) { * * 103: sex-prosthetic * * 104: beauty-prosthetic * * 105: combat-prosthetic - * * 106: feline-structural - * * 107: canine-structural - * * 108: feline-combat - * * 109: canine-combat + * * 106: quadruped + * * 107: feline + * * 108: canine * * * * !!! I think I adjusted this right but i didn't spend too long on it so it might be wrong. !!! @@ -427,19 +426,17 @@ globalThis.getLimbCount = function(slave, id = 101) { case 102: return getLimbCount(slave, 2) + getLimbCount(slave, 3) + getLimbCount(slave, 4) + getLimbCount(slave, 5) + getLimbCount(slave, 6) + getLimbCount(slave, 7) + getLimbCount(slave, 8) + getLimbCount(slave, 9) + getLimbCount(slave, 10); case 103: - return getLimbCount(slave, 3) + getLimbCount(slave, 6) + getLimbCount(slave, 7) + getLimbCount(slave, 8) + getLimbCount(slave, 9) + getLimbCount(slave, 10); + return getLimbCount(slave, 3) + getLimbCount(slave, 6); case 104: - return getLimbCount(slave, 4) + getLimbCount(slave, 6) + getLimbCount(slave, 7) + getLimbCount(slave, 8) + getLimbCount(slave, 9) + getLimbCount(slave, 10); + return getLimbCount(slave, 4) + getLimbCount(slave, 6); case 105: - return getLimbCount(slave, 5) + getLimbCount(slave, 6) + getLimbCount(slave, 7) + getLimbCount(slave, 8) + getLimbCount(slave, 9) + getLimbCount(slave, 10); + return getLimbCount(slave, 5) + getLimbCount(slave, 6) + getLimbCount(slave, 9) + getLimbCount(slave, 10); case 106: - return getLimbCount(slave, 6) + getLimbCount(slave, 7) + getLimbCount(slave, 8) + getLimbCount(slave, 9) + getLimbCount(slave, 10); - case 107: return getLimbCount(slave, 7) + getLimbCount(slave, 8) + getLimbCount(slave, 9) + getLimbCount(slave, 10); + case 107: + return getLimbCount(slave, 7) + getLimbCount(slave, 9); case 108: - return getLimbCount(slave, 8) + getLimbCount(slave, 9) + getLimbCount(slave, 10); - case 109: - return getLimbCount(slave, 9) + getLimbCount(slave, 10); + return getLimbCount(slave, 8) + getLimbCount(slave, 10); } // unknown id defaults to 0 return 0; diff --git a/src/js/statsChecker/statsChecker.js b/src/js/statsChecker/statsChecker.js index 299b3620a85..37e904045ba 100644 --- a/src/js/statsChecker/statsChecker.js +++ b/src/js/statsChecker/statsChecker.js @@ -776,7 +776,7 @@ globalThis.canHold = function(slave) { if (!slave) { return null; } else if (hasAnyQuadrupedArms) { - return null; + return false; } return hasAnyArms(slave); }; diff --git a/src/npc/children/ChildState.js b/src/npc/children/ChildState.js index a8ab3526636..857d2f24d81 100644 --- a/src/npc/children/ChildState.js +++ b/src/npc/children/ChildState.js @@ -228,55 +228,71 @@ App.Facilities.Nursery.ChildState = class ChildState { /** Is there an inner ear implant device * 0: no; 1: yes */ this.earImplant = 0; - /** The shape of their outer ears - * "none", "damaged", "normal", "pointy", "elven", "ushi" */ - this.earShape = "normal"; - /** Type of kemonomimi ears if any - * "neko", "inu", "kit", "tanuki", "usagi" */ - this.earT = "none"; - /** Kemonomimi ear color - * "hairless" */ - this.earTColor = "hairless"; - /** Sense of smell - 0 - yes, -1 - no */ - this.smells = 0; - /** Sense of taste - 0 - yes, -1 - no */ - this.tastes = 0; - /** Horn type if any - * "none", "curved succubus horns", "backswept horns", "cow horns", "one long oni horn", "two long oni horns", "small horns" */ - this.horn = "none"; - /** Horn color */ - this.hornColor = "none"; - /** Type of tail installed - * "none", "mod", "combat", "sex"*/ - this.tail = "none"; - /** - * Does she have a tail interface installed - * * 0: no - * * 1: yes - * @type {FC.Bool} - */ - this.PTail = 0; - /** The current shape of their modular tail - * "none", "neko", "inu", "kit", "kitsune", "tanuki", "ushi", "usagi", "risu", "uma" */ - this.tailShape = "none"; - /** Tail color */ - this.tailColor = "none"; - /** Child's original hair color, defaults to their initial hair color. */ - this.origHColor = "brown"; - /** Hair color */ - this.hColor = "brown"; - /** Pubic hair color */ - this.pubicHColor = "brown"; - /** Armpit hair style */ - this.underArmHColor = "brown"; - /** eyebrowHColor*/ - this.eyebrowHColor = "brown"; - /** Child's original skin color. */ - this.origSkin = "light"; - /** Skin color */ - this.skin = "light"; + /** the shape of their outer ears + * @type {FC.EarShape} */ + this.earShape = "normal"; + /** type of top ears if any + * @type {FC.EarTopType}*/ + this.earT = "none"; + /** top ear color + * "hairless" */ + this.earTColor = "hairless"; + /** sense of smell + 0 - yes, -1 - no */ + this.smells = 0; + /** sense of taste + 0 - yes, -1 - no */ + this.tastes = 0; + /** horn type if any + * "none", "curved succubus horns", "backswept horns", "cow horns", "one long oni horn", "two long oni horns", "small horns" + * @type {FC.HornType} */ + this.horn = "none"; + /** horn color */ + this.hornColor = "none"; + /** type of tail installed + * @type {FC.TailType}*/ + this.tail = "none"; + /** + * Does she have a tail interface installed + * * 0: no + * * 1: yes + * @type {FC.Bool} + */ + this.PTail = 0; + /** the current shape of their modular tail + * @type {FC.TailShape} */ + this.tailShape = "none"; + /** tail color */ + this.tailColor = "none"; + /** type of dorsal appendages installed + * @type {FC.AppendagesType}*/ + this.appendages = "none"; + /** + * Does she have a back interface installed + * * 0: no + * * 1: yes + * @type {FC.Bool} + */ + this.PBack = 0; + /** the current shape of their modular wings + * @type {FC.WingsShape} */ + this.wingsShape = "none"; + /** tail color */ + this.appendagesColor = "none"; + /** slave's original hair color, defaults to their initial hair color. */ + this.origHColor = "brown"; + /** hair color */ + this.hColor = "brown"; + /** pubic hair color */ + this.pubicHColor = "brown"; + /** armpit hair style */ + this.underArmHColor = "brown"; + /** eyebrowHColor*/ + this.eyebrowHColor = "brown"; + /** Slave's original skin color. */ + this.origSkin = "light"; + /** skin color */ + this.skin = "light"; /** * hair length * * 150: calf-length diff --git a/src/npc/descriptions/descriptionWidgets.js b/src/npc/descriptions/descriptionWidgets.js index 53760cb94bb..5e322fd71e7 100644 --- a/src/npc/descriptions/descriptionWidgets.js +++ b/src/npc/descriptions/descriptionWidgets.js @@ -861,67 +861,63 @@ App.Desc.limbs = function(slave) { r += `${He} has ${idToDescription(getLeftArmID(slave))} limbs, making ${him} quadrupedal.`; } } else { - if (!hasAnyArms(slave) && !isQuadrupedal(slave)) { + if (!hasAnyArms(slave)) { r += `Both of ${his} arms have been amputated`; - } else if (!hasBothArms(slave)) { + } else if (!hasBothArms(slave) && !hasAnyQuadrupedArms(slave)) { if (hasLeftArm(slave)) { r += `${He} has ${addA(idToDescription(getLeftArmID(slave)))} left arm, but ${his} right has been amputated,`; } else { r += `${He} has ${addA(idToDescription(getRightArmID(slave)))} right arm, but ${his} left has been amputated,`; } - } else if (hasAnyQuadrupedArms(slave) && !isQuadrupedal(slave)) { - if (getLeftArmID(slave) > 6 && getRightArmID(slave) < 6) { - r += `${He} has ${addA(idToDescription(getLeftArmID(slave)))} left foreleg, but a mismatched ${addA(idToDescription(getRightArmID(slave)))} right arm that hinders ${him},`; - } else if (getLeftArmID(slave) < 6 && getRightArmID(slave) > 6) { - r += `${He} has ${addA(idToDescription(getRightArmID(slave)))} right foreleg, but a mismatched ${addA(idToDescription(getLeftArmID(slave)))} left arm that hinders ${him},`; - } - } else if (hasBothQuadrupedArms(slave) && isQuadrupedal(slave)) { - r += `${He} has ${addA(idToDescription(getLeftArmID(slave)))} left foreleg, ${addA(idToDescription(getRightArmID(slave)))} right foreleg,`; - } else if (hasBothQuadrupedArms(slave) && !isQuadrupedal(slave)) { - if (getLeftArmID(slave) === getRightArmID(slave)) { - r += `${He} has ${idToDescription(getLeftLegID(slave))} forelegs, with which she can't grab or hold anything,`; + } else if (!hasBothArms(slave) && hasAnyQuadrupedArms(slave)) { + if (hasLeftArm(slave)) { + r += `${He} has ${addA(idToDescription(getLeftArmID(slave)))} left foreleg, but ${his} right has been amputated,`; } else { - r += `${He} has ${addA(idToDescription(getLeftArmID(slave)))} left foreleg and ${addA(idToDescription(getRightArmID(slave)))} right foreleg, with which she can't grab or hold anything,`; + r += `${He} has ${addA(idToDescription(getRightArmID(slave)))} right foreleg, but ${his} left has been amputated,`; } + } else if (hasBothQuadrupedArms(slave) && isQuadrupedal(slave) && !(getLeftArmID(slave) === getRightArmID(slave))) { + r += `${He} has ${addA(idToDescription(getLeftArmID(slave)))} left foreleg, ${addA(idToDescription(getRightArmID(slave)))} right foreleg,`; + } else if (hasBothQuadrupedArms(slave) && isQuadrupedal(slave) && (getLeftArmID(slave) === getRightArmID(slave))) { + r += `${He} has ${idToDescription(getLeftLegID(slave))} forelegs, with which she can't grab or hold anything,`; } else { - if (getLeftArmID(slave) === getRightArmID(slave) && !isQuadrupedal(slave)) { + if (getLeftArmID(slave) === getRightArmID(slave) && !hasAnyQuadrupedArms(slave)) { r += `${He} has ${idToDescription(getLeftArmID(slave))} arms`; } else { r += `${He} has ${addA(idToDescription(getRightArmID(slave)))} right arm, but ${addA(idToDescription(getLeftArmID(slave)))} left arm`; } } r += ` and `; - if (!hasAnyLegs(slave) && !isQuadrupedal(slave)) { + if (!hasAnyLegs(slave)) { r += `both of ${his} legs have been amputated.`; - } else if (!hasBothLegs(slave)) { + } else if (!hasBothLegs(slave) && !hasAnyQuadrupedLegs(slave)) { if (hasLeftLeg(slave)) { r += `${he} has ${addA(idToDescription(getLeftLegID(slave)))} left leg, but ${his} right has been amputated.`; } else { r += `${he} has ${addA(idToDescription(getRightLegID(slave)))} right leg, but ${his} left has been amputated.`; } - } else if (hasAnyQuadrupedLegs(slave) && !isQuadrupedal(slave)) { - if (getLeftLegID(slave) > 6 && getRightLegID(slave) < 6) { - r += `${he} has ${addA(idToDescription(getLeftLegID(slave)))} left backleg, but a mismatched ${addA(idToDescription(getRightLegID(slave)))} right leg that hinders ${him} greatly,`; - } else if (getLeftArmID(slave) < 6 && getRightArmID(slave) > 6) { - r += `${he} has ${addA(idToDescription(getRightLegID(slave)))} right backleg, but a mismatched ${addA(idToDescription(getLeftLegID(slave)))} left leg that hinders ${him} greatly,`; - } - } else if (hasBothQuadrupedLegs(slave) && isQuadrupedal(slave)) { - r += ` ${addA(idToDescription(getLeftLegID(slave)))} left backleg, ${addA(idToDescription(getRightLegID(slave)))} right backleg.`; - } else if (hasBothQuadrupedLegs(slave) && !isQuadrupedal(slave)) { - if (getLeftLegID(slave) === getRightLegID(slave)) { - r += `${he} has ${idToDescription(getLeftLegID(slave))} backlegs, that make it difficult to walk.`; + } else if (!hasBothLegs(slave) && hasAnyQuadrupedLegs(slave)) { + if (hasLeftLeg(slave)) { + r += `${he} has ${addA(idToDescription(getLeftLegID(slave)))} left backleg, but ${his} right has been amputated.`; } else { - r += `${he} has ${addA(idToDescription(getLeftLegID(slave)))} left backleg and ${addA(idToDescription(getRightLegID(slave)))} right backleg, that make it difficult to walk.`; + r += `${he} has ${addA(idToDescription(getRightLegID(slave)))} right backleg, but ${his} left has been amputated.`; } + } else if (hasBothQuadrupedLegs(slave) && isQuadrupedal(slave) && !(getLeftLegID(slave) === getRightLegID(slave))) { + r += ` ${addA(idToDescription(getLeftLegID(slave)))} left backleg, ${addA(idToDescription(getRightLegID(slave)))} right backleg.`; + } else if (hasBothQuadrupedLegs(slave) && isQuadrupedal(slave) && (getLeftLegID(slave) === getRightLegID(slave))) { + r += `${he} has ${idToDescription(getLeftLegID(slave))} backlegs.`; } else { - if (getLeftLegID(slave) === getRightLegID(slave) && !isQuadrupedal(slave)) { + if (getLeftLegID(slave) === getRightLegID(slave) && !hasAnyQuadrupedLegs(slave)) { r += `${he} has ${idToDescription(getLeftLegID(slave))} legs.`; } else { r += `${he} has ${addA(idToDescription(getRightLegID(slave)))} right leg, but ${addA(idToDescription(getLeftLegID(slave)))} left leg.`; } } } - + if (hasAnyQuadrupedLimbs(slave) && !(getLeftArmID(slave) === getRightArmID(slave) && + getLeftArmID(slave) === getLeftLegID(slave) && + getLeftArmID(slave) === getRightLegID(slave))){ + r += `The nature of ${his} prosthetics force ${him} to walk like an qaudrupedal animal.`; + } return r; /* if (slave.am p) { diff --git a/src/npc/descriptions/ears.js b/src/npc/descriptions/ears.js index 9e5103fda53..cfa6d53261a 100644 --- a/src/npc/descriptions/ears.js +++ b/src/npc/descriptions/ears.js @@ -66,7 +66,7 @@ App.Desc.ears = function(slave) { } r.push(`${either(`tend to droop when ${he} is relaxed or sad`, `twitch at the slightest touch`)}.`); } else if (slave.earT === "leopard") { - r.push(`${He} has cute leopard ears, that are covered in soft ${slave.earTColor} fur and have black leopard spots; they`); + r.push(`${He} has cute leopard ears, they are ${slave.earTColor === "hairless" ? `hairless.` : `covered in soft ${slave.earTColor} fur and have black leopard spots`}; they`); if (slave.earImplant === 1) { r.push(`perk up at`); if (slave.devotion > 20) { @@ -77,7 +77,7 @@ App.Desc.ears = function(slave) { } r.push(`${either(`tend to droop when ${he} is relaxed or sad`, `twitch at the slightest touch`)}.`); } else if (slave.earT === "tiger") { - r.push(`${He} has pretty tiger ears on top of ${his} head; the ears are covered in dense ${slave.earTColor} fur and have distinct vertical stripes unique to ${him}. They`); + r.push(`${He} has pretty tiger ears on top of ${his} head; the ears are ${slave.earTColor === "hairless" ? "hairless but" : `covered in dense ${slave.earTColor} fur and`} have distinct vertical stripes unique to ${him}. They`); if (slave.earImplant === 1) { r.push(`perk up at`); if (slave.devotion > 20) { @@ -88,7 +88,7 @@ App.Desc.ears = function(slave) { } r.push(`${either(`tend to droop when ${he} is relaxed or sad`, `twitch at the slightest touch`)}.`); } else if (slave.earT === "jaguar") { - r.push(`${He} has adorable jaguar ears on top of ${his} head; the ears are covered in ${slave.earTColor} fur and packed with black rosettes with central dots. They`); + r.push(`${He} has adorable jaguar ears on top of ${his} head; the ears are ${slave.earTColor === "hairless" ? `hairless` : `covered in ${slave.earTColor} fur and packed with black rosettes with central dots`}. They`); if (slave.earImplant === 1) { r.push(`perk up at`); if (slave.devotion > 20) { @@ -99,7 +99,7 @@ App.Desc.ears = function(slave) { } r.push(`${either(`tend to droop when ${he} is relaxed or sad`, `twitch at the slightest touch`)}.`); } else if (slave.earT === "lion") { - r.push(`${He} has charming lion ears on ${his} head; the ears are covered in ${slave.earTColor} fur and have ${slave.hColor} fur at their base. They`); + r.push(`${He} has charming lion ears on ${his} head; the ears are ${slave.earTColor === "hairless" ? `hairless` : `covered in ${slave.earTColor} fur and have ${slave.hColor} fur at their base`}. They`); if (slave.earImplant === 1) { r.push(`perk up at`); if (slave.devotion > 20) { diff --git a/src/npc/descriptions/limbs.js b/src/npc/descriptions/limbs.js index 7e178a7646a..074d72ffeb5 100644 --- a/src/npc/descriptions/limbs.js +++ b/src/npc/descriptions/limbs.js @@ -51,6 +51,10 @@ App.Medicine.Limbs.amputate = function(slave, oldLimbs, returnTo) { implant = true; r.push(App.UI.DOM.makeElement("div", App.UI.DOM.link("Install advanced interface", () => install(2)))); } + if (slave.PLimb < 3 && isProstheticAvailable(slave, "interfaceP3")) { + implant = true; + r.push(App.UI.DOM.makeElement("div", App.UI.DOM.link("Install advanced quadruped interface", () => install(3)))); + } // check if we can install a limb interface and if yes, give player the option to do so. if (implant) { @@ -92,9 +96,9 @@ App.Medicine.Limbs.amputate = function(slave, oldLimbs, returnTo) { App.Medicine.Limbs.prosthetic = function(slave, oldLimbs, returnTo) { if (!(isProstheticAvailable(slave, "basicL") || isProstheticAvailable(slave, "sexL") || isProstheticAvailable(slave, "beautyL") || isProstheticAvailable(slave, "combatL") - || isProstheticAvailable(slave, "felidaeL") || isProstheticAvailable(slave, "canidaeL") - || isProstheticAvailable(slave, "felidaeCL") || isProstheticAvailable(slave, "canidaeCL") - || (isProstheticAvailable(slave, "cyberneticL") && slave.PLimb > 1))) { + || (isProstheticAvailable(slave, "cyberneticL") && slave.PLimb > 1) || (isProstheticAvailable(slave, "felidaeL") && slave.PLimb > 2) + || (isProstheticAvailable(slave, "canidaeL") && slave.PLimb > 2) || (isProstheticAvailable(slave, "felidaeCL") && slave.PLimb > 2) + || (isProstheticAvailable(slave, "canidaeCL") && slave.PLimb > 2))) { return App.Medicine.Limbs.reaction(slave, oldLimbs, returnTo); } const {him} = getPronouns(slave); @@ -269,8 +273,10 @@ App.Medicine.Limbs.selector = function(slave, oldLimbs, returnTo = "") { */ App.Medicine.Limbs.reaction = function(slave, oldLimbs, returnTo = "") { let r = ""; - if (oldLimbs.PLimb !== slave.PLimb) { + if (oldLimbs.PLimb !== slave.PLimb && slave.PLimb < 3) { r += `Prosthetic interface was ${oldLimbs.PLimb === 0 ? "none" : "basic"} and is now ${slave.PLimb === 1 ? "basic" : "advanced"}. `; + } else if (oldLimbs.PLimb !== slave.PLimb && slave.PLimb === 3) { + r += `Prosthetic interface was advanced and is now advanced quadruped. `; } if (getLeftArmID(oldLimbs) !== getLeftArmID(slave)) { r += `Left arm was ${idToDescription(getLeftArmID(oldLimbs))} and is now ${idToDescription(getLeftArmID(slave))}. `; diff --git a/src/npc/startingGirls/startingGirls.js b/src/npc/startingGirls/startingGirls.js index 0085a6b8812..6ec458214a0 100644 --- a/src/npc/startingGirls/startingGirls.js +++ b/src/npc/startingGirls/startingGirls.js @@ -768,6 +768,7 @@ App.StartingGirls.physical = function(slave, cheat = false) { ["None", 0], ["Basic", 1], ["Advanced", 2], + ["Quadruped", 3], ]); } @@ -788,14 +789,18 @@ App.StartingGirls.physical = function(slave, cheat = false) { ["Advanced: Sex", 3], ["Advanced: Beauty", 4], ["Advanced: Combat", 5], - ["Feline: Structural", 7], - ["Canine: Structural", 8], - ["Feline: Combat", 9], - ["Canine: Combat", 10], ]); if (slave.PLimb > 1) { option.addValue("Cybernetic", 6); } + if (slave.PLimb > 2) { + option.addValueList([ + ["Feline: Structural", 7], + ["Canine: Structural", 8], + ["Feline: Combat", 9], + ["Canine: Combat", 10], + ]); + } } } else { options.addCustomOption(`${capFirstChar(side)} ${limb}: amputated`) diff --git a/src/player/js/PlayerState.js b/src/player/js/PlayerState.js index aad6102cbb8..be79042f7de 100644 --- a/src/player/js/PlayerState.js +++ b/src/player/js/PlayerState.js @@ -522,6 +522,7 @@ App.Entity.PlayerState = class PlayerState { * * 0: no interface * * 1: basic interface * * 2: advanced interface + * * 3: quadruped interface */ this.PLimb = 0; /** -- GitLab