diff --git a/src/facilities/salon/salonPassage.js b/src/facilities/salon/salonPassage.js index bebe975fa5e5904c660702a33beb88604bbc0535..fd45b723a7ac04066addaf56e0aa8d23791faa7d 100644 --- a/src/facilities/salon/salonPassage.js +++ b/src/facilities/salon/salonPassage.js @@ -147,9 +147,106 @@ App.UI.salon = function(slave, cheat = false) { function hair() { const el = new DocumentFragment(); + let option; App.UI.DOM.appendNewElement("h3", el, "Hair"); + const options = new App.UI.OptionsGroup(); + let title; + let showChoices = true; + const hasWig = (slave.bald === 1 && slave.hStyle !== "bald"); + + if (slave.bald === 1) { + if (slave.hStyle === "bald") { + title = `${He} is completely bald.`; + showChoices = false; + } else { + title = `${His} wig is ${slave.hColor}.`; + } + } else { + title = `${His} hair is ${slave.hColor}.`; + } + App.UI.DOM.appendNewElement("div", el, title); + + if (slave.bald === 1) { + options.addOption(`Use a wig`, "hStyle", slave) + .addValue("Enable", "neat").on() + .addValue("Disable", "bald").off(); + } + + if (showChoices) { + // Color + option = options.addOption("Primary color", "hColor", slave); + if (slave.origHColor !== slave.hColor) { + option.addValue("Restore natural color", slave.origHColor, billMod); + } + for (const color of App.Medicine.Modification.Color.Primary) { + option.addValue(capFirstChar(color.value), color.value, billMod); + } + option.pulldown(); + + option = options.addOption("Secondary color", "hColor", slave); + for (const color of App.Medicine.Modification.Color.Secondary) { + option.addValue(color.title, (slave.hColor + color.value), billMod); + } + option.pulldown(); - el.append(App.Medicine.Salon.hair(slave, {cheat: cheat})); + // Style + if (slave.hLength > 1) { + title = `Style ${hasWig ? "wig" : "hair"} `; + } else { + title = `${His} ${hasWig ? "wig" : "hair"} is too short to style meaningfully`; + } + option = options.addOption(title, "hStyle", slave); + if (slave.hLength > 1) { + for (const style of App.Medicine.Modification.hairStyles.Normal) { + option.addValue(style.title, style.value, billMod); + } + option.pulldown(); + } + + // Style + Cut + if (slave.hLength > 1) { + option = options.addOption(`${hasWig ? "Change wig style and length" : "Cut and style hair"}`, "hStyle", slave); + if (slave.hLength > 1) { + for (const style of App.Medicine.Modification.hairStyles.Cut) { + option.addValue( + style.title, + style.value, + () => { + slave.hLength = style.hLength; + billMod(); + }); + } + } + + // Length + option = options.addOption(`${hasWig ? "Find longer or shorter wig" : "Cut or lengthen hair"}`, "hLength", slave); + for (const style of App.Medicine.Modification.hairStyles.Length) { + if (style.hasOwnProperty("requirements") && !style.requirements(slave)) { + continue; + } + const length = style.hasOwnProperty("hLength") ? style.hLength : slave.hLength; + option.addValue( + style.title, + length, + () => { + if (style.hasOwnProperty("onApplication")) { + style.onApplication(slave); + } + billMod(); + }); + } + option.showTextBox(); + } + + // Maintain + if (!hasWig) { + options.addOption(`Maintain this length`, "haircuts", slave) + .addValue("Enable", 1).on() + .addValue("Disable", 0).off(); + } + } + + el.append(options.render()); return el; } diff --git a/src/js/salon.js b/src/js/salon.js index 04e21f62dd86d985cdc01560d2e7a31783211afb..74916eb4ff5a80df035fa3a44c6ce96fda0e8b43 100644 --- a/src/js/salon.js +++ b/src/js/salon.js @@ -328,402 +328,6 @@ App.Medicine.Salon.ears = function(slave, {primaryEarColor = 0, secondaryEarColo } }; -/** - * Update hair in salon - * @param {App.Entity.SlaveState} slave - * @param {object} params - * @param {number|string} [params.primaryHairColor] - * @param {string} [params.secondaryHairColor] - * @param {Boolean} [params.cheat=false] - * @returns {HTMLElement} - */ -App.Medicine.Salon.hair = function(slave, {primaryHairColor = 0, secondaryHairColor = "", cheat = false} = {}) { - let updatePrimary = (newVal) => { primaryHairColor = newVal.value; apply(); }; - let updateSecondary = (newVal) => { secondaryHairColor = newVal.value; apply(); }; - const {His, his, He, him} = getPronouns(slave); - const div = document.createElement("div"); - div.id = "salon-hair"; - div.append(contents()); - - return div; - - function contents() { - const frag = new DocumentFragment(); - if (slave.bald !== 1) { - frag.append(hairDye()); - frag.append(hairStyle()); - frag.append(hairLength()); - frag.append(hairMaint()); - } else { - // Bald - if (slave.hStyle === "bald") { - frag.append(`${He} is completely bald. `); - } else { - frag.append(wigDye()); - } - frag.append(wigStyle()); - frag.append(wigLength()); - } - return frag; - } - - function hairDye() { - const frag = new DocumentFragment(); - let div; - let p; - frag.append(`${His} hair is ${slave.hColor}.`); - - div = document.createElement("div"); - div.classList.add("choices"); - if (slave.origHColor !== slave.hColor) { - div.append( - App.UI.DOM.link( - "Restore natural color", - () => { - slave.hColor = slave.origHColor; - App.Art.refreshSlaveArt(slave, 3, "art-frame"); - if (!cheat) { - cashX(forceNeg(V.modCost), "slaveMod", slave); - } - apply(); - } - ) - ); - div.append(" or "); - App.UI.DOM.appendNewElement("span", div, "choose a new one: ", "note"); - } else { - App.UI.DOM.appendNewElement("span", div, `Choose a dye color before dyeing ${his} hair:`, "note"); - } - frag.append(div); - - div = document.createElement("div"); - div.classList.add("choices"); - div.append(`Colors:`); - div.append(createList(App.Medicine.Modification.Color.Primary, updatePrimary)); - frag.append(div); - - div = document.createElement("div"); - div.classList.add("choices"); - div.append(`Highlights:`); - div.append(createList(App.Medicine.Modification.Color.Secondary, updateSecondary)); - frag.append(div); - - if (primaryHairColor !== 0) { - p = document.createElement("p"); - p.classList.add("choices"); - p.append( - App.UI.DOM.link( - `Color ${his} hair`, - () => { - slave.hColor = (primaryHairColor + secondaryHairColor); - App.Art.refreshSlaveArt(slave, 3, "art-frame"); - if (!cheat) { - cashX(forceNeg(V.modCost), "slaveMod", slave); - } - App.Medicine.Salon.hair(slave); // discard selections after locking them in. - } - ) - ); - p.append(` ${primaryHairColor}${secondaryHairColor} now?`); - frag.append(p); - } - return frag; - } - - function hairStyle() { - const frag = new DocumentFragment(); - let div; - let method; - div = document.createElement("div"); - if (slave.hStyle !== "shaved") { - div.append(`${His} ${slave.hStyle} hair is ${lengthToEitherUnit(slave.hLength)} long. `); - } else { - div.append(`${His} hair is shaved smooth. `); - } - App.UI.DOM.appendNewElement("span", div, `General hairstyles will conform to hair length and clothing choices.`, "note"); - frag.append(div); - - // Normal styles - div = document.createElement("div"); - div.classList.add("choices"); - method = (newVal) => { - slave.hStyle = newVal.value; - if (!cheat) { - cashX(forceNeg(V.modCost), "slaveMod", slave); - } - apply(); - }; - if (slave.hLength > 1) { - div.append(`Style ${his} hair:`); - div.append(createList(App.Medicine.Modification.hairStyles.Normal, method)); - } else { - App.UI.DOM.appendNewElement("span", div, `${His} hair is too short to style meaningfully`, "note"); - } - frag.append(div); - - // Short styles, includes cutting - div = document.createElement("div"); - div.classList.add("choices"); - method = (newVal) => { - slave.hStyle = newVal.value; - slave.hLength = newVal.hLength; - if (!cheat) { - cashX(forceNeg(V.modCost), "slaveMod", slave); - } - apply(); - }; - if (slave.hLength > 1) { - div.append(`Cut and style ${his} hair:`); - div.append(createList(App.Medicine.Modification.hairStyles.Cut, method)); - } - frag.append(div); - - return frag; - } - - function hairLength() { - const frag = new DocumentFragment(); - let div = document.createElement("div"); - div.classList.add("choices"); - let method = (newVal) => { - if (newVal.hasOwnProperty("onApplication")) { - newVal.onApplication(slave); - } - if (newVal.hasOwnProperty("hLength")) { - slave.hLength = newVal.hLength; - } - apply(); - }; - const oldHLength = (V.showInches === 2) ? Math.round(slave.hLength / 2.54) : slave.hLength; - - App.UI.DOM.appendNewElement("span", div, `Cut or lengthen ${his} hair:`); - div.append(createList(App.Medicine.Modification.hairStyles.Length, method)); - div.append(" | Custom length: "); - div.append( - App.UI.DOM.makeTextBox( - oldHLength, - v => { - v = Math.max(v, 0); // Positive hair length only - // If they entered "inches," convert - if (V.showInches === 2) { - v = Math.round(v * 2.54); - } - slave.hLength = v; - if (!cheat) { - cashX(forceNeg(V.modCost), "slaveMod", slave); - } - apply(); - }, - true - ) - ); - if (V.showInches === 1) { - div.append(`cm (${cmToInchString(slave.hLength)})`); - } else if (V.showInches === 2) { - div.append(`inches`); - } - - frag.append(div); - - return frag; - } - - function hairMaint() { - let div = document.createElement("div"); - div.classList.add("choices"); - div.append(`Have ${his} hair carefully maintained at its current length: `); - let haircuts; - let text; - if (slave.haircuts === 1) { - text = "Cease maintenance"; - haircuts = 0; - } else { - text = "Begin maintenance"; - haircuts = 1; - } - div.append( - App.UI.DOM.link( - text, - () => { - slave.haircuts = haircuts; - apply(); - } - ) - ); - return div; - } - - function wigDye() { - const frag = new DocumentFragment(); - let div; - let p; - frag.append(`${His} current wig is ${slave.hColor}. `); - - if (slave.hStyle !== "bald") { - frag.append( - App.UI.DOM.link( - "Remove wig", - () => { - slave.hStyle = "bald"; - slave.hLength = 0; - // I'm not going to charge you for taking off a fucking wig. - apply(); - } - ) - ); - frag.append(" or "); - App.UI.DOM.appendNewElement("span", frag, "choose a new one: ", "note"); - } else { - App.UI.DOM.appendNewElement("span", frag, `Choose a wig color:`, "note"); - } - - div = document.createElement("div"); - div.classList.add("choices"); - div.append(`Colors:`); - div.append(createList(App.Medicine.Modification.Color.Primary, updatePrimary)); - frag.append(div); - - div = document.createElement("div"); - div.classList.add("choices"); - div.append(`Highlights:`); - div.append(createList(App.Medicine.Modification.Color.Secondary, updateSecondary)); - frag.append(div); - - if (primaryHairColor !== 0) { - p = document.createElement("p"); - p.classList.add("choices"); - p.append( - App.UI.DOM.link( - `Change`, - () => { - slave.earTColor = (primaryHairColor + secondaryHairColor); - App.Art.refreshSlaveArt(slave, 3, "art-frame"); - if (!cheat) { - cashX(forceNeg(V.modCost), "slaveMod", slave); - } - App.Medicine.Salon.hair(slave); // discard selections after locking them in. - } - ) - ); - p.append(` ${his} wig color to ${primaryHairColor}${secondaryHairColor} now?`); - frag.append(p); - } - return frag; - } - - function wigLength() { - const frag = new DocumentFragment(); - if (slave.hStyle === "bald") { - return frag; - } - let div = document.createElement("div"); - div.classList.add("choices"); - const array = []; - for (const number of [10, 30, 60, 90, 120, 150]) { - const obj = {}; - obj.title = lengthToEitherUnit(number); - obj.hLength = number; - array.push(obj); - } - let method = (newVal) => { - slave.hLength = newVal.hLength; - apply(); - }; - const oldHLength = (V.showInches === 2) ? Math.round(slave.hLength / 2.54) : slave.hLength; - App.UI.DOM.appendNewElement("span", div, `Set wig length to:`, "choices"); - div.append(createList(array, method)); - div.append(" | Custom length: "); - div.append( - App.UI.DOM.makeTextBox( - oldHLength, - v => { - v = Math.max(v, 10); // Wigs must be at least 10 cm - // If they entered "inches," convert - if (V.showInches === 2) { - v = Math.round(v * 2.54); - } - slave.hLength = v; - if (!cheat) { - cashX(forceNeg(V.modCost), "slaveMod", slave); - } - apply(); - }, - true - ) - ); - if (V.showInches === 1) { - div.append(`cm (${cmToInchString(slave.hLength)})`); - } else if (V.showInches === 2) { - div.append(`inches`); - } - - frag.append(div); - - return frag; - } - - function wigStyle() { - const frag = new DocumentFragment(); - let div = document.createElement("div"); - div.classList.add("choices"); - const method = (newVal) => { - slave.hStyle = newVal.value; - if (!cheat) { - cashX(forceNeg(V.modCost), "slaveMod", slave); - } - apply(); - }; - - if (slave.hStyle !== "bald") { - frag.append(`${His} ${slave.hStyle} wig is ${lengthToEitherUnit(slave.hLength)} long. `); - } else { - frag.append(`${He} is not wearing a wig. `); - } - App.UI.DOM.appendNewElement("span", frag, `General hairstyles will conform to hair length and clothing choices.`, "note"); - - div = document.createElement("div"); - div.classList.add("choices"); - if (slave.hStyle === "bald") { - div.append(`Give ${him} a wig:`); - } else { - div.append(`Set wig style:`); - } - div.append(createList(App.Medicine.Modification.hairStyles.Normal, method)); - frag.append(div); - return frag; - } - - function createList(array, method) { - const links = []; - for (const item of array) { - if (item.hasOwnProperty("requirements")) { - if (item.requirements(slave) === false) { - continue; - } - } - const title = item.title || capFirstChar(item.value); - links.push( - App.UI.DOM.link( - title, - () => method(item) - ) - ); - } - return App.UI.DOM.generateLinksStrip(links); - } - - function apply() { - App.Art.refreshSlaveArt(slave, 3, "art-frame"); - App.Medicine.Salon.hair( - slave, - { - primaryHairColor: primaryHairColor, - secondaryHairColor: secondaryHairColor, - } - ); - } -}; - /** * Update hair in salon * @param {App.Entity.SlaveState} slave