diff --git a/src/004-base/organFarmBase.js b/src/004-base/organFarmBase.js index 11fd5eb80313f09d911d47f8f4eb7d04f1d9c0f2..b6e2c6a7e2627f9f63c7158e6ca6686452bc2ccf 100644 --- a/src/004-base/organFarmBase.js +++ b/src/004-base/organFarmBase.js @@ -8,8 +8,10 @@ App.Medicine.OrganFarm.Organ = class { * @param {function(App.Entity.SlaveState):boolean} canGrow * @param {string[]} dependencies - organs that are implanted first if possible, use type of other organs as values * @param {App.Medicine.OrganFarm.OrganImplantAction[]} actions + * @param {boolean} [displayMultipleActions=false] allow multiple implant links to be displayed */ - constructor({type: type, name, tooltip= "", cost, time, canGrow = () => true, dependencies = [], actions= []} = {}) { + constructor({type, name, tooltip = "", cost, time, canGrow = () => true, dependencies = [], + displayMultipleActions = false, actions = []} = {}) { this.type = type; this.name = name; this.tooltip = tooltip; @@ -19,6 +21,7 @@ App.Medicine.OrganFarm.Organ = class { this.canGrow = canGrow; /** @type {string[]} */ this.dependencies = dependencies; + this.displayMultipleActions = displayMultipleActions; /** @type {App.Medicine.OrganFarm.OrganImplantAction[]} */ this.implantActions = actions; diff --git a/src/gui/css/mainStyleSheet.css b/src/gui/css/mainStyleSheet.css index 47af08439aa425221b30d19aad0d3ea1023f235f..99a23af72c15df74833beeb920c99ff775bd56d1 100644 --- a/src/gui/css/mainStyleSheet.css +++ b/src/gui/css/mainStyleSheet.css @@ -409,3 +409,8 @@ div.center { div.flex-container { display: flex; } + +/* TODO unify tooltip systems */ +.hasTooltip { + text-decoration: underline; +} \ No newline at end of file diff --git a/src/npc/surgery/organFarm.js b/src/npc/surgery/organFarm.js index a1aafe6b95602ff4b32fc893d9000de38c122f55..ec09f300f84a86d33d04f80ef6e4c208088678df 100644 --- a/src/npc/surgery/organFarm.js +++ b/src/npc/surgery/organFarm.js @@ -85,49 +85,57 @@ App.Medicine.OrganFarm.growIncubatorOrgan = function(slave, organType) { /** * @param {App.Entity.SlaveState} slave - * @returns {string} + * @returns {DocumentFragment} */ App.Medicine.OrganFarm.implantActions = function(slave) { let slaveOrgans = V.completedOrgans.filter(o => o.ID === slave.ID); - if (slaveOrgans.length === 0) { return ""; } + if (slaveOrgans.length === 0) { return null; } const F = App.Medicine.OrganFarm; - let r = ""; + const grid = document.createElement("div"); + grid.classList.add("grid-2columns-auto"); for (const organ of slaveOrgans) { - r += `<div>${F.Organs[organ.type].name}:</div><div>`; + App.UI.DOM.appendNewElement("div", grid, F.Organs[organ.type].name); - let anyAction = false; - let lines = []; + let links = []; for (let i = 0; i < F.Organs[organ.type].implantActions.length; i++) { const action = F.Organs[organ.type].implantActions[i]; if (action.canImplant(slave)) { - const implantLink = App.UI.link(action.name, App.Medicine.OrganFarm.implant, [slave, organ.type, i], "Surgery Degradation"); - lines.push(`<span class="detail">${action.tooltip === "" ? "" : `${capFirstChar(action.tooltip)}: `}</span>${implantLink}`); - anyAction = true; - break; // there can only be one implant action + const link = App.UI.DOM.link(action.name, App.Medicine.OrganFarm.implant, [slave, organ.type, i], "Surgery Degradation"); + const tooltip = action.tooltip === "" ? "" : `${capFirstChar(action.tooltip)}.`; + if (tooltip !== "") { + link.title = tooltip; + link.classList.add("hasTooltip"); + } + links.push(link); + if (!F.Organs[organ.type].displayMultipleActions) { + break; // there can only be one implant action + } } else { const error = action.implantError(slave); if (error !== "") { - lines.push(`ERROR: ${error} `); + const disabledLink = document.createElement("span"); + disabledLink.append(action.name); + disabledLink.title = (error); + disabledLink.classList.add("hasTooltip"); + links.push(disabledLink); } } } - // each error on a new line - for (let i = 0; i < lines.length - 1; i++) { - r += `<div>${lines[i]}</div>`; + // all links in a row + const div = document.createElement("div"); + for (let i = 0; i < links.length; i++) { + div.append(links[i], " | "); } // last error or implant action has "Discard" after them. - r += `<div>${lines[lines.length - 1]}`; - if (anyAction) { - r += " | "; - } - r += `${App.UI.link("Discard", App.Medicine.OrganFarm.removeOrgan, [slave, organ.type], "Remote Surgery")}</div></div>`; + div.append(App.UI.DOM.link("Discard", App.Medicine.OrganFarm.removeOrgan, [slave, organ.type], "Remote Surgery")); + grid.append(div); } - return `The fabricator has completed ${slaveOrgans.length} organ(s):<div class="grid-2columns-auto">${r}</div>`; + return App.UI.DOM.combineNodes(`The fabricator has completed ${slaveOrgans.length} organ(s):`, grid); }; /** @@ -194,30 +202,34 @@ App.Medicine.OrganFarm.getSortedOrgans = function(slave) { * Returns the full organ farm menu, hiding empty parts * * @param {App.Entity.SlaveState} slave - * @returns {string} + * @returns {DocumentFragment} */ App.Medicine.OrganFarm.fullMenu = function(slave) { - if (V.organFarmUpgrade >= 1 && slave.indentureRestrictions < 2) { - let r = ""; - - let actions = App.Medicine.OrganFarm.growActions(slave); - if (actions !== "") { - r += `<h3>Grow new organs</h3><div class="indent">${actions}</div>`; - } + const fragment = document.createDocumentFragment(); + if (!(V.organFarmUpgrade >= 1 && slave.indentureRestrictions < 2)) { + return fragment; + } - actions = App.Medicine.OrganFarm.implantActions(slave); - if (actions !== "") { - r += `<h3>Implant organs</h3><div class="indent">${actions}</div>`; - } + let actions = App.Medicine.OrganFarm.growActions(slave); + let anyAction = false; + if (actions !== "") { + $(fragment).append(Wikifier.wikifyEval(`<h3>Grow new organs</h3><div class="indent">${actions}</div>`)); + anyAction = true; + } - if (r === "") { - return ""; - } + actions = App.Medicine.OrganFarm.implantActions(slave); + if (actions !== null) { + App.UI.DOM.appendNewElement("h3", fragment, "Implant Organs"); + App.UI.DOM.appendNewElement("div", fragment, actions, "indent"); + anyAction = true; + } - return `<h2>Organ Farm</h2>${r}`; - } else { - return ""; + if (!anyAction) { + return fragment; } + + fragment.prepend(App.UI.DOM.makeElement("h2", "Organ Farm")); + return fragment; }; App.Medicine.OrganFarm.currentlyGrowing = function() { diff --git a/src/npc/surgery/organs.js b/src/npc/surgery/organs.js index 4861d11cc80f5dc7ed0214eb84de400eecf4acb7..8401afec4f33f5c39ccc3ed0cab2cf7ec2ea634b 100644 --- a/src/npc/surgery/organs.js +++ b/src/npc/surgery/organs.js @@ -387,7 +387,7 @@ App.Medicine.OrganFarm.init = function() { }); new App.Medicine.OrganFarm.Organ({ - type: "hair", name: "Hair Follicles", cost: 500, time: 2, + type: "hair", name: "Hair Follicles", cost: 500, time: 2, displayMultipleActions: true, actions: [ new App.Medicine.OrganFarm.OrganImplantAction({ name: "Scalp", healthImpact: 10, surgeryType: "restoreHairHead", @@ -424,7 +424,7 @@ App.Medicine.OrganFarm.init = function() { name: "Brow", healthImpact: 5, surgeryType: "restoreHairBrow", autoImplant: false, canImplant: s => (s.eyebrowHStyle === "bald"), - implantError: () => "This slave already has eyebrows.", + implantError: () => "", implant: s => { s.eyebrowHStyle = "natural"; s.eyebrowFullness = "natural"; @@ -435,7 +435,7 @@ App.Medicine.OrganFarm.init = function() { name: "Axillary", healthImpact: 5, surgeryType: "restoreHairPits", autoImplant: false, canImplant: s => (s.underArmHStyle === "bald" || s.underArmHStyle === "hairless"), - implantError: () => "This slave already has underarm hair.", + implantError: () => "", implant: s => { s.underArmHStyle = "bushy"; s.underArmHColor = s.origHColor; @@ -445,7 +445,7 @@ App.Medicine.OrganFarm.init = function() { name: "Pubic", healthImpact: 5, surgeryType: "restoreHairPubes", autoImplant: false, canImplant: s => (s.pubicHStyle === "bald" || s.pubicHStyle === "hairless"), - implantError: () => "This slave already has pubic hair.", + implantError: () => "", implant: s => { s.pubicHStyle = "very bushy"; s.pubicHColor = s.origHColor; diff --git a/src/npc/surgery/reproductiveOrgans.js b/src/npc/surgery/reproductiveOrgans.js index d0b4ae72f263adeceb761699ea38481cc2bdc035..bdf1598930b4e38f4aec53ed754ee5b179e9f2f3 100644 --- a/src/npc/surgery/reproductiveOrgans.js +++ b/src/npc/surgery/reproductiveOrgans.js @@ -70,7 +70,7 @@ App.Medicine.OrganFarm.Testicles = class extends App.Medicine.OrganFarm.Organ { }), new App.Medicine.OrganFarm.TesticlesImplantAction({ name: "Implant", - tooltip: "you can forgo standard procedure and implant testicles directly into $his abdomen", + tooltip: "you can forgo standard procedure and implant testicles directly into their abdomen", ballType: ballType, animal: animal, surgeryType: "addTesticles", autoImplant: false, canImplant: slave => (slave.dick === 0 && slave.balls <= 0), implantError: slave => ((slave.balls > 0) ? "This slave already has testicles." : ""), diff --git a/src/uncategorized/remoteSurgery.tw b/src/uncategorized/remoteSurgery.tw index 44958ba77558e1cfdc28bc4f8c025719682cda91..66cece0c3f6c9af68874cd534ce07a8a6b3dcf2c 100644 --- a/src/uncategorized/remoteSurgery.tw +++ b/src/uncategorized/remoteSurgery.tw @@ -2084,7 +2084,7 @@ <</if>> </div> - <<print App.Medicine.OrganFarm.fullMenu(getSlave($AS))>> + <<includeDOM App.Medicine.OrganFarm.fullMenu(getSlave($AS))>> <<if $geneticMappingUpgrade >= 1>> <h3>Retro-virus treatments:</h3>