From b9f1c7626eaecb22cbb9ad073c3a6e530f9a3a3e Mon Sep 17 00:00:00 2001 From: lowercasedonkey <lowercasedonkey@gmail.com> Date: Mon, 4 Jan 2021 01:45:32 -0500 Subject: [PATCH] on to teeth --- src/005-passages/facilitiesPassages.js | 9 + .../surgery/remoteSurgeryPassage.js | 1418 +++++++++++++++++ 2 files changed, 1427 insertions(+) create mode 100644 src/facilities/surgery/remoteSurgeryPassage.js diff --git a/src/005-passages/facilitiesPassages.js b/src/005-passages/facilitiesPassages.js index 8aab5295314..d11f09ce738 100644 --- a/src/005-passages/facilitiesPassages.js +++ b/src/005-passages/facilitiesPassages.js @@ -77,3 +77,12 @@ new App.DomPassage("Toy Shop", return App.UI.toyShop(); }, ["jump-to-safe", "jump-from-safe"] ); + +new App.DomPassage("Remote Surgery", + (slave) => { + V.nextButton = "Confirm changes"; + V.nextLink = "Slave Interact"; + V.encyclopedia = "The Remote Surgery"; + return App.UI.remoteSurgery(slave); + }, ["jump-to-safe", "jump-from-safe"] +); diff --git a/src/facilities/surgery/remoteSurgeryPassage.js b/src/facilities/surgery/remoteSurgeryPassage.js new file mode 100644 index 00000000000..2e7ceeb792a --- /dev/null +++ b/src/facilities/surgery/remoteSurgeryPassage.js @@ -0,0 +1,1418 @@ +/** + * UI for performing surgery. Refreshes without refreshing the passage. + * @param {App.Entity.SlaveState} slave + * @returns {HTMLElement} + */ +App.UI.remoteSurgery = function(slave) { + const { + His, He, + his, he, him + } = getPronouns(slave); + const container = document.createElement("span"); + container.append(intro()); + container.append(displayWithTabs()); + + App.UI.tabBar.handlePreSelectedTab(V.tabChoice.Options); + + return container; + + function intro() { + const el = new DocumentFragment(); + const r = []; + + App.UI.DOM.appendNewElement("h1", el, "The Remote Surgery"); + + r.push(`${slave.slaveName} is lying strapped down on the table in your`); + if (V.surgeryUpgrade === 1) { + r.push(`heavily upgraded and customized`); + } + r.push(`remote surgery. The surgical equipment reads`); + if (getSlave(V.AS).health.health < -20) { + r.push(App.UI.DOM.makeElement("span", "SLAVE UNHEALTHY, SURGERY NOT RECOMMENDED.", "red")); + } else if (getSlave(V.AS).health.health <= 20) { + r.push(App.UI.DOM.makeElement("span", "SLAVE HEALTHY, SURGERY SAFE.", "yellow")); + } else { + r.push(App.UI.DOM.makeElement("span", "SLAVE HEALTHY, SURGERY ENCOURAGED.", "green")); + } + if (V.PC.skill.medicine >= 100) { + r.push(`The remote surgery mechanisms that allow a surgeon to be brought in by telepresence are inactive, and the autosurgery is ready for your control inputs. Surgery on your slaves is a challenge and a pleasure you wouldn't dream of sharing.`); + } + App.Events.addNode(el, r, "div"); + + if (getSlave(V.AS).indentureRestrictions >= 1) { + App.UI.DOM.appendNewElement("div", el, `This slave is subject to a restrictive indenture which forbids many invasive surgeries.`, "yellow"); + } + + return el; + } + + function hairAndFace() { + const el = new DocumentFragment(); + const _pubertyAge = Math.min(slave.pubertyAgeXX, slave.pubertyAgeXY); + let linkArray; + + App.Events.drawEventArt(el, slave); + App.UI.DOM.appendNewElement("h3", el, `Hair:`); + let r = []; + + // Main Hair + if (slave.bald === 0 && slave.hStyle !== "bald") { + App.UI.DOM.appendNewElement("div", el, `${He} naturally grows ${slave.origHColor} hair from ${his} head.`); + if (slave.indentureRestrictions > 1) { + App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]); + } else { + App.UI.DOM.appendNewElement("div", el, + makeLink( + `Surgically remove ${his} ability to grow hair`, + "hair removal", + () => { slave.bald = 1; }), + "note"); + } + } else { + App.UI.DOM.appendNewElement("div", el, `${He} is no longer capable of growing hair on ${his} head.`); + } + + // Eyebrows + if (slave.eyebrowHStyle !== "bald") { + App.UI.DOM.appendNewElement("div", el, `${He} has ${slave.origHColor} eyebrows.`); + if (slave.indentureRestrictions > 1) { + App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]); + } else { + App.UI.DOM.appendNewElement("div", el, + makeLink( + `Surgically remove ${his} ability to grow eyebrows`, + "eyebrow removal", + ), + "note"); + } + } else { + App.UI.DOM.appendNewElement("div", el, `${He} is no longer capable of growing eyebrow hair.`); + } + + // Armpit hair + r = []; + if ((slave.underArmHStyle !== "bald" && slave.underArmHStyle !== "hairless") || (slave.pubicHStyle !== "bald" && slave.pubicHStyle !== "hairless")) { + r.push(`${He}`); + if (slave.physicalAge >= _pubertyAge) { + r.push(`naturally grows`); + } else if (slave.physicalAge >= _pubertyAge - 1) { + r.push(`is beginning to grow`); + } else { + r.push(`will someday grow`); + } + r.push(`${slave.origHColor} body hair.`); + App.Events.addNode(el, r, "div"); + if (slave.indentureRestrictions > 1) { + App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]); + } else { + App.UI.DOM.appendNewElement("div", el, + makeLink( + `Surgically remove ${his} ability to grow body hair`, + "body hair removal", + ), + "note"); + } + } else { + r.push(`${His} ${slave.skin} skin is silky smooth and hair free from ${his} neck to ${his}`); + if (!hasAnyLegs(slave)) { + r.push(`hips.`); + } else { + r.push(`toes.`); + } + App.Events.addNode(el, r, "div"); + } + + + + App.UI.DOM.appendNewElement("h3", el, `Face:`); + const _artificiality = 25 - (5 * Math.trunc(V.PC.skill.medicine / 50)) - (5 * V.surgeryUpgrade); + r = []; + r.push(`${His} ${slave.faceShape} face is`); + if (slave.face < -95) { + r.push(`very ugly.`); + } else if (slave.face < -40) { + r.push(`ugly.`); + } else if (slave.face < -10) { + r.push(`unattractive.`); + } else if (slave.face <= 10) { + r.push(`quite average.`); + } else if (slave.face <= 40) { + r.push(`attractive.`); + } else if (slave.face <= 95) { + r.push(`beautiful.`); + } else if (slave.face > 95) { + r.push(`very beautiful.`); + } + + if (slave.faceImplant === 0) { + r.push(`It is entirely natural.`); + } else if (slave.faceImplant > 5) { + r.push(`It has seen some work.`); + } else if (slave.faceImplant > 30) { + r.push(`It has been totally reworked.`); + } + App.Events.addNode(el, r, "div"); + + if (slave.indentureRestrictions > 1) { + App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]); + } else if (slave.faceImplant > 95) { + App.UI.DOM.appendNewElement("div", el, `${His} face cannot sustain further cosmetic surgery`, ["choices", "note"]); + } else { + linkArray = []; + linkArray.push(makeLink( + `Surgically remove ${his} ability to grow eyebrows`, + "eyebrow removal", + )); + + if (slave.faceShape !== "normal") { + linkArray.push(makeLink( + `Make conventionally feminine`, + "face", + () => { + slave.faceShape = "normal"; + slave.faceImplant = Math.clamp(slave.faceImplant + _artificiality, 0, 100) + surgeryDamage(slave, 10) + } + )); + } + if (slave.faceShape === "masculine") { + linkArray.push(makeLink( + `Soften to androgynous`, + "face", + () => { + slave.faceShape = "androgynous"; + slave.faceImplant = Math.clamp(slave.faceImplant + _artificiality, 0, 100); + surgeryDamage(slave, 10); + } + )); + } else { + if (slave.faceShape !== "cute") { + linkArray.push(makeLink( + `Cute`, + "face", + () => { + slave.faceShape = "cute"; + slave.faceImplant = Math.clamp(slave.faceImplant + _artificiality, 0, 100); + surgeryDamage(slave, 10); + } + )); + } + if (slave.faceShape !== "exotic") { + linkArray.push(makeLink( + `Exotic`, + "face", + () => { + slave.faceShape = "exotic"; + slave.faceImplant = Math.clamp(slave.faceImplant + _artificiality, 0, 100); + surgeryDamage(slave, 10); + } + )); + } + if (slave.faceShape !== "sensual") { + linkArray.push(makeLink( + `Sensual`, + "face", + () => { + slave.faceShape = "sensual"; + slave.faceImplant = Math.clamp(slave.faceImplant + _artificiality, 0, 100); + surgeryDamage(slave, 10); + } + )); + } + if (slave.faceShape !== "androgynous") { + linkArray.push(makeLink( + `Androgynous`, + "face", + () => { + slave.faceShape = "androgynous"; + slave.faceImplant = Math.clamp(slave.faceImplant + _artificiality, 0, 100); + surgeryDamage(slave, 10); + } + )); + } else { + linkArray.push(makeLink( + `Masculine`, + "face", + () => { + slave.faceShape = "masculine"; + slave.faceImplant = Math.clamp(slave.faceImplant + _artificiality, 0, 100); + surgeryDamage(slave, 10); + } + )); + } + } + linkArray.push(makeLink( + `Just improve attractiveness`, + "face", + () => { + slave.faceImplant = Math.clamp(slave.faceImplant + _artificiality, 0, 100); + surgeryDamage(slave, 10); + } + )); + const links = App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices") + r = []; + r.push(`Facial surgery can either rework it and improve its attractiveness, or simply make it more attractive. No facial surgery is perfect and each surgery will make it look less natural.`); + if (V.PC.skill.medicine >= 100 && V.surgeryUpgrade) { + r.push(`Your surgical skills and the advanced surgical suite will minimize this effect as much as possible.`); + } else if (V.PC.skill.medicine >= 100) { + r.push(`Your surgical skills will reduce this effect.`); + } else if (V.surgeryUpgrade) { + r.push(`The advanced surgical suite will reduce this effect.`); + } + if (slave.faceImplant + _artificiality > 95) { + r.push(App.UI.DOM.makeElement("span", `${(slave.faceImplant !== 0) ? `Further facial` : `Facial`} surgery will create a severe uncanny valley effect.`, "yellow")); + } else if (slave.faceImplant + _artificiality > 60 && slave.faceImplant <= 60) { + r.push(App.UI.DOM.makeElement("span", `${(slave.faceImplant !== 0) ? `Further facial` : `Facial`}surgery will be extremely obvious.`, "yellow")); + } else if (slave.faceImplant + _artificiality > 30 && slave.faceImplant <= 30) { + r.push(App.UI.DOM.makeElement("span", `${(slave.faceImplant !== 0) ? `Further facial` : `Facial`} surgery will eliminate a natural appearance.`, "yellow")); + } else if (slave.faceImplant + _artificiality > 10 && slave.faceImplant <= 10) { + r.push(App.UI.DOM.makeElement("span", `${(slave.faceImplant !== 0) ? `Further facial` : `Facial`} surgery will disturb a perfectly natural appearance.`, "yellow")); + } else { + r.push(`A single facial surgery is not projected to significantly impact artificiality.`); + } + App.Events.addNode(el, r, "span", "note"); + } + + + if (slave.eyebrowHStyle !== "bald") { + App.UI.DOM.appendNewElement("div", el, `${He} has ${slave.origHColor} eyebrows.`); + if (slave.indentureRestrictions > 1) { + App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]); + } else { + App.UI.DOM.appendNewElement("div", el, + makeLink( + `Surgically remove ${his} ability to grow eyebrows`, + "eyebrow removal", + ), + "note"); + } + } else { + App.UI.DOM.appendNewElement("div", el, `${He} is no longer capable of growing eyebrow hair.`); + } + + + if (slave.indentureRestrictions < 2 && slave.faceImplant <= 95) { + if (slave.ageImplant > 1) { + App.UI.DOM.appendNewElement("div", el, `${He}'s had a multiple facelifts and other cosmetic procedures in an effort to preserve ${his} youth.`); + } else if ((slave.ageImplant > 0)) { + App.UI.DOM.appendNewElement("div", el, `${He}'s had a face lift and other minor cosmetic procedures to make ${him} look younger.`); + } else if ((slave.physicalAge >= 25) && (slave.visualAge >= 25)) { + App.UI.DOM.appendNewElement("div", el, `${He}'s old enough that a face lift and other minor cosmetic procedures could make ${him} look younger.`); + App.UI.DOM.appendNewElement("div", el, makeLink( + "Age lift", + "age", + () => { + applyAgeImplant(slave); + slave.faceImplant = Math.clamp(slave.faceImplant + _artificiality, 0, 100); cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave); + surgeryDamage(slave, 10); + } + ), "choices"); + + } + } + + /*Eyes*/ + //<div> + r.push(`${He} has ${App.Desc.eyesType(slave)}`); + if (hasAnyEyes(slave)) { + r.push(`, they are ${App.Desc.eyesVision(slave)}`); + } + r.push(`.`); + //<div class="choices"> + /* eye blur and fix */ + if (hasAnyEyes(slave)) { + /* Blur eyes*/ + if (slave.indentureRestrictions > 1) { + App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]); + } else { + linkArray = []; + if (getLeftEyeVision(slave) === 2 && getLeftEyeType(slave) === 1) { + linkArray.push(makeLink( + "Blur left eye", + "eyeBlur", + () => { + eyeSurgery(slave, "left", "blur"); + surgeryDamage(slave, 5); + } + )); + } + if (getRightEyeVision(slave) === 2 && getRightEyeType(slave) === 1) { + linkArray.push(makeLink( + "Blur right eye", + "eyeBlur", + () => { + eyeSurgery(slave, "right", "blur"); + surgeryDamage(slave, 5); + } + )); + } + if (linkArray.length === 2) { + linkArray.push(makeLink( + "Blur both eye", + "eyeBlur", + () => { + eyeSurgery(slave, "both", "blur"); + surgeryDamage(slave, 5); + } + )); + } + App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices"); + } + + /* Fix eyes */ + linkArray = []; + if (getLeftEyeVision(slave) === 1 && getLeftEyeType(slave) === 1) { + linkArray.push(makeLink( + "Fix left eye", + "eyeFix", + () => { + eyeSurgery(slave, "left", "fix"); + surgeryDamage(slave, 5); + } + )); + } + if (getRightEyeVision(slave) === 1 && getRightEyeType(slave) === 1) { + linkArray.push(makeLink( + "Fix right eye", + "eyeFix", + () => { + eyeSurgery(slave, "right", "fix"); + surgeryDamage(slave, 5); + } + )); + } + if (linkArray.length === 2) { + linkArray.push(makeLink( + "Fix both", + "eyeFix", + () => { + eyeSurgery(slave, "both", "fix"); + surgeryDamage(slave, 5); + } + )); + } + App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices"); + } + + if (V.seeExtreme === 1) { + if (slave.indentureRestrictions < 1) { + /* blind */ + linkArray = []; + if (getLeftEyeVision(slave) > 0 && getLeftEyeType(slave) === 1) { + linkArray.push(makeLink( + "Blind left eye", + "blind", + () => { + eyeSurgery(slave, "left", "blind"); + surgeryDamage(slave, 5); + } + )); + } + if (getRightEyeVision(slave) > 0 && getRightEyeType(slave) === 1) { + linkArray.push(makeLink( + "Blind right eye", + "blind", + () => { + eyeSurgery(slave, "right", "blind"); + surgeryDamage(slave, 5); + } + )); + } + if (linkArray.length === 2) { + linkArray.push(makeLink( + "Blind both eyes", + "blind", + () => { + eyeSurgery(slave, "both", "blind"); + surgeryDamage(slave, 5); + } + )); + } + App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices"); + + /* remove */ + linkArray = []; + if (hasLeftEye(slave)) { + linkArray.push(makeLink( + "Remove left eye", + "remove eyes", + () => { + eyeSurgery(slave, "left", "remove"); + surgeryDamage(slave, 5); + } + )); + } + if (hasRightEye(slave)) { + linkArray.push(makeLink( + "Remove right eye", + "remove eyes", + () => { + eyeSurgery(slave, "right", "remove"); + surgeryDamage(slave, 5); + } + )); + } + if (linkArray.length === 2) { + linkArray.push(makeLink( + "Remove both eyes", + "remove eyes", + () => { + eyeSurgery(slave, "both", "remove"); + surgeryDamage(slave, 5); + } + )); + } + App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices"); + /* implant */ + if (isProstheticAvailable(slave, "ocular")) { + //<div> + linkArray = []; + if (!hasLeftEye(slave)) { + linkArray.push(makeLink( + "Give left eye ocular implant", + "ocular implant", + () => { + eyeSurgery(slave, "left", "remove"); + surgeryDamage(slave, 5); + } + )); + } + if (!hasRightEye(slave)) { + linkArray.push(makeLink( + "Give right eye ocular implant", + "ocular implant", + () => { + eyeSurgery(slave, "right", "remove"); + surgeryDamage(slave, 5); + } + )); + } + if (linkArray.length === 2) { + linkArray.push(makeLink( + "Give eyes eyes ocular implants", + "ocular implant", + () => { + eyeSurgery(slave, "both", "remove"); + surgeryDamage(slave, 5); + } + )); + } + App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices"); + } + } + } + + + /*Regular Ears*/ + //<div> + r = []; + linkArray = [] + r.push(`${He} has`); + if (slave.earShape === "normal") { + r.push(`normal ears.`); + } else if (slave.earShape === "damaged") { + r.push(`damaged ears.`); + linkArray.push(makeLink( + "Repair", + "earRestore", + () => { + slave.earShape = "normal"; + surgeryDamage(slave, 10); + } + )); + } else if (slave.earShape === "pointy") { + r.push(`small elfin ears.`); + } else if (slave.earShape === "elven") { + r.push(`long elf ears.`); + } else if (slave.earShape === "ushi") { + r.push(`floppy cow ears.`); + } else if (slave.earShape === "none") { + r.push(`no ears.`); + } else { + r.push(`bugged ears. You done goofed. <span class="note">Report This//</span>`); + } + + //<div class="choices"> + if (slave.indentureRestrictions >= 2) { + App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]); + } else { + if (slave.earShape !== "normal" && slave.earShape !== "none") { + linkArray.push(makeLink( + "Restore to normal", + "earRestore", + () => { + slave.earShape = "normal"; + surgeryDamage(slave, 10); + } + )); + } + + if (slave.earShape !== "none" && V.seeExtreme === 1 && slave.indentureRestrictions < 1) { + linkArray.push(makeLink( + "Remove them", + "earGone", + () => { + surgeryAmp(slave, "left ear"); + surgeryAmp(slave, "right ear"); + surgeryDamage(slave, 20); + } + )); + } + if (slave.earShape === "none") { + //TODO: remove this BC code + if (slave.hears !== -2 && slave.earImplant !== 1) { + slave.hears = -1; + } + } else { + if (slave.earShape !== "pointy") { + linkArray.push(makeLink( + "Reshape into small elfin ears", + "earMinor", + () => { + slave.earShape = "pointy"; + surgeryDamage(slave, 10); + } + )); + } + if (V.surgeryUpgrade === 1) { + if (slave.earShape !== "elven") { + linkArray.push(makeLink( + "Reshape into long elf ears", + "earMajor", + () => { + slave.earShape = "elven"; + surgeryDamage(slave, 10); + } + )); + } + if (slave.earShape !== "ushi") { + linkArray.push(makeLink( + "Reshape into bovine ears", + "earMajor", + () => { + slave.earShape = "ushi"; + surgeryDamage(slave, 10); + } + )); + } + } + } + } + App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices"); + + /*Top Ears*/ + r = []; + linkArray = []; + r.push(`${He} has`); + if (slave.earT === "none") { + if (slave.earShape !== "none") { + r.push(`only one set of ears.`); + } else { + r.push(`no secondary ears.`); + } + } else if (slave.earT === "normal") { + if (slave.earShape !== "none") { + r.push(`a second pair of ears grafted to ${his} head.`); + } else { + r.push(`a pair of ears grafted to the top of ${his} head.`); + } + } else if (slave.earT === "neko") { + r.push(`a pair of cat ears adorning ${his} head.`); + } else if (slave.earT === "inu") { + r.push(`a pair of dog ears adorning ${his} head.`); + } else if (slave.earT === "kit") { + r.push(`a pair of fox ears adorning ${his} head.`); + } else if (slave.earT === "tanuki") { + r.push(`a pair of tanuki ears adorning ${his} head.`); + } else if (slave.earT === "usagi") { + r.push(`a pair of rabbit ears adorning ${his} head.`); + } else { + r.push(`You done goofed.`); + r.push(`<span class="note">Report This</span>`); + } + + if (slave.indentureRestrictions >= 2) { + App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]); + } else { + if (slave.earT !== "none" && V.seeExtreme === 1 && slave.indentureRestrictions < 1) { + linkArray.push(makeLink( + "Remove them", + "earGone", + () => { + slave.earT = "none" + surgeryDamage(slave, 20); + } + )); + } + if (slave.earT !== "neko") { + linkArray.push(makeLink( + "Reshape into cat Ears", + "earMajor", + () => { + slave.earT = "neko" + surgeryDamage(slave, 10); + } + )); + } + if (slave.earT !== "inu") { + linkArray.push(makeLink( + "Reshape into dog Ears", + "earMajor", + () => { + slave.earT = "inu" + surgeryDamage(slave, 10); + } + )); + } + if (slave.earT !== "kit") { + linkArray.push(makeLink( + "Reshape into fox Ears", + "earMajor", + () => { + slave.earT = "kit" + surgeryDamage(slave, 10); + } + )); + } + if (slave.earT !== "tanuki") { + linkArray.push(makeLink( + "Reshape into tanuki Ears", + "earMajor", + () => { + slave.earT = "tanuki" + surgeryDamage(slave, 10); + } + )); + } + if (slave.earT !== "usagi") { + linkArray.push(makeLink( + "Reshape into rabbit Ears", + "earMajor", + () => { + slave.earT = "usagi" + surgeryDamage(slave, 10); + } + )); + } + if (slave.earTColor === "hairless") { + r.push(`They are completely bald.`); + linkArray.push(makeLink( + "Implant hair mimicking fibers", + "earMinor", + () => { + slave.earTColor = slave.hColor + surgeryDamage(slave, 10); + } + )); + } else { + r.push(`They are covered by a multitude of implanted ${slave.earTColor} fibers mimicking hair.`); + linkArray.push(makeLink( + "Remove them", + "earMinor", + () => { + slave.earTColor = "hairless" + surgeryDamage(slave, 10); + } + )); + } + App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices"); + } + + /*Hearing*/ + r = []; + if (slave.earImplant === 1) { + r.push(`${He} has cochlear implants.`); + } else if (slave.hears <= -2) { + r.push(`${He} is deaf.`); + } else { + r.push(`${He} has working`); + if (slave.hears === -1) { + r.push(`inner ears, but is hearing impaired`); + if (slave.earShape === "none") { + r.push(`, likely due to missing the outer structure`); + } + r.push(`.`); + } else { + r.push(`ears and good hearing.`); + } + } + App.Events.addNode(el, r, "div"); + + //<div class="choices"> + if (slave.earImplant !== 1) { + if (slave.hears === -1) { + if (slave.earImplant !== 1 && slave.earShape !== "none") { + linkArray.push(makeLink( + "Correct hearing", + "earFix", + () => { + slave.hears = 0; + surgeryDamage(slave, 10); + } + )); + } + } else if (slave.hears === 0) { + if (V.seeExtreme === 1 && slave.earImplant !== 1 && slave.indentureRestrictions < 1) { + linkArray.push(makeLink( + "Muffle hearing", + "earMuffle", + () => { + slave.hears = -1; + surgeryDamage(slave, 10); + } + )); + } + } + } + + if (V.seeExtreme === 1 && slave.indentureRestrictions < 1) { + if (slave.earImplant === 0) { + if (slave.hears > -2) { + linkArray.push(makeLink( + "Deafen", + "deafen", + () => { + slave.hears = -2; + surgeryDamage(slave, 10); + } + )); + } + if (isProstheticAvailable(slave, "cochlear")) { + linkArray.push(makeLink( + `Give ${him} cochlear implants`, + "cochlear implant", + () => { + slave.earImplant = 1; + surgeryDamage(slave, 20); + } + )); + } + } + } + App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices"); + + /*Horns*/ + //<div> + r = [] + r.push(`${He} has`); + if (slave.horn === "none") { + r.push(`no horns.`); + } else { + r.push(`${slave.horn}.`); + } + App.Events.addNode(el, r, "div"); + //<div class="choices"> + if (slave.indentureRestrictions >= 2) { + App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]); + } else if (slave.horn === "none") { + linkArray = []; + if (slave.horn !== "curved succubus horns") { + linkArray.push(makeLink( + "Succubus horns", + "horn", + () => { + slave.horn = "curved succubus horns"; + slave.hornColor = "jet black" + surgeryDamage(slave, 10); + } + )); + } + if (slave.horn !== "backswept horns") { + linkArray.push(makeLink( + "Backswept horns", + "horn", + () => { + slave.horn = "backswept horns"; + slave.hornColor = "jet black" + surgeryDamage(slave, 10); + } + )); + } + if (slave.horn !== "cow horns") { + linkArray.push(makeLink( + "Bovine horns", + "horn", + () => { + slave.horn = "cow horns"; + slave.hornColor = "ivory" + surgeryDamage(slave, 10); + } + )); + } + if (slave.horn !== "one long oni horn") { + linkArray.push(makeLink( + "One oni horn", + "horn", + () => { + slave.horn = "one long oni horn"; + slave.hornColor = slave.skin; + surgeryDamage(slave, 10); + } + )); + } + if (slave.horn !== "two long oni horns") { + linkArray.push(makeLink( + "Two oni horns", + "horn", + () => { + slave.horn = "two long oni horns"; + slave.hornColor = slave.skin; + surgeryDamage(slave, 10); + } + )); + } + if (slave.horn !== "small horns") { + linkArray.push(makeLink( + "Small horns", + "horn", + () => { + slave.horn = "small horns"; + slave.hornColor = "ivory"; + surgeryDamage(slave, 10); + } + )); + } + } else if (slave.horn !== "one long oni horn") { + linkArray.push(makeLink( + "Remove them", + "hornGone", + () => { + surgeryAmp(slave, "horn") + } + )); + } else { + linkArray.push(makeLink( + "Remove it", + "hornGone", + () => { + surgeryAmp(slave, "horn") + } + )); + } + App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices"); + + /*Lips*/ + r = []; + linkArray = []; + r.push(`${He} has`); + if (slave.lips <= 10) { + r.push(`thin, unattractive lips.`); + } else if (slave.lips <= 20) { + r.push(`normal lips.`); + } else if (slave.lips <= 40) { + r.push(`full, attractive lips.`); + } else if (slave.lips <= 70) { + r.push(`plump, beestung lips.`); + } else if (slave.lips <= 95) { + r.push(`huge, obviously augmented lips.`); + } else { + r.push(`a facepussy: ${his} lips are so huge that they're always a bit parted in the middle, forming a moist, inviting hole for cock.`); + } + if (slave.lipsImplant === 0) { + } else if (slave.lipsImplant <= 10) { + r.push(`${He} has moderate lip implants.`); + } else if (slave.lipsImplant <= 20) { + r.push(`${He} has large lip implants.`); + } else { + r.push(`${He} has enormous lip implants.`); + } + r.push(App.UI.DOM.makeElement("span", `Installing implants will reduce ${his} oral skills`, "note")) + App.Events.addNode(el, r, "div"); + + if (slave.indentureRestrictions >= 2) { + App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]); + } else if ((slave.lips <= 75) || ((slave.lips <= 95) && (V.seeExtreme === 1))) { + if (slave.lipsImplant > 0) { + linkArray.push(makeLink( + "Replace with the next size up", + "lips", + () => { + slave.lipsImplant += 20; + slave.lips += 20 + surgeryDamage(slave, 10); + } + )); + } else { + linkArray.push(makeLink( + "Lip implant", + "lips", + () => { + slave.lipsImplant = 20; + slave.lips += 20 + surgeryDamage(slave, 10); + } + )); + } + } + if (slave.lipsImplant !== 0) { + if (slave.indentureRestrictions < 2) { + linkArray.push(makeLink( + "Remove lip implants", + "lips", + () => { + surgeryAmp(slave, "lips") + } + )); + } + } + if (slave.lips >= 10 && slave.lipsImplant === 0) { + if (slave.indentureRestrictions < 2) { + linkArray.push(makeLink( + "Reduce lips", + "lips", + () => { + slave.lips -= 10; + surgeryDamage(slave, 10);; + } + )); + } + } + + /*Teeth*/ + r = []; + linkArray = []; + const someNaturalteeth = new Set(["normal", "crooked", "gapped", "straightening braces", "cosmetic braces", "baby"]) + switch (slave.teeth) { + case "crooked": + r.push(`${He} has crooked teeth.`); + linkArray.push(makeLink( + "Apply braces", + "braces", + () => { + slave.teeth = "straightening braces" + } + )); + if (V.seeExtreme === 1 && slave.indentureRestrictions < 1) { + linkArray.push(makeLink( + "Replace them with removable prosthetics", + "teeth", + () => { + slave.teeth = "removable"; + surgeryDamage(slave, 20) + } + )); + linkArray.push(makeLink( + "Replace them with sharp teeth", + "teeth", + () => { + slave.teeth = "pointy"; + surgeryDamage(slave, 20) + } + )); + } + case "gapped": + r.push(`${He} has a noticeable gap in ${his} front teeth.`); + //<div class="choices"> + linkArray.push(makeLink( + "Apply braces", + "braces", + () => { + slave.teeth = "straightening braces"; + } + )); + if (V.seeExtreme === 1 && slave.indentureRestrictions < 1) { + linkArray.push(makeLink( + "Replace them with removable prosthetics", + "teeth", + () => { + slave.teeth = "removable"; + surgeryDamage(slave, 20); + } + )); + linkArray.push(makeLink( + "Replace them with sharp teeth", + "teeth", + () => { + slave.teeth = "pointy"; + surgeryDamage(slave, 20); + } + )); + } + case "straightening braces": + r.push(`${His} crooked teeth are in braces.`); + //<div class="choices"> + linkArray.push(makeLink( + "Remove braces", + "teeth", + () => { + slave.teeth = "crooked"; + } + )); + + + if (V.seeExtreme === 1) && (slave.indentureRestrictions < 1) { + linkArray.push(makeLink( + "Replace them with removable prosthetics", + "teeth", + () => { + slave.teeth = "removable"; + surgeryDamage(slave, 20); + } + )); + linkArray.push(makeLink( + "Replace them with sharp teeth", + "teeth", + () => { + slave.teeth = "pointy"; + surgeryDamage(slave, 20); + } + )); + } + //</div> + case "cosmetic braces": + r.push(`${He} has braces on ${his} straight teeth.`); + //<div class="choices"> + [[Remove braces | Remote Surgery][slave.teeth = "normal"]] + if (V.seeExtreme === 1) && (slave.indentureRestrictions < 1) { + linkArray.push(makeLink( + "Replace them with removable prosthetics", + "teeth", + () => { + slave.teeth = "removable"; + surgeryDamage(slave, 20); + } + )); + linkArray.push(makeLink( + "Replace them with sharp teeth", + "teeth", + () => { + slave.teeth = "pointy"; + surgeryDamage(slave, 20); + } + } + //</div> + case "removable": + r.push(`${He} has prosthetic teeth that can be removed for extreme oral sex.`); + //<div class="choices"> + if (V.seeExtreme === 1) && (slave.indentureRestrictions < 1) { + linkArray.push(makeLink( + "Replace them with sharp teeth", + "teeth", + () => { + slave.teeth = "pointy"; + surgeryDamage(slave, 20); + } + [[Normal dental implants | Surgery Degradation][slave.teeth = "normal", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 10), V.surgeryType = "oral"]] + } + //</div> + case "pointy": + r.push(`${His} teeth have been replaced with sturdy, realistic implants that mimic the dentition of a predator.`); + //<div class="choices"> + if (V.seeExtreme === 1) && (slave.indentureRestrictions < 1) { + linkArray.push(makeLink( + "Replace them with removable prosthetics", + "teeth", + () => { + slave.teeth = "removable"; + surgeryDamage(slave, 20); + } + )); + | + [[Normal dental implants | Surgery Degradation][slave.teeth = "normal", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 10), V.surgeryType = "oral"]] + } + //</div> + case "fangs": + r.push(`${His} upper canines have been replaced with sturdy, realistic implants that can only be described as vampiric.`); + //<div class="choices"> + if (V.seeExtreme === 1) && (slave.indentureRestrictions < 1) { + [[Replace them with removable prosthetics | Surgery Degradation][slave.teeth = "removable", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 20), V.surgeryType = "teeth"]] | + [[Remove a fang | Surgery Degradation][slave.teeth = "fang", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 20), V.surgeryType = "fang"]] | + [[Normal dental implants | Surgery Degradation][slave.teeth = "normal", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 10), V.surgeryType = "oral"]] + } + //</div> + case "fang": + r.push(`A single one of ${his} upper canines has been replaced with a sturdy, realistic implant shaped like a fang.`); + if (slave.lips <= 50) { + r.push(`It is occasionally visible over ${his} lower lip.`); + } + //<div class="choices"> + if (V.seeExtreme === 1) && (slave.indentureRestrictions < 1) { + [[Replace them with removable prosthetics | Surgery Degradation][slave.teeth = "removable", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 20), V.surgeryType = "teeth"]] | + [[Add another fang | Surgery Degradation][slave.teeth = "fangs", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 20), V.surgeryType = "fangs"]] | + [[Normal dental implants | Surgery Degradation][slave.teeth = "normal", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 10), V.surgeryType = "oral"]] + } + //</div> + case "baby": + r.push(`${He} has baby teeth.`); + //<div class="choices"> + if (V.seeExtreme === 1) && (slave.indentureRestrictions < 1) { + linkArray.push(makeLink( + "Replace them with removable prosthetics", + "teeth", + () => { + slave.teeth = "removable"; + surgeryDamage(slave, 20); + } + )); + linkArray.push(makeLink( + "Replace them with sharp teeth", + "teeth", + () => { + slave.teeth = "pointy"; + surgeryDamage(slave, 20); + } + | + [[Normal dental implants | Surgery Degradation][slave.teeth = "normal", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 10), V.surgeryType = "oral"]] + } + //</div> + case "mixed": + r.push(`${He} has a mix of baby and normal teeth.`); + //<div class="choices"> + if (V.seeExtreme === 1) && (slave.indentureRestrictions < 1) { + [[Replace them with removable prosthetics | Surgery Degradation][slave.teeth = "removable", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 20), V.surgeryType = "teeth"]] | + [[Replace them with sharp teeth | Surgery Degradation][slave.teeth = "pointy", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 20), V.surgeryType = "sharp"]] | + [[Normal dental implants | Surgery Degradation][slave.teeth = "normal", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 10), V.surgeryType = "oral"]] + } + //</div> + default: + r.push(`${He} has normal, healthy teeth.`); + //<div class="choices"> + [[Unnecessary braces | Surgery Degradation][slave.teeth = "cosmetic braces", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), V.surgeryType = "braces"]] + if (V.seeExtreme === 1) && (slave.indentureRestrictions < 1) { + | [[Replace them with removable prosthetics | Surgery Degradation][slave.teeth = "removable", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 20), V.surgeryType = "teeth"]] | + [[Replace them with sharp teeth | Surgery Degradation][slave.teeth = "pointy", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 20), V.surgeryType = "sharp"]] | + [[Replace them with fangs | Surgery Degradation][slave.teeth = "fangs", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 20), V.surgeryType = "fangs"]] | + [[Add a fang | Surgery Degradation][slave.teeth = "fang", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 20), V.surgeryType = "fang"]] | + } + //</div> + } + //</div> + + /*Voice*/ + //<div> + if (slave.electrolarynx === 1) { + r.push(`${He} has an artificial larynx.`); + } else { + if (slave.voice === 0) { + r.push(`${He} is mute.`); + } else if (slave.voice === 1) { + r.push(`${He} has a deep voice.`); + } else if (slave.voice === 2) { + r.push(`${He} has a feminine voice.`); + } else if (slave.voice === 3) { + r.push(`${He} has a high, girly voice.`); + } + if (slave.voiceImplant >= 1) { + r.push(`${He} has had surgery on ${his} voice box to raise ${his} voice.`); + } else if (slave.voiceImplant <= -1) { + r.push(`${He} has had surgery on ${his} voice box to lower ${his} voice.`); + } + } + if (slave.indentureRestrictions < 1) && (slave.electrolarynx !== 1) { + //<div class="choices"> + if (slave.voice !== 0) { + if (slave.voice < 3) { + [[Perform surgery to raise voice | Surgery Degradation][slave.voice += 1, slave.voiceImplant += 1, cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 10), V.surgeryType = "voice"]] + } + if (slave.voice === 2) { + | + } + if (slave.voice > 1) { + [[Perform surgery to lower voice | Surgery Degradation][slave.voice -= 1, slave.voiceImplant -= 1, cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 10), V.surgeryType = "voice2"]] + } + if (V.seeExtreme === 1) { + | [[Remove vocal cords | Surgery Degradation][surgeryAmp(slave, "voicebox"), V.surgeryType = "mute", cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave)]] + } + } else if (isProstheticAvailable(slave, "electrolarynx")) { + [["Give " + ${ him } + " an electrolarynx" | Surgery Degradation][slave.electrolarynx = 1, slave.voice = 2, cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 20), V.surgeryType = "electrolarynx"]] + } + //</div> + } + //</div> + + /*Smell*/ + //<div> + if (slave.smells === 0 && slave.tastes === 0) { + r.push(`${He} has a working chemosensory system.`); + } else if (slave.smells === 0) { + r.push(`${He} has a working olfactory system and an impaired gustatory system.`); + } else if (slave.tastes === 0) { + r.push(`${He} has a working gustatory system and an impaired olfactory system.`); + } else { + r.push(`${He} has an impaired chemosensory system.`); + } + if (slave.indentureRestrictions < 1) { + //<div class="choices"> + if (slave.smells === 0) && (V.seeExtreme === 1) { + [[Remove sense of smell | Surgery Degradation][slave.smells = -1, cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 10), V.surgeryType = "desmell"]] + } else if (slave.smells === -1) { + | [[Repair sense of smell | Surgery Degradation][slave.smells = 0, cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 10), V.surgeryType = "resmell"]] + } + if (slave.tastes === 0) && (V.seeExtreme === 1) { + | [[Remove sense of taste | Surgery Degradation][slave.tastes = -1, cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 10), V.surgeryType = "detaste"]] + } else if (slave.tastes === -1) { + | [[Repair sense of taste | Surgery Degradation][slave.tastes = 0, cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 10), V.surgeryType = "retaste"]] + } + //</div> + } + //</div> + + /*Scars*/ + //<div> + if (slave.scar["left cheek"]) { + r.push(`${He} has `); + V.App.Desc.expandScarString(slave, "left cheek") + r.push(` on ${his} left cheek.`); + //<div class="choices"> + [[Remove all scars there | Surgery Degradation][delete slave.scar["left cheek"], cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 5), V.surgeryType = "scarRemov"]] + //</div> + } else { + r.push(`${His} face is unscarred.`); + //<div class="choices"> + if (slave.indentureRestrictions > 1) { + //<span class="note">${His} indenture forbids elective surgery//</span> + } else { + [[Give a menacing scar | Surgery Degradation][App.Medicine.Modification.addScar(slave, "left cheek", "menacing"), cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 5), V.surgeryType = "scarFear"]] | + [[Give an exotic scar | Surgery Degradation][App.Medicine.Modification.addScar(slave, "left cheek", "exotic"), cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave), surgeryDamage(slave, 5), V.surgeryType = "scarExo"]] + } + //</div> + } + //</div> + //</div> + return el; + } + + function capacity() { + const el = new DocumentFragment(); + let r = []; + + App.Events.addNode(el, r, "div"); + return el; + } + + /** + * + * @param {string} title + * @param {string} surgeryType + * @param {function(void):void} [func] + * @param {number} [mult=1] + * @returns {HTMLAnchorElement} + */ + function makeLink(title, surgeryType, func, mult = 1) { + const cost = Math.trunc(mult * V.upgradeMultiplierArcology); + return App.UI.DOM.link( + title, + () => { + func(); + V.surgeryType = surgeryType; + cashX(forceNeg(V.surgeryCost * mult), "slaveSurgery", slave); + }, + [], + "Surgery Degredation", + `Costs ${cashFormat(cost)}` + ); + } + + function displayWithTabs() { + const el = new DocumentFragment(); + + /** + * @typedef {Object} siCategory + * @property {string} title + * @property {string} id + * @property {DocumentFragment|HTMLElement} node + * @property {Function} [onClick] + */ + + /** @type {Array<siCategory>} */ + const buttons = [ + { + title: "Hair and Face", + id: "hairAndFace", + get node() { return hairAndFace(); } + }, + { + title: "Upper", + id: "upper", + get node() { return upper(); } + }, + { + title: "Lower", + id: "lower", + get node() { return lower(); } + }, + { + title: "Race", + id: "race", + get node() { return race(); } + }, + { + title: "Structural", + id: "structural", + get node() { return structural(); } + }, + { + title: "Extreme Surgery", + id: "extremeSurgery", + get node() { return extremeSurgery(); } + }, + + ]; + + const tabBar = document.createElement("div"); + tabBar.classList.add("tab-bar"); + const tabContents = new DocumentFragment(); + + for (const item of buttons) { + tabBar.append(makeTabButton(item)); + tabContents.append(makeTabContents(item)); + } + + el.append(tabBar); + + App.Events.drawEventArt(el, slave); + + el.append(tabContents); + + return el; + + /** + * @param {siCategory} item + * @returns {HTMLElement} + */ + function makeTabButton(item) { + const btn = document.createElement("button"); + btn.className = "tab-links"; + btn.id = `tab ${item.id}`; + btn.innerHTML = item.title; + btn.onclick = (event) => { + App.UI.tabBar.openTab(event, item.id); + jQuery(`#content-${item.id}`).empty().append(item.node); + if (item.hasOwnProperty("onClick")) { + item.onClick(); + } + }; + + return btn; + } + /** + * @param {siCategory} item + * @returns {HTMLElement} + */ + function makeTabContents(item) { + const wrapperEl = document.createElement("div"); + wrapperEl.id = item.id; + wrapperEl.classList.add("tab-content"); + + const classEl = document.createElement("div"); + classEl.classList.add("content"); + + classEl.append(makeContentSpan(item)); + wrapperEl.append(classEl); + + return wrapperEl; + } + + /** + * @param {siCategory} item + * @returns {HTMLElement} + */ + function makeContentSpan(item) { + const uniqueContent = document.createElement("span"); + uniqueContent.id = `content-${item.id}`; + + uniqueContent.append(item.node); + return uniqueContent; + } + } +}; -- GitLab