diff --git a/src/interaction/siUtilities.js b/src/interaction/siUtilities.js new file mode 100644 index 0000000000000000000000000000000000000000..789913b34c5bf9f0d0a35595a5ced81949b3baaa --- /dev/null +++ b/src/interaction/siUtilities.js @@ -0,0 +1,149 @@ +/** Find the previous and next slaves' IDs based on the current sort order + * @param {App.Entity.SlaveState} slave + * @returns {[number, number]} - previous and next slave ID + */ +App.UI.SlaveInteract.placeInLine = function(slave) { + const useSlave = assignmentVisible(slave) ? ((s) => assignmentVisible(s)) : ((s) => slave.assignment === s.assignment); + const slaveList = V.slaves.filter(useSlave); + SlaveSort.slaves(slaveList); + const curSlaveIndex = slaveList.findIndex((s) => s.ID === slave.ID); + + let nextIndex; + if (curSlaveIndex + 1 > slaveList.length - 1) { + nextIndex = 0; // wrap around to first slave + } else { + nextIndex = curSlaveIndex + 1; + } + let prevIndex; + if (curSlaveIndex - 1 < 0) { + prevIndex = slaveList.length - 1; // wrap around to last slave + } else { + prevIndex = curSlaveIndex - 1; + } + + return [slaveList[prevIndex].ID, slaveList[nextIndex].ID]; +}; + +/** @typedef RowItem + * @type {object} + * @property {string} [FS] - FS requirement, if any + * @property {string} [text] - link text + * @property {object} [updateSlave] - properties to be merged onto the slave + * @property {object} [update] - properties to be merged into global state + * @property {string} [disabled] - text indicating why the option is unavailable + * @property {string} [note] + */ + +/** Append a simple row of choices with a label to a container, if there are choices to be made. + * @param {Node} parent + * @param {string} label + * @param {RowItem[]} array + * @param {App.Entity.SlaveState} slave + * @param {Function} [refresh] + */ +App.UI.SlaveInteract.appendLabeledChoiceRow = function(parent, label, array, slave, refresh) { + if (array.length > 0) { + let links = document.createElement('div'); + links.append(`${label}: `); + links.appendChild(App.UI.SlaveInteract.generateRows(array, slave, "", false, refresh)); + links.className = "choices"; + return parent.appendChild(links); + } +}; + +/** Generate a row of choices + * @param {RowItem[]} array + * @param {App.Entity.SlaveState} slave + * @param {string} [category] - should be in the form of slave.category, the thing we want to update. + * @param {boolean} [accessCheck=false] + * @param {Function} [refresh] + * @returns {HTMLSpanElement} + */ +App.UI.SlaveInteract.generateRows = function(array, slave, category, accessCheck = false, refresh) { + let row = document.createElement('span'); + let useSep = false; + for (let i = 0; i < array.length; i++) { + let link; + const separator = document.createTextNode(` | `); + const keys = Object.keys(array[i]); + + // Test to see if there was a problem with the key + for (let j = 0; j < keys.length; j++) { + if (["FS", "text", "updateSlave", "update", "note", "disabled"].includes(keys[j])) { + continue; + } else { + array[i].text += " ERROR, THIS SCENE WAS NOT ENTERED CORRECTLY"; + console.log("Trash found while generateRows() was running: " + keys[j] + ": " + array[i][keys[j]]); + break; + } + } + // Some items will never be in App.Data.slaveWear, especially "none" if it falls in between harsh and nice data sets. Trying to look it up would cause an error, which is what access check works around. + let unlocked = false; + if (accessCheck === true) { + if (category === "chastity") { + let text = array[i].text.toLowerCase(); // Yucky. Category name does not match for chastity (since it sets multiple kinds of chastity at once). Compare using a lowercase name instead. + unlocked = isItemAccessible.entry(text, category, slave); + } else { + unlocked = isItemAccessible.entry(array[i].updateSlave[category], category, slave); + } + } + if (accessCheck === false || unlocked) { + if (i < array.length && i !== 0 && useSep === true) { // start with separator (after first loop); can't after since the last loop may not have any text. + row.appendChild(separator); + } + useSep = true; // First item may not appear and if it doesn't we don't want the second to start with a '|' + // is it just text? + if (array[i].disabled) { + link = App.UI.DOM.disabledLink(array[i].text, [array[i].disabled]); + } else if (typeof unlocked === 'string') { + link = App.UI.DOM.disabledLink(array[i].text, [unlocked]); + } else { + link = document.createElement('span'); + + // Set up the link + link.appendChild( + App.UI.DOM.link( + `${array[i].text} `, + () => { click(array[i]); }, + ) + ); + + if (array[i].FS) { + let FS = App.UI.DOM.disabledLink(`FS`, [FutureSocieties.displayAdj(array[i].FS)]); + FS.style.fontStyle = "italic"; + link.appendChild(FS); + } + + // add a note node if required + if (array[i].note) { + link.appendChild(App.UI.DOM.makeElement('span', ` ${array[i].note}`, 'note')); + } + } + row.appendChild(link); + } + } + + return row; + + /** @param {RowItem} arrayOption */ + function click(arrayOption) { + if (arrayOption.updateSlave) { + for (const slaveProperty in arrayOption.updateSlave) { + _.set(slave, slaveProperty, arrayOption.updateSlave[slaveProperty]); + } + } + if (arrayOption.update) { + Object.assign(V, arrayOption.update); + } + if (typeof refresh === "function") { + refresh(); + } else { + App.UI.SlaveInteract.refreshAll(slave); + } + } +}; + +App.UI.SlaveInteract.refreshAll = function(slave) { + App.UI.SlaveInteract.custom(slave); + App.UI.SlaveInteract.work(slave); +}; diff --git a/src/interaction/siWardrobe.js b/src/interaction/siWardrobe.js new file mode 100644 index 0000000000000000000000000000000000000000..074312444eb65be5967386d41a7420c8947d4c11 --- /dev/null +++ b/src/interaction/siWardrobe.js @@ -0,0 +1,842 @@ +App.UI.SlaveInteract.wardrobe = function(slave) { + const el = document.createElement("p"); + el.id = "si-wardrobe"; + el.append(wardrobeContent()); + return el; + + function wardrobeContent() { + const { + // eslint-disable-next-line no-unused-vars + he, + him, + his, + } = getPronouns(slave); + const el = new DocumentFragment(); + el.append(clothes()); + el.append(collar()); + el.append(mask()); + el.append(mouth()); + el.append(armAccessory()); + el.append(shoes()); + el.append(legAccessory()); + el.append(bellyAccessory()); + el.append(buttplug()); + el.append(buttplugAttachment()); + el.append(vaginalAccessory()); + el.append(vaginalAttachment()); + el.append(dickAccessory()); + el.append(chastity()); + + App.UI.DOM.appendNewElement("h3", el, `Shopping`); + el.append(shopping()); + + return el; + + function clothes() { + let el = document.createElement('div'); + let links; + if (slave.fuckdoll === 0) { + // <<= App.Desc.clothing($activeSlave)>> + + let label = document.createElement('div'); + label.append(`Clothes: `); + + let choice = document.createElement('span'); + choice.style.fontWeight = "bold"; + choice.textContent = (`${slave.clothes} `); + label.appendChild(choice); + + // Choose her own + if (slave.clothes !== `choosing her own clothes`) { + let choiceOptionsArray = []; + choiceOptionsArray.push({text: `Let ${him} choose`, updateSlave: {clothes: `choosing her own clothes`, choosesOwnClothes: 1}}); + label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "clothes", false, refresh)); + } + el.appendChild(label); + + + let niceOptionsArray = []; + let harshOptionsArray = []; + + let clothingOption; + // Nice clothes + App.Data.slaveWear.niceClothes.forEach(item => { + clothingOption = { + text: item.name, + updateSlave: {clothes: item.value, choosesOwnClothes: 0}, + FS: item.fs + }; + niceOptionsArray.push(clothingOption); + }); + // Harsh clothes + App.Data.slaveWear.harshClothes.forEach(item => { + clothingOption = { + text: item.name, + updateSlave: {clothes: item.value, choosesOwnClothes: 0}, + FS: item.fs + }; + if (item.value !== "choosing her own clothes") { + harshOptionsArray.push(clothingOption); + } + }); + + // Sort + niceOptionsArray = niceOptionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); + harshOptionsArray = harshOptionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); + + // Nice options + links = document.createElement('div'); + links.className = "choices"; + links.append(`Nice: `); + links.appendChild(App.UI.SlaveInteract.generateRows(niceOptionsArray, slave, "clothes", true, refresh)); + el.appendChild(links); + + // Harsh options + links = document.createElement('div'); + links.className = "choices"; + links.append(`Harsh: `); + links.appendChild(App.UI.SlaveInteract.generateRows(harshOptionsArray, slave, "clothes", true, refresh)); + el.appendChild(links); + } + if (slave.fuckdoll !== 0 || slave.clothes === "restrictive latex" || slave.clothes === "a latex catsuit" || slave.clothes === "a cybersuit" || slave.clothes === "a comfortable bodysuit") { + if (V.seeImages === 1 && V.imageChoice === 1) { + // Color options + links = document.createElement('div'); + links.className = "choices"; + links.append(`Color: `); + links.appendChild(colorOptions("clothingBaseColor")); + el.appendChild(links); + } + } + + return el; + } + + function collar() { + if (slave.fuckdoll !== 0) { + return; + } + // <<= App.Desc.collar($activeSlave)>> + let el = document.createElement('div'); + + let label = document.createElement('div'); + label.append(`Collar: `); + + let choice = document.createElement('span'); + choice.style.fontWeight = "bold"; + choice.textContent = (`${slave.collar} `); + label.appendChild(choice); + + // Choose her own + if (slave.collar !== `none`) { + let choiceOptionsArray = []; + choiceOptionsArray.push({text: `None`, updateSlave: {collar: `none`}}); + label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "collar", false, refresh)); + } + + el.appendChild(label); + + let niceOptionsArray = []; + let harshOptionsArray = []; + + let clothingOption; + // Nice collar + App.Data.slaveWear.niceCollars.forEach(item => { + clothingOption = { + text: item.name, + updateSlave: {collar: item.value}, + FS: item.fs + }; + niceOptionsArray.push(clothingOption); + }); + // Harsh collar + App.Data.slaveWear.harshCollars.forEach(item => { + clothingOption = { + text: item.name, + updateSlave: {collar: item.value}, + FS: item.fs + }; + harshOptionsArray.push(clothingOption); + }); + + // Sort + niceOptionsArray = niceOptionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); + harshOptionsArray = harshOptionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); + + // Nice options + let links = document.createElement('div'); + links.className = "choices"; + links.append(`Nice: `); + links.appendChild(App.UI.SlaveInteract.generateRows(niceOptionsArray, slave, "collar", true, refresh)); + el.appendChild(links); + + // Harsh options + links = document.createElement('div'); + links.className = "choices"; + links.append(`Harsh: `); + links.appendChild(App.UI.SlaveInteract.generateRows(harshOptionsArray, slave, "collar", true, refresh)); + el.appendChild(links); + + return el; + } + + function mask() { + if (slave.fuckdoll !== 0) { + return; + } + let el = document.createElement('div'); + + let label = document.createElement('div'); + label.append(`Mask: `); + + let choice = document.createElement('span'); + choice.style.fontWeight = "bold"; + choice.textContent = (`${slave.faceAccessory} `); + label.appendChild(choice); + + // Choose her own + if (slave.faceAccessory !== `none`) { + let choiceOptionsArray = []; + choiceOptionsArray.push({text: `None`, updateSlave: {faceAccessory: `none`}}); + label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "faceAccessory", false, refresh)); + } + + el.appendChild(label); + + let array = []; + + let clothingOption; + App.Data.slaveWear.faceAccessory.forEach(item => { + clothingOption = { + text: item.name, + updateSlave: {faceAccessory: item.value}, + FS: item.fs + }; + array.push(clothingOption); + }); + + // Sort + array = array.sort((a, b) => (a.text > b.text) ? 1 : -1); + + let links = document.createElement('div'); + links.className = "choices"; + links.appendChild(App.UI.SlaveInteract.generateRows(array, slave, "faceAccessory", true, refresh)); + el.appendChild(links); + + if (slave.eyewear === "corrective glasses" || slave.eyewear === "glasses" || slave.eyewear === "blurring glasses" || slave.faceAccessory === "porcelain mask") { + // Color options + links = document.createElement('div'); + links.className = "choices"; + links.append(`Color: `); + links.appendChild(colorOptions("glassesColor")); + let note = document.createElement('span'); + note.className = "note"; + note.textContent = ` Only glasses and porcelain masks support a custom color. If both are worn, they will share the same color.`; + links.appendChild(note); + el.appendChild(links); + } + + return el; + } + + function mouth() { + if (slave.fuckdoll !== 0) { + return; + } + let el = document.createElement('div'); + + let label = document.createElement('div'); + label.append(`Gag: `); + + let choice = document.createElement('span'); + choice.style.fontWeight = "bold"; + choice.textContent = (`${slave.mouthAccessory} `); + label.appendChild(choice); + + // Choose her own + if (slave.mouthAccessory !== `none`) { + let choiceOptionsArray = []; + choiceOptionsArray.push({text: `None`, updateSlave: {mouthAccessory: `none`}}); + label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "mouthAccessory", false, refresh)); + } + + el.appendChild(label); + + let array = []; + + let clothingOption; + // mouthAccessory + App.Data.slaveWear.mouthAccessory.forEach(item => { + clothingOption = { + text: item.name, + updateSlave: {mouthAccessory: item.value}, + FS: item.fs + }; + array.push(clothingOption); + }); + + // Sort + array = array.sort((a, b) => (a.text > b.text) ? 1 : -1); + + let links = document.createElement('div'); + links.className = "choices"; + links.appendChild(App.UI.SlaveInteract.generateRows(array, slave, "mouthAccessory", true, refresh)); + el.appendChild(links); + + return el; + } + + function armAccessory() { + if (slave.fuckdoll !== 0) { + return; + } + + let el = document.createElement('div'); + // App.Desc.armwear(slave) + + let label = document.createElement('div'); + label.append(`Arm accessory: `); + + let choice = document.createElement('span'); + choice.style.fontWeight = "bold"; + choice.textContent = (`${slave.armAccessory} `); + label.appendChild(choice); + + let array = []; + + // Choose her own + if (slave.armAccessory !== "none") { + array.push({text: `None`, updateSlave: {armAccessory: `none`}}); + label.appendChild(App.UI.SlaveInteract.generateRows(array, slave, "armAccessory", false, refresh)); + } + + el.appendChild(label); + + let links = document.createElement('div'); + links.className = "choices"; + array = [ + {text: "Hand gloves", updateSlave: {armAccessory: "hand gloves"}}, + {text: "Elbow gloves", updateSlave: {armAccessory: "elbow gloves"}} + ]; + links.appendChild(App.UI.SlaveInteract.generateRows(array, slave, "armAccessory", false, refresh)); + el.appendChild(links); + + return el; + } + + function shoes() { + if (slave.fuckdoll !== 0) { + return; + } + let el = document.createElement('div'); + + let label = document.createElement('div'); + label.append(`Shoes: `); + + let choice = document.createElement('span'); + choice.style.fontWeight = "bold"; + choice.textContent = (`${slave.shoes} `); + label.appendChild(choice); + + /* We have "barefoot" in App.Data.slaveWear to cover for this + // Choose her own + if (slave.shoes !== `none`) { + let choiceOptionsArray = []; + choiceOptionsArray.push({text: `None`, updateSlave: {shoes: `none`}}); + label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "shoes", false, refresh)); + } + */ + el.appendChild(label); + + let optionsArray = []; + + let clothingOption; + App.Data.slaveWear.shoes.forEach(item => { + clothingOption = { + text: item.name, + updateSlave: {shoes: item.value}, + FS: item.fs + }; + optionsArray.push(clothingOption); + }); + + // Sort + // No sort here since we want light -> advanced. optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); + + // Options + let links = document.createElement('div'); + links.className = "choices"; + links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "shoes", true, refresh)); + el.appendChild(links); + + if (V.seeImages === 1 && V.imageChoice === 1 && slave.shoes !== "none") { + // Color options + links = document.createElement('div'); + links.className = "choices"; + links.append(`Color: `); + links.appendChild(colorOptions("shoeColor")); + el.appendChild(links); + } + + return el; + } + + function legAccessory() { + if (slave.fuckdoll !== 0) { + return; + } + + let el = document.createElement('div'); + + let label = document.createElement('div'); + label.append(`Leg accessory: `); + + let choice = document.createElement('span'); + choice.style.fontWeight = "bold"; + choice.textContent = (`${slave.legAccessory} `); + label.appendChild(choice); + + let array = []; + + // Choose her own + if (slave.legAccessory !== "none") { + array.push({text: `None`, updateSlave: {legAccessory: `none`}}); + label.appendChild(App.UI.SlaveInteract.generateRows(array, slave, "legAccessory", false, refresh)); + } + + el.appendChild(label); + + let links = document.createElement('div'); + links.className = "choices"; + array = [ + {text: "Short stockings", updateSlave: {legAccessory: "short stockings"}}, + {text: "Long stockings", updateSlave: {legAccessory: "long stockings"}} + ]; + links.appendChild(App.UI.SlaveInteract.generateRows(array, slave, "legAccessory", false, refresh)); + el.appendChild(links); + + return el; + } + + function bellyAccessory() { + if (slave.fuckdoll !== 0) { + return; + } + // <<waistDescription>><<= App.Desc.pregnancy($activeSlave)>><<clothingCorsetDescription>> + let choiceOptionsArray = []; + choiceOptionsArray.push({text: `None`, updateSlave: {bellyAccessory: `none`}}); + + let optionsArray = []; + + let clothingOption; + App.Data.slaveWear.bellyAccessories.forEach(item => { + clothingOption = { + text: item.name, + updateSlave: {bellyAccessory: item.value}, + FS: item.fs + }; + if (item.value !== "none") { + // skip none in set, we set the link elsewhere. + optionsArray.push(clothingOption); + } + }); + // Sort + // No sort here since we want small -> large.optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); + + let el = document.createElement('div'); + + let label = document.createElement('div'); + label.append(`Belly accessory: `); + + let choice = document.createElement('span'); + choice.style.fontWeight = "bold"; + choice.textContent = (`${slave.bellyAccessory} `); + label.appendChild(choice); + + // Choose her own + if (slave.bellyAccessory !== `none`) { + label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "bellyAccessory", false, refresh)); + } + + el.appendChild(label); + + // Options + let links = document.createElement('div'); + links.className = "choices"; + links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "bellyAccessory", true, refresh)); + if (slave.pregKnown === 1) { + let note = document.createElement('span'); + note.className = "note"; + note.textContent = ` Extreme corsets will endanger the life within ${him}.`; + links.appendChild(note); + } + el.appendChild(links); + + return el; + } + + function buttplug() { + if (slave.fuckdoll !== 0) { + return; + } + // App.Desc.buttplug(slave) + + let el = document.createElement('div'); + + let label = document.createElement('div'); + label.append(`Anal accessory: `); + + let choice = document.createElement('span'); + choice.style.fontWeight = "bold"; + choice.textContent = (`${slave.buttplug} `); + label.appendChild(choice); + + if (slave.buttplug !== `none`) { + let choiceOptionsArray = []; + choiceOptionsArray.push({text: `None`, updateSlave: {buttplug: `none`, buttplugAttachment: `none`}}); + label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "buttplug", false, refresh)); + } + el.appendChild(label); + + let optionsArray = []; + + let clothingOption; + App.Data.slaveWear.buttplugs.forEach(item => { + clothingOption = { + text: item.name, + updateSlave: {buttplug: item.value}, + FS: item.fs + }; + if (item.value !== "none") { + // skip none in set, we set the link elsewhere. + optionsArray.push(clothingOption); + } + }); + + // Sort + // No sort here since we want small -> large. optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); + + // Options + let links = document.createElement('div'); + links.className = "choices"; + links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "buttplug", true, refresh)); + el.appendChild(links); + + return el; + } + + function buttplugAttachment() { + let el = document.createElement('div'); + if (slave.fuckdoll !== 0 || slave.buttplug === "none") { + return el; + } + + let label = document.createElement('div'); + label.append(`Anal accessory attachment: `); + + let choice = document.createElement('span'); + choice.style.fontWeight = "bold"; + choice.textContent = (`${slave.buttplugAttachment} `); + label.appendChild(choice); + + if (slave.buttplugAttachment !== `none`) { + let choiceOptionsArray = []; + choiceOptionsArray.push({text: `None`, updateSlave: {buttplugAttachment: `none`}}); + label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "buttplugAttachment", false, refresh)); + } + el.appendChild(label); + + let optionsArray = []; + + let clothingOption; + App.Data.slaveWear.buttplugAttachments.forEach(item => { + clothingOption = { + text: item.name, + updateSlave: {buttplugAttachment: item.value}, + FS: item.fs + }; + if (item.value !== "none") { + // skip none in set, we set the link elsewhere. + optionsArray.push(clothingOption); + } + }); + + // Sort + optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); + + // Options + let links = document.createElement('div'); + links.className = "choices"; + links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "buttplugAttachment", true, refresh)); + el.appendChild(links); + + return el; + } + + function vaginalAccessory() { + if (slave.fuckdoll !== 0) { + return; + } + + // <<vaginalAccessoryDescription>> + + let el = document.createElement('div'); + + let label = document.createElement('div'); + label.append(`Vaginal accessory: `); + + let choice = document.createElement('span'); + choice.style.fontWeight = "bold"; + choice.textContent = (`${slave.vaginalAccessory} `); + label.appendChild(choice); + + if (slave.vaginalAccessory !== `none`) { + let choiceOptionsArray = []; + choiceOptionsArray.push({text: `None`, updateSlave: {vaginalAccessory: `none`}}); + label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "vaginalAccessory", false, refresh)); + } + el.appendChild(label); + + let optionsArray = []; + + let clothingOption; + App.Data.slaveWear.vaginalAccessories.forEach(item => { + clothingOption = { + text: item.name, + updateSlave: {vaginalAccessory: item.value}, + FS: item.fs + }; + if (item.value !== "none") { + // skip none in set, we set the link elsewhere. + optionsArray.push(clothingOption); + } + }); + + // Sort + // No sort here since we want small -> large. optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); + + // Options + let links = document.createElement('div'); + links.className = "choices"; + links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "vaginalAccessory", true, refresh)); + el.appendChild(links); + + return el; + } + + function vaginalAttachment() { + let el = document.createElement('div'); + if (slave.fuckdoll !== 0 || (["none", "bullet vibrator", "smart bullet vibrator"].includes(slave.vaginalAccessory))) { + return el; + } + + let label = document.createElement('div'); + label.append(`Vaginal accessory attachment: `); + + let choice = document.createElement('span'); + choice.style.fontWeight = "bold"; + choice.textContent = (`${slave.vaginalAttachment} `); + label.appendChild(choice); + + if (slave.vaginalAttachment !== `none`) { + let choiceOptionsArray = []; + choiceOptionsArray.push({text: `None`, updateSlave: {vaginalAttachment: `none`}}); + label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "vaginalAttachment", false, refresh)); + } + el.appendChild(label); + + let optionsArray = []; + + let clothingOption; + App.Data.slaveWear.vaginalAttachments.forEach(item => { + clothingOption = { + text: item.name, + updateSlave: {vaginalAttachment: item.value}, + FS: item.fs + }; + if (item.value !== "none") { + // skip none in set, we set the link elsewhere. + optionsArray.push(clothingOption); + } + }); + + // Sort + optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); + + // Options + let links = document.createElement('div'); + links.className = "choices"; + links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "vaginalAttachment", true, refresh)); + el.appendChild(links); + + return el; + } + + function dickAccessory() { + if (slave.fuckdoll !== 0) { + return; + } + // <<= App.Desc.dickAccessory($activeSlave)>> + let el = document.createElement('div'); + + let label = document.createElement('div'); + label.append(`Dick accessory: `); + + let choice = document.createElement('span'); + choice.style.fontWeight = "bold"; + choice.textContent = (`${slave.dickAccessory} `); + label.appendChild(choice); + + if (slave.dickAccessory !== `none`) { + let choiceOptionsArray = []; + choiceOptionsArray.push({text: `None`, updateSlave: {dickAccessory: `none`}}); + label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "dickAccessory", false, refresh)); + } + el.appendChild(label); + + let optionsArray = []; + + let clothingOption; + App.Data.slaveWear.dickAccessories.forEach(item => { + clothingOption = { + text: item.name, + updateSlave: {dickAccessory: item.value}, + FS: item.fs + }; + if (item.value !== "none") { + // skip none in set, we set the link elsewhere. + optionsArray.push(clothingOption); + } + }); + + // Sort + // No sort here since we want small -> large. optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); + + // Options + let links = document.createElement('div'); + links.className = "choices"; + links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "dickAccessory", true, refresh)); + el.appendChild(links); + + return el; + } + + function chastity() { + if (slave.fuckdoll !== 0) { + return; + } + + let el = document.createElement('div'); + + let label = document.createElement('div'); + label.append(`Chastity devices: `); + + let choice = document.createElement('span'); + choice.style.fontWeight = "bold"; + if (slave.choosesOwnChastity === 1) { + choice.textContent = `choosing ${his} own chastity `; + } else if (slave.chastityAnus === 1 && slave.chastityPenis === 1 && slave.chastityVagina === 1) { + choice.textContent = `full chastity `; + } else if (slave.chastityPenis === 1 && slave.chastityVagina === 1) { + choice.textContent = `genital chastity `; + } else if (slave.chastityAnus === 1 && slave.chastityPenis === 1) { + choice.textContent = `combined chastity cage `; + } else if (slave.chastityAnus === 1 && slave.chastityVagina === 1) { + choice.textContent = `combined chastity belt `; + } else if (slave.chastityVagina === 1) { + choice.textContent = `chastity belt `; + } else if (slave.chastityPenis === 1) { + choice.textContent = `chastity cage `; + } else if (slave.chastityAnus === 1) { + choice.textContent = `anal chastity `; + } else if (slave.chastityAnus === 0 && slave.chastityPenis === 0 && slave.chastityVagina === 0) { + choice.textContent = `none `; + } else { + choice.textContent = `THERE HAS BEEN AN ERROR `; + } + label.appendChild(choice); + + if (slave.chastityAnus !== 0 || slave.chastityPenis !== 0 || slave.chastityVagina !== 0) { + let choiceOptionsArray = []; + choiceOptionsArray.push({ + text: `None`, + updateSlave: { + choosesOwnChastity: 0, + chastityAnus: 0, + chastityPenis: 0, + chastityVagina: 0 + } + }); + label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "chastity", false, refresh)); + } + el.appendChild(label); + + let optionsArray = []; + + let clothingOption; + App.Data.slaveWear.chastityDevices.forEach(item => { + clothingOption = { + text: item.name, + updateSlave: {}, + FS: item.fs + }; + Object.assign(clothingOption.updateSlave, item.updateSlave); + if (item.value !== "none") { + // skip none in set, we set the link elsewhere. + optionsArray.push(clothingOption); + } + }); + + // Sort + // skip sort for this one too. optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); + + // Options + let links = document.createElement('div'); + links.className = "choices"; + links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "chastity", true, refresh)); + el.appendChild(links); + + return el; + } + + function shopping() { + return App.UI.DOM.passageLink( + `Go shopping for more options`, + "Wardrobe" + ); + } + + /** + * @param {string} update + * @returns {Node} + */ + function colorOptions(update) { + let el = new DocumentFragment(); + let colorChoice = App.UI.DOM.colorInput( + slave[update], + v => { + slave[update] = v; + refresh(); + } + ); + el.appendChild(colorChoice); + + if (slave[update]) { + el.appendChild( + App.UI.DOM.link( + ` Reset`, + () => { + delete slave[update]; + refresh(); + }, + ) + ); + } + return el; + } + } + function refresh() { + App.Art.refreshSlaveArt(slave, 3, "art-frame"); + jQuery("#si-wardrobe").empty().append(wardrobeContent()); + } +}; diff --git a/src/interaction/slaveInteract.js b/src/interaction/slaveInteract.js index 5bfcc38d6da81811e1acf8f2214f0a0ecd80a276..f6851c1be55d9fcb81d8c75b25fd14c65241efbe 100644 --- a/src/interaction/slaveInteract.js +++ b/src/interaction/slaveInteract.js @@ -1,30 +1,4 @@ -/* eslint-disable no-unused-vars */ // TODO: remove after testing -/** Find the previous and next slaves' IDs based on the current sort order - * @param {App.Entity.SlaveState} slave - * @returns {[number, number]} - previous and next slave ID - */ -App.UI.SlaveInteract.placeInLine = function(slave) { - const useSlave = assignmentVisible(slave) ? ((s) => assignmentVisible(s)) : ((s) => slave.assignment === s.assignment); - const slaveList = V.slaves.filter(useSlave); - SlaveSort.slaves(slaveList); - const curSlaveIndex = slaveList.findIndex((s) => s.ID === slave.ID); - - let nextIndex; - if (curSlaveIndex + 1 > slaveList.length - 1) { - nextIndex = 0; // wrap around to first slave - } else { - nextIndex = curSlaveIndex + 1; - } - let prevIndex; - if (curSlaveIndex - 1 < 0) { - prevIndex = slaveList.length - 1; // wrap around to last slave - } else { - prevIndex = curSlaveIndex - 1; - } - - return [slaveList[prevIndex].ID, slaveList[nextIndex].ID]; -}; /** * @param {App.Entity.SlaveState} slave @@ -930,8 +904,6 @@ App.UI.SlaveInteract.useSlaveDisplay = function(slave) { return el; }; - - App.UI.SlaveInteract.custom = (function() { let el; let label; @@ -1790,128 +1762,3 @@ App.UI.SlaveInteract.custom = (function() { return el; } })(); - -/** @typedef RowItem - * @type {object} - * @property {string} [FS] - FS requirement, if any - * @property {string} [text] - link text - * @property {object} [updateSlave] - properties to be merged onto the slave - * @property {object} [update] - properties to be merged into global state - * @property {string} [disabled] - text indicating why the option is unavailable - * @property {string} [note] - */ - -/** Append a simple row of choices with a label to a container, if there are choices to be made. - * @param {Node} parent - * @param {string} label - * @param {RowItem[]} array - * @param {App.Entity.SlaveState} slave - * @param {Function} [refresh] - */ -App.UI.SlaveInteract.appendLabeledChoiceRow = function(parent, label, array, slave, refresh) { - if (array.length > 0) { - let links = document.createElement('div'); - links.append(`${label}: `); - links.appendChild(App.UI.SlaveInteract.generateRows(array, slave, "", false, refresh)); - links.className = "choices"; - return parent.appendChild(links); - } -}; - -/** Generate a row of choices - * @param {RowItem[]} array - * @param {App.Entity.SlaveState} slave - * @param {string} [category] - should be in the form of slave.category, the thing we want to update. - * @param {boolean} [accessCheck=false] - * @param {Function} [refresh] - * @returns {HTMLSpanElement} - */ -App.UI.SlaveInteract.generateRows = function(array, slave, category, accessCheck = false, refresh) { - let row = document.createElement('span'); - let useSep = false; - for (let i = 0; i < array.length; i++) { - let link; - const separator = document.createTextNode(` | `); - const keys = Object.keys(array[i]); - - // Test to see if there was a problem with the key - for (let j = 0; j < keys.length; j++) { - if (["FS", "text", "updateSlave", "update", "note", "disabled"].includes(keys[j])) { - continue; - } else { - array[i].text += " ERROR, THIS SCENE WAS NOT ENTERED CORRECTLY"; - console.log("Trash found while generateRows() was running: " + keys[j] + ": " + array[i][keys[j]]); - break; - } - } - // Some items will never be in App.Data.slaveWear, especially "none" if it falls in between harsh and nice data sets. Trying to look it up would cause an error, which is what access check works around. - let unlocked = false; - if (accessCheck === true) { - if (category === "chastity") { - let text = array[i].text.toLowerCase(); // Yucky. Category name does not match for chastity (since it sets multiple kinds of chastity at once). Compare using a lowercase name instead. - unlocked = isItemAccessible.entry(text, category, slave); - } else { - unlocked = isItemAccessible.entry(array[i].updateSlave[category], category, slave); - } - } - if (accessCheck === false || unlocked) { - if (i < array.length && i !== 0 && useSep === true) { // start with separator (after first loop); can't after since the last loop may not have any text. - row.appendChild(separator); - } - useSep = true; // First item may not appear and if it doesn't we don't want the second to start with a '|' - // is it just text? - if (array[i].disabled) { - link = App.UI.DOM.disabledLink(array[i].text, [array[i].disabled]); - } else if (typeof unlocked === 'string') { - link = App.UI.DOM.disabledLink(array[i].text, [unlocked]); - } else { - link = document.createElement('span'); - - // Set up the link - link.appendChild( - App.UI.DOM.link( - `${array[i].text} `, - () => { click(array[i]); }, - ) - ); - - if (array[i].FS) { - let FS = App.UI.DOM.disabledLink(`FS`, [FutureSocieties.displayAdj(array[i].FS)]); - FS.style.fontStyle = "italic"; - link.appendChild(FS); - } - - // add a note node if required - if (array[i].note) { - link.appendChild(App.UI.DOM.makeElement('span', ` ${array[i].note}`, 'note')); - } - } - row.appendChild(link); - } - } - - return row; - - /** @param {RowItem} arrayOption */ - function click(arrayOption) { - if (arrayOption.updateSlave) { - for (const slaveProperty in arrayOption.updateSlave) { - _.set(slave, slaveProperty, arrayOption.updateSlave[slaveProperty]); - } - } - if (arrayOption.update) { - Object.assign(V, arrayOption.update); - } - if (typeof refresh === "function") { - refresh(); - } else { - App.UI.Wardrobe.refreshAll(slave); - App.UI.SlaveInteract.refreshAll(slave); - } - } -}; - -App.UI.SlaveInteract.refreshAll = function(slave) { - App.UI.SlaveInteract.custom(slave); - App.UI.SlaveInteract.work(slave); -}; diff --git a/src/interaction/wardrobeUse.js b/src/interaction/wardrobeUse.js deleted file mode 100644 index 772d8800f22d362d24390ad902940a9c8e6c0f86..0000000000000000000000000000000000000000 --- a/src/interaction/wardrobeUse.js +++ /dev/null @@ -1,888 +0,0 @@ -App.UI.Wardrobe = {}; - -App.UI.Wardrobe.clothes = function(slave) { - const { - // eslint-disable-next-line no-unused-vars - he, him, his, hers, himself, boy, He, His - } = getPronouns(slave); - - let el = document.createElement('div'); - let links; - if (slave.fuckdoll === 0) { - // <<= App.Desc.clothing($activeSlave)>> - - let label = document.createElement('div'); - label.append(`Clothes: `); - - let choice = document.createElement('span'); - choice.style.fontWeight = "bold"; - choice.textContent = (`${slave.clothes} `); - label.appendChild(choice); - - // Choose her own - if (slave.clothes !== `choosing her own clothes`) { - let choiceOptionsArray = []; - choiceOptionsArray.push({text: `Let ${him} choose`, updateSlave: {clothes: `choosing her own clothes`, choosesOwnClothes: 1}}); - label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "clothes", false)); - } - el.appendChild(label); - - - let niceOptionsArray = []; - let harshOptionsArray = []; - - let clothingOption; - // Nice clothes - App.Data.slaveWear.niceClothes.forEach(item => { - clothingOption = { - text: item.name, - updateSlave: {clothes: item.value, choosesOwnClothes: 0}, - FS: item.fs - }; - niceOptionsArray.push(clothingOption); - }); - // Harsh clothes - App.Data.slaveWear.harshClothes.forEach(item => { - clothingOption = { - text: item.name, - updateSlave: {clothes: item.value, choosesOwnClothes: 0}, - FS: item.fs - }; - if (item.value !== "choosing her own clothes") { - harshOptionsArray.push(clothingOption); - } - }); - - // Sort - niceOptionsArray = niceOptionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); - harshOptionsArray = harshOptionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); - - // Nice options - links = document.createElement('div'); - links.className = "choices"; - links.append(`Nice: `); - links.appendChild(App.UI.SlaveInteract.generateRows(niceOptionsArray, slave, "clothes", true)); - el.appendChild(links); - - // Harsh options - links = document.createElement('div'); - links.className = "choices"; - links.append(`Harsh: `); - links.appendChild(App.UI.SlaveInteract.generateRows(harshOptionsArray, slave, "clothes", true)); - el.appendChild(links); - } - if (slave.fuckdoll !== 0 || slave.clothes === "restrictive latex" || slave.clothes === "a latex catsuit" || slave.clothes === "a cybersuit" || slave.clothes === "a comfortable bodysuit") { - if (V.seeImages === 1 && V.imageChoice === 1) { - // Color options - links = document.createElement('div'); - links.className = "choices"; - links.append(`Color: `); - links.appendChild(App.UI.Wardrobe.colorOptions(slave, "clothingBaseColor")); - el.appendChild(links); - } - } - - return jQuery('#clothes').empty().append(el); -}; - -App.UI.Wardrobe.collar = function(slave) { - if (slave.fuckdoll !== 0) { - return; - } - // <<= App.Desc.collar($activeSlave)>> - let el = document.createElement('div'); - - let label = document.createElement('div'); - label.append(`Collar: `); - - let choice = document.createElement('span'); - choice.style.fontWeight = "bold"; - choice.textContent = (`${slave.collar} `); - label.appendChild(choice); - - // Choose her own - if (slave.collar !== `none`) { - let choiceOptionsArray = []; - choiceOptionsArray.push({text: `None`, updateSlave: {collar: `none`}}); - label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "collar", false)); - } - - el.appendChild(label); - - let niceOptionsArray = []; - let harshOptionsArray = []; - - let clothingOption; - // Nice collar - App.Data.slaveWear.niceCollars.forEach(item => { - clothingOption = { - text: item.name, - updateSlave: {collar: item.value}, - FS: item.fs - }; - niceOptionsArray.push(clothingOption); - }); - // Harsh collar - App.Data.slaveWear.harshCollars.forEach(item => { - clothingOption = { - text: item.name, - updateSlave: {collar: item.value}, - FS: item.fs - }; - harshOptionsArray.push(clothingOption); - }); - - // Sort - niceOptionsArray = niceOptionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); - harshOptionsArray = harshOptionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); - - // Nice options - let links = document.createElement('div'); - links.className = "choices"; - links.append(`Nice: `); - links.appendChild(App.UI.SlaveInteract.generateRows(niceOptionsArray, slave, "collar", true)); - el.appendChild(links); - - // Harsh options - links = document.createElement('div'); - links.className = "choices"; - links.append(`Harsh: `); - links.appendChild(App.UI.SlaveInteract.generateRows(harshOptionsArray, slave, "collar", true)); - el.appendChild(links); - - return jQuery('#collar').empty().append(el); -}; - -App.UI.Wardrobe.mask = function(slave) { - if (slave.fuckdoll !== 0) { - return; - } - let el = document.createElement('div'); - - let label = document.createElement('div'); - label.append(`Mask: `); - - let choice = document.createElement('span'); - choice.style.fontWeight = "bold"; - choice.textContent = (`${slave.faceAccessory} `); - label.appendChild(choice); - - // Choose her own - if (slave.faceAccessory !== `none`) { - let choiceOptionsArray = []; - choiceOptionsArray.push({text: `None`, updateSlave: {faceAccessory: `none`}}); - label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "faceAccessory", false)); - } - - el.appendChild(label); - - let array = []; - - let clothingOption; - App.Data.slaveWear.faceAccessory.forEach(item => { - clothingOption = { - text: item.name, - updateSlave: {faceAccessory: item.value}, - FS: item.fs - }; - array.push(clothingOption); - }); - - // Sort - array = array.sort((a, b) => (a.text > b.text) ? 1 : -1); - - let links = document.createElement('div'); - links.className = "choices"; - links.appendChild(App.UI.SlaveInteract.generateRows(array, slave, "faceAccessory", true)); - el.appendChild(links); - - if (slave.eyewear === "corrective glasses" || slave.eyewear === "glasses" || slave.eyewear === "blurring glasses" || slave.faceAccessory === "porcelain mask") { - // Color options - links = document.createElement('div'); - links.className = "choices"; - links.append(`Color: `); - links.appendChild(App.UI.Wardrobe.colorOptions(slave, "glassesColor")); - let note = document.createElement('span'); - note.className = "note"; - note.textContent = ` Only glasses and porcelain masks support a custom color. If both are worn, they will share the same color.`; - links.appendChild(note); - el.appendChild(links); - } - - return jQuery('#faceAccessory').empty().append(el); -}; - -App.UI.Wardrobe.mouth = function(slave) { - if (slave.fuckdoll !== 0) { - return; - } - let el = document.createElement('div'); - - let label = document.createElement('div'); - label.append(`Gag: `); - - let choice = document.createElement('span'); - choice.style.fontWeight = "bold"; - choice.textContent = (`${slave.mouthAccessory} `); - label.appendChild(choice); - - // Choose her own - if (slave.mouthAccessory !== `none`) { - let choiceOptionsArray = []; - choiceOptionsArray.push({text: `None`, updateSlave: {mouthAccessory: `none`}}); - label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "mouthAccessory", false)); - } - - el.appendChild(label); - - let array = []; - - let clothingOption; - // mouthAccessory - App.Data.slaveWear.mouthAccessory.forEach(item => { - clothingOption = { - text: item.name, - updateSlave: {mouthAccessory: item.value}, - FS: item.fs - }; - array.push(clothingOption); - }); - - // Sort - array = array.sort((a, b) => (a.text > b.text) ? 1 : -1); - - let links = document.createElement('div'); - links.className = "choices"; - links.appendChild(App.UI.SlaveInteract.generateRows(array, slave, "mouthAccessory", true)); - el.appendChild(links); - - return jQuery('#mouthAccessory').empty().append(el); -}; - -App.UI.Wardrobe.armAccessory = function(slave) { - if (slave.fuckdoll !== 0) { - return; - } - - let el = document.createElement('div'); - // App.Desc.armwear(slave) - - let label = document.createElement('div'); - label.append(`Arm accessory: `); - - let choice = document.createElement('span'); - choice.style.fontWeight = "bold"; - choice.textContent = (`${slave.armAccessory} `); - label.appendChild(choice); - - let array = []; - - // Choose her own - if (slave.armAccessory !== "none") { - array.push({text: `None`, updateSlave: {armAccessory: `none`}}); - label.appendChild(App.UI.SlaveInteract.generateRows(array, slave, "armAccessory", false)); - } - - el.appendChild(label); - - let links = document.createElement('div'); - links.className = "choices"; - array = [ - {text: "Hand gloves", updateSlave: {armAccessory: "hand gloves"}}, - {text: "Elbow gloves", updateSlave: {armAccessory: "elbow gloves"}} - ]; - links.appendChild(App.UI.SlaveInteract.generateRows(array, slave, "armAccessory", false)); - el.appendChild(links); - - return jQuery('#armAccessory').empty().append(el); -}; - -App.UI.Wardrobe.shoes = function(slave) { - if (slave.fuckdoll !== 0) { - return; - } - - const - { - // eslint-disable-next-line no-unused-vars - he, him, his, hers, himself, boy, He, His - } = getPronouns(slave); - - let el = document.createElement('div'); - - let label = document.createElement('div'); - label.append(`Shoes: `); - - let choice = document.createElement('span'); - choice.style.fontWeight = "bold"; - choice.textContent = (`${slave.shoes} `); - label.appendChild(choice); - - /* We have "barefoot" in App.Data.slaveWear to cover for this - // Choose her own - if (slave.shoes !== `none`) { - let choiceOptionsArray = []; - choiceOptionsArray.push({text: `None`, updateSlave: {shoes: `none`}}); - label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "shoes", false)); - } - */ - el.appendChild(label); - - let optionsArray = []; - - let clothingOption; - App.Data.slaveWear.shoes.forEach(item => { - clothingOption = { - text: item.name, - updateSlave: {shoes: item.value}, - FS: item.fs - }; - optionsArray.push(clothingOption); - }); - - // Sort - // No sort here since we want light -> advanced. optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); - - // Options - let links = document.createElement('div'); - links.className = "choices"; - links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "shoes", true)); - el.appendChild(links); - - if (V.seeImages === 1 && V.imageChoice === 1 && slave.shoes !== "none") { - // Color options - links = document.createElement('div'); - links.className = "choices"; - links.append(`Color: `); - links.appendChild(App.UI.Wardrobe.colorOptions(slave, "shoeColor")); - el.appendChild(links); - } - - return jQuery('#shoes').empty().append(el); -}; - -App.UI.Wardrobe.legAccessory = function(slave) { - if (slave.fuckdoll !== 0) { - return; - } - - const { - // eslint-disable-next-line no-unused-vars - he, him, his, hers, himself, boy, He, His - } = getPronouns(slave); - - let el = document.createElement('div'); - - let label = document.createElement('div'); - label.append(`Leg accessory: `); - - let choice = document.createElement('span'); - choice.style.fontWeight = "bold"; - choice.textContent = (`${slave.legAccessory} `); - label.appendChild(choice); - - let array = []; - - // Choose her own - if (slave.legAccessory !== "none") { - array.push({text: `None`, updateSlave: {legAccessory: `none`}}); - label.appendChild(App.UI.SlaveInteract.generateRows(array, slave, "legAccessory", false)); - } - - el.appendChild(label); - - let links = document.createElement('div'); - links.className = "choices"; - array = [ - {text: "Short stockings", updateSlave: {legAccessory: "short stockings"}}, - {text: "Long stockings", updateSlave: {legAccessory: "long stockings"}} - ]; - links.appendChild(App.UI.SlaveInteract.generateRows(array, slave, "legAccessory", false)); - el.appendChild(links); - - return jQuery('#legAccessory').empty().append(el); -}; - -App.UI.Wardrobe.bellyAccessory = function(slave) { - if (slave.fuckdoll !== 0) { - return; - } - // <<waistDescription>><<= App.Desc.pregnancy($activeSlave)>><<clothingCorsetDescription>> - - const { - // eslint-disable-next-line no-unused-vars - he, him, his, hers, himself, boy, He, His - } = getPronouns(slave); - - let choiceOptionsArray = []; - choiceOptionsArray.push({text: `None`, updateSlave: {bellyAccessory: `none`}}); - - let optionsArray = []; - - let clothingOption; - App.Data.slaveWear.bellyAccessories.forEach(item => { - clothingOption = { - text: item.name, - updateSlave: {bellyAccessory: item.value}, - FS: item.fs - }; - if (item.value !== "none") { - // skip none in set, we set the link elsewhere. - optionsArray.push(clothingOption); - } - }); - // Sort - // No sort here since we want small -> large.optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); - - let el = document.createElement('div'); - - let label = document.createElement('div'); - label.append(`Belly accessory: `); - - let choice = document.createElement('span'); - choice.style.fontWeight = "bold"; - choice.textContent = (`${slave.bellyAccessory} `); - label.appendChild(choice); - - // Choose her own - if (slave.bellyAccessory !== `none`) { - label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "bellyAccessory", false)); - } - - el.appendChild(label); - - // Options - let links = document.createElement('div'); - links.className = "choices"; - links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "bellyAccessory", true)); - if (slave.pregKnown === 1) { - let note = document.createElement('span'); - note.className = "note"; - note.textContent = ` Extreme corsets will endanger the life within ${him}.`; - links.appendChild(note); - } - el.appendChild(links); - - return jQuery('#bellyAccessory').empty().append(el); -}; - -App.UI.Wardrobe.buttplug = function(slave) { - if (slave.fuckdoll !== 0) { - return; - } - // App.Desc.buttplug(slave) - - const { - // eslint-disable-next-line no-unused-vars - he, him, his, hers, himself, boy, He, His - } = getPronouns(slave); - - let el = document.createElement('div'); - - let label = document.createElement('div'); - label.append(`Anal accessory: `); - - let choice = document.createElement('span'); - choice.style.fontWeight = "bold"; - choice.textContent = (`${slave.buttplug} `); - label.appendChild(choice); - - if (slave.buttplug !== `none`) { - let choiceOptionsArray = []; - choiceOptionsArray.push({text: `None`, updateSlave: {buttplug: `none`, buttplugAttachment: `none`}}); - label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "buttplug", false)); - } - el.appendChild(label); - - let optionsArray = []; - - let clothingOption; - App.Data.slaveWear.buttplugs.forEach(item => { - clothingOption = { - text: item.name, - updateSlave: {buttplug: item.value}, - FS: item.fs - }; - if (item.value !== "none") { - // skip none in set, we set the link elsewhere. - optionsArray.push(clothingOption); - } - }); - - // Sort - // No sort here since we want small -> large. optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); - - // Options - let links = document.createElement('div'); - links.className = "choices"; - links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "buttplug", true)); - el.appendChild(links); - - return jQuery('#buttplug').empty().append(el); -}; - -App.UI.Wardrobe.buttplugAttachment = function(slave) { - if (slave.fuckdoll !== 0) { - return; - } else if (slave.buttplug === "none") { - return jQuery('#buttplugAttachment').empty(); - } - - const { - // eslint-disable-next-line no-unused-vars - he, him, his, hers, himself, boy, He, His - } = getPronouns(slave); - - let el = document.createElement('div'); - - let label = document.createElement('div'); - label.append(`Anal accessory attachment: `); - - let choice = document.createElement('span'); - choice.style.fontWeight = "bold"; - choice.textContent = (`${slave.buttplugAttachment} `); - label.appendChild(choice); - - if (slave.buttplugAttachment !== `none`) { - let choiceOptionsArray = []; - choiceOptionsArray.push({text: `None`, updateSlave: {buttplugAttachment: `none`}}); - label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "buttplugAttachment", false)); - } - el.appendChild(label); - - let optionsArray = []; - - let clothingOption; - App.Data.slaveWear.buttplugAttachments.forEach(item => { - clothingOption = { - text: item.name, - updateSlave: {buttplugAttachment: item.value}, - FS: item.fs - }; - if (item.value !== "none") { - // skip none in set, we set the link elsewhere. - optionsArray.push(clothingOption); - } - }); - - // Sort - optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); - - // Options - let links = document.createElement('div'); - links.className = "choices"; - links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "buttplugAttachment", true)); - el.appendChild(links); - - return jQuery('#buttplugAttachment').empty().append(el); -}; - -App.UI.Wardrobe.vaginalAccessory = function(slave) { - if (slave.fuckdoll !== 0) { - return; - } - - // <<vaginalAccessoryDescription>> - const { - // eslint-disable-next-line no-unused-vars - he, him, his, hers, himself, boy, He, His - } = getPronouns(slave); - - let el = document.createElement('div'); - - let label = document.createElement('div'); - label.append(`Vaginal accessory: `); - - let choice = document.createElement('span'); - choice.style.fontWeight = "bold"; - choice.textContent = (`${slave.vaginalAccessory} `); - label.appendChild(choice); - - if (slave.vaginalAccessory !== `none`) { - let choiceOptionsArray = []; - choiceOptionsArray.push({text: `None`, updateSlave: {vaginalAccessory: `none`}}); - label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "vaginalAccessory", false)); - } - el.appendChild(label); - - let optionsArray = []; - - let clothingOption; - App.Data.slaveWear.vaginalAccessories.forEach(item => { - clothingOption = { - text: item.name, - updateSlave: {vaginalAccessory: item.value}, - FS: item.fs - }; - if (item.value !== "none") { - // skip none in set, we set the link elsewhere. - optionsArray.push(clothingOption); - } - }); - - // Sort - // No sort here since we want small -> large. optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); - - // Options - let links = document.createElement('div'); - links.className = "choices"; - links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "vaginalAccessory", true)); - el.appendChild(links); - - return jQuery('#vaginalAccessory').empty().append(el); -}; - -App.UI.Wardrobe.vaginalAttachment = function(slave) { - if (slave.fuckdoll !== 0) { - return; - } else if (["none", "bullet vibrator", "smart bullet vibrator"].includes(slave.vaginalAccessory)) { - return jQuery('#vaginalAttachment').empty(); - } - // App.Desc.vaginalAttachment(slave); - - const { - // eslint-disable-next-line no-unused-vars - he, him, his, hers, himself, boy, He, His - } = getPronouns(slave); - - let el = document.createElement('div'); - - let label = document.createElement('div'); - label.append(`Vaginal accessory attachment: `); - - let choice = document.createElement('span'); - choice.style.fontWeight = "bold"; - choice.textContent = (`${slave.vaginalAttachment} `); - label.appendChild(choice); - - if (slave.vaginalAttachment !== `none`) { - let choiceOptionsArray = []; - choiceOptionsArray.push({text: `None`, updateSlave: {vaginalAttachment: `none`}}); - label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "vaginalAttachment", false)); - } - el.appendChild(label); - - let optionsArray = []; - - let clothingOption; - App.Data.slaveWear.vaginalAttachments.forEach(item => { - clothingOption = { - text: item.name, - updateSlave: {vaginalAttachment: item.value}, - FS: item.fs - }; - if (item.value !== "none") { - // skip none in set, we set the link elsewhere. - optionsArray.push(clothingOption); - } - }); - - // Sort - optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); - - // Options - let links = document.createElement('div'); - links.className = "choices"; - links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "vaginalAttachment", true)); - el.appendChild(links); - - return jQuery('#vaginalAttachment').empty().append(el); -}; - -App.UI.Wardrobe.dickAccessory = function(slave) { - if (slave.fuckdoll !== 0) { - return; - } - // <<= App.Desc.dickAccessory($activeSlave)>> - - const { - // eslint-disable-next-line no-unused-vars - he, him, his, hers, himself, boy, He, His - } = getPronouns(slave); - - let el = document.createElement('div'); - - let label = document.createElement('div'); - label.append(`Dick accessory: `); - - let choice = document.createElement('span'); - choice.style.fontWeight = "bold"; - choice.textContent = (`${slave.dickAccessory} `); - label.appendChild(choice); - - if (slave.dickAccessory !== `none`) { - let choiceOptionsArray = []; - choiceOptionsArray.push({text: `None`, updateSlave: {dickAccessory: `none`}}); - label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "dickAccessory", false)); - } - el.appendChild(label); - - let optionsArray = []; - - let clothingOption; - App.Data.slaveWear.dickAccessories.forEach(item => { - clothingOption = { - text: item.name, - updateSlave: {dickAccessory: item.value}, - FS: item.fs - }; - if (item.value !== "none") { - // skip none in set, we set the link elsewhere. - optionsArray.push(clothingOption); - } - }); - - // Sort - // No sort here since we want small -> large. optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); - - // Options - let links = document.createElement('div'); - links.className = "choices"; - links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "dickAccessory", true)); - el.appendChild(links); - - return jQuery('#dickAccessory').empty().append(el); -}; - -App.UI.Wardrobe.chastity = function(slave) { - if (slave.fuckdoll !== 0) { - return; - } - - const { - // eslint-disable-next-line no-unused-vars - he, him, his, hers, himself, boy, He, His - } = getPronouns(slave); - - let el = document.createElement('div'); - - let label = document.createElement('div'); - label.append(`Chastity devices: `); - - let choice = document.createElement('span'); - choice.style.fontWeight = "bold"; - if (slave.choosesOwnChastity === 1) { - choice.textContent = `choosing ${his} own chastity `; - } else if (slave.chastityAnus === 1 && slave.chastityPenis === 1 && slave.chastityVagina === 1) { - choice.textContent = `full chastity `; - } else if (slave.chastityPenis === 1 && slave.chastityVagina === 1) { - choice.textContent = `genital chastity `; - } else if (slave.chastityAnus === 1 && slave.chastityPenis === 1) { - choice.textContent = `combined chastity cage `; - } else if (slave.chastityAnus === 1 && slave.chastityVagina === 1) { - choice.textContent = `combined chastity belt `; - } else if (slave.chastityVagina === 1) { - choice.textContent = `chastity belt `; - } else if (slave.chastityPenis === 1) { - choice.textContent = `chastity cage `; - } else if (slave.chastityAnus === 1) { - choice.textContent = `anal chastity `; - } else if (slave.chastityAnus === 0 && slave.chastityPenis === 0 && slave.chastityVagina === 0) { - choice.textContent = `none `; - } else { - choice.textContent = `THERE HAS BEEN AN ERROR `; - } - label.appendChild(choice); - - if (slave.chastityAnus !== 0 || slave.chastityPenis !== 0 || slave.chastityVagina !== 0) { - let choiceOptionsArray = []; - choiceOptionsArray.push({ - text: `None`, - updateSlave: { - choosesOwnChastity: 0, - chastityAnus: 0, - chastityPenis: 0, - chastityVagina: 0 - } - }); - label.appendChild(App.UI.SlaveInteract.generateRows(choiceOptionsArray, slave, "chastity", false)); - } - el.appendChild(label); - - let optionsArray = []; - - let clothingOption; - App.Data.slaveWear.chastityDevices.forEach(item => { - clothingOption = { - text: item.name, - updateSlave: {}, - FS: item.fs - }; - Object.assign(clothingOption.updateSlave, item.updateSlave); - if (item.value !== "none") { - // skip none in set, we set the link elsewhere. - optionsArray.push(clothingOption); - } - }); - - // Sort - // skip sort for this one too. optionsArray = optionsArray.sort((a, b) => (a.text > b.text) ? 1 : -1); - - // Options - let links = document.createElement('div'); - links.className = "choices"; - links.appendChild(App.UI.SlaveInteract.generateRows(optionsArray, slave, "chastity", true)); - el.appendChild(links); - - return jQuery('#chastity').empty().append(el); -}; - -App.UI.Wardrobe.shopping = function(slave) { - return jQuery('#shopping').empty().append( - App.UI.DOM.link( - ` Go shopping for more options`, - () => {}, - [], - "Wardrobe" - ) - ); -}; - -/** - * @param {App.Entity.SlaveState} slave - * @param {string} update - * @returns {Node} - */ -App.UI.Wardrobe.colorOptions = function(slave, update) { - let el = new DocumentFragment(); - let colorChoice = App.UI.DOM.colorInput( - slave[update], - v => { - slave[update] = v; - App.UI.Wardrobe.refreshAll(slave); - } - ); - el.appendChild(colorChoice); - - if (slave[update]) { - el.appendChild( - App.UI.DOM.link( - ` Reset`, - () => { - delete slave[update]; - App.UI.Wardrobe.refreshAll(slave); - }, - ) - ); - } - return el; -}; - -App.UI.Wardrobe.refreshAll = function(slave) { - App.UI.Wardrobe.clothes(slave); - App.UI.Wardrobe.collar(slave); - App.UI.Wardrobe.mask(slave); - App.UI.Wardrobe.mouth(slave); - App.UI.Wardrobe.armAccessory(slave); - App.UI.Wardrobe.shoes(slave); - App.UI.Wardrobe.legAccessory(slave); - App.UI.Wardrobe.bellyAccessory(slave); - App.UI.Wardrobe.buttplug(slave); - App.UI.Wardrobe.buttplugAttachment(slave); - App.UI.Wardrobe.vaginalAccessory(slave); - App.UI.Wardrobe.vaginalAttachment(slave); - App.UI.Wardrobe.dickAccessory(slave); - App.UI.Wardrobe.chastity(slave); - App.Art.refreshSlaveArt(slave, 3, "art-frame"); - return; -}; diff --git a/src/uncategorized/slaveInteract.tw b/src/uncategorized/slaveInteract.tw index 788b0bef7f7e00db6900cda024752a813ed34d9c..426aa8d00c3c328b74cda3fd0fd75955707d5aa0 100644 --- a/src/uncategorized/slaveInteract.tw +++ b/src/uncategorized/slaveInteract.tw @@ -57,7 +57,7 @@ <button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Description'), jQuery('#LSD').empty().append(App.Desc.longSlave(getSlave(V.AS), {noArt: true}))" id="tab Description">Description</button> <button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Modify')" id="tab Modify">Modify</button> <button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Work')" id="tab Work">Work</button> - <button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Appearance'), App.UI.Wardrobe.refreshAll(getSlave(V.AS))" id="tab Appearance">Appearance</button> + <button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Appearance')" id="tab Appearance">Appearance</button> <button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'PhysicalRegimen')" id="tab PhysicalRegimen">Physical Regimen</button> <button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Rules')" id="tab Rules">Rules</button> <button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Financial')" id="tab Financial">Financial</button> @@ -126,61 +126,7 @@ <div id="Appearance" class="tab-content"> <div class="content"> - <p> - <span id="clothes"></span> - /*<script>App.UI.Wardrobe.clothes(getSlave(V.AS))</script>*/ - - <<if getSlave($AS).fuckdoll == 0>> - <span id="collar"></span> - /*<script>App.UI.Wardrobe.collar(getSlave(V.AS))</script>*/ - - <span id="faceAccessory"></span> - - <span id="mouthAccessory"></span> - - <span id="armAccessory"></span> - /*<script>App.UI.Wardrobe.armAccessory(getSlave(V.AS))</script>*/ - - <<if hasAnyLegs(getSlave($AS))>> - <span id="shoes"></span> - /*<script>App.UI.Wardrobe.shoes(getSlave(V.AS))</script>*/ - - <span id="legAccessory"></span> - /*<script>App.UI.Wardrobe.legAccessory(getSlave(V.AS))</script>*/ - <</if>> - - <span id="bellyAccessory"></span> - /*<script>App.UI.Wardrobe.bellyAccessory(getSlave(V.AS))</script>*/ - - <span id="buttplug"></span> - /*<script>App.UI.Wardrobe.buttplug(getSlave(V.AS))</script>*/ - - <<if isItemAccessible.entry("tail", "buttplugAttachment") && getSlave($AS).buttplug != "none">> - <span id="buttplugAttachment"></span> - /*<script>App.UI.Wardrobe.buttplugAttachment(getSlave(V.AS))</script>*/ - <</if>> - - <<if getSlave($AS).vagina > -1>> - <span id="vaginalAccessory"></span> - /*<script>App.UI.Wardrobe.vaginalAccessory(getSlave(V.AS))</script>*/ - <span id="vaginalAttachment"></span> - /*<script>App.UI.Wardrobe.vaginalAttachment(getSlave(V.AS))</script>*/ - <</if>> - - <<if getSlave($AS).dick > 0>> - <span id="dickAccessory"></span> - /*<script>App.UI.Wardrobe.dickAccessory(getSlave(V.AS))</script>*/ - <</if>> - - <span id="chastity"></span> - /*<script>App.UI.Wardrobe.chastity(getSlave(V.AS))</script>*/ - - <h3>Shopping</h3> - <span id="shopping"></span> - <script>App.UI.Wardrobe.shopping(getSlave(V.AS))</script> - - <</if>> /* CLOSES FUCKDOLL CHECK */ - </p> + <<includeDOM App.UI.SlaveInteract.wardrobe(getSlave(V.AS))>> </div> </div>