diff --git a/js/003-data/playerData.js b/js/003-data/playerData.js new file mode 100644 index 0000000000000000000000000000000000000000..b0848899a3e7b43388d4d809d4ea4b82a4f6155c --- /dev/null +++ b/js/003-data/playerData.js @@ -0,0 +1,12 @@ +App.Data.player = { + // Value is stored in player object as the index of this array: If V.PC.refreshmentType === 0, we should display "Smoked". + refreshmentType: [ + `Smoked`, + `Drank`, + `Eaten`, + `Snorted`, + `Injected`, + `Popped`, + `Dissolved orally`, + ] +}; diff --git a/src/cheats/PCCheatMenu.tw b/src/cheats/PCCheatMenu.tw index c1257c0f6085e02a8f1644033a3b4e2d1b188694..2080a5037f90d368b9981ac8519bc4fec0223a5d 100644 --- a/src/cheats/PCCheatMenu.tw +++ b/src/cheats/PCCheatMenu.tw @@ -47,14 +47,11 @@ Sex: ''$tempSlave.genes'' <br><<radiobutton "$tempSlave.refreshment" "cigar">> Cigar <<radiobutton "$tempSlave.refreshment" "whiskey">> Whiskey -<br>Preferred method of consumption: <<if $tempSlave.refreshmentType == 0>>Smoked<<elseif $tempSlave.refreshmentType == 1>>Drank<<elseif $tempSlave.refreshmentType == 2>>Eaten<<elseif $tempSlave.refreshmentType == 3>>Snorted<<elseif $tempSlave.refreshmentType == 4>>Injected<<elseif $tempSlave.refreshmentType == 5>>Popped<<else>>Orally Dissolved<</if>> -<br><<radiobutton "$tempSlave.refreshmentType" 0>> Smoked - <<radiobutton "$tempSlave.refreshmentType" 1>> Drank - <<radiobutton "$tempSlave.refreshmentType" 2>> Eaten - <<radiobutton "$tempSlave.refreshmentType" 3>> Snorted - <<radiobutton "$tempSlave.refreshmentType" 4>> Injected - <<radiobutton "$tempSlave.refreshmentType" 5>> Popped - <<radiobutton "$tempSlave.refreshmentType" 6>> Orally Dissolved +<br>Preferred method of consumption: <<print App.Data.player.refreshmentType[$tempSlave.refreshmentType]>> +<br> +<<for _i = 0; _i < App.Data.player.refreshmentType.length; _i++>> + <<radiobutton "$tempSlave.refreshmentType" _i>> <<print App.Data.player.refreshmentType[_i]>> +<</for>> <br> <br>''Skin'': <<textbox "$tempSlave.skin" $tempSlave.skin>> diff --git a/src/events/intro/introSummary.js b/src/events/intro/introSummary.js index 494b7edb30f6ce77128f8f23c0dafed7197b6642..cc7962813c962563b4f45a04accc7c7f28a564af 100644 --- a/src/events/intro/introSummary.js +++ b/src/events/intro/introSummary.js @@ -664,28 +664,7 @@ App.Intro.summary = function() { ["Exotic", "exotic"] ]); - options.addOption("Your preferred refreshment is", "refreshment", V.PC).showTextBox() - .addValue("Cigars", "cigar", () => { V.PC.refreshmentType = 0; }) - .addValue("Whiskey", "whiskey", () => { V.PC.refreshmentType = 1; }); - - option = options.addOption("Which you", "refreshmentType", V.PC) - .addValueList([ - ["Smoke", 0], - ["Drink", 1], - ["Eat", 2], - ["Snort", 3], - ["Inject", 4], - ["Pop", 5], - ["Orally dissolve", 6] - ]); - - if (V.PC.refreshmentType === 0) { - option.addComment(`"Smoked" must fit into the following sentence: "I smoked a ${V.PC.refreshment}" to fit events properly.`); - } else if (V.PC.refreshmentType === 5) { - option.addComment(`"Popped" must fit into the following sentence: "I shook the bottle of ${V.PC.refreshment}" to fit events properly.`); - } else if (V.PC.refreshmentType === 6) { - option.addComment(`"Orally Dissolved" must fit into the following sentence: "I placed a tab of ${V.PC.refreshment} under my tongue" to fit events properly.`); - } + App.Intro.refreshmentChoice(options); option = options.addOption("Before you came to the Free Cities, you were a", "career", V.PC); if (V.PC.career === "arcology owner") { @@ -896,28 +875,8 @@ App.Intro.summary = function() { .addValue("Set custom title", "Master", () => V.PC.customTitleLisp = 'Mather'); } - options.addOption("Your preferred refreshment is", "refreshment", V.PC).showTextBox() - .addValue("Cigars", "cigar", () => { V.PC.refreshmentType = 0; }) - .addValue("Whiskey", "whiskey", () => { V.PC.refreshmentType = 1; }); + App.Intro.refreshmentChoice(options); - option = options.addOption("Which you", "refreshmentType", V.PC) - .addValueList([ - ["Smoke", 0], - ["Drink", 1], - ["Eat", 2], - ["Snort", 3], - ["Inject", 4], - ["Pop", 5], - ["Orally dissolve", 6] - ]); - - if (V.PC.refreshmentType === 0) { - option.addComment(`"Smoked" must fit into the following sentence: "I smoked a ${V.PC.refreshment}" to fit events properly.`); - } else if (V.PC.refreshmentType === 5) { - option.addComment(`"Popped" must fit into the following sentence: "I shook the bottle of ${V.PC.refreshment}" to fit events properly.`); - } else if (V.PC.refreshmentType === 6) { - option.addComment(`"Orally Dissolved" must fit into the following sentence: "I placed a tab of ${V.PC.refreshment} under my tongue" to fit events properly.`); - } el.append(options.render()); r = []; diff --git a/src/events/intro/pcAppearance.js b/src/events/intro/pcAppearance.js index e413c771cb61cb0a6fdaf08d146c68b68128b2c8..a0a821ec0fd81a015d93b3448a6dc83acf84eef5 100644 --- a/src/events/intro/pcAppearance.js +++ b/src/events/intro/pcAppearance.js @@ -22,3 +22,22 @@ App.Intro.pcAppearance = function(options) { return Array.from(iterable, (k => [capFirstChar(k), k])); } }; + +App.Intro.refreshmentChoice = function(options) { + options.addOption("Your preferred refreshment is", "refreshment", V.PC).showTextBox() + .addValue("Cigars", "cigar", () => { V.PC.refreshmentType = 0; }) + .addValue("Whiskey", "whiskey", () => { V.PC.refreshmentType = 1; }); + + const option = options.addOption("Which you", "refreshmentType", V.PC) + .addValueList(Array.from(App.Data.player.refreshmentType, (v, i) => [v, i])); + + let comment = `Flavor only; no mechanical effect. If entering a custom refreshment, please assign proper usage.`; + if (V.PC.refreshmentType === 0) { + comment += ` "Smoked" must fit into the following sentence: "I smoked a ${V.PC.refreshment}" to fit events properly.`; + } else if (V.PC.refreshmentType === 5) { + comment += ` "Popped" must fit into the following sentence: "I shook the bottle of ${V.PC.refreshment}" to fit events properly.`; + } else if (V.PC.refreshmentType === 6) { + comment += ` "Orally Dissolved" must fit into the following sentence: "I placed a tab of ${V.PC.refreshment} under my tongue" to fit events properly.`; + } + option.addComment(comment); +}; diff --git a/src/events/intro/pcBodyIntro.js b/src/events/intro/pcBodyIntro.js new file mode 100644 index 0000000000000000000000000000000000000000..3037e70ebac2ac1c5fe0adf0e313b11f29008293 --- /dev/null +++ b/src/events/intro/pcBodyIntro.js @@ -0,0 +1,184 @@ +App.Intro.PCBodyIntro = function() { + V.PC.actualAge = Math.clamp(V.PC.actualAge, 14, 80); + V.PC.physicalAge = V.PC.actualAge; + V.PC.visualAge = V.PC.actualAge; + + const el = new DocumentFragment(); + let r = []; + + r.push(`Most slaveowners in the Free Cities are male. The preexisting power structures of the old world have mostly migrated to the new, and it can often be very hard to be a free woman in the Free Cities. Some manage to make their way, but in many arcologies, men are the owners, and women are the owned. You'll cut a striking figure as the owner and leader of your arcology, but`); + r.push(App.UI.DOM.makeElement("span", `what's under your business attire?`, ["intro", "question"])); + App.Events.addNode(el, r, "p"); + + el.append(body()); + el.append(age()); + el.append(nameIndulgence()); + el.append(endScene()); + + return el; + + function body() { + const el = document.createElement("p"); + const options = new App.UI.OptionsGroup(); + let r = []; + let comment; + + // Gender + r.push(`You are a`); + if (V.PC.genes === "XX") { + r.push(`woman`); + } else { + r.push(`man`); + } + r.push(`with a`); + if (V.PC.title > 0) { + r.push(`masculine figure and will be referred to as <strong>Master.</strong>`); + } else { + r.push(`feminine figure and will be referred to as <strong>Mistress.</strong>`); + } + options.addOption(r.join(" "), "title", V.PC) + .addValue("Feminine appearance", 0) + .addValue("Masculine appearance", 1) + .addComment("This option will affect scenes. Femininity may increase difficulty in the future, but for now only your chest and junk matter."); + + // Chest + comment = "These options will affect scenes. Sporting breasts will increase difficulty"; + if (V.PC.boobs > 300) { + options.addOption(`Under my suit jacket, <strong>feminine breasts.</strong>`, "boobs", V.PC) + .addValue("Remove breasts", 100).addComment(comment); + } else { + options.addOption(`Under my suit jacket, <strong>${(V.PC.title > 0) ? `masculine muscles` : `a flat chest`}.</strong>`, "boobs", V.PC) + .addValue("Add breasts", 900).addComment(comment); + } + + // Lower deck + comment = `These options will affect sex scenes. Feminine options will increase difficulty.`; + r = []; + r.push(`Behind the front of my tailored`); + if (V.PC.dick !== 0) { + if (V.PC.vagina !== -1) { + r.push(`slacks, <strong>both a penis and a vagina.</strong>`); + options.addOption(r.join(" ")) + .customButton("Remove the penis", penisRemove, "PC Body Intro") + .customButton("Remove the vagina", vaginaRemove, "PC Body Intro"); + } else { + r.push(`slacks, a <strong>penis.</strong>`); + options.addOption(r.join(" ")) + .customButton( + "Switch to vagina", + () => { + penisRemove(); + V.PC.genes = "XX"; + vaginaAdd(); + }, + "PC Body Intro" + ) + .customButton("Add a vagina", vaginaAdd, "PC Body Intro"); + } + } else { + r.push(`skirt, a <strong>vagina.</strong>`); + options.addOption(r.join(" ")) + .customButton( + "Switch to penis", + () => { + penisAdd(); + V.PC.genes = "XY"; + vaginaRemove(); + }, + "PC Body Intro" + ) + .customButton("Add a penis", penisAdd, "PC Body Intro"); + } + + el.append(options.render()); + + return el; + + function penisAdd() { + V.PC.dick = 4; + V.PC.balls = 3; + V.PC.scrotum = 3; + V.PC.prostate = 1; + } + + function penisRemove() { + V.PC.dick = 0; + V.PC.balls = 0; + V.PC.scrotum = 0; + V.PC.prostate = 0; + } + + function vaginaAdd() { + V.PC.vagina = 1; + V.PC.ovaries = 1; + } + + function vaginaRemove() { + V.PC.vagina = -1; + V.PC.ovaries = 0; + } + } + + function age() { + const el = document.createElement("p"); + const options = new App.UI.OptionsGroup(); + + App.UI.DOM.appendNewElement("div", el, `How old are you?`, ["intro", "question"]); + const r = []; + r.push(`I'm`); + if (V.PC.actualAge >= 65) { + r.push(`getting up in years. I've made a legacy for myself, and I'm not done yet.`); + } else if (V.PC.actualAge >= 50) { + r.push(`well into middle age. I've made a name for myself, and I've still got it.`); + } else if (V.PC.actualAge >= 35) { + r.push(`entering middle age. I'm accomplished, and I retain some youthful vigor.`); + } else { + r.push(`surprisingly young. I'll need to prove myself, but I've got energy to burn.`); + } + r.push(`My age:`); + options.addOption(r.join(" "), "actualAge", V.PC).showTextBox() + .addComment(`Older player characters start with more reputation and maintain reputation somewhat more easily, but have slightly less sexual energy.`); + + el.append(options.render()); + + return el; + } + + function nameIndulgence() { + const el = document.createElement("p"); + const options = new App.UI.OptionsGroup(); + + App.UI.DOM.appendNewElement("div", el, `What is your name and alternate indulgence?`, ["intro", "question"]); + + options.addOption(`Name your character: `, "slaveName", V.PC).showTextBox().addComment(`As with all text boxes in FC, press the enter key to commit your changes.`); + options.addOption(`Surname: `, "slaveSurname", V.PC).showTextBox().addComment("Optional"); + + if (V.PC.slaveSurname) { + options.addOption("Go by a single name") + .customButton( + "Apply", + () => { + V.PC.slaveSurname = 0; + V.PC.birthSurname = ""; + }, + "PC Body Intro" + ); + } + App.Intro.refreshmentChoice(options); + + el.append(options.render()); + + return el; + } + + function endScene() { + const el = document.createElement("p"); + const linkTitle = "Confirm player character customization"; + if (V.PC.vagina !== -1) { + el.append(App.UI.DOM.passageLink(linkTitle, "PC Preg Intro")); + } else { + el.append(App.UI.DOM.passageLink(linkTitle, "PC Appearance Intro")); + } + return el; + } +}; diff --git a/src/events/intro/pcBodyIntro.tw b/src/events/intro/pcBodyIntro.tw index 79df64667f1aaae2426df5550764bf93893bdada..1d857050e432f15ae9ece9ee57952db52706c38b 100644 --- a/src/events/intro/pcBodyIntro.tw +++ b/src/events/intro/pcBodyIntro.tw @@ -1,152 +1,3 @@ :: PC Body Intro [nobr] -<p> - Most slaveowners in the Free Cities are male. The preexisting power structures of the old world have mostly migrated to the new, and it can often be very hard to be a free woman in the Free Cities. Some manage to make their way, but in many arcologies, men are the owners, and women are the owned. You'll cut a striking figure as the owner and leader of your arcology, but - <span class="intro question"> - what's under your business attire? - </span> -</p> - -<<set $PC.actualAge = Math.clamp($PC.actualAge, 14, 80)>> - -<p> - <div> - <<if $PC.title > 0>> - You are a <<if $PC.genes == "XX">>wo<</if>>man with a masculine figure and will be referred to as - <span style="font-weight:Bold"> - Master. - </span> - [[Switch to a feminine appearance|PC Body Intro][$PC.title = 0]] - <<else>> - You are a <<if $PC.genes == "XX">>wo<</if>>man with a feminine figure and will be referred to as - <span style="font-weight:Bold"> - Mistress. - </span> - [[Switch to a masculine appearance|PC Body Intro][$PC.title = 1]] - <</if>> - </div> - <div class="indent note"> - This option will affect scenes. Femininity may increase difficulty in the future, but for now only your chest and junk matter. - </div> - - <div> - Under my suit jacket, - <<if $PC.boobs > 300>> - <span style="font-weight:Bold"> - feminine breasts. - </span> - [[Remove breasts|PC Body Intro][$PC.boobs = 100]] - <<else>> - <<if $PC.title > 0>> - <span style="font-weight:Bold"> - masculine muscles. - </span> - [[Add breasts|PC Body Intro][$PC.boobs = 900]] - <<else>> - <span style="font-weight:Bold"> - a flat chest. - </span> - [[Add breasts|PC Body Intro][$PC.boobs = 900]] - <</if>> - <</if>> - <div class="indent note"> - These options will affect scenes. Sporting breasts will increase difficulty. - </div> - </div> - - <div> - Behind the front of my tailored - <<if $PC.dick != 0>> - <<if $PC.vagina != -1>> - slacks, - <span style="font-weight:Bold"> - both a penis and a vagina. - </span> - [[Remove the penis|PC Body Intro][$PC.dick = 0, $PC.balls = 0, $PC.scrotum = 0, $PC.prostate = 0]] | [[Remove the vagina|PC Body Intro][$PC.vagina = -1, $PC.ovaries = 0]] - <<else>> - slacks, a - <span style="font-weight:Bold"> - penis. - </span> - [[Switch to vagina|PC Body Intro][$PC.dick = 0, $PC.balls = 0, $PC.scrotum = 0, $PC.prostate = 0, $PC.genes = "XX", $PC.vagina = 1, $PC.ovaries = 1]] | [[Add a vagina|PC Body Intro][$PC.vagina = 1, $PC.ovaries = 1]] - <</if>> - <<else>> - skirt, a - <span style="font-weight:Bold"> - vagina. - </span> - [[Switch to penis|PC Body Intro][$PC.dick = 4, $PC.balls = 3, $PC.scrotum = 3, $PC.prostate = 1, $PC.genes = "XY", $PC.vagina = -1, $PC.ovaries = 0]] | [[Add a penis|PC Body Intro][$PC.dick = 4, $PC.balls = 3, $PC.scrotum = 3, $PC.prostate = 1]] - <</if>> - </div> - <div class="indent note"> - These options will affect sex scenes. Feminine options will increase difficulty. - </div> -</p> - -<p> - <div class="intro question"> - How old are you? - </div> - <div> - I'm - <<if $PC.actualAge >= 65>> - getting up in years. I've made a legacy for myself, and I'm not done yet. - <<elseif $PC.actualAge >= 50>> - well into middle age. I've made a name for myself, and I've still got it. - <<elseif $PC.actualAge >= 35>> - entering middle age. I'm accomplished, and I retain some youthful vigor. - <<else>> - surprisingly young. I'll need to prove myself, but I've got energy to burn. - <</if>> - My age: - <span style="font-weight:Bold"> - <<textbox "$PC.actualAge" $PC.actualAge "PC Body Intro">> - </span> - <<set $PC.physicalAge = $PC.actualAge, $PC.visualAge = $PC.actualAge>> - </div> - <div class="indent note"> - Older player characters start with more reputation and maintain reputation somewhat more easily, but have slightly less sexual energy. - </div> -</p> - -<p> - <div class="intro question"> - What is your name and alternate indulgence? - </div> - - <div> - Name your character: <<textbox "$PC.slaveName" $PC.slaveName "PC Body Intro">> (surname) - <<if $PC.slaveSurname>> - <<textbox "$PC.slaveSurname" $PC.slaveSurname "PC Body Intro">> - <<link "Go by a single name">><<set $PC.slaveSurname = 0, $PC.birthSurname = "">><<goto "PC Body Intro">><</link>> - <<else>> - <<textbox "$PC.slaveSurname" "" "PC Body Intro">> - <</if>> - </div> - <div class="indent note"> - As with all text boxes in FC, press the enter key to commit your changes. - </div> - <div> - Preferred refreshment: <<textbox "$PC.refreshment" $PC.refreshment "PC Body Intro">> [[Cigars|PC Body Intro][$PC.refreshment = "cigar",$PC.refreshmentType = 0]] | [[Whiskey|PC Body Intro][$PC.refreshment = "whiskey",$PC.refreshmentType = 1]] - </div> - <div> - Preferred method of consumption: - <span style="font-weight:Bold"><<if $PC.refreshmentType == 0>>Smoked<<elseif $PC.refreshmentType == 1>>Drank<<elseif $PC.refreshmentType == 2>>Eaten<<elseif $PC.refreshmentType == 3>>Snorted<<elseif $PC.refreshmentType == 4>>Injected<<elseif $PC.refreshmentType == 5>>Popped<<elseif $PC.refreshmentType == 6>>Dissolved orally<</if>></span>. - </div> - [[Smoked|PC Body Intro][$PC.refreshmentType = 0]] | [[Drank|PC Body Intro][$PC.refreshmentType = 1]] | [[Eaten|PC Body Intro][$PC.refreshmentType = 2]] | [[Snorted|PC Body Intro][$PC.refreshmentType = 3]] | [[Injected|PC Body Intro][$PC.refreshmentType = 4]] | [[Popped|PC Body Intro][$PC.refreshmentType = 5]] | [[Orally Dissolved|PC Body Intro][$PC.refreshmentType = 6]] - <div class="indent note"> - Flavor only; no mechanical effect. If entering a custom refreshment, please assign proper usage. - <<if $PC.refreshmentType == 0>>"Smoke" must fit into the following sentence: "I smoked a $PC.refreshment" to fit events properly - <<elseif $PC.refreshmentType == 5>>"Popped" must fit into the following sentence: "I shook the bottle of $PC.refreshment" to fit events properly - <<elseif $PC.refreshmentType == 6>>"Orally Dissolved" must fit into the following sentence: "I placed a tab of $PC.refreshment under my tongue" to fit events properly - <</if>> - </div> -</p> - -<p> - <<if $PC.vagina != -1>> - [[Confirm player character customization|PC Preg Intro]] - <<else>> - [[Confirm player character customization|PC Appearance Intro]] - <</if>> -</p> +<<includeDOM App.Intro.PCBodyIntro()>> \ No newline at end of file diff --git a/src/gui/options/options.js b/src/gui/options/options.js index 112f8eb8ca0737860d3eef5222d9bb9ff597f090..8fabc3c368bfb78a3614dd084aa9095be640584d 100644 --- a/src/gui/options/options.js +++ b/src/gui/options/options.js @@ -285,6 +285,7 @@ App.UI.OptionsGroup = (function() { } else { option.object[option.property] = Number(O.value); } + App.UI.reload(); }; buttonGroup.append(select); } diff --git a/src/gui/options/optionsPassage.js b/src/gui/options/optionsPassage.js index 4807dce4c2f71b2be9d6ab68a32abc260b9bd904..7c215b4159d2bc819477bfe1cbb16467c2813da5 100644 --- a/src/gui/options/optionsPassage.js +++ b/src/gui/options/optionsPassage.js @@ -1064,4 +1064,4 @@ App.UI.artOptions = function() { } el.append(options.render()); return el; -} +};