v6.1.1 "Echo Hunter"<br>
<<include TierSubtitle>><<if $charview gt 0>>
/* TODO a stat display for this? */
<<if $events.length gt 0>>
<p><<print $events.length>> events left</p>
<</if>>
/*<code>back: <<print $back>></code>*/
<div id="sidebar-stats">
<<include "sidebar stats">>
</div>
<br>
<<if Story.get(passage()).tags.includes("dressing")>>
<p class="framed-icons" style="font-size: smaller">You can change clothes here. ?changing_room</p>
<</if>>
<div class="grid3col" style="margin: auto; font-weight: 900">
<<if not Story.get(passage()).tags.includes("no-deck")>>
<<button "Deck">><<script>>
Dialog.setup("Action Deck", "inv-dialog autoanim");
Dialog.wiki(Story.get("player deck page").processText());
Dialog.open();
<</script>><</button>>
<<else>>
<button disabled>Deck</button>
<</if>>
<<button "Equipment">><<script>>
Dialog.setup("Equipment", "inv-dialog autoanim");
Dialog.wiki(Story.get("player equipment page").processText());
Dialog.open();
<</script>><</button>>
<<button "Inventory">><<script>>
Dialog.setup("Inventory", "inv-dialog autoanim");
Dialog.wiki(Story.get("inventory dialog").processText());
Dialog.open();
<</script>><</button>>
<div style="grid-column: 1/-1">
<<button "What are these icons?">><<script>>
Dialog.setup("Information", "help-dialog");
Dialog.wiki(Story.get("information dialog").processText());
Dialog.open();
<</script>><</button>>
</div>
</div>
/* end of charview check */
<</if>><<set _statbar_stats to ["balance", "corruption", "identity", "fem", "stress", "arousal"]>>
<div class="flexdown">
<div class="flexhoriz" style="font-size: 2em; line-height: 0;">
<span style="font-size: 1.0rem; margin: auto;">Debt: ?money<<print $debt.payment>></span>
<<statnum "money">>
</div>
<<for _stat range _statbar_stats>>
<<statbar _stat>>
<</for>>
</div>
<br>
<div class="flexdown">
<p>Core SIFA Stats:</p>
<<sifa_stats $player_stats.core_stats>>
<<if def $current_loop?.bonuses>>
<p>Equipment Bonuses:</p>
<div style="font-size: 0.55em; margin: auto;">
<<loop_bonuses $current_loop>>
</div>
<</if>>
<p>With Bonuses:</p>
<<sifa_stats>>
</div>SIFA Games[[Game Patreon|https://www.patreon.com/sifagames]]
[[Feedback Discord|https://discord.gg/sZqtvENVXp]]<<include "body cards init">>
<<include "style cards init">>
<<include "clothing cards init">>
<<include "char init">>
<<include "view boxes init">>
<<include "action cards init">>
<<include "enemy init">>
<<include "functions init">>
<<include "other init">><<set setup.matches_current_loop to function(item) {
return (item.id gt 0) and
(item.rarity lt $current_loop.difficulty) and
item.styles.some(st => $current_loop.event_styles.has(st)) and
item.colors.some(cl => $current_loop.event_colors.has(cl));
}>>
<<set setup.items_matching_current_loop to function(category, ...places) {
let droplist = [];
const items = setup["all_" + category];
for(const place of places) {
droplist.push(...items?.[place]?.filter(setup.matches_current_loop));
}
return droplist;
}>>
<<set setup.matches_difficulty to function(item) {
return (item.id gt 0) and
(item.rarity lt $current_loop.difficulty);
}>>
<<set setup.items_matching_difficulty to function(category, ...places) {
let droplist = [];
const items = setup["all_" + category];
for(const place of places) {
droplist.push(...items?.[place]?.filter(setup.matches_difficulty));
}
return droplist;
}>>
<<set setup.item_not_worn to function(item) {
return not item.is_equal($player_equipment[item.place]);
}>>
<<set setup.payment_adjust to function(old_diff, new_diff) {
if(old_diff === new_diff) {
return;
}
$debt.payment = Math.max(0, Math.round(setup.payments[new_diff][$debt.index] - (setup.payments[old_diff][$debt.index] - $debt.payment)));
}>>
/* given an array of items, return a list with numeric weights for each item
* where carrying *fewer* items in a category weights it higher */
<<set setup.weight_items_by_carried to function(item_list) {
const quants = $inv.quantities();
let max_quant = 0;
for(const place in quants) {
if($player_equipment[place].id !== 0) {
quants[place] += 1;
}
max_quant = Math.max(max_quant, quants[place]);
}
max_quant += 1; /* so every answer is at least 1 */
for(const place in quants) {
quants[place] = max_quant - quants[place];
}
return item_list.map((item) => quants[item.place] ?? 1);
}>><<set $back to []>>
<<set $temp to {}>>
<<set $complete_difficulty to 0>>
<<set $loop_choices to []>>
<<set $events to []>>
<<set $charview to 0>>
<<set $debug_passages to new Set()>>
<<set $game_difficulty to 1>>
<<set setup.event_passages to {}>>
<<for _tag range ["event", "instant-event", "complex-event"]>>
<<set setup.event_passages[_tag] to Story.lookup("tags", _tag).map(p => p.title)>>
<</for>>
/*<<set setup.event_passages.all to Array.from(new Set(Object.values(setup.event_passages).flat()))>>*/
<<set setup.ok_choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<set setup.payments to [
null, /* so we count from 1 */
[100, 110, 130, 160, 200, 250, 310, 380, 460, 550],
[150, 165, 195, 240, 300, 375, 465, 570, 690, 825],
[200, 220, 260, 320, 400, 500, 620, 760, 920, 1100],
]>>
<<set setup.interest_rates to [0.5, 0.3, 0.2, 0.1, 0.05]>>
<<set $debt to {
payment: setup.payments[$game_difficulty][0],
index: 0,
/* interest_idx: 0, */
}>><<set setup.all_body to {
body: [
new EquipItem({name:"Male Body", gender:"male", styles: ["male"], rarity:"common", fem:-2, hips:1, waist:1, shoulders:1, boobs:0, nipples:1, sub: 0, int: 0, fit: 1, att: 0}),
new EquipItem({name:"Male Body", gender:"male", styles: ["male"], rarity:"common", fem:-1, hips:1, waist:1, shoulders:1, boobs:0, nipples:2, sub: 0, int: 0, fit: 1, att: 0}),
new EquipItem({name:"Male Body", gender:"male", styles: ["male"], rarity:"rare", fem:-1, hips:1, waist:2, shoulders:1, boobs:0, nipples:2, sub: 0, int: 0, fit: 2, att: 0}),
new EquipItem({name:"Male Body", gender:"male", styles: ["male"], rarity:"rare", fem:-1, hips:2, waist:2, shoulders:1, boobs:0, nipples:2, sub: 0, int: 0, fit: 3, att: 0}),
new EquipItem({name:"Male Body", gender:"male", styles: ["male"], rarity:"rare", fem:0, hips:2, waist:2, shoulders:2, boobs:0, nipples:2, sub: 0, int: 0, fit: 2, att: 1}),
new EquipItem({name:"Androgen Body", gender:"unisex", styles: ["unisex"], rarity:"rare", fem:1, hips:2, waist:2, shoulders:2, boobs:2, nipples:2, sub: 0, int: 0, fit: 1, att: 2}),
new EquipItem({name:"Androgen Body", gender:"unisex", styles: ["unisex"], rarity:"epic", fem:1, hips:2, waist:3, shoulders:2, boobs:2, nipples:2, sub: 0, int: 0, fit: 2, att: 2}),
new EquipItem({name:"Androgen Body", gender:"unisex", styles: ["unisex"], rarity:"epic", fem:1, hips:2, waist:3, shoulders:2, boobs:2, nipples:3, sub: 0, int: 0, fit: 1, att: 3}),
new EquipItem({name:"Androgen Body", gender:"unisex", styles: ["unisex"], rarity:"epic", fem:2, hips:2, waist:3, shoulders:3, boobs:2, nipples:3, sub: 0, int: 0, fit: 2, att: 3}),
new EquipItem({name:"Female Body", gender:"female", styles: ["female"], rarity:"epic", fem:2, hips:2, waist:3, shoulders:3, boobs:4, nipples:3, sub: 0, int: 0, fit: 0, att: 4}),
new EquipItem({name:"Female Body", gender:"female", styles: ["female"], rarity:"epic", fem:2, hips:3, waist:3, shoulders:3, boobs:4, nipples:3, sub: 0, int: 0, fit: 1, att: 4}),
new EquipItem({name:"Female Body", gender:"female", styles: ["female"], rarity:"legendary", fem:2, hips:3, waist:3, shoulders:3, boobs:4, nipples:4, sub: 0, int: 0, fit: 1, att: 5}),
],
/* would be nice to fix the order, but its also about fixing all the bottom clothes */
penis: [
new EquipItem({name:"Pussy", gender:"female", styles: ["female"], rarity:"epic", fem:2, sub: 4}),
new EquipItem({name:"Tiny Clitty", gender:"female", styles: ["female"], rarity:"legendary", fem:2, sub: 4, fit: 1}),
new EquipItem({name:"Little Winkle", gender:"male", styles: ["unisex"], rarity:"epic", fem:1, sub: 3, int: 0, fit: 1, att: 0}),
new EquipItem({name:"Small Prick", gender:"male", styles: ["unisex"], rarity:"rare", fem:0, sub: 2, int: 0, fit: 1, att: 0}),
new EquipItem({name:"Normal Stick", gender:"male", styles: ["male"], rarity:"common", fem:-1, sub: 0, int: 0, fit: 2, att: 0}),
new EquipItem({name:"Big Tool", gender:"male", styles: ["male"], rarity:"epic", fem:-2, sub: 0, int: 0, fit: 4, att: 0}),
],
face: [
new EquipItem({name:"Masculine Face", gender:"male", styles: ["male"], head:1, rarity:"common", fem:-1, sub: 0, int: 0, fit: 0, att: 0}),
new EquipItem({name:"Boy Face", gender:"male", styles: ["male"], head:2, rarity:"rare", fem:-0, sub: 0, int: 0, fit: 0, att: 1}),
new EquipItem({name:"Femboy Face", gender:"male", styles: ["unisex"], head:2, rarity:"epic", fem:1, sub: 0, int: 0, fit: 0, att: 2}),
new EquipItem({name:"Girly Face", gender:"female", styles: ["female"], head:2, rarity:"legendary", fem:2, sub: 0, int: 0, fit: 0, att: 3}),
],
hair: [
new EquipItem({name:"Short Hair", gender:"male", styles: ["male"], ears:"both", rarity:"common", fem:-1, sub: 0, int: 0, fit: 1, att: 0}),
new EquipItem({name:"Medium Hair", gender:"unisex", styles: ["unisex"], ears:"right", rarity:"rare", fem:0, sub: 0, int: 1, fit: 0, att: 1}),
new EquipItem({name:"Long Hair", gender:"female", styles: ["female"], ears:"left", rarity:"epic", fem:1, sub: 1, int: 1, fit: 0, att: 1}),
],
nails: [
new EquipItem({name:"Short Nails", gender:"male", styles: ["male"], rarity:"common", fem:-1, sub: 0, int: 0, fit: 1, att: 0}),
new EquipItem({name:"Long Nails", gender:"female", styles: ["female"], rarity:"rare", fem:1, sub: 1, int: 0, fit: 0, att: 1}),
],
}>>
<<for _place, _list range setup.all_body>>
<<for _id, _bd range _list>>
<<set _bd.id to _id>>
<<set _bd.place to _place>>
<</for>>
<</for>>/* more feminine styles get higher rarity.
In the lore it's explained like "males don't even use most of style options, styles are more for women.
So the most feminine stuff is quite hard to find" */
<<set setup.all_styles to {
hairstyle: [
new EquipItem({name:"Natural Hair", ears: ["both", "right", "left"], colors: ["black"], styles: ["unisex"], rarity:"rare", int:1, att:1}),
new EquipItem({name:"Natural Hair", ears: ["both", "right", "left"], colors: ["blonde"], styles: ["unisex"], rarity:"rare", int:1, att:1}),
new EquipItem({name:"Natural Hair", ears: ["both", "right", "left"], colors: ["blue"], styles: ["unisex"], rarity:"rare", int:1, att:1}),
new EquipItem({name:"Natural Hair", ears: ["both", "right", "left"], colors: ["brown"], styles: ["unisex"], rarity:"rare", int:1, att:1}),
new EquipItem({name:"Natural Hair", ears: ["both", "right", "left"], colors: ["darkblue"], styles: ["unisex"], rarity:"rare", int:1, att:1}),
new EquipItem({name:"Natural Hair", ears: ["both", "right", "left"], colors: ["ginger"], styles: ["unisex"], rarity:"rare", int:1, att:1}),
new EquipItem({name:"Natural Hair", ears: ["both", "right", "left"], colors: ["gray"], styles: ["unisex"], rarity:"rare", int:1, att:1}),
new EquipItem({name:"Natural Hair", ears: ["both", "right", "left"], colors: ["green"], styles: ["unisex"], rarity:"rare", int:1, att:1}),
new EquipItem({name:"Natural Hair", ears: ["both", "right", "left"], colors: ["pink"], styles: ["unisex"], rarity:"rare", int:1, att:1}),
new EquipItem({name:"Natural Hair", ears: ["both", "right", "left"], colors: ["purple"], styles: ["unisex"], rarity:"rare", int:1, att:1}),
new EquipItem({name:"Natural Hair", ears: ["both", "right", "left"], colors: ["red"], styles: ["unisex"], rarity:"rare", int:1, att:1}),
new EquipItem({name:"Natural Hair", ears: ["both", "right", "left"], colors: ["white"], styles: ["unisex"], rarity:"rare", int:1, att:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["black"], styles: ["unisex"], rarity:"epic", int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["blonde"], styles: ["unisex"], rarity:"epic", int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["blue"], styles: ["unisex"], rarity:"epic", int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["brown"], styles: ["unisex"], rarity:"epic", int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["darkblue"], styles: ["unisex"], rarity:"epic", int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["ginger"], styles: ["unisex"], rarity:"epic", int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["gray"], styles: ["unisex"], rarity:"epic", int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["green"], styles: ["unisex"], rarity:"epic", int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["pink"], styles: ["unisex"], rarity:"epic", int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["purple"], styles: ["unisex"], rarity:"epic", int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["red"], styles: ["unisex"], rarity:"epic", int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["white"], styles: ["unisex"], rarity:"epic", int:1, sub:1}),
],
makeup: [
new EquipItem({name:"No Makeup", gender:"male", colors: ["nocolor"], styles: ["male"], rarity:"common"}),
new EquipItem({name:"Natural Makeup", gender:"unisex", colors: ["black", "pink"], styles: ["unisex"], rarity:"common", att:1}),
new EquipItem({name:"Light Makeup", gender:"female", colors: ["black", "pink"], styles: ["female"], rarity:"rare", att:2}),
new EquipItem({name:"Heavy Makeup", gender:"female", colors: ["black", "pink"], styles: ["female"], rarity:"epic", att:3}),
],
lipstick: [
new EquipItem({name:"No Lipstick", gender:"male", colors: ["nocolor"], styles: ["male"], rarity:"common"}),
new EquipItem({name:"Soft Lipstick", gender:"unisex", colors: ["black"], styles: ["unisex"], rarity:"common", int:1}),
new EquipItem({name:"Soft Lipstick", gender:"unisex", colors: ["red"], styles: ["unisex"], rarity:"common", att:1}),
new EquipItem({name:"Soft Lipstick", gender:"unisex", colors: ["pink"], styles: ["unisex"], rarity:"common", sub:1}),
new EquipItem({name:"Subtle Lipstick", gender:"female", colors: ["black"], styles: ["female"], rarity:"rare", int:2}),
new EquipItem({name:"Subtle Lipstick", gender:"female", colors: ["red"], styles: ["female"], rarity:"rare", att:2}),
new EquipItem({name:"Subtle Lipstick", gender:"female", colors: ["pink"], styles: ["female"], rarity:"rare", sub:2}),
new EquipItem({name:"Bold Lipstick", gender:"female", colors: ["black"], styles: ["female"], rarity:"epic", int:3}),
new EquipItem({name:"Bold Lipstick", gender:"female", colors: ["red"], styles: ["female"], rarity:"epic", att:3}),
new EquipItem({name:"Bold Lipstick", gender:"female", colors: ["pink"], styles: ["female"], rarity:"epic", sub:3}),
],
nail_polish: [
new EquipItem({name:"No Polish Nails", gender:"male", colors: ["nocolor"], styles: ["male"], rarity:"common"}),
new EquipItem({name:"Nail Polish", gender:"unisex", colors: ["transparent"], styles: ["unisex"], rarity:"common", fit:1}),
new EquipItem({name:"Nail Polish", gender:"unisex", colors: ["black"], styles: ["unisex"], rarity:"common", int:1}),
new EquipItem({name:"Nail Polish", gender:"female", colors: ["blue"], styles: ["female"], rarity:"common", att:1}),
new EquipItem({name:"Nail Polish", gender:"female", colors: ["white"], styles: ["female"], rarity:"common", sub:1}),
new EquipItem({name:"Nail Polish", gender:"female", colors: ["red"], styles: ["female"], rarity:"rare", sub:2}),
new EquipItem({name:"Nail Polish", gender:"female", colors: ["pink"], styles: ["female"], rarity:"rare", att:2}),
],
toenail_polish: [
new EquipItem({name:"No Polish Toenails", gender:"male", colors: ["nocolor"], styles: ["male"], rarity:"common"}),
new EquipItem({name:"Toenail Polish", gender:"unisex", colors: ["transparent"], styles: ["unisex"], rarity:"common", fit:1}),
new EquipItem({name:"Toenail Polish", gender:"unisex", colors: ["black"], styles: ["unisex"], rarity:"common", int:1}),
new EquipItem({name:"Toenail Polish", gender:"female", colors: ["blue"], styles: ["female"], rarity:"common", att:1}),
new EquipItem({name:"Toenail Polish", gender:"female", colors: ["white"], styles: ["female"], rarity:"common", sub:1}),
new EquipItem({name:"Toenail Polish", gender:"female", colors: ["red"], styles: ["female"], rarity:"rare", sub:2}),
new EquipItem({name:"Toenail Polish", gender:"female", colors: ["pink"], styles: ["female"], rarity:"rare", att:2}),
],
}>>
<<for _place, _list range setup.all_styles>>
<<for _id, _st range _list>>
<<set _st.id to _id>>
<<set _st.place to _place>>
<</for>>
<</for>>
<<stylesfemgen setup.all_styles.hairstyle "mid">>
<<stylesfemgen setup.all_styles.makeup "mid">>
<<stylesfemgen setup.all_styles.lipstick "small">>
<<stylesfemgen setup.all_styles.nail_polish "small">>
<<stylesfemgen setup.all_styles.toenail_polish "small">><<widget "stylesfemgen">>
<<set _scale to _args[1]>>
<<for _item range _args[0]>>
<<set _fem to _item.base_fem ?? 0>>
<<set _genpts to {
small: {
male: {fem: 0},
unisex: {fem: 0},
female: {fem: 1},
},
mid: {
male: {fem: -1},
unisex: {fem: 1},
female: {fem: 2},
},
big: {
male: {fem: -3},
unisex: {fem: 2},
female: {fem: 7},
},
}>>
<<set _fem += _genpts[_scale]?.[_item.styles]?.fem ?? 0>>
<<set _rarpts to {
common: {fem: 0},
rare: {fem: 0},
epic: {fem: 0},
legendary: {fem: 1},
}>>
<<set _rar to _item.rarity>>
<<set _fem += _rarpts[_rar]?.fem ?? 0>>
<<set _colorpts to {
black: {fem: -1},
blonde: {fem: 1},
blue: {fem: 1},
brown: {fem: -1},
darkblue: {fem: -1},
ginger: {fem: 0},
gray: {fem: 0},
green: {fem: 0},
pink: {fem: 2},
purple: {fem: 2},
red: {fem: 1},
white: {fem: 1},
cyan: {fem: 1},
nocolor: {fem:0},
transparent:{fem:0},
}>>
<<for _col range _item.colors>>
<<set _fem += _colorpts?.[_col]?.fem ?? 0>>
<</for>>
<<set _item.base_fem to Math.clamp(_fem, -2, 2)>>
<</for>>
<</widget>><<set setup.all_clothes to {
undies: [
new EquipItem({name:"No Undies", gender: "unisex", colors: ["nocolor"], styles: ["lewd", "lewd"]}),
new EquipItem({name:"Boxers", gender: "male", colors: ["black", "white"], styles: ["formal", "modest"]}),
new EquipItem({name:"Boxers", gender: "male", colors: ["blue", "white"], styles: ["formal", "modest"]}),
new EquipItem({name:"Boxers", gender: "male", colors: ["white", "pink"], styles: ["formal", "modest"]}),
new EquipItem({name:"Boxers", gender: "male", colors: ["red", "white"], styles: ["formal", "modest"]}),
new EquipItem({name:"Boxers", gender: "male", colors: ["pink", "cyan"], styles: ["formal", "modest"]}),
new EquipItem({name:"Briefs", gender: "unisex", colors: ["black"], styles: ["active"]}),
new EquipItem({name:"Briefs", gender: "unisex", colors: ["blue"], styles: ["active"]}),
new EquipItem({name:"Briefs", gender: "unisex", colors: ["white"], styles: ["active"]}),
new EquipItem({name:"Briefs", gender: "unisex", colors: ["red"], styles: ["active"]}),
new EquipItem({name:"Briefs", gender: "unisex", colors: ["pink"], styles: ["active"]}),
new EquipItem({name:"Heart Thongs", gender: "female", colors: ["green", "white"], styles: ["comfy", "party", "cute"]}),
new EquipItem({name:"Heart Thongs", gender: "female", colors: ["red", "white"], styles: ["comfy", "party", "cute"]}),
new EquipItem({name:"Heart Boxers", gender: "male", colors: ["green", "white"], styles: ["comfy", "party", "cute"]}),
new EquipItem({name:"Heart Boxers", gender: "male", colors: ["red", "white"], styles: ["comfy", "party", "cute"]}),
new EquipItem({name:"Thongs", gender: "female", colors: ["black"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Striped Panties", gender: "unisex", colors: ["black", "pink"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Striped Panties", gender: "unisex", colors: ["white", "cyan"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Striped Panties", gender: "unisex", colors: ["multicolor"], styles: ["study", "party"]}),
new EquipItem({name:"Striped Panties", gender: "unisex", colors: ["cyan", "pink", "white"], styles: ["study", "party"]}),
new EquipItem({name:"Heart Panties", gender: "female", colors: ["black", "red"], styles: ["casual", "cute"]}),
new EquipItem({name:"Heart Panties", gender: "female", colors: ["blue", "red"], styles: ["casual", "cute"]}),
new EquipItem({name:"Heart Panties", gender: "female", colors: ["cyan", "white"], styles: ["casual", "cute"]}),
new EquipItem({name:"Heart Panties", gender: "female", colors: ["green", "red"], styles: ["casual", "cute"]}),
new EquipItem({name:"Heart Panties", gender: "female", colors: ["pink", "red"], styles: ["casual", "cute"]}),
new EquipItem({name:"Heart Panties", gender: "female", colors: ["red", "black"], styles: ["casual", "cute"]}),
new EquipItem({name:"Heart Panties", gender: "female", colors: ["white", "red"], styles: ["casual", "cute"]}),
new EquipItem({name:"Lace Panties", gender: "female", colors: ["black"], styles: ["casual", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Panties", gender: "female", colors: ["white"], styles: ["casual", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Panties", gender: "female", colors: ["blue"], styles: ["casual", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Panties", gender: "female", colors: ["green"], styles: ["casual", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Panties", gender: "female", colors: ["pink"], styles: ["casual", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Panties", gender: "female", colors: ["red"], styles: ["casual", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Retro Panties", gender: "female", colors: ["black"], styles: ["formal", "comfy", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Retro Panties", gender: "female", colors: ["white"], styles: ["formal", "comfy", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Retro Panties", gender: "female", colors: ["blue"], styles: ["formal", "comfy", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Retro Panties", gender: "female", colors: ["green"], styles: ["formal", "comfy", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Retro Panties", gender: "female", colors: ["pink"], styles: ["formal", "comfy", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Retro Panties", gender: "female", colors: ["red"], styles: ["formal", "comfy", "sexy"], extra: ["lace"]}),
],
bra: [
new EquipItem({name:"No Bra", gender:"unisex", colors: ["nocolor"], styles: []}),
new EquipItem({name:"Beginners Bra", gender:"unisex", colors: ["black"], styles: ["study", "comfy"]}),
new EquipItem({name:"Beginners Bra", gender:"unisex", colors: ["red"], styles: ["study", "comfy"]}),
new EquipItem({name:"Beginners Bra", gender:"unisex", colors: ["white"], styles: ["study", "comfy"]}),
new EquipItem({name:"Beginners Bra", gender:"unisex", colors: ["pink"], styles: ["study", "comfy"]}),
new EquipItem({name:"Beginners Bra", gender:"unisex", colors: ["blue"], styles: ["study", "comfy"]}),
new EquipItem({name:"Crop Cami", gender:"female", colors: ["black"], styles: ["modest"]}),
new EquipItem({name:"Crop Cami", gender:"female", colors: ["blue"], styles: ["modest"]}),
new EquipItem({name:"Crop Cami", gender:"female", colors: ["white"], styles: ["modest"]}),
new EquipItem({name:"Crop Cami", gender:"female", colors: ["red"], styles: ["modest"]}),
new EquipItem({name:"Crop Cami", gender:"female", colors: ["pink"], styles: ["modest"]}),
new EquipItem({name:"Sports Bra", gender:"unisex", colors: ["black"], styles: ["active", "comfy"], extra: ["tight"]}),
new EquipItem({name:"Sports Bra", gender:"unisex", colors: ["blue"], styles: ["active", "comfy"], extra: ["tight"]}),
new EquipItem({name:"Sports Bra", gender:"unisex", colors: ["green"], styles: ["active", "comfy"], extra: ["tight"]}),
new EquipItem({name:"Sports Bra", gender:"unisex", colors: ["pink", "white"], styles: ["active", "comfy"], extra: ["tight"]}),
new EquipItem({name:"Sports Bra", gender:"unisex", colors: ["red"], styles: ["active", "comfy"], extra: ["tight"]}),
new EquipItem({name:"Sports Bra", gender:"unisex", colors: ["white", "black"], styles: ["active", "comfy"], extra: ["tight"]}),
new EquipItem({name:"Push-Up Bra", gender:"female", colors: ["black"], styles: ["casual", "cute"]}),
new EquipItem({name:"Push-Up Bra", gender:"female", colors: ["blue"], styles: ["casual", "cute"]}),
new EquipItem({name:"Push-Up Bra", gender:"female", colors: ["white"], styles: ["casual", "cute"]}),
new EquipItem({name:"Push-Up Bra", gender:"female", colors: ["red"], styles: ["casual", "cute"]}),
new EquipItem({name:"Push-Up Bra", gender:"female", colors: ["pink"], styles: ["casual", "cute"]}),
new EquipItem({name:"Heart Bra", gender:"female", colors: ["green", "white"], styles: ["party", "cute", "sexy"]}),
new EquipItem({name:"Heart Bra", gender:"female", colors: ["red", "white"], styles: ["party", "cute", "sexy"]}),
new EquipItem({name:"Lace Bra", gender:"female", colors: ["black", ], styles: ["formal", "sexy"], extra: ["lace", "transparent"]}),
new EquipItem({name:"Lace Bra", gender:"female", colors: ["blue"], styles: ["formal", "sexy"], extra: ["lace", "transparent"]}),
new EquipItem({name:"Lace Bra", gender:"female", colors: ["green"], styles: ["formal", "sexy"], extra: ["lace", "transparent"]}),
new EquipItem({name:"Lace Bra", gender:"female", colors: ["pink"], styles: ["formal", "sexy"], extra: ["lace", "transparent"]}),
new EquipItem({name:"Lace Bra", gender:"female", colors: ["red"], styles: ["formal", "sexy"], extra: ["lace", "transparent"]}),
new EquipItem({name:"Lace Bra", gender:"female", colors: ["white"], styles: ["formal", "sexy"], extra: ["lace", "transparent"]}),
new EquipItem({name:"Strapless Bra", gender:"female", colors: ["black"], styles: ["casual", "party", "sexy"]}),
],
bottom: [
new EquipItem({name:"No Bottom", gender:"unisex", colors: ["nocolor"], styles: ["lewd"]}),
new EquipItem({name:"Pants", gender:"male", colors: ["black"], styles: ["formal", "modest"]}),
new EquipItem({name:"Pants", gender:"male", colors: ["white"], styles: ["formal", "modest"]}),
new EquipItem({name:"Pants", gender:"male", colors: ["pink"], styles: ["formal", "modest"]}),
new EquipItem({name:"High Waisted Pants", gender:"female", colors: ["black"], styles: ["formal", "casual"]}),
new EquipItem({name:"High Waisted Pants", gender:"female", colors: ["white"], styles: ["formal", "casual"]}),
new EquipItem({name:"High Waisted Pants", gender:"female", colors: ["pink"], styles: ["formal", "casual"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["black"], styles: ["formal"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["white"], styles: ["formal"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["pink"], styles: ["formal"]}),
new EquipItem({name:"Mini Tube Skirt", gender:"female", colors: ["black"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Mini Tube Skirt", gender:"female", colors: ["white"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Mini Tube Skirt", gender:"female", colors: ["pink"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"female", colors: ["black", "white"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"female", colors: ["blue", "white"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"female", colors: ["green", "white"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"female", colors: ["pink", "white"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"female", colors: ["red", "black"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"female", colors: ["white", "black"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Denim Shorts", gender:"unisex", colors: ["black"], styles: ["casual", "party"]}),
new EquipItem({name:"Denim Shorts", gender:"unisex", colors: ["blue"], styles: ["casual", "party"]}),
new EquipItem({name:"Denim Shorts", gender:"unisex", colors: ["green"], styles: ["casual", "party"]}),
new EquipItem({name:"Denim Shorts", gender:"unisex", colors: ["white"], styles: ["casual", "party"]}),
new EquipItem({name:"Denim Shorts", gender:"unisex", colors: ["red"], styles: ["casual", "party"]}),
new EquipItem({name:"Denim Shorts", gender:"unisex", colors: ["pink"], styles: ["casual", "party"]}),
new EquipItem({name:"Seifuku Pants", gender:"male", colors: ["black"], styles: ["study"]}),
new EquipItem({name:"Seifuku Pants", gender:"male", colors: ["blue"], styles: ["study"]}),
new EquipItem({name:"Seifuku Pants", gender:"male", colors: ["cyan"], styles: ["study"]}),
new EquipItem({name:"Seifuku Pants", gender:"male", colors: ["green"], styles: ["study"]}),
new EquipItem({name:"Seifuku Pants", gender:"male", colors: ["pink"], styles: ["study"]}),
new EquipItem({name:"Seifuku Pants", gender:"male", colors: ["white"], styles: ["study"]}),
new EquipItem({name:"Seifuku Long Skirt", gender:"female", colors: ["black"], styles: ["study"]}),
new EquipItem({name:"Seifuku Long Skirt", gender:"female", colors: ["blue"], styles: ["study"]}),
new EquipItem({name:"Seifuku Long Skirt", gender:"female", colors: ["cyan"], styles: ["study"]}),
new EquipItem({name:"Seifuku Long Skirt", gender:"female", colors: ["green"], styles: ["study"]}),
new EquipItem({name:"Seifuku Long Skirt", gender:"female", colors: ["pink"], styles: ["study"]}),
new EquipItem({name:"Seifuku Long Skirt", gender:"female", colors: ["white"], styles: ["study"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["black", "red"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["blue", "brown"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["blue", "white"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["cyan"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["green", "white"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["pink", "white"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["red", "white"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["white", "black"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Formal Pants", gender:"female", colors: ["black"], styles: ["formal", "study", "party"]}),
new EquipItem({name:"Winter Pants", gender:"male", colors: ["green", "white"], styles: ["comfy", "party"], extra: ["thick"]}),
new EquipItem({name:"Winter Pants", gender:"male", colors: ["red", "white"], styles: ["comfy", "party"], extra: ["thick"]}),
new EquipItem({name:"Winter Short Skirt", gender:"female", colors: ["green", "white", "black"], styles: ["comfy", "party", "cute"], extra: ["thick"]}),
new EquipItem({name:"Winter Short Skirt", gender:"female", colors: ["red", "white", "black"], styles: ["comfy", "party", "cute"], extra: ["thick"]}),
],
top: [
new EquipItem({name:"No Top", gender:"unisex", colors: ["nocolor"], styles: ["lewd"]}),
new EquipItem({name:"T-Shirt", gender:"male", colors: ["black"], styles: ["active", "casual"]}),
new EquipItem({name:"T-Shirt", gender:"male", colors: ["white"], styles: ["active", "casual"]}),
new EquipItem({name:"T-Shirt", gender:"male", colors: ["pink"], styles: ["active", "casual"]}),
new EquipItem({name:"Tank Top", gender:"unisex", colors: ["pink"], styles: ["active"]}),
new EquipItem({name:"Tank Top", gender:"unisex", colors: ["black"], styles: ["active"]}),
new EquipItem({name:"Tank Top", gender:"unisex", colors: ["white"], styles: ["active"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["white"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["black"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["red"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["pink"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Light Shirt", gender:"unisex", colors: ["black", "red"], styles: ["modest", "study"], extra: ["baggy"]}),
new EquipItem({name:"Light Shirt", gender:"unisex", colors: ["cyan"], styles: ["modest", "study"], extra: ["baggy"]}),
new EquipItem({name:"Light Shirt", gender:"unisex", colors: ["white", "blue", "red"], styles: ["modest", "study"], extra: ["baggy"]}),
new EquipItem({name:"Light Shirt", gender:"unisex", colors: ["white", "green"], styles: ["modest", "study"], extra: ["baggy"]}),
new EquipItem({name:"Light Shirt", gender:"unisex", colors: ["white", "pink", "red"], styles: ["modest", "study"], extra: ["baggy"]}),
new EquipItem({name:"Light Shirt", gender:"unisex", colors: ["yellow", "black"], styles: ["modest", "study"], extra: ["baggy"]}),
new EquipItem({name:"Sailor Shirt", gender:"unisex", colors: ["black", "red"], styles: ["study", "cute"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Shirt", gender:"unisex", colors: ["cyan"], styles: ["study", "cute"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Shirt", gender:"unisex", colors: ["white", "blue", "red"], styles: ["study", "cute"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Shirt", gender:"unisex", colors: ["white", "green"], styles: ["study", "cute"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Shirt", gender:"unisex", colors: ["white", "pink", "red"], styles: ["study", "cute"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Shirt", gender:"unisex", colors: ["yellow", "black"], styles: ["study", "cute"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Crop Top", gender:"female", colors: ["black", "red"], styles: ["study", "party", "sexy"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Crop Top", gender:"female", colors: ["cyan"], styles: ["study", "party", "sexy"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Crop Top", gender:"female", colors: ["white", "blue", "red"], styles: ["study", "party", "sexy"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Crop Top", gender:"female", colors: ["white", "green"], styles: ["study", "party", "sexy"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Crop Top", gender:"female", colors: ["white", "pink", "red"], styles: ["study", "party", "sexy"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Crop Top", gender:"female", colors: ["white", "red"], styles: ["study", "party", "sexy"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Crop Top", gender:"female", colors: ["yellow", "black"], styles: ["study", "party", "sexy"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Vest", gender:"male", colors: ["red", "yellow", "white"], styles: ["active", "party"]}),
new EquipItem({name:"Vest", gender:"male", colors: ["green", "yellow", "white"], styles: ["active", "party"]}),
new EquipItem({name:"Blouse", gender:"female", colors: ["green", "white", "red"], styles: ["comfy", "party", "cute"]}),
new EquipItem({name:"Blouse", gender:"female", colors: ["red", "white", "green"], styles: ["comfy", "party", "cute"]}),
],
shoes: [
new EquipItem({name:"No Shoes", gender:"unisex", colors: ["nocolor"], styles: []}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["black"], styles: ["formal"]}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["black", "red"], styles: ["formal"]}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["cyan"], styles: ["formal"]}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["green"], styles: ["formal"]}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["pink"], styles: ["formal"]}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["pink", "black"], styles: ["formal"]}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["red", "black"], styles: ["formal"]}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["white", "black"], styles: ["formal"]}),
new EquipItem({name:"Sneakers", gender:"unisex", colors: ["black", "white"], styles: ["active", "party", "casual"]}),
new EquipItem({name:"Sneakers", gender:"unisex", colors: ["cyan", "white"], styles: ["active", "casual"]}),
new EquipItem({name:"Sneakers", gender:"unisex", colors: ["green", "white"], styles: ["active", "casual"]}),
new EquipItem({name:"Sneakers", gender:"unisex", colors: ["pink", "white"], styles: ["active", "party", "casual"]}),
new EquipItem({name:"Sneakers", gender:"unisex", colors: ["red", "white"], styles: ["active", "party", "casual"]}),
new EquipItem({name:"Sneakers", gender:"unisex", colors: ["white"], styles: ["active", "casual"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["black", "red"], styles: ["study", "comfy"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["black"], styles: ["study", "comfy"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["cyan"], styles: ["study", "comfy"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["green"], styles: ["study", "comfy"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["pink", "white"], styles: ["study", "comfy"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["pink"], styles: ["study", "comfy"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["red"], styles: ["study", "comfy"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["white"], styles: ["study", "comfy"]}),
new EquipItem({name:"Womens Oxfords", gender:"female", colors: ["brown", "black"], styles: ["formal", "study", "party"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["black", "black"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["cyan"], styles: ["study", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["green"], styles: ["study", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["pink"], styles: ["study", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["pink", "black"], styles: ["study", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["pink", "white"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["red"], styles: ["study", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["white"], styles: ["study", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["white", "black"], styles: ["study", "cute"]}),
new EquipItem({name:"Winter Boots", gender:"male", colors: ["black"], styles: ["modest", "party"]}),
new EquipItem({name:"Winter Boots", gender:"male", colors: ["green", "white"], styles: ["modest", "party"]}),
new EquipItem({name:"Winter Boots", gender:"male", colors: ["red", "white"], styles: ["modest", "party"]}),
new EquipItem({name:"Winter Heels", gender:"female", colors: ["green", "white"], styles: ["party", "cute"], extra: ["highheels"]}),
new EquipItem({name:"Winter Heels", gender:"female", colors: ["red", "white"], styles: ["party", "cute"], extra: ["highheels"]}),
],
legwear: [
new EquipItem({name:"No Legwear", gender:"unisex", colors: ["nocolor"], styles: []}),
new EquipItem({name:"Long Socks", gender:"male", colors: ["white", "green"], styles: ["formal", "modest"]}),
new EquipItem({name:"Long Socks", gender:"male", colors: ["white", "red"], styles: ["formal", "modest"]}),
new EquipItem({name:"Ankle Socks", gender:"unisex", colors: ["white"], styles: ["active", "casual"]}),
new EquipItem({name:"Small Bow Stockings", gender:"female", colors: ["brown", "green", "white"], styles: ["party", "cute"], extra: ["transparent"]}),
new EquipItem({name:"Small Bow Stockings", gender:"female", colors: ["brown", "red", "white"], styles: ["party", "cute"], extra: ["transparent"]}),
new EquipItem({name:"Stockings", gender:"female", colors: ["brown", "black"], styles: ["formal", "casual", "sexy"], extra: ["transparent"]}),
new EquipItem({name:"Seifuku Thigh Highs", gender:"female", colors: ["black", "red"], styles: ["study", "party", "comfy"]}),
new EquipItem({name:"Seifuku Thigh Highs", gender:"female", colors: ["blue", "brown"], styles: ["study", "comfy"]}),
new EquipItem({name:"Seifuku Thigh Highs", gender:"female", colors: ["cyan", "white"], styles: ["study", "comfy"]}),
new EquipItem({name:"Seifuku Thigh Highs", gender:"female", colors: ["green", "white"], styles: ["study", "comfy"]}),
new EquipItem({name:"Seifuku Thigh Highs", gender:"female", colors: ["pink", "white"], styles: ["study", "party", "comfy"]}),
new EquipItem({name:"Seifuku Thigh Highs", gender:"female", colors: ["white", "blue"], styles: ["study", "party", "comfy"]}),
new EquipItem({name:"Seifuku Thigh Highs", gender:"female", colors: ["red", "white"], styles: ["study", "comfy"]}),
],
mask: [
new EquipItem({name:"No Mask", gender:"unisex", colors: ["nocolor"], styles: []}),
new EquipItem({name:"Santas Beard", gender:"male", colors: ["white"], styles: ["party", "party", "party"], extra: ["fake"]}),
new EquipItem({name:"Lexington Glasses", gender:"male", colors: ["black"], styles: ["formal", "modest", "study"], extra: "transparent"}),
new EquipItem({name:"Lexington Glasses", gender:"male", colors: ["red"], styles: ["formal", "modest", "study"], extra: "transparent"}),
new EquipItem({name:"Lexington Glasses", gender:"male", colors: ["white"], styles: ["formal", "modest", "study"], extra: "transparent"}),
new EquipItem({name:"Lexington Glasses", gender:"male", colors: ["cyan"], styles: ["formal", "modest", "study"], extra: "transparent"}),
new EquipItem({name:"Lexington Glasses", gender:"male", colors: ["pink"], styles: ["formal", "modest", "study"], extra: "transparent"}),
new EquipItem({name:"Lexington Glasses", gender:"male", colors: ["green"], styles: ["formal", "modest", "study"], extra: "transparent"}),
new EquipItem({name:"Wellington Glasses", gender:"female", colors: ["black"], styles: ["study", "casual", "cute"], extra: "transparent"}),
new EquipItem({name:"Wellington Glasses", gender:"female", colors: ["red"], styles: ["study", "casual", "cute"], extra: "transparent"}),
new EquipItem({name:"Wellington Glasses", gender:"female", colors: ["white"], styles: ["study", "casual", "cute"], extra: "transparent"}),
new EquipItem({name:"Wellington Glasses", gender:"female", colors: ["cyan"], styles: ["study", "casual", "cute"], extra: "transparent"}),
new EquipItem({name:"Wellington Glasses", gender:"female", colors: ["pink"], styles: ["study", "casual", "cute"], extra: "transparent"}),
new EquipItem({name:"Wellington Glasses", gender:"female", colors: ["green"], styles: ["study", "casual", "cute"], extra: "transparent"}),
],
}>>
/* TODO 'multi' & 'hp' property for clothes? */
<<set _default_zero to ["fem", "sub", "int", "fit", "att"]>>
<<for _place, _list range setup.all_clothes>>
<<for _id, _cl range _list>>
<<set _cl.id to _id>>
<<set _cl.place to _place>>
<<set _cl.extra ??= []>>
<<for _prop range _default_zero>>
<<set _cl[_prop] ??= 0>>
<</for>>
<</for>>
<<clothesstatgen _list>>
<<clothesraritygen _list>>
<</for>><<widget "clothesraritygen">>
<<for _item range _args[0]>>
<<set _value to _item.colors.length+_item.styles.length+_item.extra.length>>
<<if _item.rarity is 0>>
<<if _value gte 5>>
<<set _item.rarity to 3>>
<<elseif _value gte 4>>
<<set _item.rarity to 2>>
<<elseif _value gte 3>>
<<set _item.rarity to 1>>
<<else>>
<<set _item.rarity to 0>>
<</if>>
<</if>>
<</for>>
<</widget>>
<<widget "clothesstatgen">>
<<set _scale to _args[1]>>
<<for _item range _args[0]>>
<<set _fem to _item.fem ?? 0>>
<<set _stylepts to {
modest: {fem:-1, sub:1, int:0, fit:0, att:0},
formal: {fem:-1, sub:0, int:1, fit:0, att:0},
active: {fem:0, sub:0, int:0, fit:1, att:0},
comfy: {fem:0, sub:1, int:0, fit:0, att:0},
casual: {fem:0, sub:0, int:0, fit:1, att:0},
study: {fem:0, sub:0, int:1, fit:0, att:0},
party: {fem:0, sub:0, int:0, fit:0, att:1},
cute: {fem:1, sub:0, int:0, fit:0, att:1},
sexy: {fem:1, sub:0, int:0, fit:0, att:1},
lewd: {fem:1, sub:1, int:0, fit:0, att:0},
}>>
<<for _sty range _item.styles>>
<<set _fem += _stylepts?.[_sty]?.fem ?? 0>>
<<set _item.base_sub += _stylepts?.[_sty]?.sub ?? 0>>
<<set _item.base_int += _stylepts?.[_sty]?.int ?? 0>>
<<set _item.base_fit += _stylepts?.[_sty]?.fit ?? 0>>
<<set _item.base_att += _stylepts?.[_sty]?.att ?? 0>>
<</for>>
<<set _colorpts to {
pink: {fem:2},
black: {fem:-1},
nocolor: {fem:0},
blue: {fem:-1},
brown: {fem:-1},
yellow: {fem:0},
cyan: {fem:0},
green: {fem:0},
white: {fem:1},
red: {fem:1},
multicolor: {fem:1},
}>>
<<set _fem += _colorpts?.[_item.colors[0]]?.fem ?? 0>>
<<set _fem += _colorpts?.[_item.colors[1]]?.fem ?? 0>>
<<set _extrapts to {
tight: {fem:1},
lace: {fem:1},
thick: {fem:-1},
baggy: {fem:-1},
loose: {fem:1},
transparent: {fem:1},
heels: {fem:1},
highheels: {fem:2},
fake: {fem:1},
}>>
<<for _extra range _item.extra>>
<<set _fem += _extrapts?.[_extra]?.fem ?? 0>>
<</for>>
<<set _genpts to {
male: {fem: -1},
unisex: {fem: 0},
female: {fem: 1},
}>>
<<set _fem += _genpts[_item.gender]?.fem ?? 0>>
<<set _item.base_fem to Math.clamp(_fem, -2, 2)>>
<</for>>
<</widget>><<set setup.svg_views to {
"undies": "#svgView(viewBox(-11.400, 203.30, 231.00, 176.50))",
"bra": "#svgView(viewBox(8.9000, 91.800, 190.30, 145.40))",
"bottom": "#svgView(viewBox(-153.80, 203.40, 515.70, 394.00))",
"top": "#svgView(viewBox(-46.300, 91.800, 300.80, 229.90))",
"shoes": "#svgView(viewBox(-15.000, 417.20, 238.10, 181.90))",
"handwear": "#svgView(viewBox(-64.200, 201.70, 185.30, 141.60))",
"penis": "#svgView(viewBox(32.600, 240.70, 142.90, 109.20))",
"hair": "#svgView(viewBox(-29.800, 0.90000, 267.70, 204.50))",
"makeup": "#svgView(viewBox(34.700, 20.800, 138.80, 106.10))",
"nails": "#svgView(viewBox(-22.400, 281.40, 90.500, 69.100))",
"choker": "#svgView(viewBox(69.100, 89.600, 69.900, 53.400))",
"earrings": "#svgView(viewBox(42.300, 64.200, 67.300, 51.400))",
"full_body": "#svgView(viewBox(-286.40, 0.90000, 780.80, 596.50))",
/* Full body is not default; its zoomed out! */
}>>
<<set setup.svg_views.legwear to setup.svg_views.bottom>>
<<set setup.svg_views.outerwear to setup.svg_views.top>>
<<set setup.svg_views.headgear to setup.svg_views.hair>>
<<set setup.svg_views.mask to setup.svg_views.hair>>
/* body SVG views */
<<set setup.svg_views.body to setup.svg_views.top>>
<<set setup.svg_views.face to setup.svg_views.makeup>>
/* style SVG views */
<<set setup.svg_views.hairstyle to setup.svg_views.hair>>
<<set setup.svg_views.lipstick to setup.svg_views.makeup>>
<<set setup.svg_views.toenail_polish to setup.svg_views.shoes>>
<<set setup.svg_views.nail_polish to setup.svg_views.nails>>
<<set setup.equip_layers to {
undies: 1,
bra: 1,
bottom: 2,
top: 2,
shoes: 2,
legwear: 1,
mask: 2,
body: 0,
penis: 0,
face: 0,
hair: 2,
hairstyle: 2,
makeup: 2,
lipstick: 2,
nails: 0,
nail_polish: 0,
toenail_polish: 0,
}>><<set setup.action_cards to [
new ActionCard({"name": "Apologize", "power": "8", "color": "Red", "rarity": "0", "sub-": "1", "stat1": "Stress+", }),
new ActionCard({"name": "Talk", "power": "8", "color": "Blue", "rarity": "0", "int-": "1", "stat1": "Stress+", }),
new ActionCard({"name": "Slap", "power": "8", "color": "Green", "rarity": "0", "fit-": "1", "stat1": "Stress+", }),
new ActionCard({"name": "Flirt", "power": "8", "color": "Purple", "rarity": "0", "att-": "1", "stat1": "Arousal+", }),
new ActionCard({"name": "Meditate", "power": "5", "color": "Red", "rarity": "1", "sub-": "2", "stat1": "Stress-", "card+bott": "1", }),
new ActionCard({"name": "Take a Break", "power": "5", "color": "Blue", "rarity": "1", "int-": "2", "stat1": "Stress-", "card+bott": "1", }),
new ActionCard({"name": "Respite", "power": "5", "color": "Green", "rarity": "1", "fit-": "2", "stat1": "Stress-", "card+bott": "1", }),
new ActionCard({"name": "Freshen Up", "power": "5", "color": "Purple", "rarity": "1", "att-": "2", "stat1": "Stress-", "card+bott": "1", }),
new ActionCard({"name": "Apathy", "power": "17", "color": "Red", "rarity": "2", "sub-": "2", "stat1": "Arousal-", "stat2": "Arousal-", "unique_effects": "<<power_is 17>> - ?arousal", "pre_play_fn": "subt_arousal_pre", }),
new ActionCard({"name": "Cheer Up", "power": "17", "color": "Blue", "rarity": "2", "int-": "2", "stat1": "Stress-", "stat2": "Arousal-", "unique_effects": "<<power_is 17>> - ?stress", "pre_play_fn": "subt_stress_pre", }),
new ActionCard({"name": "Embrace Masculinity", "power": "19", "color": "Green", "rarity": "2", "fit-": "2", "stat1": "Arousal-", "stat2": "Stress+", "unique_effects": "<<power_is 19>> - ?identity", "pre_play_fn": "subt_identity_pre", }),
new ActionCard({"name": "Embrace Femininity", "power": "9", "color": "Purple", "rarity": "2", "att-": "2", "stat1": "Stress-", "stat2": "Arousal+", "unique_effects": "<<power_is 9>> + ?fem", "pre_play_fn": "add_fem_pre", }),
new ActionCard({"name": "Obey", "power": "11", "color": "Red", "rarity": "3", "sub-": "3", "stat1": "Stress-", "stat2": "Arousal+", "stat3": "Arousal+", "unique_effects": "<<power_is 11>> + ?sub", "pre_play_fn": "add_mana_sub_pre", }),
new ActionCard({"name": "Complain", "power": "12", "color": "Blue", "rarity": "3", "int-": "3", "stat1": "Stress+", "stat2": "Stress+", "unique_effects": "<<power_is 12>> + ?int", "pre_play_fn": "add_mana_int_pre", }),
new ActionCard({"name": "Special Move", "power": "11", "color": "Green", "rarity": "3", "fit-": "3", "stat1": "Arousal-", "stat2": "Stress+", "stat3": "Stress+", "unique_effects": "<<power_is 11>> + ?fit", "pre_play_fn": "add_mana_fit_pre", }),
new ActionCard({"name": "Seduction", "power": "12", "color": "Purple", "rarity": "3", "att-": "3", "stat1": "Arousal+", "stat2": "Arousal+", "unique_effects": "<<power_is 12>> + ?att", "pre_play_fn": "add_mana_att_pre", }),
]>>
<<set setup.balance_cards to [
new ActionCard({"balance-": 1, "name": "Awkward Silence", "power": 13, "color": "Blue", "rarity": 1, "stat1": "Arousal-", "int+": 2, "fit+": 2, "card+top": 2, }),
new ActionCard({"balance-": 1, "name": "Friendly Talk", "power": 17, "color": "Blue", "rarity": 2, "stat1": "Stress-", "stat2": "Arousal-", "int+": 3, "fit+": 3, "card+top": 3, }),
new ActionCard({"balance-": 1, "name": "Friendzone", "power": 21, "color": "Blue", "rarity": 3, "stat1": "Stress-", "stat2": "Stress-", "stat3": "Arousal-", "int+": 4, "fit+": 4, "card+top": 4, }),
]>>
<<set setup.corruption_cards to [
new ActionCard({"corruption-": 1, "name": "Get Closer", "power": 21, "color": "Purple", "rarity": 1, "stat1": "Arousal+", "sub+": 3, "att+": 3, "card+top": 2, }),
new ActionCard({"corruption-": 1, "name": "Blowjob", "power": 26, "color": "Purple", "rarity": 2, "stat1": "Stress+", "stat2": "Arousal+", "sub+": 4, "att+": 4, "card+top": 3, }),
new ActionCard({"corruption-": 1, "name": "Hardcore", "power": 31, "color": "Purple", "rarity": 3, "stat1": "Stress+", "stat2": "Arousal+", "stat3": "Arousal+", "sub+": 5, "att+": 5, "card+top": 4, }),
]>>
<<set setup.punish_cards to [
new ActionCard({"name": "Spanked", "power": "0", "color": "Red", "rarity": "1", "sub-": "2", "stat1": "Stress+", "card+bott": "1", "unique_effects": "<b>Pain</b><br><<power_is 0>> - ?sub", "pre_play_fn": "spanked_pre", }),
new ActionCard({"name": "Boredom", "power": "0", "color": "Blue", "rarity": "1", "int-": "2", "stat1": "Arousal+", "card+bott": "1", "unique_effects": "<b>Distraction</b><br><<power_is 0>> - ?int", "pre_play_fn": "boredom_pre", }),
new ActionCard({"name": "Stiff Muscles", "power": "0", "color": "Green", "rarity": "1", "fit-": "2", "stat1": "Stress+", "card+bott": "1", "unique_effects": "<b>Pain</b><br><<power_is 0>> - ?fit", "pre_play_fn": "stiff_muscles_pre", }),
new ActionCard({"name": "Ditzy Thought", "power": "0", "color": "Purple", "rarity": "1", "att-": "2", "stat1": "Arousal+", "card+bott": "1", "unique_effects": "<b>Distraction</b><br><<power_is 0>> - ?att", "pre_play_fn": "ditzy_thought_pre", }),
]>>
<<set setup.cleanse_cards to [
new ActionCard({"name": "Clear Mind", "power": "11", "color": "Blue", "rarity": "2", "int-": "1", "att-": "1", "stat1": "Arousal-", "card+bott": "2", "unique_effects": "?delete<br>?remove2 1 <b>Distraction</b>", "pre_play_fn": "clear_mind_pre", "effect_fn": "clear_mind_effect", }),
new ActionCard({"name": "Painkillers", "power": "11", "color": "Green", "rarity": "2", "sub-": "1", "fit-": "1", "stat1": "Stress-", "card+bott": "2", "unique_effects": "?delete<br>?remove2 1 <b>Pain</b>", "pre_play_fn": "painkiller_pre", "effect_fn": "painkiller_effect", }),
]>>
<<set setup.get_pain_cards to [
new ActionCard({"name": "Try Hard", "power": "0", "color": "Green", "rarity": "1", "stat1": "Stress+", "int+": "3", "fit+": "3", "card+top": "2", "unique_effects": "?new_card <b>Stiff Muscles</b>", "effect_fn": "try_hard_effect", }),
new ActionCard({"name": "Helping Hand", "power": "0", "color": "Red", "rarity": "1", "stat1": "Arousal+", "sub+": "3", "fit+": "3", "card+top": "2", "unique_effects": "?new_card <b>Spanked</b>", "effect_fn": "helping_hand_effect", }),
]>>
/* TODO: Remove when 3+ cards exist for this */
<<run setup.get_pain_cards.push(... clone(setup.get_pain_cards))>>
<<set setup.get_distraction_cards to [
new ActionCard({"name": "Pay Attention", "power": "0", "color": "Blue", "rarity": "1", "stat1": "Stress+", "int+": "3", "att+": "3", "card+top": "2", "unique_effects": "?new_card <b>Boredom</b>", "effect_fn": "pay_attention_effect", }),
new ActionCard({"name": "Play Dumb", "power": "0", "color": "Purple", "rarity": "1", "stat1": "Arousal+", "sub+": "3", "att+": "3", "card+top": "2", "unique_effects": "?new_card <b>Ditzy Thought</b>", "effect_fn": "play_dumb_effect", }),
]>>
/* TODO: Remove when 3+ cards exist for this */
<<run setup.get_distraction_cards.push(... clone(setup.get_distraction_cards))>>
<<set $player_deck to [
setup.action_cards[0],
setup.action_cards[1],
setup.action_cards[2],
setup.action_cards[3],
]>>
/*<<set $player_deck to clone(setup.action_cards)>>*/<<set setup.regular_enemies to [
{name: "Furious Echo", style: "active", gender:"female", power_rate: 1},
{name: "Gross Echo", style: "modest", gender:"male", power_rate: 1},
{name: "Well-Dressed Echo", style: "formal", gender:"male", power_rate: 1},
{name: "Horny Echo", style: "casual", gender:"male", power_rate: 1},
]>>
<<for _id, _enm range setup.regular_enemies>>
<<set _enm.id to _id>>
<<set _enm.image ??= _enm.name + "_b.jpg">>
<</for>>
<<set setup.training_enemies to [
{name: "Submission Training", style: "lewd", gender:"unisex", power_rate: 1, bal_cor_cards: setup.get_pain_cards},
{name: "Intelligence Training", style: "study", gender:"unisex", power_rate: 1, bal_cor_cards: setup.get_distraction_cards},
{name: "Fitness Training", style: "active", gender:"unisex", power_rate: 1, bal_cor_cards: setup.get_pain_cards},
{name: "Attractiveness Training", style: "cute", gender:"unisex", power_rate: 1, bal_cor_cards: setup.get_distraction_cards},
]>>
<<for _id, _enm range setup.training_enemies>>
<<set _enm.id to _id>>
<<set _enm.image ??= _enm.name + "_b.jpg">>
/* probably not needed... yet <<set _enm.type to "training">> */
<</for>><<set $player_equipment to new PlayerEquipment({
body: setup.all_body.body[0],
penis: setup.all_body.penis[5],
face: setup.all_body.face[0],
nails: setup.all_body.nails[0],
hair: setup.all_body.hair[0],
hairstyle: setup.all_styles.hairstyle[0],
toenail_polish: setup.all_styles.toenail_polish[0],
nail_polish: setup.all_styles.nail_polish[0],
makeup: setup.all_styles.makeup[0],
lipstick: setup.all_styles.lipstick[0],
undies: setup.all_clothes.undies[0],
bra: setup.all_clothes.bra[0],
legwear: setup.all_clothes.legwear[0],
mask: setup.all_clothes.mask[0],
top: setup.all_clothes.top[0],
shoes: setup.all_clothes.shoes[0],
bottom: setup.all_clothes.bottom[0],
})>>
<<set $player_perm_equip to clone($player_equipment)>>
<<set $player_stats to new PlayerStats()>>
<<set $player_stats.cor_cards to 1; $player_stats.bal_cards to 1>>
<<set $inv to new PlayerInventory()>><<widget "statbar">>
/* args[0] is expected to be a value in PlayerStats e.g. fem, stress... one of the ones capped at 10
* args[1] is an optional icon name (uses 0 otherwise) */
<<set _wis_icon to _args[1] ?? _args[0]>>
<<set _wis_stat to $player_stats[_args[0]]>>
<span @class='"statbar statbar-" + _wis_icon'>
<img class="statbar-icon" @alt="_args[0]" @src='"img2/icons/" + _wis_icon + ".svg"'>
<<for _i = 1; _i lte 10; ++_i>>
<<set _wis_class to "statbar-block">>
<<if _wis_stat gte _i>>
<<set _wis_class += " statbar-block-on">>
<</if>>
<span @class="_wis_class">
<<if _i is _wis_stat>>
<<print _i>>
<<elseif (_i is 1 and _wis_stat lt 1) or (_i is 10 and _wis_stat gt 10)>>
/* first block should have lte 1, last block has gte 10 */
<<print _wis_stat>>
<</if>>
</span>
<</for>>
</span>
<</widget>>
<<widget "raw_stat_num">>
/* args:
* 0: icon name (path in icons dir), also becomes extra class name
* 1: display value-- rendered literally; no safety precautions.
* 2: add'l CSS classes to apply after statnum instead of defaults */
<<set _wrsn_classes to _args[2] ?? "statnum-" + _args[0]>>
<span @class='"statnum " + _wrsn_classes'>
<img class="statnum-img" @alt="_args[0]" @src='"img2/icons/" + _args[0] + ".svg"'>
<span class="statnum-txt"><<print _args[1]>></span>
</span>
<</widget>>
<<widget "statnum">>
/* args:
* 0: icon name & key in lookup object (usually $player_stats)
* 1: OPTIONAL lookup object, defaults to PlayerStats */
<<set _wisn_icon to _args[0]>>
<<set _wisn_value to (_args[1] ?? $player_stats)[_args[0]]>>
<<if typeof _wisn_value isnot "number">>
<<set _wisn_value to "??">>
<<else>>
<<set _wisn_value to Math.clamp(Math.round(_wisn_value), 0, 9999).toString()>>
<</if>>
<<raw_stat_num _wisn_icon _wisn_value>>
<</widget>>
<<widget "sifa_stats">>
/* args[0] is lookup object for statnum, optional */
<div class="grid4col" style="margin: auto;">
<<for _wis_sifa range setup.SIFA>>
<<statnum _wis_sifa _args[0]>>
<</for>>
</div>
<</widget>>
<<widget "loop_bonuses">>
/* args[0] is expected to be a loop object (i.e. from loop gen passage) */
<<for _sty, _bonuses range _args[0].bonuses.styles>>
<span class="loop-bonuses">
<<print "?" + _sty>> ➡
<<for _sifa, _quant range _bonuses>>
/* no newline for print to avoid introducing needless whitespace */
<<for _i to 0; _i lt _quant; ++_i>><<print "?" + _sifa>><</for>>
<</for>>
</span>
<</for>>
<</widget>><<widget render_char>>
/* args[0] layer num: 0 naked, 1 underwear, 2 all
* args[1] SVG view (string to append to .svg)
* args[2] character object (object w/ body, hair, etc. properties that point to equipment, TODO list them)
*/
<<set _layer to _args[0]>>
<<set _view to _args[1] ?? "">>
<<set _char to _args[2] ?? $player_equipment>>
<<set _svg to ".svg" + _view>>
<div class="imgstack">
/* hair back */
<img @src='"img2/char/styles/hair/" + _char.hairstyle.name + "/" + "".concat(... _char.hairstyle.colors) + "/" + _char.hair.id + "/b" + _svg' onerror="this.src='img2/char/styles/hair/ears_no.svg';">
/* buttocks */
<img @src='"img2/char/body/other/buttocks" + _svg'>
/* body */
<img @src='"img2/char/body/body/h" + _char.body.hips + "_w" + _char.body.waist + "_s" + _char.body.shoulders + _svg'>
/* If no underwear + bottoms... */
<<if _layer is 0 or (_layer is 1 and _char.undies.id is 0) or (_char.undies.id is 0 and _char.bottom.id is 0)>>
<img @src='"img2/char/body/other/thigh_shadow" + _svg'>
/* testicles */
<img @src='"img2/char/body/penis/testicles" + _char.penis.id + _svg'>
/* penis */
<<if $player_stats.arousal gte 10>>
<img @src='"img2/char/body/penis/erect" + _char.penis.id + _svg'>
<<else>>
<img @src='"img2/char/body/penis/soft" + _char.penis.id + _svg'>
<</if>>
<</if>>
/* boobs */
<img @src='"img2/char/body/boobs/b" + _char.body.boobs + "_s" + _char.body.shoulders + _svg'>
/* nipples */
<img @src='"img2/char/body/nipples/n" + _char.body.nipples + "_b" + _char.body.boobs + "_s" + _char.body.shoulders + _svg'>
/* toenails */
<img @src='"img2/char/styles/toenails/" + _char.toenail_polish.name + "/" + "".concat(... _char.toenail_polish.colors) + _svg'>
/* nails */
<img @src='"img2/char/styles/nails/" + _char.nail_polish.name + "/" + "".concat(... _char.nail_polish.colors) + "/" + _char.nails.id + "/s" + _char.body.shoulders + _svg'>
/* undies */
<<if _layer gte 1>>
<img @src='"img2/char/clothes/undies/" + _char.undies.name + "/" + "".concat(... _char.undies.colors) + "/h" + _char.body.hips + "w" + _char.body.waist + _svg'>
/* undies penis */
<img @src='"img2/char/clothes/undies/" + _char.undies.name + "/" + "".concat(... _char.undies.colors) + "/p" + _char.penis.id + _svg'>
/* legwear */
<img @src='"img2/char/clothes/legwear/" + _char.legwear.name + "/" + "".concat(... _char.legwear.colors) + "/h" + _char.body.hips + "w" + _char.body.waist + _svg'>
/* bra */
<img @src='"img2/char/clothes/bra/" + _char.bra.name + "/" + "".concat(... _char.bra.colors) + "/b" + _char.body.boobs + "w" + _char.body.waist + "s" + _char.body.shoulders + _svg'>
<</if>>
<<if _layer gte 2>>
/* shoes */
<img @src='"img2/char/clothes/shoes/" + _char.shoes.name + "/" + "".concat(... _char.shoes.colors) + _svg'>
/* tops */
<<set _baggy to _char.top.extra.includes("baggy")>>
<<set _top_src to "img2/char/clothes/tops/" + _char.top.name + "/" + "".concat(... _char.top.colors) + "/b" + _char.body.boobs + "h" + _char.body.hips + "w" + _char.body.waist + "s" + _char.body.shoulders + _svg>>
<<if not _baggy>>
<img @src="_top_src">
<</if>>
/* bottoms */
<img @src='"img2/char/clothes/bottoms/" + _char.bottom.name + "/" + "".concat(... _char.bottom.colors) + "/h" + _char.body.hips + "w" + _char.body.waist + _svg'>
/* bottoms penis */
<img @src='"img2/char/clothes/bottoms/" + _char.bottom.name + "/" + "".concat(... _char.bottom.colors) + "/p" + _char.penis.id + _svg'>
/* baggy tops */
<<if _baggy>>
<img @src="_top_src">
<</if>>
<</if>>
/* head */
<img @src='"img2/char/body/other/" + _char.face.head + _svg'>
/* makeup svg */
<img @src='"img2/char/styles/makeup/" + _char.makeup.name + "/" + "".concat(... _char.makeup.colors) + "/" + _char.face.id + _svg'>
/* lipstick svg */
<img @src='"img2/char/styles/lipstick/" + _char.lipstick.name + "/" + "".concat(... _char.lipstick.colors) + "/" + _char.face.id + _svg'>
/* front hair & ears */
<img @src='"img2/char/styles/hair/" + _char.hairstyle.name + "/" + "".concat(... _char.hairstyle.colors) + "/" + _char.hair.id + "/f" + _svg'>
<img @src='"img2/char/styles/hair/ears_" + _char.hairstyle.ears[_char.hair.id] + _svg'>
/* face */
<img @src='"img2/char/body/face/" + _char.face.id + _svg'>
/* mask */
<<if _layer gte 1>>
<img @src='"img2/char/clothes/mask/" + _char.mask.name + "/" + "".concat(... _char.mask.colors) + _svg'>
<</if>>
</div>
<</widget>><<widget equip_card>>
/* _args[0] is expected to be an EquipItem.
* Also, note that in widgets, using a common name like _card can accidentally overwrite stuff :\ */
<<set _weq_card to _args[0]>>
<<if _weq_card is undefined or _weq_card is null>>
<<run $debug_passages.add(passage())>>
<div class="equipgrid">
<img src="img2/gear/static2.svg" class="equipgridbg" style='background: orange'>
<span style="grid-row: 2; font-size: 8cqh; margin: 1em;">
An equipment card belongs here but it was null or undefined.
Please save here and report this bug.
</span>
</div>
<<else>>
<<set _rarity_text to _weq_card.rarity_text>>
<<if _rarity_text is "unique">>
<<set _rarity_text to "legendary">>
<</if>>
/* patches for new equipment card style */
<<switch _rarity_text>>
<<case "rare">>
<<set _bg to "deepskyblue">>
<<case "epic">>
<<set _bg to "blueviolet">>
<<case "legendary">>
<<set _bg to "orange">>
<<default>> /* common */
<<set _bg to "gray">>
<</switch>>
<<set _fem to _weq_card.fem>>
<div class="equipgrid">
<img src="img2/gear/static2.svg" class="equipgridbg" @style='"background: " + _bg'>
<div class="equipgridheader">
<span class="equipgridtitle">_weq_card.name</span>
<span class="equipgridstyles">
<<for _style range _weq_card.styles>>
<<if def $current_loop?.bonuses?.styles?.[_style]>>
<<set _weq_bnscls to "loop-bonus">>
<<else>>
<<set _weq_bnscls to "">>
<</if>>
<img @class="_weq_bnscls" @src='"img2/gear/style/" + _style + ".svg"'>
<</for>>
</span>
</div>
<div class="equipgridart">
<<render_char setup.equip_layers[_weq_card.place] setup.svg_views[_weq_card.place]
$player_equipment.with_alt_equip(_weq_card)>>
</div>
<img src="img2/gear/frame.svg" class="equipgridbg" style="z-index: 10">
<div class="equipgridinfo">
<div class="equipgriddesc">
<<for _sifa range setup.SIFA>>
/* this works, but would need CSS tweaks to fit 3 or 4 stats in the card
<<if _weq_card[_sifa] gt 0>>
<<statnum _sifa _weq_card>>
<</if>>*/
<<for _num to 1; _num lte _weq_card[_sifa]; _num++>>
<<if _num gt _weq_card["base_" + _sifa]>>
<<set _weq_bnscls to "loop-bonus">>
<<else>>
<<set _weq_bnscls to "">>
<</if>>
<img @class="_weq_bnscls" @src='"img2/icons/" + _sifa + ".svg"'>
/* TODO (works but needs CSS tweaks): <<print "?" + _sifa>> */
<</for>>
<</for>>
</div>
<img @src='"img2/gear/" + _rarity_text + ".svg"' class="equipgridrarity">
<span class="equipgridfem">
<<set _color to "equipgridfemtext">>
<<if _fem gte 0>>
<img src="img2/gear/fem.svg">
<<else>>
<img src="img2/gear/masculinity.svg">
<<set _fem to Math.abs(_fem)>>
<<set _color += " equipgridmastext">>
<</if>>
/* TODO: Adjust size based on length of string here? */
<span @class="_color">_fem</span>
</span>
</div>
</div>
<</if>> /* for null check */
<</widget>>
<<widget "equipment_type_icon">>
/* note: color is not directly inserted into style-- it's part of a class name */
<<set _color to _args[0]>>
<<set _type to _args[1]>>
/* patching over old icon naming scheme */
<<switch _type>>
<<case "face">>
<<set _type to "body1">>
<<case "body">>
<<set _type to "body2">>
<<case "penis">>
<<set _type to "body3">>
<<case "hairstyle">>
<<set _type to "hair">>
<<case "nail_polish">>
<<set _type to "nails">>
<<case "toenail_polish">>
<<set _type to "toenails">>
/* default: do nothing */
<</switch>>
<<set _classes to "eq_type_icon btn-" + _color>>
<img @class="_classes" @src='"img2/icons/onbutton/" + _type + ".svg"'>
<</widget>>
<<widget "equip_tf">>
/* args: 0, 1: two EquipItems, before & after. */
<div class="itemtfgrid">
<<equip_card _args[0]>>
<img alt="has transformed into" src="img2/icons/green_arrow.svg">
<<equip_card _args[1]>>
</div>
<</widget>><<widget action_card>>
/* _args[0] is expected to be an ActionCard.
* All other args are optional string literals:
* "notilt" to disable js-tilt
* "disabled" to add grayscale effect */
<<set _wac_card to _args[0]>>
<<if _wac_card is undefined or _wac_card is null>>
<<run $debug_passages.add(passage())>>
<div class="cardgrid">
<img src="img2/actions/static.svg" class="cardgridbg" style='background: orange'>
<span style="grid-row: 2; font-size: 7cqh; margin: 1em;">
An action card belongs here but it was null or undefined.
Please save here and report this bug.
</span>
</div>
<<else>>
<<set _wac_class to "cardgrid">>
<<if _args.slice(1).includes("disabled")>>
<<set _wac_class += " grayscale">>
<</if>>
<<if not _args.slice(1).includes("notilt")>>
<<set _wac_class += " js-tilt">>
<</if>>
<div @class="_wac_class">
<img src="img2/actions/static.svg" class="cardgridbg" @style='"background: " + _wac_card.background'>
<div class="cardgridheader">
<span class="cardgridtitle">_wac_card.name</span>
<span class="cardgridcost">
<<for _type, _qty range _wac_card.mana_cost>>
<<for _i = 0; _i < _qty; ++_i>>
<img @src='"img2/icons/" + _type + ".svg"'>
<</for>>
<</for>>
</span>
</div>
<img class="cardgridart" @alt="_wac_card.img_alt" @src="_wac_card.img_path">
<img src="img2/gear/frame.svg" class="cardgridbg" style="z-index: 10">
<div class="cardgridicons">
<span class="cardgridicon">
<img src="img2/actions/power.svg">
/* TODO: Adjust size based on length of string here? */
<<set _color to "cardgridicontext">>
<<if _wac_card.power_mod_up>>
<<set _color += " mod_up">>
<<elseif _wac_card.power_mod_down>>
<<set _color += " mod_down">>
<</if>>
<span @class="_color">_wac_card.power</span>
</span>
<img @alt="_wac_card.rarity_text" @src='"img2/icons/" + _wac_card.rarity_text + ".svg"' class="cardgridrarity">
<<set _wac_icon_count to 0; _wac_draw_descr to true>>
<<for _type, _qty range _wac_card.stat_effects>>
<<for _i = 0; _i < Math.abs(_qty); ++_i>>
<span class="cardgridicon">
<img src="img2/actions/status.svg">
<<if _qty gt 0>>
<img src="img2/actions/negative.svg">
/* TODO something... better */
<span class="cardgridicon-sign">+</span>
<<else>>
<img src="img2/actions/positive.svg">
<</if>>
<img class="cardgridicon-primary" @alt="_type" @src='"img2/icons/" + _type + ".svg"'>
/* emoji fallback... <span class="cardgridicontext">_icon</span> */
</span>
<<set _wac_icon_count += 1>>
<</for>>
<</for>>
/* Assuming we don't have both draw front and draw back simultaneously */
<<if _wac_icon_count lte 2>>
<<if _wac_card.side_effects.draw_front gt 0>>
<<set _wac_draw_descr to false>>
<<set _type to "card_front">>
<<set _wac_num to _wac_card.side_effects.draw_front>>
<<elseif _wac_card.side_effects.draw_back gt 0>>
<<set _wac_draw_descr to false>>
<<set _type to "card_back">>
<<set _wac_num to _wac_card.side_effects.draw_back>>
<</if>>
<<if not _wac_draw_descr>>
<span class="cardgridicon">
<img src="img2/actions/status.svg">
<img src="img2/actions/positive.svg">
<img class="cardgridicon-primary" @alt="_type" @src='"img2/icons/" + _type + ".svg"'>
<span class="cardgridicon-sign cardgridicon-num">_wac_num</span>
</span>
<</if>>
<</if>>
</div>
<div class="cardgriddesc">
<<print _wac_card.description>>
<<if _wac_draw_descr>>
<<if _wac_card.side_effects.draw_front gt 0>>
<<raw_stat_num "card_front" _wac_card.side_effects.draw_front>>
<</if>>
<<if _wac_card.side_effects.draw_back gt 0>>
<<raw_stat_num "card_back" _wac_card.side_effects.draw_back>>
<</if>>
<</if>>
</div>
</div>
<</if>> /* end of null check */
<</widget>>
<<widget "power_is">>
<span class="cardgridicon cardgridicon-inline">
<img src="img2/actions/power.svg">
/* TODO: Adjust size based on length of string here? */
<span class="cardgridicontext" style="font-size: unset;">_args[0]</span>
</span>
<</widget>>
<<widget reshuffle_deck>>
<<set $temp_deck to clone($player_deck).shuffle()>>
<<if def $draw_filter>>
<<set $temp_deck to $temp_deck.filter($draw_filter)>>
<</if>>
<</widget>>
<<widget playable_action>>
/* args[0] is an array of cards usable in action_card widget, typically $player_hand
* args[1] is an index in that array */
<<set _deck to _args[0]>>
<<set _idx to _args[1]>>
<<set _card to _deck[_idx]>>
<<capture _deck, _idx>>
<<link "<<action_card _card>>">>
<<set $next_power_multiplier to 0; $next_power_addition to 0;>>
/* To avoid issues w/ manipulating hand, remove the card being played before running its effect. */
<<run _deck.splice(_idx, 1)[0].run_effect()>>
<<if $enemy_power lte 0>>
<<set $battle_won to true>>
<<goto $back.pop()>>
<</if>>
/* Drawing cards can be annoying since we *might* run out & need to re-shuffle player deck=>temp to get more */
<<if $draw_front > 0>>
<<if $temp_deck.length >= $draw_front>>
/* the plucks here aren't really needed since deck was shuffled /shrug */
<<run $player_hand.unshift(... $temp_deck.pluckMany($draw_front))>>
<<else>>
<<run $player_hand.unshift(... $temp_deck)>>
<<set $draw_front -= $temp_deck.length>>
<<reshuffle_deck>>
<<run $player_hand.unshift(... $temp_deck.pluckMany($draw_front))>>
<</if>>
<</if>>
<<if $draw_back > 0>>
<<if $temp_deck.length >= $draw_back>>
/* the plucks here aren't really needed since deck was shuffled /shrug */
<<run $player_hand.push(... $temp_deck.pluckMany($draw_back))>>
<<else>>
<<run $player_hand.push(... $temp_deck)>>
<<set $draw_back -= $temp_deck.length>>
<<reshuffle_deck>>
<<run $player_hand.push(... $temp_deck.pluckMany($draw_back))>>
<</if>>
<</if>>
<<replace "#battlediv">><<include "battle page incl">><</replace>>
<<replace "#sidebar-stats">><<include "sidebar stats">><</replace>>
<</link>>
<</capture>>
<</widget>><div style="line-height: 1">
<h1 style="margin-top: 0">Icon Reference</h1>
<h2>SIFA Statistics</h2>
</div>
<p>These are the main statistics representing your character's abilities.
They affect your ability to play cards in combat and are used for some skill checks.
You have a set of "core" SIFA stats that can be increased by training,
but your cosmetics, clothing, and body also contribute to your SIFA stats.</p>
<ul style="columns: 4">
<li>?sub Submissiveness</li>
<li>?int Intelligence</li>
<li>?fit Fitness</li>
<li>?att Attractiveness</li>
</ul>
<h2 style="line-height: 1">Story Statistics</h2>
<ul style="columns: 2">
<li>?money Money. Makes the world go 'round.</li>
<li>?new_card Possibly change your action deck.</li>
</ul>
<p>These stats relate to your karma. You can gain and lose points from story events,
and you can spend karma to play special cards in combat.</p>
<ul style="columns: 2">
<li>?balance Balance</li>
<li>?corruption Corruption</li>
</ul>
<p>These stats relate to your femininity:</p>
<ul>
<li>?fem Femininity of your appearance.
All of your cosmetics, clothing, and body parts contribute to this score.</li>
<li>?identity Identity. This represents how feminine your thoughts and actions are.</li>
</ul>
<p>These stats relate to other mental states:</p>
<ul style="columns: 2">
<li>?stress Stress. Stay calm!</li>
<li>?arousal Arousal. Stay focused!</li>
</ul>
<h2 style="line-height: 1">Card Effects</h2>
<ul>
<li>?card_back Draw cards into your hand from the back. Play existing cards to see new ones.</li>
<li>?card_front Draw cards into your hand to the front. New cards are available immediately.</li>
<li>?new_card Adds a persistent card to your deck when played.</li>
<li>?delete Card removes itself from your deck when played.</li>
<li>?remove2 Removes other card(s) from your deck when played.</li>
</ul>
<h2 style="line-height: 1">Rarity Icons</h2>
<p>These describe the relative value of equipment items and cards:</p>
<ul style="columns: 4">
<<for _icon range setup.rarities.slice(0, 4)>>
<li><<print "?" + _icon>> _icon</li>
<</for>>
</ul>
<h2 style="line-height: 1">Style Icons</h2>
<p>These icons show up on equipment items, and relate to the "style" or "type" of item they are:</p>
<ul style="columns: 9em;">
<<for _icon range
["modest", "formal", "active", "comfy", "casual",
"study", "party", "cute", "sexy", "lewd",]>>
<li><<print "?" + _icon>> _icon</li>
<</for>>
</ul>/* formerly "collected cards page". Note that cards tag reduces margin-top CSS...*/
/*<<set _can_change to Story.get($back.at(-1)).tags.includes("dressing")>>*/
<<set _can_change to Story.get(passage()).tags.includes("dressing")>>
/* TODO CSS fuckery continues */
<div style="width: 80%; margin: auto;">
<<if _can_change>>
<p>Click a clothing item to take it off and move it to
<<link "your inventory">><<script>>
Dialog.close();
Dialog.setup("Inventory", "inv-dialog autoanim");
Dialog.wiki(Story.get("inventory dialog").processText());
Dialog.open();
<</script>><</link>>.
</p>
<<else>>
<p>You are not allowed to change right now.</p>
<</if>>
/* Removable clothing items */
<<set _r_slots to ["mask", "top", "bra", "bottom", "undies", "legwear", "shoes"]>>
<div id="changeable-equip" class="grid5col">
<<for _slot range _r_slots>><<capture _slot>>
<<set _item to $player_equipment[_slot]>>
<div class="flexdown" style="row-gap: 0;">
<div style="width: 60%">
<<if _item.id isnot 0>>
<<equipment_type_icon "green" _slot>>
<<else>>
<<equipment_type_icon "red" _slot>>
<</if>>
</div>
/*
<<if _can_change and _item.id isnot 0>>
<a data-passage="passage()"
data-setter="$inv.push(clone($player_equipment[_slot])); $player_equipment[_slot] to clone(setup.all_clothes[_slot][0]);">
<<equip_card _item>>
</a>
<<else>>
<<equip_card _item>>
<</if>>
*/
<<equip_card _item>>
</div>
<</capture>><</for>>
</div>
/* Body & Style items (not changeable) */
<<set _slots to ["hair", "face", "body", "nails", "penis",
"hairstyle", "makeup", "lipstick", "nail_polish", "toenail_polish"]>>
<div class="grid5col">
<<for _slot range _slots>>
<<set _item to $player_equipment[_slot]>>
<div class="flexdown" style="row-gap: 0;">
<div style="width: 60%"> <<equipment_type_icon "green" _slot>> </div>
<<equip_card _item>>
</div>
<</for>>
</div>
/* end width hack */
</div>
<<done>><<script>>
const SCV = variables();
const TMP = temporary();
if(TMP.can_change) {
$('#changeable-equip .equipgrid').each((idx, el) => {
/* tie the element back to the slot... */
const slot = TMP.r_slots[idx];
const jqel = $(el);
if(SCV.player_equipment[slot].id !== 0) {
/* TODO use <a> tags like a normal person (messes w/ hierarchy) */
jqel.css('cursor', 'pointer');
jqel.ariaClick((event) => {
SCV.inv.push(clone(SCV.player_equipment[slot]));
SCV.player_equipment[slot] = clone(setup.all_clothes[slot][0]);
const parent = jqel.parent();
jqel.remove();
/* fix label color above */
parent.find('img').addClass("btn-red").removeClass("btn-green");
/* add replacement card */
parent.wiki('<<equip_card $player_equipment["' + slot + '"]>>');
/* redraw avatar (TODO: on dialog close instead?) */
$('#avatar').empty().wiki("<<include avatar_sidebar>>");
});
}
});
}
<</script>><</done>><<set _can_change to Story.get(passage()).tags.includes("dressing")>>
<<set _delete_items to false>>
<<for _idx, _item range $inv>>
<<set _item.inv_idx to _idx>>
<</for>>
<<if $inv.is_empty>>
<p class="largertext">Your inventory is empty...</p>
<<else>>
/* TODO should probably be a setup var. see also: Object.keys(setup.all_clothes) */
<<set _first_place to $inv.first_category>>
<div id="inv-seln" class="flexbuttons" style="gap: 0.15em;">
<<for _place, _items range $inv>>
<<if _items.length gt 0>>
<<set _color to _place is _first_place ? "green" : "red">>
<a @data-place="_place"><<equipment_type_icon _color _place>></a>
<</if>>
<</for>>
<<if not passage().startsWith("introduction")>>
<button id="deletebtn" class="btn btn-delete togglebtn">Delete Items</button>
<</if>>
</div>
<div id="inv-items">
<<inventory_group _first_place>>
</div>
<</if>>
<<done>><<script>>
const SCV = variables();
const TMP = temporary();
$('#inv-seln a').each((_, el) => {
const jqel = $(el);
jqel.ariaClick((ev) => {
const place = jqel[0].dataset.place;
delete TMP.inv_swap;
TMP.delete_items = false;
delbtn.removeClass("toggle-on");
$('#inv-items').empty().wiki("<<inventory_group '" + place + "'>>");
$('#inv-seln a .btn-green').addClass("btn-red").removeClass("btn-green");
jqel.children().first().addClass("btn-green").removeClass("btn-red");
});
});
const delbtn = $('#deletebtn');
delbtn.ariaClick((ev) => {
const item_area = $('#inv-items .grid4col');
const worn = $('#inv-items .flexdown').first();
TMP.delete_items = !TMP.delete_items;
$('#inv-notice').empty().wiki("<<inventory_notice>>");
delete TMP.inv_swap;
$('#inv-items .cardselect').removeClass(setup.card_select_classes);
if(TMP.delete_items) {
delbtn.addClass("toggle-on");
item_area.addClass("warning-bg");
worn.hide();
} else {
delbtn.removeClass("toggle-on");
item_area.removeClass("warning-bg");
worn.show();
}
});
<</script>><</done>><<widget "inventory_notice">>
/* no args, but reads _can_change and _delete_items */
<<if not _delete_items>>
Click any two items to swap them, for organization.
<<if _can_change>>
This includes your currently worn equipment, to change.
<br>(You can remove worn clothing from
<<link "the equipment page">><<script>>
Dialog.close();
Dialog.setup("Equipment", "inv-dialog autoanim");
Dialog.wiki(Story.get("player equipment page").processText());
Dialog.open();
<</script>><</link>>.)
<<else>>
You are not able to change your clothes right now.
<</if>>
<<else>>
Click the same item twice to delete it <em>permanently</em>.
<<link "Consider saving first.">><<script>>
Dialog.close();
UI.saves();
<</script>><</link>>
<</if>>
<</widget>>
<<widget "inventory_group">>
/* args: 0: name of key in $inv-- should be a valid equipment "place".
* also reads _delete_items & _can_change (via inventory_notice widget) */
<<set _wig_place to _args[0]>>
<p id="inv-notice"><<inventory_notice>></p>
<div class="flexhoriz" style="gap: 1em;">
<div class="flexdown" style="flex: 1;">
<p style="text-align: center;">Current _wig_place</p>
<<if _can_change>>
<a @data-place="_wig_place"><<equip_card $player_equipment[_wig_place]>></a>
<<else>>
<<equip_card $player_equipment[_wig_place]>>
<</if>>
</div>
<div class="grid4col" style="flex: 5;">
<<if $inv[_wig_place].length > 0>>
<<for _wig_inv_idx, _wig_item range $inv[_wig_place]>>
<a @data-place="_wig_place" @data-inv-idx="_wig_inv_idx"><<equip_card _wig_item>></a>
<</for>>
<<else>>
<p class="gridfilltxt">You have no _wig_place items.</p>
<</if>>
</div>
</div>
<<done>><<script>>
$('#inv-items a').each((_, el) => {
$(el).ariaClick(setup.inventory_click_event);
});
<</script>><</done>>
<</widget>><p>This is your deck of actions. Click two cards to swap them (for organization).</p>
<div id="deck-inv" class="grid5col">
<<for _card range $player_deck>>
<<action_card _card>>
<</for>>
</div>
<<done>><<script>>
setup.activate_tilt();
const SCV = variables();
$('#deck-inv .cardgrid').each((idx, el) => {
const jqel = $(el);
jqel.data("deckidx", idx)
.ariaClick((ev) => {
const my_idx = jqel.data("deckidx");
if(SCV.card_swap === undefined) {
/* no card set, "activate" it */
SCV.card_swap = my_idx;
jqel.addClass(setup.card_select_classes);
} else if(SCV.card_swap === my_idx) {
/* picked same card, deactivate */
jqel.removeClass(setup.card_select_classes);
delete SCV.card_swap;
} else {
/* Swap their data... */
SCV.player_deck[my_idx] = SCV.player_deck.splice(SCV.card_swap, 1, SCV.player_deck[my_idx])[0];
const other = $($('#deck-inv .cardgrid')[SCV.card_swap]);
other.removeClass(setup.card_select_classes);
other.data("deckidx", my_idx);
jqel.data("deckidx", SCV.card_swap);
delete SCV.card_swap;
/* finally, swap them in HTML */
jqel.swapWith(other);
/* and reset both cards' tilt... */
jqel[0].vanillaTilt?.reset();
other[0].vanillaTilt?.reset();
}
});
});
$(document).one(':dialogclosed', function (ev) {
delete variables().card_swap;
});
<</script>><</done>><h1>Thank you for trying EP: Backrooms.</h1>
<div class="textwall">
<p>Before we begin, we want to emphasize that this game is a work of fiction created by adults, <em>for adults</em>.
This game contains pornographic content such as nudity and sex scenes.
You should not interact with this sort of work until you are <strong>at least 18 years of age, or better yet, 21.</strong></p>
<p>If you aren't old enough yet, please consider that these age gates exist for a reason.
It's very easy to watch, play, or read porn too much, at the expense of your relationships and responsiblities.</p>
<p>It's OK to uninstall the game. It'll be around if you decide to come back.</p>
<div class="flexbuttons" style="justify-content: center; gap: 1em;">
<<button "I'm an adult" "starting content warning">><</button>>
<<button "I'm not an adult" "starting age fail">><</button>>
</div>
</div><div class="textwall">
<p>There are two reasons the authors can think of for answering that way.
You might actually be an adult, but you're either curious about this option or just being funny.
Well, here we are...</p>
<p>Otherwise, you're being honest, in which case, we wonder how you got this game in the first place.
Seriously, please consider looking for other forms of entertainment; porn isn't <em>that</em> worthwhile.
Again, it's OK to uninstall the game. It'll be around if you decide to come back.</p>
</div>
<<done>>
<<run UIBar.stow()>>
<<addclass "#right-ui-bar" "stowed">>
<</done>><h1>Content Warnings & Disclaimers</h1>
<div class="textwall" style="text-indent: unset">
<p>To elaborate, this game contains content related to:</p>
<ul>
<li>Forced feminization</li>
<li>Male-to-female transformation</li>
<li>Hypnosis</li>
<li>...and of course, character nudity and sex.</li>
</ul>
<p>Many parts of the game may intentionally prevent you, the player, from making choices the way you want to.
However, we ensure that you retain the ability to consent to your character's sexual actions.</p>
</div>
<div class="textwall">
<p>Again, this is a work of pure fiction. This work uses potentially offensive gendered stereotypes
that do not reflect the authors' views of reality. Please treat everyone with respect, regardless of how they present themselves.</p>
<p style="text-align: center; text-indent: 0;"><strong>If you have any issue with the above, please close the game.</strong></p>
<div class="flexbuttons" style="justify-content: center; gap: 1em;">
<<button "I've read the disclaimer." "introduction 1">><</button>>
</div>
</div><svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 210 600"><defs><style>.color-1{fill:#c90000;}.black,.color-1,.color-2,.color-3,.color-4,.transparent{stroke:#1d1d1b;stroke-width:0.25px;}.black,.color-1,.color-2,.color-3,.color-4{stroke-miterlimit:10;}.color-2{fill:#0000c9;}.color-3{fill:#00c900;}.color-4{fill:aqua;}.transparent{fill:none;stroke-linecap:round;stroke-linejoin:round;}.black{fill:#282828;}</style></defs><path class="color-1" d="M141.4,163.85c0,.72,18.23-2.9,18.63-3.38s-1.53-7.84-1.9-15.36c-.17-3.47-1.22-10.19-3.77-13.72a14.41,14.41,0,0,0-8.36-5.75c-3.08-.55-21-2.61-21.45-2.26s-2.06,8.23-5.52,14.77-10.24,12.38-14.69,12.38-11.21-5.84-14.67-12.38-5-14.36-5.53-14.77-18.47,1.7-21.63,2.26a14.43,14.43,0,0,0-8.37,5.75c-2.55,3.53-3.59,10.25-3.76,13.72-.37,7.52-2.3,14.87-1.9,15.36s18.57,4.1,18.63,3.38c0-.5-.15-3.27-.48-7.89.51,4.21,1.12,7.38,1.12,7.38,3.39,21.92,2.15,37.13.86,47.21s-3.1,22-4.76,29.36-4.75,22.93-4.17,24,22.69,3.43,44.66,3.2h0c22,.23,44.15-2.24,44.67-3.2s-2.52-16.61-4.18-24-3.45-19.14-4.75-29.36-2.59-25.74,1-48.21c0-.09.47-3.77.79-6.38C141.55,160.59,141.36,163.35,141.4,163.85Z"/><rect class="color-2" x="77.57" y="157.74" width="54.13" height="30.58"/><rect class="color-3" x="77.57" y="188.4" width="54.13" height="30.58"/><rect class="color-4" x="77.57" y="218.44" width="54.13" height="30.58"/><path class="transparent" d="M81.51,199.75a7.66,7.66,0,0,1,5.6.82c1.72.87,3.24,2.1,4.89,3.11a30.52,30.52,0,0,0,13.45,4,90.33,90.33,0,0,0,14.15-.28"/><path class="transparent" d="M130.65,233.73a56,56,0,0,0-19.16,4.13c-2.86,1.17-5.68,2.59-8.75,2.88"/><path class="transparent" d="M68.16,253.57l10.67,2.75"/><path class="transparent" d="M98.66,177.39a14.56,14.56,0,0,1,5.62-1.37,14,14,0,0,1,5.21,1.19"/><path class="black" d="M160.3,160.79c-.31.36-18.22,3.46-18.78,3.22s-.7-2.46-.3-2.84,18.31-3.65,18.74-3.42S160.61,160.42,160.3,160.79Z"/><path class="black" d="M48.26,160.79c.31.36,18.22,3.46,18.78,3.22s.7-2.46.3-2.84-18.3-3.65-18.73-3.42S48,160.42,48.26,160.79Z"/><path class="transparent" d="M64.81,153.85a14.19,14.19,0,0,0-4.58-3.11"/><path class="transparent" d="M67.34,154.11A5.1,5.1,0,0,1,68.91,150"/><path class="transparent" d="M143.38,154.57a5.23,5.23,0,0,1,4.41-2"/><path class="transparent" d="M140.89,153.09l-1.27-1"/><path class="transparent" d="M65.15,150.19l-.68-3.06"/><path class="transparent" d="M143.45,151.21a19.73,19.73,0,0,0,2-5.78"/></svg><svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 210 600"><defs><style>.color-2{fill:#0000c9;}.color-1,.color-2,.color-3,.color-4,.transparent{stroke:#1d1d1b;stroke-width:0.25px;}.color-1,.color-2,.color-3,.color-4{stroke-miterlimit:10;}.transparent{fill:none;stroke-linecap:round;stroke-linejoin:round;}.color-4{fill:aqua;}.color-1{fill:#c90000;}.color-3{fill:#00c900;}.shadows{fill:#1d1d1b;isolation:isolate;opacity:0.2;}</style></defs><path class="color-2" d="M137,159.79c.55-2.17,1.28,3.49,1.31,4,.06.71,18.23-2.9,18.63-3.39s-1.76-8.2-2.73-15.67c-.51-3.92-1.4-9.36-4.5-13.59a14.57,14.57,0,0,0-9.28-5.47h0c-1.44-.29-15.72-2.39-15.87-2.28-.52.41-1.63,12.06-5.17,18.6s-10.59,13.35-15,13.35-11.48-6.81-15-13.35-4.66-18.19-5.18-18.6c-.15-.11-14.74,2-16,2.28a14.57,14.57,0,0,0-9.28,5.47c-3.11,4.23-4,9.67-4.5,13.59-1,7.47-3.13,15.19-2.73,15.67s18.57,4.1,18.62,3.39c0-.5.77-6.16,1.32-4,0,0,.34,1,.58,2.09,1.13,20.65,4.76,30.44,3.43,48.67-.68,12.63-3.27,17-9.32,29s-9.81,22-9.2,23.06,25.37,4.75,47.34,4.52h0c22,.23,46.79-3.57,47.35-4.52s-3.17-11.14-9.21-23.06c-5.92-11.67-8.53-16.15-9.28-28.21v-.75c-1.33-18.23,2.3-28,3.43-48.67A15.26,15.26,0,0,1,137,159.79Z"/><path class="transparent" d="M81.51,199.75a7.66,7.66,0,0,1,5.6.82c1.72.87,3.24,2.1,4.89,3.11a30.52,30.52,0,0,0,13.45,4,90.33,90.33,0,0,0,14.15-.28"/><path class="transparent" d="M130.65,233.73a56,56,0,0,0-19.16,4.13c-2.86,1.17-5.68,2.59-8.75,2.88"/><path class="transparent" d="M68.16,253.57l10.67,2.75"/><path class="color-4" d="M51.36,160.71c.31.37,18.22,3.47,18.77,3.22s.71-2.45.31-2.83-18.31-3.65-18.74-3.43S51,160.35,51.36,160.71Z"/><path class="color-4" d="M157.12,160.71c-.31.37-18.22,3.47-18.78,3.22s-.7-2.45-.3-2.83,18.31-3.65,18.74-3.43S157.43,160.35,157.12,160.71Z"/><path class="transparent" d="M71.35,159.39a4,4,0,0,1-.14-1.14,6.86,6.86,0,0,0-.65-2.55"/><path class="transparent" d="M70.29,154.16l-.68-3.07"/><path class="transparent" d="M70,157.82a14.18,14.18,0,0,0-4.57-3.12"/><path class="transparent" d="M73.13,152.12a5.09,5.09,0,0,1-1.56,4.07"/><path class="transparent" d="M138.76,158.55a5.23,5.23,0,0,1,4.41-2"/><path class="transparent" d="M137.24,156.06a5.07,5.07,0,0,1-1.28-2.77"/><path class="transparent" d="M138.83,155.2a19.9,19.9,0,0,0,2-5.79"/><path class="transparent" d="M137.18,159.06a8.93,8.93,0,0,1,1.41-2.7"/><path class="color-1" d="M104.36,181.46c4.55,0,10.73,5.16,21.21,5.16a17.73,17.73,0,0,0,8.65-2.51h0a18.82,18.82,0,0,0,9.5-18.92c-.95-6.75-4-11.37-6.79-15.58"/><path class="color-3" d="M72,149.38c-2.85,4.27-6,8.94-6.94,15.82a18.77,18.77,0,0,0,9.49,18.91h0a17.69,17.69,0,0,0,8.64,2.51c10.48,0,16.67-5.16,21.21-5.16h0"/><path class="shadows" d="M104.35,183.2c2.81,0,10.63,5,16,5,3.15,0,7.48-.23,10-1.09,2-.7,3.61-.47,3.85-2.87,4-2.44,6.23-5.16,6.05-5.4-.33-.45-5.87,6.07-13.59,6.38s-10.79-1.43-14.29-2.77-5.54-2.58-8-2.58h0c-2.44,0-4.48,1.24-8,2.58s-6.58,3.08-14.3,2.77-13.26-6.83-13.59-6.38c-.18.24,2,3,6,5.4.24,2.4,1.83,2.17,3.85,2.87,2.5.86,6.84,1.09,10,1.09C93.73,188.18,101.55,183.2,104.35,183.2Z"/><path class="transparent" d="M97.06,168.7s3.71,2.43,13,1.07"/><path class="transparent" d="M107.87,175.3a43.64,43.64,0,0,1-9.27.76"/></svg><p class="largertext">Please pardon our dust.
We literally used these pages for development testing and haven't spent too much time making them pretty.
By the way, you can use your browser's search feature (usually Ctrl/Cmd + F) to find specific items.</p>
/* [[Text|Link][Setter]] */
/* Most "events" should return here */
/*<<run $back.push(passage())>>*/
<ul>
<li>[[Go back|back]]</li>
<li>[[Change your body|body check][$back.push(passage())]]</li>
<li>[[Change your styles (cosmetics)|styles check][$back.push(passage())]]</li>
<li>[[Change your clothes (beware: lag)|clothes check][$back.push(passage())]]</li>
<li>[[Change your deck|cards check][$back.push(passage())]]</li>
/*
<li>[[event test]]</li>
<li>[[event card test]]</li>
<li>[[action cards test]]</li>
<li>[[loop selection]]</li>
<li> ?changing_room changing allowed from here </li>
*/
<li><<link "Add 10 random inventory items" "test starting page">>
<<set _inv_padding to 10>>
<<run $inv.push(...Object.values(setup.all_clothes).flat()
.filter(({id}) => id isnot 0).randomMany(_inv_padding))>>
<</link>></li>
/*
<li style="overflow-wrap: break-word;">your overall stats: <<print JSON.stringify($player_stats.plain_obj)>></li>
<<if def $current_loop>>
<li>
<p>chosen loop stats: <<print JSON.stringify($current_loop)>></p>
[[Start the loop!|start loop]]
</li>
<<else>>
<li>Go to loop selection and pick something to begin...</li>
<</if>>
*/
</ul>
<div class="flexbuttons">
<<button "+1 ?sub" "test starting page">><<set $player_stats.bsub+=1>><</button>>
<<button "+1 ?int" "test starting page">><<set $player_stats.bint+=1>><</button>>
<<button "+1 ?fit" "test starting page">><<set $player_stats.bfit+=1>><</button>>
<<button "+1 ?att" "test starting page">><<set $player_stats.batt+=1>><</button>>
<<button "+5 ?money" "test starting page">><<set $player_stats.money+=5>><</button>>
<<button "+1 ?stress" "test starting page">><<set $player_stats.stress+=1>><</button>>
<<button "+1 ?arousal" "test starting page">><<set $player_stats.arousal+=1>><</button>>
<<button "+1 ?balance" "test starting page">><<set $player_stats.balance+=1>><</button>>
<<button "+1 ?corruption" "test starting page">><<set $player_stats.corruption+=1>><</button>>
<<button "+1 ?identity" "test starting page">><<set $player_stats.identity+=1>><</button>>
</div>
<div class="flexbuttons">
<<button "-1 ?sub" "test starting page">><<set $player_stats.bsub-=1>><</button>>
<<button "-1 ?int" "test starting page">><<set $player_stats.bint-=1>><</button>>
<<button "-1 ?fit" "test starting page">><<set $player_stats.bfit-=1>><</button>>
<<button "-1 ?att" "test starting page">><<set $player_stats.batt-=1>><</button>>
<<button "-5 ?money" "test starting page">><<set $player_stats.money-=5>><</button>>
<<button "-1 ?stress" "test starting page">><<set $player_stats.stress-=1>><</button>>
<<button "-1 ?arousal" "test starting page">><<set $player_stats.arousal-=1>><</button>>
<<button "-1 ?balance" "test starting page">><<set $player_stats.balance-=1>><</button>>
<<button "-1 ?corruption" "test starting page">><<set $player_stats.corruption-=1>><</button>>
<<button "-1 ?identity" "test starting page">><<set $player_stats.identity-=1>><</button>>
</div>
/*
<br>
<p>and now, for some stat blocks:</p>
<<for _stat range PlayerEquipment._stats.concat(PlayerStats._stats)>>
<<statbar _stat>>
<</for>>
<p>and for the numeric versions:</p>
<<for _stat range PlayerEquipment._stats.concat(PlayerStats._stats, ["money"])>>
<<statnum _stat>>
<</for>>
<p>sifa stats (at full passage width)</p>
<<sifa_stats>>
*/
<br>
<<set _shirts to ["img/test/shirt.svg", "img/test/b4h3w3s3.svg"]>>
<div class="grid5col">
<<for _shirt range _shirts>>
<span>uncolored: <<include _shirt>></span>
<span>blue: <span class="item-blue"><<include _shirt>></span></span>
<span>green: <span class="item-green"><<include _shirt>></span></span>
<</for>>
</div><<set _svg_passages to Story.lookup("tags", "svg").map(p => p.title).slice(0, 10)>>
<div class="grid5col" style="background: grey;">
<<for _svgpsg range _svg_passages>>
<div>
<code><<print _svgpsg>></code>
<<include _svgpsg>>
</div>
<</for>>
</div><<button "Back" "back">><</button>>
<br>
<<for _j to 0; _j lt Object.keys(setup.all_body).length; _j++>>
<<set _place to Object.keys(setup.all_body)[_j]>>
<<print _place>>
<<set _items_at_place to clone(setup.all_body[_place])>>
/*<<set _drop_items to _items_at_place.filter(item => item.rarity.includes("common") or item.rarity.includes("rare") or item.rarity.includes("epic") or item.rarity.includes("legendary"))>>*/
<div class="cards5" style="gap: 0.25em">
<<for _card range _items_at_place>>
<<capture _card>>
<a data-passage=passage() data-setter="$player_equipment[_card.place] to _card">
<<equip_card _card>>
</a>
<</capture>>
<</for>>
</div>
<</for>><<button "Back" "back">><</button>>
<br>
<<for _j to 0; _j lt Object.keys(setup.all_styles).length; _j++>>
<<set _place to Object.keys(setup.all_styles)[_j]>>
<<print _place>>
<<set _items_at_place to clone(setup.all_styles[_place])>>
/*<<set _drop_items to _items_at_place.filter(item => item.rarity.includes("common") or item.rarity.includes("rare") or item.rarity.includes("epic") or item.rarity.includes("legendary"))>>*/
<div class="cards5" style="gap: 0.25em">
<<for _card range _items_at_place>>
<<capture _card>>
<a data-passage=passage() data-setter="$player_equipment[_card.place] to _card">
<<equip_card _card>>
</a>
<</capture>>
<</for>>
</div>
<</for>><<button "Back" "back">><</button>><br>
/*
<<set _styles to {}; _rarities to {}>>
<<set _stats to {min: Infinity, max: -Infinity, sum: 0}>>
<<set _sifa_stats to {}>>
<<for _sifa range setup.SIFA>>
<<set _sifa_stats[_sifa] to clone(_stats)>>
<</for>>
<<set _count to 0>>
<<for _i range setup.all_clothes>>
<<for _k range _i>>
<<set _count++>>
<<for _st range _k.styles>>
<<set _styles[_st] to (_styles[_st] ?? 0) + 1>>
<</for>>
<<set _rarities[_k.rarity] to (_rarities[_k.rarity] ?? 0) + 1>>
<<for _sifa range setup.SIFA>>
<<set _k_stat to _k[_sifa] ?? 0>>
<<set _sifa_stats[_sifa].sum += _k_stat>>
<<set _sifa_stats[_sifa].min to Math.min(_sifa_stats[_sifa].min, _k_stat)>>
<<set _sifa_stats[_sifa].max to Math.max(_sifa_stats[_sifa].max, _k_stat)>>
<</for>>
<</for>>
<</for>>
<<for _sifa, _stat range _sifa_stats>>
<<set _stat.avg to (_stat.sum / _count).toPrecision(5)>>
<</for>>
<p>Counts: (total items: _count)</p>
<<set _pr_st to []>>
<<for _ty, _val range _styles>>
<<run _pr_st.push(_ty + " <img style='height: 1em' src='img2/gear/style/" + _ty + ".svg'>: " + _val)>>
<</for>>
<p><<print _pr_st.join(" | ")>></p>
<<set _pr_st to []>>
<<for _ty, _val range _rarities>>
<<run _pr_st.push(_ty + " <img style='height: 1em' src='img2/gear/" + _ty + ".svg'>: " + _val)>>
<</for>>
<p><<print _pr_st.join(" | ")>></p>
<p>SIFA stats:</p>
<<for _sifa, _stat range _sifa_stats>>
<p><<print _sifa + ": " + JSON.stringify(_stat)>></p>
<</for>>
*/
<<for _j to 0; _j lt Object.keys(setup.all_clothes).length; _j++>>
<<set _place to Object.keys(setup.all_clothes)[_j]>>
<<print _place>>
<<set _items_at_place to clone(setup.all_clothes[_place])>>
/*<<set _drop_items to _items_at_place.filter(item => item.rarity.includes("common") or item.rarity.includes("rare") or item.rarity.includes("epic") or item.rarity.includes("legendary"))>>*/
<div class="cards5" style="gap: 0.25em">
<<for _card range _items_at_place>>
<<capture _card>>
<a data-passage=passage() data-setter="$player_equipment[_card.place] to _card">
<<equip_card _card>>
</a>
<</capture>>
<</for>>
</div>
<</for>><<button "Back" "back">><</button>><br>
<ul>
<li>[[Add a card|add card selection][$back.push(passage())]]</li>
<li>[[Remove a card (sorry about too many confirmations)|remove card selection][$back.push(passage())]]</li>
</ul><p>Click a card to add it to your deck immediately.</p>
<<button "Back" "back">><</button>><br>
<div class="grid4col">
<<for _card range setup.action_cards.concat(setup.punish_cards, setup.cleanse_cards)>><<capture _card>>
<<link "<<action_card _card>>" "add card selection">>
<<run $player_deck.push(clone(_card))>>
<</link>>
<</capture>><</for>>
</div>/* 0 - stat to check (the higher the stat the more likely to get enemy)
1 - bonus for stat check (negative value reduces the chance, positive improves the chance)
2 - styles of the enemy
3 - genders of the enemy
4 - power rate (power*power_rate)*/
<<widget "enemy_spawn">>
<<set _check_stat to _args[0]>>
<<set _bonus_stat to _args[1]>>
<<set _power_rate to _args[4]>>
<<set _enemychance to random(1,10)>>
<<if _enemychance gt _check_stat+_bonus_stat>>
<<set $enemy to null>>
<<else>>
<<set _possible_enemies to setup.regular_enemies.filter(item => _args[2].includes(item.style) and _args[3].includes(item.gender))>>
<<set $enemy to _possible_enemies.random()>>
<<set $enemy.power_rate to _power_rate>>
<</if>>
<</widget>>/* 0 - stat to check (the lower the stat the more likely to get trap)
1 - bonus for stat check (positive value reduces the chance, negative improves the chance)
2 - types of the trap*/
<<widget "trap_spawn">>
<<set _check_stat to _args[0]>>
<<set _bonus_stat to _args[1]>>
<<set _trapchance to random(1,10)>>
<<if _trapchance lte $player_stats[_check_stat]+_bonus_stat>>
<<set $trap to null>>
<<else>>
<<set _possible_traps to setup.traps.filter(item => _args[2].includes(item.type))>>
<<set $trap to _possible_traps.random()>>
<</if>>
<</widget>><<widget "choice_btn">>
/* Args is expected to be a single object with the properties:
* color: background color. TODO maybe more elaborate CSS.
* target: target passage name (for "high" threshold, if applicable)
* text: text on the button
* requirement: OPTIONAL statistic to check; *for now* must be a stat in $player_stats
* threshold: OPTIONAL number, requirement must be gte this for button to be enabled
* low_threshold: OPTIONAL number, if requirement is less than (not equal) this number,
enable w/ alternate target & text. If neither threshold is met, disable button.
* low_target: OPTIONAL target passage name if low_threshold is met (uses target otherwise)
* low_text: OPTIONAL text if low_threshold is met (uses text otherwise)
* mid_target: OPTIONAL target passage to use if neither threshold is met (instead of disabling)
both low & high thresholds must be defined for this to have an effect
* mid_text: OPTIONAL text to use if neither threshold is met (defaults to text)
* disabled: OPTIONAL bool, if true, always disables this button
* disabled_text: OPTIONAL text to show on the button when disabled (defaults to text)
* side_effects(): OPTIONAL function to run on click (like data-setter)
e.g. side_effects() {
$charview = 3;
$player_equipment.bottom = setup.all_clothes.bottom[1];
},
or side_effects: () => $charview to 3,
do not save a button w/ side_effects to $vars (_temp & setup are OK)
*/
<<set _btn to _args[0]>>
<<set _disable to false>>
<<set _text to _btn.text>>
<<set _target to _btn.target>>
<<if def _btn.requirement>>
<<set _req to $player_stats[_btn.requirement]>>
<<if (def _btn.threshold) and (ndef _btn.low_threshold)>>
/* only regular threshold */
<<if not (_req >= _btn.threshold)>>
<<set _disable to true>>
<<set _text to _btn.disabled_text ?? _text>>
<</if>>
/* otherwise met, nothing to do */
<<elseif (ndef _btn.threshold) and (def _btn.low_threshold)>>
/* only low threshold */
<<if _req < _btn.low_threshold>>
<<set _target to _btn.low_target ?? _target>>
<<set _text to _btn.low_text ?? _text>>
<<else>>
<<set _disable to true>>
<<set _text to _btn.disabled_text ?? _text>>
<</if>>
<<elseif (def _btn.threshold) and (def _btn.low_threshold)>>
/* low & high threshold. Test high, then low... */
<<if not (_req >= _btn.threshold)>>
/* high not met, try low */
<<if _req < _btn.low_threshold>>
/* low met */
<<set _target to _btn.low_target ?? _target>>
<<set _text to _btn.low_text ?? _text>>
<<elseif def _btn.mid_target>>
/* neither met, but there's a fallback... */
<<set _target to _btn.mid_target>>
<<set _text to _btn.mid_text ?? _text>>
<<else>>
/* neither met, no fallback */
<<set _disable to true>>
<<set _text to _btn.disabled_text ?? _text>>
<</if>>
<</if>>
/* else high is OK, use regular text & target */
<</if>>
/* else both are missing, do nothing */
<<elseif _btn.disabled>>
<<set _text to _btn.disabled_text ?? _text>>
<</if>>
<<if _disable or _btn.disabled is true>>
<button class="btn" disabled>_text</button>
<<else>>
<<capture _btn>>
<button data-setter="_btn.side_effects?.()" @data-passage="_target" class="btn" @style='"background: " + _btn.color'>_text</button>
<</capture>>
<</if>>
<</widget>>
<<widget "event_passage" container>>
/* Args:
* 0: object for event_card widget
* 1: array of "button" objects for player choices, see choice_btn widget
* _contents: passage text */
<<set _wevp_card to _args[0]>>
<<set _wevp_choices to _args[1]>>
<div class="grid2col">
<div><<print _contents>></div>
<div class="flexdown">
<div class="js-tilt" style="width: 80%;"><<event_card _wevp_card>></div>
<<for _choice range _wevp_choices>>
<<choice_btn _choice>>
<</for>>
</div>
</div>
<</widget>>
<<widget "event_card">>
/* Args is expected to be exactly 1 object with properties:
* title
* color: background color/CSS property
* bg_img: file name, relative to event images path
* fg_img: OPTIONAL like bg_img
* OR it can be an EquipItem or ActionCard-- then this will just display that widget + tilt
*/
<<set _wev_card to _args[0]>>
<<if _wev_card.is_equip_item>>
<<equip_card _wev_card>>
<<elseif _wev_card.is_action_card>>
<<action_card _wev_card notilt>>
<<else>>
<div class="eventcard">
<div class="eventcard-static" @style='"background: " + _wev_card.color'>
<img src="img2/events/static.svg">
</div>
<div class="eventcard-title"><<print _wev_card.title>></div>
<img class="eventcard-art-bg" @src='"img2/events/images/" + _wev_card.bg_img'>
<<if def _wev_card.fg_img>>
<img class="eventcard-art" @src='"img2/events/images/" + _wev_card.fg_img'>
<</if>>
</div>
<</if>>
<</widget>><<set $loop_choices to []>>
/* TODO generate these instead. Loop over all the items "properly".
Object.values(SugarCube.setup.all_body).forEach(li => li.forEach(it => it.colors.forEach(c => colors.add(c)))); */
/* removed "nocolor" and "transparent","multicolor","brown","yellow","blonde". */
/* fixed amount of colors styles, gender styles for body/style items moved out of clothing styles */
<<set _colors to ["black","white","blue","pink","red","cyan","green"]>>
<<set _styles to ["lewd","formal","modest","active","comfy","party","cute","study","casual","sexy"]>>
<<set _gender_styles to ["male", "unisex", "female"]>>
/* TODO: number of loops generated is the same as the number of complete difficulties. So at the beginning only 1 loop is generated.
If you complete first difficulty - you will see 2 loops generated. But both of them might be of the same difficulty
maybe there is a better way then using $complete_difficulty to track the number of complete difficulties xD */
/*<<set _max_diff to $complete_difficulty + 1>>*/
<<set _random_diff to Math.min(4, $debt.index + 1)>>
<<for _num = 1; _num lte 4; _num++>>
<<set _loop to {
difficulty: random(1, _random_diff),
bonuses: {
colors: {},
styles: {},
},
event_styles: new Set(),
event_colors: new Set(),
}>>
/* added all the colors and gender styles into the loop settings, so only styles that add extra stats take effect for now. Later we return gender and maybe colors */
<<set _bonuses to 3>>
<<set _bonus_colors to 0>>
<<set _bonus_styles to _bonuses - _bonus_colors>>
<<for _i = 0; _i < _bonus_colors; ++_i>>
<<set _color to _colors.random()>>
<<set _loop.event_colors.add(_color)>>
<<set _bonus to setup.SIFA.random()>>
<<set _loop.bonuses.colors[_color] ??= {}>>
<<set _loop.bonuses.colors[_color][_bonus] ??= 0>>
<<set _loop.bonuses.colors[_color][_bonus] += 1>>
<</for>>
<<for _i = 0; _i < _bonus_styles; ++_i>>
<<set _style to _styles.random()>>
<<set _loop.event_styles.add(_style)>>
<<set _bonus to setup.SIFA.random()>>
<<set _loop.bonuses.styles[_style] ??= {}>>
<<set _loop.bonuses.styles[_style][_bonus] ??= 0>>
<<set _loop.bonuses.styles[_style][_bonus] += 1>>
<</for>>
<<set _events to 10>>
<<set _event_styles to 0>>
<<set _event_gender_styles to 3>>
<<set _event_colors to _events - _event_styles - _event_gender_styles>>
<<run _styles.randomMany(_event_styles).forEach(c => _loop.event_styles.add(c))>>
<<run _colors.randomMany(_event_colors).forEach(c => _loop.event_colors.add(c))>>
<<run _gender_styles.randomMany(_event_gender_styles).forEach(c => _loop.event_styles.add(c))>>
<<set $loop_choices.push(_loop)>>
<</for>>
/* The rest of this passage is just for testing.
<<run console.log($loop_choices)>>
<<run console.log(JSON.stringify($loop_choices, null, 2))>>
<<set $current_loop to $loop_choices[0]>>
<<run $player_equipment.calc_all_stats()>>
<<goto "test starting page">>
*//* this is the "root" of the game so reset $back, just in case */
<<set $back to [passage()]>>
<<include LobbyBanner>>
<p>Each loop has different dress code preferences. <<if $debt.index lte 0>>Harder difficulties can become available after succesful payments.<</if>></p>
<p class="largertext">Your next payment when you return is ?money<<print $debt.payment>>.</p>
<<if $loop_choices.length is 0>>
<<include "loop gen">>
<</if>>
/*
[[back]]<br>
[[Regen loops?|loop selection][$loop_choices to []]]<br>*/
<<set _diff_str to [null, "Easy", "Medium", "Hard", "Hardest"]>>
<div class="grid2col">
<<for _loop range $loop_choices>><<capture _loop>>
<button class="btn btn-loop" data-passage="changing room" data-setter="$current_loop to _loop">
<h2><<print _diff_str[_loop.difficulty]>></h2>
<p>Equipment bonuses:</p>
<<loop_bonuses _loop>>
</button>
<</capture>><</for>>
</div><<set _choices to [
{
text: "Start",
target: "start loop",
color: "green",
},
{
text: "Change the Loop",
target: "loop selection",
color: "gray",
},
{
text: "Game Difficulty",
target: "game difficulty",
side_effects: () => $back.push(passage()),
color: "darkred",
},
]>>
<<include ChangingRoomExtra>>
<<set _ecard to {title: "Changing Room", color: "hotpink", bg_img: "Women Changing Room_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?changing_room</p>
<p>I can change my clothes here. It's better to wear something that fits the dress code, but it isn't necessary.</p>
<p>I can still change the loop if I want to.</p>
<br>
<p><i>You can change game difficulty here. It's one more option in addition to "loop difficulty".</i></p>
<</event_passage>><<set _old_difficulty to $game_difficulty>>
<<set _choices to [
{
text: "Easy",
color: "green",
side_effects: () => {
$game_difficulty = 1;
setup.payment_adjust(_old_difficulty, $game_difficulty);
},
target: "back",
},
{
text: "Normal",
side_effects: () => {
$game_difficulty = 2;
setup.payment_adjust(_old_difficulty, $game_difficulty);
},
target: "back",
color: "orange",
},
{
text: "Hard",
side_effects: () => {
$game_difficulty = 3;
setup.payment_adjust(_old_difficulty, $game_difficulty);
},
target: "back",
color: "darkred",
},
{
text: "Back",
target: "back",
color: "gray",
},
]>>
<<set _ecard to {title: "Game Difficulty", color: "darkred", bg_img: "complain_b.jpg"}>>
<<set _difficulties to ["[This is a bug]", "Easy", "Normal", "Hard"]>>
<<event_passage _ecard _choices>>
<p><i>Current difficulty - <b><<print _difficulties[$game_difficulty]>></b></i></p>
<br>
<p><i>You can change game difficulty here. It's one more option in addition to "loop difficulty". For now it affects Echoes hit points, amount of money you lose when giving up to Echo, and debt payments at the end of the loop. And it's still not balanced well, so don't be afraid to switch it if you're feeling too much pain, or not too much.</i></p>
<</event_passage>>/* maybe a better name is "loop event calc"? */
<<set $events to []>>
/* each "wave" should not have duplicates but repeats may happen otherwise */
<<for _i = 0; _i < 4; ++_i>>
<<set _wave to []>>
/* TODO maybe something involving weighted randomness instead? */
<<run _wave.push(...setup.event_passages["instant-event"].randomMany(6))>>
<<run _wave.push(...setup.event_passages["event"].randomMany(4))>>
<<run _wave.push(...setup.event_passages["complex-event"].randomMany(2))>>
<<run _wave.shuffle()>>
/* avoid back-to-back duplicate events-- move first event to end */
<<if $events.at(-1) === _wave[0]>>
<<run _wave.push(_wave.shift())>>
<</if>>
<<run $events.push(... _wave)>>
<</for>>
<<set $player_perm_equip to clone($player_equipment)>>
/* TODO passage to introduce TFs? */
<<goto "next event">><<set $temp to {}>>
<<if $player_stats.identity gte 10 and (not $current_loop.max_identity)>>
<<set _event to "full identity precalc">>
<<elseif $player_stats.stress gte 10>>
<<set _event to "overstressed">>
<<elseif $player_stats.arousal gte 10>>
<<set _event to "overaroused">>
<<elseif $player_stats.balance gte 10>>
<<set _event to "full balance calc">>
<<elseif $player_stats.corruption gte 10>>
<<set _event to "full corruption calc">>
<<else>>
<<set _event to $events.shift()>>
<</if>>
<<if def _event>>
/* when event is over, go back here */
<<run $back.push(passage())>>
<<goto _event>>
<<else>>
/* completed all events. TODO boss passage instead?
* for safety, scrub accidental 'next event's... */
<<for $back.at(-1) === "next event">><<run $back.pop()>><</for>>
<<goto "loop end">>
<</if>>/* 'back' should point to the lobby around here... */
<<unset $current_loop>>
<<set $loop_choices to []>>
<<set _old_equip to clone($player_equipment)>>
/* reset player body to "permanent" */
<<for _place range Object.keys(setup.all_body)>>
<<set $player_equipment[_place] to $player_perm_equip[_place]>>
<</for>>
<<if $player_stats.money gte $debt.payment>>
<<set _choices to [{
text: "Alright, here you go",
target: "loop end payment",
color: "green",
}]>>
<<else>>
<<set _choices to [{
text: "I'm a little short...",
target: "loop end debt fail calc",
color: "darkred",
}]>>
<</if>>
<<set _ecard to {title: "Welcome Back", color: "green", bg_img: "Men Changing Room_b.jpg"}>>
<<event_passage _ecard _choices>>
<p>Welcome back. Your body has been returned to its initial state.</p>
<<equip_tf _old_equip.face $player_equipment.face>>
<<equip_tf _old_equip.body $player_equipment.body>>
<p>Per the terms of your contract, you currently owe ?money<<print $debt.payment>>
for facility upkeep. Please remit these funds immediately.</p>
<</event_passage>><<set $player_stats.money -= $debt.payment>>
<<set $debt.index = Math.min($debt.index + 1, setup.payments[$game_difficulty].length - 1)>>
<<set $debt.payment to setup.payments[$game_difficulty][$debt.index]>>
<<if $debt.index gte setup.payments[$game_difficulty].length - 1>>
<<set $related_phrase to "You paid all the money, what means that you have won. Unfortunatelly, Sifa was too lazy to write some good endings. But we keep working on the game, and we have a lot of materials prepared. So the next half of the year will be quite active, so check for the updates sometimes. Thanks for your time, you're awesome!">>
<<else>>
<<set $related_phrase to "Unfortunately, due to increasing upkeep here, you will owe <strong>?money<<print $debt.payment>></strong> on your next return from a loop. Feel free to hang on to your remaining funds until then.">>
<</if>>
<<set _ecard to {title: "Debt Paid", color: "blue", bg_img: "Men Changing Room_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p>Excellent. Glad to see you're earning your keep. No need to worry about interest or otherwise, for now...</p>
<p>$related_phrase</p>
<</event_passage>><<set $debt.interest_idx to 0>>
<<if $player_stats.money lt (setup.interest_rates[0] * $debt.payment) / 2>>
<<goto "loop end debt overflow">>
<<else>>
<<goto "loop end debt fail">>
<</if>><<set _potential_debt to Math.round($debt.payment * (1 + setup.interest_rates[$debt.interest_idx]))>>
<<set _choices to [
{
text: "Compound Interest",
side_effects() {
$debt.payment = _potential_debt;
$debt.payment -= $player_stats.money;
$player_stats.money = 0;
delete $debt.interest_idx;
},
target: "back",
color: "darkred",
},
{
text: "Enhance yourself",
disabled_text: "Got enough enhancements...",
side_effects() {
$back.push(passage());
$debt.interest_idx += 1;
},
target: "feminization calc",
color: "magenta",
disabled: $debt.interest_idx gte setup.interest_rates.length - 1,
},
]>>
<<set _rate to (setup.interest_rates[$debt.interest_idx] * 100) + "%">>
<<set _ecard to {title: "Other Arrangements", color: "red", bg_img: "makeup process_b.jpg"}>>
<<event_passage _ecard _choices>>
<<if $debt.interest_idx is 0>>
/*<p>Well, you may be low on funds, but you can still pay down with what you have.</p>*/
<p>We expect you to make complete payments on your debt.</p>
<p>Since you cannot pay in full yet, we will first compound some interest at a rate of _rate,
increasing your debt to ?money<<print _potential_debt>>.
We will allow you to pay down to ?money<<print _potential_debt - $player_stats.money>> afterward. </p>
<p>That said, we do offer an option to lessen the blow a little.
We can enhance you to better fit the loop, that reduces our costs,
and we pass that on to you in the form of a temporary reduction of that interest rate. What do you say?</p>
<<elseif $debt.interest_idx lt setup.interest_rates.length - 1>>
<p>Lovely. That should make it a bit easier for you to earn money in the loop.
We have reduced your interest rate to _rate,
reducing your debt to ?money<<print _potential_debt>>,
which may be paid down to ?money<<print _potential_debt - $player_stats.money>>.</p>
<p>We are willing to reduce your interest further, should you be willing to transform more.</p>
<<else>>
<p>While we appreciate your enthusiasm, we are only willing to reduce your debt so far...
Your final interest rate is _rate, which will leave you with a new debt of
?money<<print _potential_debt>>, which may be paid down to ?money<<print _potential_debt - $player_stats.money>>.</p>
<p>Have a lovely day with your new form.</p>
<</if>>
<</event_passage>><<set _base to setup.payments[$game_difficulty][$debt.index]>>
<<set $debt.payment to Math.round(Math.clamp(
($debt.payment - $player_stats.money) * 0.8,
_base / 2, _base * 2))>>
<<set $player_stats.money to 0>>
<<set _choices to [
{
text: "Face the consequences",
color: "red",
side_effects() {
/* TODO hypno event/identity+ */
$player_stats.identity += 2;
$player_stats.arousal = 0;
$back.push(...new Array(3).fill("feminization calc"));
},
target: "back",
},
]>>
<<set _ecard to {title: "Excessive Debt?!", color: "red", bg_img: "Brainwashing Porn_b.jpg"}>>
<<event_passage _ecard _choices>>
<p>Well, this is ridiculous. You haven't even earned half of what we planned to charge in interest alone...
Since we see you're struggling, we'll forgo the interest for now, and even reduce your debt a bit to
?money<<print $debt.payment>>. However, you will be subject to some transformative measures
to help us keep our costs down. Please enjoy this instructional video...</p>
<</event_passage>>/* for "manual" links to back-- maybe should be a widget idk */
<<if $back.length > 0>>
<<goto $back.pop()>>
<<else>>
<p>Oops, we tried to "go back" without keeping track of what was "back". Please report a bug with a save file here.</p>
[[Go "back" to loop selection|loop selection]]
<</if>>/* go back, after discarding the top */
<<run $back.pop()>>
<<goto "back">><div class="grid2col">
<<set _ecard to {title: "test event", color: "blue", fg_img: "testnpc_f.png", bg_img: "testnpc_b.jpg"}>>
<div class="js-tilt">
<<event_card _ecard>>
</div>
[[back]]
</div><<set _choices to [
{
text: "Back",
target: "back",
color: "blue",
},
{
text: "Wardrobe",
target: "wardrobe",
color: "mediumvioletred",
},
{
text: "Drawer",
target: "drawer",
color: "mediumvioletred",
},
{
text: "women changing room",
target: "women changing room",
color: "mediumvioletred",
},
{
text: "Gym Entrance",
target: "gym entrance",
color: "green",
},
{
text: "Always off, even though req is met",
target: "event test",
color: "green",
requirement: "att",
threshold: -Infinity,
disabled: true,
},
{
text: "?att is >= 5",
disabled_text: "?att is < 5",
target: "event test",
color: "pink",
requirement: "att",
threshold: 5,
},
{
text: "?sub is >= 10, loop",
low_text: "?sub is < 6, go back",
disabled_text: "?sub is 5-9, disable",
target: "event test",
low_target: "back",
color: "red",
requirement: "sub",
threshold: 10,
low_threshold: 6,
},
{
text: "?att is < 5",
disabled_text: "?att is >= 5",
target: "event test",
color: "pink",
requirement: "att",
low_threshold: 5,
},
]>>
<<set _dumb to {
text: '<img style="display: inline-block; vertical-align: middle; width: 90%;" src="img2/actions/image/Show Obedience.png">',
target: "event test",
color: "blue",
}>>
/*<<set _ecard to {title: "this is a really long event", color: "blue", fg_img: "testnpc_f.png", bg_img: "testnpc_b.jpg"}>>*/
/*<<set _ecard to setup.all_clothes.bottom[1]>>*/
<<set _ecard to setup.action_cards[1]>>
<<event_passage _ecard _choices>>
<p>This is a sample event. Who knows what'll happen?</p>
<p>You have these stats: <<print JSON.stringify($player_stats.plain_obj, null, 1)>></p>
<p>Next, here's a "standalone" copy of the first button. This widget isn't really indended for "inline" usage, but it's possible. <<choice_btn _choices[0]>></p>
<p>Also, button elements can have stuff other than text: <<choice_btn _dumb>></p>
<</event_passage>><<set $get_action_card to "red">>
<<set _choices to [
{
disabled_text: "Not enough ?sub",
text: "Submission ?sub",
target: "sub action card",
color: "darkred",
requirement: "bsub",
threshold: 1,
},
{
disabled_text: "Not enough ?int",
text: "Intellect ?int",
target: "int action card",
color: "mediumblue",
requirement: "bint",
threshold: 1,
},
{
disabled_text: "Not enough ?fit",
text: "Fitness ?fit",
target: "fit action card",
color: "green",
requirement: "bfit",
threshold: 1,
},
{
disabled_text: "Not enough ?att",
text: "Attraction ?att",
target: "att action card",
color: "purple",
requirement: "batt",
threshold: 1,
},
{
text: "Skip",
side_effects: () => $player_stats.corruption += 1,
target: "back",
color: "gray",
},
]>>
<<if Object.values($player_stats.core_stats).every(s => s === 0)>>
<<goto "train sifa precalc">>
<<else>>
<<set _ecard to {title: "Lecture Hall", color: "mediumblue", bg_img: "teacher_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?new_card ?sub ?int ?fit ?att</p>
<p>Here I can learn some new skills. I need to improve my core stats first, then I can spend my points to learn new actions. However, with the new skills it would be easier to release echoes.</p>
<</event_passage>>
<</if>><<set $get_action_card to "red">>
<<set $get_action_card2 to "bsub">>
<<set _choices to [
{
text: "Back",
target: "new action card choice",
color: "gray",
},
{
disabled_text: "Not enough ?sub",
text: "Common Card -1?sub",
target: "get common action calc",
color: "green",
requirement: "bsub",
threshold: 1,
},
{
disabled_text: "Not enough ?sub",
text: "Rare Card -2?sub",
target: "get rare action calc",
color: "royalblue",
requirement: "bsub",
threshold: 2,
},
{
disabled_text: "Not enough ?sub",
text: "Epic Card -3?sub",
target: "get epic action calc",
color: "purple",
requirement: "bsub",
threshold: 3,
},
{
disabled_text: "Not enough ?sub",
text: "Legendary Card -4?sub",
target: "get legendary action calc",
color: "orange",
requirement: "bsub",
threshold: 4,
},
]>>
<<set _ecard to {title: "Submission Lesson", color: "red", bg_img: "dominant teacher_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?new_card ?sub</p>
<p>Here I can learn some new submission skills.</p>
<</event_passage>><<set $get_action_card to "blue">>
<<set $get_action_card2 to "bint">>
<<set _choices to [
{
text: "Back",
target: "new action card choice",
color: "gray",
},
{
disabled_text: "Not enough ?int",
text: "Common Card -1?int",
target: "get common action calc",
color: "green",
requirement: "bint",
threshold: 1,
},
{
disabled_text: "Not enough ?int",
text: "Rare Card -2?int",
target: "get rare action calc",
color: "royalblue",
requirement: "bint",
threshold: 2,
},
{
disabled_text: "Not enough ?int",
text: "Epic Card -3?int",
target: "get epic action calc",
color: "purple",
requirement: "bint",
threshold: 3,
},
{
disabled_text: "Not enough ?int",
text: "Legendary Card -4?int",
target: "get legendary action calc",
color: "orange",
requirement: "bint",
threshold: 4,
},
]>>
<<set _ecard to {title: "Intellect Lesson", color: "darkblue", bg_img: "smart echo_b.jpg", fg_img: "smart echo.png"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?new_card ?int</p>
<p>Here I can learn some new intellect skills.</p>
<</event_passage>><<set $get_action_card to "green">>
<<set $get_action_card2 to "bfit">>
<<set _choices to [
{
text: "Back",
target: "new action card choice",
color: "gray",
},
{
disabled_text: "Not enough ?fit",
text: "Common Card -1?fit",
target: "get common action calc",
color: "green",
requirement: "bfit",
threshold: 1,
},
{
disabled_text: "Not enough ?fit",
text: "Rare Card -2?fit",
target: "get rare action calc",
color: "royalblue",
requirement: "bfit",
threshold: 2,
},
{
disabled_text: "Not enough ?fit",
text: "Epic Card -3?fit",
target: "get epic action calc",
color: "purple",
requirement: "bfit",
threshold: 3,
},
{
disabled_text: "Not enough ?fit",
text: "Legendary Card -4?fit",
target: "get legendary action calc",
color: "orange",
requirement: "bfit",
threshold: 4,
},
]>>
<<set _ecard to {title: "Fitness Lesson", color: "green", bg_img: "fitness_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?new_card ?fit</p>
<p>Here I can learn some new fitness skills.</p>
<</event_passage>><<set $get_action_card to "purple">>
<<set $get_action_card2 to "batt">>
<<set _choices to [
{
text: "Back",
target: "new action card choice",
color: "gray",
},
{
disabled_text: "Not enough ?att",
text: "Common Card -1?att",
target: "get common action calc",
color: "green",
requirement: "batt",
threshold: 1,
},
{
disabled_text: "Not enough ?att",
text: "Rare Card -2?att",
target: "get rare action calc",
color: "royalblue",
requirement: "batt",
threshold: 2,
},
{
disabled_text: "Not enough ?att",
text: "Epic Card -3?att",
target: "get epic action calc",
color: "purple",
requirement: "batt",
threshold: 3,
},
{
disabled_text: "Not enough ?att",
text: "Legendary Card -4?att",
target: "get legendary action calc",
color: "orange",
requirement: "batt",
threshold: 4,
},
]>>
<<set _ecard to {title: "Attractiveness Lesson", color: "purple", bg_img: "hot echo_b.jpg", fg_img: "hot echo.png"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?new_card ?att</p>
<p>Here I can learn some new Attractiveness skills.</p>
<</event_passage>><<set $player_stats[$get_action_card2] += 1>>
<<if $get_action_card2 is "bint" or $get_action_card2 is "bfit">>
<<set $player_stats.balance -= 1>>
<<set $player_stats.stress += 1>>
<<else>>
<<set $player_stats.corruption -= 1>>
<<set $player_stats.identity += 1>>
<</if>>
<<goto "back">><<set $player_stats[$get_action_card2] -= 1>>
<<set $loot to setup.action_cards.filter(item => item.rarity is 0 and item.color eq $get_action_card).random()>>
<<run $player_deck.push($loot)>>
<<goto "new action card">><<set $player_stats[$get_action_card2] -= 2>>
<<set $loot to setup.action_cards.filter(item => item.rarity is 1 and item.color eq $get_action_card).random()>>
<<run $player_deck.push($loot)>>
<<goto "new action card">><<set $player_stats[$get_action_card2] -= 3>>
<<set $loot to setup.action_cards.filter(item => item.rarity is 2 and item.color eq $get_action_card).random()>>
<<run $player_deck.push($loot)>>
<<goto "new action card">><<set $player_stats[$get_action_card2] -= 4>>
<<set $loot to setup.action_cards.filter(item => item.rarity is 3 and item.color eq $get_action_card).random()>>
<<run $player_deck.push($loot)>>
<<goto "new action card">><<set $get_action_card to "red">>
<<event_passage $loot setup.ok_choices>>
<p>I learned new skill - $loot.name. Now I can use it to release the echoes.</p>
<</event_passage>><<set _choices to [
{
text: "Dress-code Preset",
target: "random matched clothing loot calc",
color: "green",
},
{
text: "Random Preset",
target: "random clothing loot calc",
color: "green",
},
{
text: "Enhance Preset",
target: "enhance clothing calc",
color: "green",
},
]>>
<<set _ecard to {title: "Wardrobe", color: "orange", bg_img: "Wardrobe_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?balance ?corruption ?fem</p>
Cool, I can find some new clothes in this wardrobe. It's said this wardrobe has 3 presets. Dress-code clothing, random clothing, and "Enhance", whatever that means.
<</event_passage>><<set $player_stats.balance += 1>>
<<set _droplist to setup.items_matching_current_loop("clothes", "top", "bottom", "shoes")
.filter(setup.item_not_worn)>>
<<if _droplist.length is 0>>
<<set _droplist to setup.items_matching_difficulty("clothes", "top", "bottom", "shoes")
.filter(setup.item_not_worn)>>
<</if>>
<<set $loot to clone(_droplist[alias_sampler(setup.weight_items_by_carried(_droplist))()])>>
<<if $loot is undefined>>
<<goto "no clothing loot results">>
<<else>>
<<goto "clothing loot results">>
<</if>><<set $player_stats.corruption += 1>>
<<set _droplist to setup.items_matching_difficulty("clothes", "top", "bottom", "shoes")
.filter(setup.item_not_worn)>>
<<set $loot to clone(_droplist[alias_sampler(setup.weight_items_by_carried(_droplist))()])>>
<<if $loot is undefined>>
<<goto "no clothing loot results">>
<<else>>
<<goto "clothing loot results">>
<</if>><<set _current_clothing to Object.keys(setup.all_clothes).shuffle()
.map(clty => $player_equipment[clty])
.reduce((ans, cur) => {
/* return the least fem item that isn't "empty" (unless all empty...) */
if(ans.id === 0) {
return cur;
} else if(cur.id === 0 || ans.fem < cur.fem) {
return ans;
} else {
return cur;
}
})
>>
<<set _matching_clothes to setup.all_clothes[_current_clothing.place]
.filter(item => item.fem gte _current_clothing.fem and item.rarity lte $current_loop.difficulty and item.id gt 0 and item.id neq $old_item.id)>>
<<if _matching_clothes.length is 0>>
<<goto "no clothing loot results">>
<<else>>
<<set $loot to _matching_clothes.random()>>
<<set $old_item to $player_equipment.replace_with($loot)>>
<<if $loot.fem eq $old_item.fem>>
<<set $player_stats.stress -= 1>>
<<set $related_phrase to "I don't feel any major differences from before.">>
<<else>>
<<set $related_phrase to "I can only change that in private if I want to.">>
<</if>>
<<goto "enhanced clothing results">>
<</if>><<set _choices to [
{
text: "Dress-code Preset",
target: "random matched underwear loot calc",
color: "green",
},
{
text: "Random Preset",
target: "random underwear loot calc",
color: "green",
},
{
text: "Enhance Preset",
target: "enhance clothing calc",
color: "green",
},
]>>
<<set _ecard to {title: "Drawer", color: "orange", bg_img: "Drawer_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?balance ?corruption ?fem</p>
<p>Great, I can try to find new underwear in this drawer. Maybe someone even left some accessories there. It's said this wardrobe has 3 presets. Dress-code item, random item, and "Enhance", whatever that means.</p>
<</event_passage>><<set $player_stats.balance += 1>>
<<set _droplist to setup.items_matching_current_loop("clothes", "mask", "undies", "bra", "legwear")
.filter(setup.item_not_worn)>>
<<if _droplist.length is 0>>
<<set _droplist to setup.items_matching_difficulty("clothes", "mask", "undies", "bra", "legwear")
.filter(setup.item_not_worn)>>
<</if>>
<<set $loot to clone(_droplist[alias_sampler(setup.weight_items_by_carried(_droplist))()])>>
<<if $loot is undefined>>
<<goto "no clothing loot results">>
<<else>>
<<goto "clothing loot results">>
<</if>><<set $player_stats.corruption += 1>>
<<set _droplist to setup.items_matching_difficulty("clothes", "mask", "undies", "bra", "legwear")
.filter(setup.item_not_worn)>>
<<set $loot to clone(_droplist[alias_sampler(setup.weight_items_by_carried(_droplist))()])>>
<<if $loot is undefined>>
<<goto "no clothing loot results">>
<<else>>
<<goto "clothing loot results">>
<</if>><<set _current_clothing to clone($player_equipment[$loot.place])>>
<<set _choices to [
{
disabled_text: "Not enough ?corruption",
text: "Put in inventory -?corruption",
side_effects() {
$player_stats.corruption -= 1;
$inv.push(clone($loot));
},
target: "back",
color: "purple",
requirement: "corruption",
threshold: 1,
},
{
text: "Wear $loot.name",
side_effects: () => $player_equipment.wear_and_keep_old($loot),
target: "back",
color: "hotpink",
},
{
disabled_text: "Not enough ?balance",
text: "Skip -?balance",
side_effects: () => $player_stats.balance -= 1,
target: "back",
color: "blue",
requirement: "balance",
threshold: 1,
},
]>>
<<set _ecard to $loot>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?identity ?fem ?stress ?arousal</p>
<p>I found $loot.gender $loot.name. I can put it in my bag.</p>
<p>From the other hand, I can change $loot.place right here if I don't want to look for changing room.</p>
<p>I currently have <<print $player_equipment[$loot.place].name>>.</p>
<div class="bigcard">
<<equip_card _current_clothing>>
</div>
<</event_passage>><<event_passage $loot setup.ok_choices>>
<p>Robotic voice told me to place my $old_item.place inside.
After a while it was unlocked and I was told to try $loot.name on. $related_phrase</p>
<p>I had <<print $old_item.name>> before, but now it's gone.</p>
<div class="bigcard">
<<equip_card $old_item>>
</div>
<</event_passage>><<set _ecard to {title: "Nothing", color: "deepskyblue", bg_img: "Nothing_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
Eh, nothing useful here.
<</event_passage>><<set _choices to [
{
disabled_text: "Not enough ?balance",
text: "Subtle Cosmetics -?balance",
target: "subtle cosmetics calc",
color: "royalblue",
requirement: "balance",
threshold: 1,
},
{
disabled_text: "Not enough ?corruption",
text: "Heavy Cosmetics -?corruption",
target: "heavy cosmetics calc",
color: "purple",
requirement: "corruption",
threshold: 2,
},
{
text: "Ignore the chair",
target: "back",
color: "gray",
},
]>>
<<if $player_stats.balance gte 1 or $player_stats.corruption gte 2>>
<<if $player_stats.identity gte 4 and $player_stats.fem lt $player_stats.identity>>
<<if ($player_stats.identity gte 5) and
($player_stats.identity - $player_stats.fem gte 4) and
($player_stats.corruption gte 2)>>
<<set _choices[0].disabled to true>>
<<set _choices[0].disabled_text to "I could use a retouch...">>
<<set _choices[2].disabled to true>>
<<set _choices[2].disabled_text to "Yeah, I <em>really</em> need a retouch.">>
<<else>>
<<set _choices[2].disabled to true>>
<<set _choices[2].disabled_text to "I could use a retouch...">>
<</if>>
<<elseif $player_stats.stress gte 7>>
<<set _choices[2].disabled to true>>
<<set _choices[2].disabled_text to "I really need to calm down...">>
<</if>>
<</if>>
<<set _ecard to {title: "Makeup Chair", color: "hotpink", bg_img: "makeup chair_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?fem ?stress</p>
<p>Ok, it's not just a chair. It's an automatic makeup chair. It can change my look, like hairstyle, makeup, etc. It has 2 modes, subtle and heavy.</p>
<p>I can also relax a bit during the process.</p>
<</event_passage>><<set $player_stats.balance -= 1>>
<<set $player_stats.stress -= 2>>
<<set _droplist to Object.values(setup.all_styles).flat()
.filter(item => item.id gt 0 and item.fem lte 1 and setup.item_not_worn(item))>>
<<set $loot to _droplist.random()>>
<<set $old_item to $player_equipment.replace_with($loot)>>
<<goto "new cosmetics">><<set $player_stats.corruption -= 2>>
<<set $player_stats.stress -= 2>>
<<set _droplist to Object.values(setup.all_styles).flat()
.filter(item => item.fem gt 1 and setup.item_not_worn(item))>>
<<set $loot to _droplist.random()>>
<<set $old_item to $player_equipment.replace_with($loot)>>
<<goto "new cosmetics">><<set _ecard to {title: "Makeup Chair", color: "hotpink", bg_img: "makeup process_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p>A robotic voice told me to sit down and relax. After some time my new $loot.name was finished.</p>
<<equip_tf $old_item $loot>>
<</event_passage>><<set _choices to [
{
disabled_text: "Not enough ?stress to sleep",
text: "Sleep",
target: "sleeping in the bedroom of love calc",
color: "green",
requirement: "stress",
threshold: 4,
},
{
disabled_text: "Not enough ?arousal to masturbate",
text: "Masturbate",
target: "masturbate calc",
color: "red",
requirement: "arousal",
threshold: 4,
},
{
text: "Skip",
target: "back",
color: "gray",
},
]>>
<<set _ecard to {title: "The Bedroom of Love", color: "red", bg_img: "The Bedroom of Love_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?changing_room ?balance ?corruption ?identity ?fem ?stress ?arousal</p>
<p>It should be a brothel room. Dim lights, red colors, and everything is "love" themed. At least I'm alone here, so I can change clothes.</p>
<p>This place has a bed, so it's good enough to take a break and sleep for a while. Especially if I'm stressed out. But it's a brothel. I don't want to think what might happen if someone mistakes me for a worker.</p>
<p>I also spotted a TV set here. Though, I couldn't find the remote control. Instead I noticed the instructions. It is said that TV has a sensor, so when you want to masturbate it shows you the channel based on your look. Sounds stupid, but interesting. What they might show me this time?</p>
<</event_passage>><<enemy_spawn $player_stats.fem 2 "modest" "male" 1.5>>
<<set $player_stats.stress to 0>>
<<set $player_stats.balance++>>
<<if $enemy>>
<<set $player_stats.stress += Math.round((10-$player_stats.identity)/4)>>
<<set $player_stats.identity++>>
<<if $player_stats.identity lt 5>>
<<set $related_phrase to '"What the fuck?!" I shouted loudly and pushed the guy and the groin I`ve been exploring a moment ago with all my strength. "Get off me!"'>>
<<elseif $player_stats.identity lt 8>>
<<set $related_phrase to 'I wasn`t suprised to see the guy waiting for me to finish him off. I`m in the brothel after all. "You know, I actually don`t work here." You told him.'>>
<<else>>
<<set $related_phrase to 'Your wishes came true. It is a man above you, and seems like his cock is as fat as the guy himself. "You know, I would like to work here, but unfortunately I don`t." You explained him.'>>
<</if>>
/*<<run $back.push("next event")>>*/
<<goto "waking up in the bedroom of love">>
<<else>>
<<goto "back">>
<</if>><<set _choices to [
{
disabled_text: "Not enough ?corruption",
text: "Suck him off for <<print Math.round((10+$player_stats.fem+$player_stats.att)*$current_loop.difficulty/2)>>?money",
target: "suck the pickle calc",
color: "purple",
requirement: "corruption",
threshold: 1,
},
{
disabled_text: "Not enough ?corruption",
text: "Let him fuck you for <<print Math.round((10+$player_stats.fem+$player_stats.att)*$current_loop.difficulty)>>?money",
target: "sex in the brothel calc",
color: "red",
requirement: "corruption",
threshold: 1,
},
{
text: "Release the echo",
side_effects: () => $back.push("post event battle"),
target: "battle pre calc",
color: "royalblue",
},
]>>
<<set _ecard to {title: "Good Morning", color: "red", bg_img: "good morning brothel_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?changing_room ?money ?fem ?identity ?stress ?arousal ?corruption</p>
<p>Half asleep I touched something hard above me. After few more touches and a squeeze I still had no clue what was that. So I decided to open my eyes.</p>
<p>"Good morning, cutie. It's time to work."</p>
<p>A fat man was right above me. And I was squeezing nothing else but his bulge.</p>
<p>$related_phrase</p>
<p>"Oh my! I'm truly sorry. I didn't know you're not working here. But... How did such a cutie end up sleeping in the brothel?.." The echo started to get suspicious. I need to deal with him now.</p>
<p>I can still tell him that I'm working here. This way I can get the extra money I need so much. But working here means being a submissive whore who sells her body to strangers. Do I really want to do this?</p>
<p>I can also try to release the echo. It would be harder than usual, though.</p>
<</event_passage>><<set $player_stats.money += Math.round((10+$player_stats.fem+$player_stats.att)*$current_loop.difficulty/2)>>
<<set $player_stats.stress += Math.round((2+10-$player_stats.identity)/2)>>
<<set $player_stats.identity += 1>>
<<set $player_stats.bsub += 1>>
<<set $player_stats.corruption -= 1>>
<<if $player_stats.arousal gte 8>>
<<set $player_stats.arousal to 0>>
<<set $player_stats.corruption += 1>>
<<set $player_stats.identity += 1>>
<<set $related_phrase to "I was too horny to just worship someone's dick. I wanted to get some relief too. So I started to wank myself. In a moment we both came. Cumming while sucking stranger's dick... Great... ">>
<<else>>
<<set $player_stats.arousal += 2>>
<<set $related_phrase to "For some reason my arousal got higher from sucking stranger's dick. However it wasn't enough for shame orgasm, so I just made my client happy, gulped and received the payment.">>
<</if>>
<<goto "suck the pickle">><<set $player_stats.money += (10+$player_stats.fem+$player_stats.att)*$current_loop.difficulty>>
<<set $player_stats.stress += (2+10-$player_stats.identity)>>
<<set $player_stats.bsub += 1>>
<<set $player_stats.identity += 1>>
<<set $player_stats.corruption -= 1>>
<<if $player_stats.arousal gte 4>>
<<set $player_stats.arousal to 0>>
<<set $player_stats.corruption += 1>>
<<set $player_stats.identity += 1>>
<<set $related_phrase to "I told the fat guy that he can use me anyway he wants. So he used me quite hard, like I'm a complete whore. It took us just a few minutes untill we came. Then the echo thanked me and gave me my payment.">>
<<else>>
<<set $player_stats.arousal += 4>>
<<set $related_phrase to "I told the fat guy that he can use me anyway he wants. So he used me quite hard, like I'm a complete whore. It took him just a few minutes untill he came. Then the echo thanked me and gave me the payment I deserved and left me with my raised arousal.">>
<</if>>
<<goto "sex in the brothel">><<set _ecard to {title: "Blowjob", color: "hotpink", bg_img: "blowjob_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p class="framed-icons">?changing_room</p>
<p>$related_phrase</p>
<</event_passage>><<set _ecard to {title: "Use Me", color: "red", bg_img: "Use Me_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p class="framed-icons">?changing_room</p>
<p>$related_phrase</p>
<</event_passage>><<set $player_stats.arousal to 0>>
<<set $player_stats.corruption++>>
<<set $player_stats.bsub += 1>>
<<if $player_stats.identity lt $player_stats.fem>>
<<set $player_stats.identity++>>
<<set $player_stats.stress++>>
<<set $related_phrase to "Oh, I should have worn something that fits my identity. I feel more feminine after masturbating on this porn. Realization hit me with a bit of extra stress.">>
<<elseif $player_stats.identity gt $player_stats.fem>>
<<set $player_stats.identity-->>
<<set $player_stats.stress += 2>>
<<set $related_phrase to "Oh, I should have worn something that fits my identity. I feel more masculine after masturbating on this porn. Trying to convince myself that it's good I got more stressed.">>
<<else>>
<<set $player_stats.balance++>>
<<set $player_stats.stress-->>
<<set $related_phrase to "It didn't take much time till I came. Wanking on something that fits your preferences is cool. You start to feel that you're supposed to be here at moments like that.">>
<</if>>
<<goto "masturbate in the brothel">><<if $player_stats.fem lt 1>>
<<set _ecard to {title: "Straight Porn", color: "red", bg_img: "Straight Porn_b.jpg"}>>
<<elseif $player_stats.fem lt 2>>
<<set _ecard to {title: "Lesbian Porn", color: "red", bg_img: "Lesbian Porn_b.jpg"}>>
<<elseif $player_stats.fem lt 4>>
<<set _ecard to {title: "Blowjob Porn", color: "red", bg_img: "Blowjob Porn_b.jpg"}>>
<<elseif $player_stats.fem lt 6>>
<<set _ecard to {title: "Brainwashing Porn", color: "red", bg_img: "Brainwashing Porn_b.jpg"}>>
<<elseif $player_stats.fem lt 8>>
<<set _ecard to {title: "Femdom Porn", color: "red", bg_img: "Femdom Porn_b.jpg"}>>
<<elseif $player_stats.fem lt 10>>
<<set _ecard to {title: "Sissy Porn", color: "red", bg_img: "Sissy Porn_b.jpg"}>>
<<else>>
<<set _ecard to {title: "Threesome Porn", color: "red", bg_img: "Threesome Porn_b.jpg"}>>
<</if>>
<<event_passage _ecard setup.ok_choices>>
<p class="framed-icons">?changing_room</p>
<p>Right at the moment I touched my $player_equipment.penis.name the screen changed the channel to _ecard.title.</p>
<p>$related_phrase</p>
<p>The fact of masturbating in the brothel where everyone having sex made me feel more submissive.</p>
<</event_passage>><<set _striptease_cost to 4 * $current_loop.difficulty>>
<<set _bar_cost to 2 * $current_loop.difficulty>>
<<set _choices to [
{
disabled_text: "Not enough ?money",
text: "Striptease Show -<<print _striptease_cost>>?money",
target: "striptease show calc",
color: "crimson",
requirement: "money",
threshold: _striptease_cost,
},
{
disabled_text: "Not enough ?money",
text: "Relax at the bar -<<print _bar_cost>>?money",
side_effects() {
$player_stats.money -= _bar_cost;
$player_stats.balance += 1;
$player_stats.stress -= 4;
},
target: "relax at the bar",
color: "green",
requirement: "money",
threshold: _bar_cost,
},
{
disabled_text: "Not enough ?balance",
text: "Bartender Shift -?balance",
target: "bartender shift calc",
color: "slateblue",
requirement: "balance",
threshold: 1,
},
{
disabled_text: "Not enough ?corruption",
text: "Pole Dancer Shift -?corruption",
target: "pole dancer shift calc",
color: "hotpink",
requirement: "corruption",
threshold: 1,
},
{
text: "Skip",
target: "back",
color: "gray",
},
]>>
<<set _ecard to {title: "Striptease Bar", color: "darkred", bg_img: "striptease bar_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?changing_room ?money ?balance ?corruption ?identity ?stress ?arousal</p>
<p>It's definetaly a striptease bar. Ok, let's see what I can do here.</p>
<p>Obviously, I could hire a pole dancer if I need some... relief. The price is _striptease_cost ?money.
I could also buy a drink at the bar for _bar_cost ?money.</p>
<p>If you look at this from the other angle, I can work here. One of the options is a shift as a bartender.
I just need to be smart and charming enough to communicate with the customers.
Another option is a pole dancer shift. The performance is based basically on everything I have, sure except of my brain.
At least I can be sure customers won't touch me, the rules are quite strict here.</p>
<p>I can change my clothes using one of the private rooms.</p>
<</event_passage>><<set $player_stats.money -= 4*$current_loop.difficulty>>
<<set $player_stats.arousal += 3>>
<<if $player_stats.arousal gt 5>>
<<set $player_stats.arousal to 0>>
<<set $related_phrase to "It's good they allow masturbating here. But don't you dare touch a girl here, what actually isn't a problem at all. I came right before the time is up. The girl gave me a wink and went to the next customer.">>
<<else>>
<<set $related_phrase to "I wasn't aroused enough to masturbate, so I just watched the full show, gave the dancer the money she deserved, so she smiled for the last time and went to the next customer.">>
<</if>>
<<set $player_stats.corruption += 1>>
<<set $player_stats.stress -= 2>>
<<goto "striptease show">><<set _ecard to {title: "Personal Striptease Show", color: "darkred", bg_img: "striptease show_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p class="framed-icons">?changing_room</p>
<p>$related_phrase
I can still change the clothes.</p>
<</event_passage>><<set _ecard to {title: "At the Bar", color: "orange", bg_img: "bartender_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p class="framed-icons">?changing_room</p>
<p>I spent some time at the bar. Nothing special, a regular chat with the bartender, few shots, and I'm refreshed and ready to go.
I can still change the clothes in the private room.</p>
<</event_passage>><<set $sallary to Math.round(((($player_stats.int + $player_stats.att) / 2)-(($player_stats.stress + $player_stats.arousal) / 4)+10) * $current_loop.difficulty)>>
<<set $player_stats.money += $sallary>>
<<set $player_stats.balance -= 1>>
<<set $player_stats.stress += Math.round((6 + Math.abs($player_stats.fem - $player_stats.identity))/2)>>
<<if $player_stats.identity lt $player_stats.fem>>
<<set $player_stats.identity += 1>>
<<set $related_phrase to "Working infront of the others while looking more feminine made me feel more accustomed to the girly stuff.">>
<<elseif $player_stats.identity gt $player_stats.fem>>
<<set $player_stats.identity -= 1>>
<<set $related_phrase to "Working infront of the others while looking less feminine made me feel less accustomed to the girly stuff.">>
<<else>>
<<set $related_phrase to "Wasn't hard at all.">>
<<set $player_stats.stress -= 1>>
<</if>>
<<goto "bartender shift">><<set _ecard to {title: "Bartender Shift", color: "orange", bg_img: "bartender_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p class="framed-icons">?changing_room</p>
<p>I spent some time at the bar, but this time I was the bartender myself. $related_phrase I earned <<print $sallary>>?money.
I can still change the clothes in the private room.</p>
<</event_passage>><<set $sallary to Math.round(((($player_stats.sub + $player_stats.fit + $player_stats.att + $player_stats.fem) / 2)+10) * $current_loop.difficulty)>>
<<set $player_stats.money += $sallary>>
<<set $player_stats.corruption -= 1>>
<<set $player_stats.stress += 12 - $player_stats.identity>>
<<set $player_stats.arousal += $player_stats.identity>>
<<if $player_stats.identity lt $player_stats.fem>>
<<set $player_stats.identity += 2>>
<<set $related_phrase to "Dancing on a pole infront of the masturbating men while looking more feminine than usual made me feel way more accustomed to the girly stuff.">>
<<elseif $player_stats.identity gte $player_stats.fem>>
<<set $player_stats.identity += 1>>
<<set $related_phrase to "Dancing on a pole infront of the others while looking less feminine than usual didn't change the fact that I'm actually a pole dancer now, and the guys are wanking at me.">>
<</if>>
<<goto "pole dancer shift">><<set _ecard to {title: "Pole Dancer Shift", color: "darkred", bg_img: "striptease show_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p class="framed-icons">?changing_room</p>
<p>$related_phrase However, I earned <<print $sallary>>?money.
I can still change the clothes in the private room.</p>
<</event_passage>><<set _choices to [
{
text: "Take the Money",
side_effects() {
$player_stats.corruption += 1;
$player_stats.money += random(3,6) * $current_loop.difficulty;
},
target: "back",
color: "green",
},
{
text: "Skip the Money",
side_effects: () => $player_stats.balance += 1,
target: "back",
color: "royalblue",
},
]>>
<<set _ecard to {title: "Lost Money", color: "royalblue", bg_img: "lost money_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?money ?balance ?corruption</p>
<p>I spotted some ?money on the floor. Should I take it or just skip?</p>
<</event_passage>><<set $player_stats.stress += 1>>
<<set _ecard to {title: "Tripped Over", color: "darkslategray", bg_img: "trip over_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p class="framed-icons">?stress</p>
<p>Ouch! I tripped over. My butt hurts...</p>
<</event_passage>><<set $player_stats.arousal += 1>>
<<set _ecard to {title: "Lewd Scene", color: "magenta", bg_img: "lewd scene_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p class="framed-icons">?arousal</p>
<p>Oh, what is that in her butt? It's definitely a plug. Such a lewd scene... And hot!</p>
<</event_passage>><<set _loss to Math.clamp(5 * $current_loop.difficulty, 0, $player_stats.money)>>
<<set $player_stats.money -= _loss>>
<<set _ecard to {title: "Pickpocket", color: "brown", bg_img: "pickpocket_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p class="framed-icons">?money</p>
<p>A guy bumped into me in passing. It wasn't that bad, so he just apologized and left.
It took me a moment to realize-- he stole <<print _loss>>?money from me!</p>
<</event_passage>><<set $enemy to clone(setup.regular_enemies.random())>>
<<goto "regular enemy encounter">><<set _choices to [
{
text: "Release the Echo",
side_effects: () => $back.push("post event battle"),
target: "battle pre calc",
color: "darkred",
},
]>>
<<set _bg to $enemy.name+"_b.jpg">>
<<set _ecard to {title: $enemy.name, color: "darkred", bg_img: _bg}>>
<<event_passage _ecard _choices>>
<p>I bumped into $enemy.name. Seems like I have no other choice than to release it.
And I can get some extra money from the echo.</p>
<</event_passage>><<set $player_stats.corruption += 1>>
<<set $player_stats.stress += 2>>
<<set _ecard to {title: "Spanked", color: "brown", bg_img: "spanked_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p class="framed-icons">?corruption ?stress</p>
<p>Something got stuck on my leg. I bent over to remove it when my butt got spanked.
Ouch! I closed my eyes for a moment, but when I opened them, I couldn't see anyone nearby.</p>
<</event_passage>><<set $player_stats.balance += 1>>
<<set $player_stats.arousal += 2>>
<<set _ecard to {title: "A Fall", color: "brown", bg_img: "a fall_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p class="framed-icons">?balance ?arousal</p>
<p>A guy bumped into me. Something wrong with people here... However, the guy tried his best to catch me up, but failed. Now both of us are on the floor, he is on top of me, hand squeezing my chest. The guy turned red immediately, got up, apologized and ran off.</p>
<</event_passage>><<if $testing_subject_meeting>>
<<goto "testing subject 3">>
<<else>>
<<goto "testing subject 1">>
<</if>><<set $testing_subject_meeting to true>>
<<set _choices to [
{
text: "I'm a boy",
side_effects: () => $player_stats.identity -= 1,
target: "testing subject 2",
color: "green",
},
{
disabled_text: "Not enough ?corruption",
text: "I'm a girl -?corruption",
side_effects() {
$player_stats.identity += 1;
$player_stats.corruption -= 1;
},
target: "no testing subject",
color: "slateblue",
requirement: "corruption",
threshold: 1,
},
]>>
<<set _ecard to {title: "Lab Assistant", color: "deepskyblue", bg_img: "smart echo_b.jpg", fg_img: "smart echo.png"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?identity</p>
<p>When I was passing by a shy girl she asked about my gender.</p>
<p>"It's not common to ask this, you know?" You decided to act carefuly this time. It's about laboratory stuff, who knows what stuff they make there.
<p>"Sorry again, don't get me wrong, please." She tried to hide her eyes behind the glasses. "But I just need your biological gender. You know, our lab is looking for new testing subjects, we pay good money for that. Unfortunately, we need biological male subjects to test this new supplement."</p>
<p>"So why not telling that before asking about genders?" You smirked.</p>
<p>Her face became red even more.</p>
<p>"I'm sorry... I'm just an assistant..."</p>
<p>It seemes like she is about to burst into tears. It's better to answer something before it happened.</p>
<</event_passage>><<set _ecard to {title: "Lab Assistant", color: "deepskyblue", bg_img: "smart echo_b.jpg", fg_img: "smart echo.png"}>>
<<event_passage _ecard setup.ok_choices>>
<p>"Oh, really? I mean... Maybe next time... Goodbye then."</p>
<br>
<p><i>"Lab Assistant" arc with this character comming soon. If you want it to happen sooner, vote for the character you like the most [[here|https://www.patreon.com/posts/character-106693649]]. It's free for all.</i></p>
<</event_passage>><<set _choices to [
{
text: "Next",
target: "testing subject 3",
color: "green",
},
]>>
<<set _ecard to {title: "Smart Coffee", color: "darkblue", bg_img: "smart coffee_b.jpg"}>>
<<event_passage _ecard _choices>>
<p>"It's good. I mean, it's good for us, not for you... Sorry! I mean maybe it's also good for you... I don't know... Maybe it's not..."</p>
<p>"You said something about the testing and the money?" I decided to save her this time.</p>
<p>"Oh, right! So, I have a new formula here with me. It's just a coffee, but with some special component that supposed to improve male's brain power."</p>
<p>"Yeah, like the label says." I mentioned. Finally something for males.</p>
<p>"Definetaly! "Smart Coffee" it is. However, formula isn't perfect yet, bcz it still has side effects. But don't worry, nothing dangerous to health."</p>
<</event_passage>><<set _choices to [
{
text: "Drink it",
target: "testing subject calc",
color: "green",
},
{
disabled_text: "Not enough ?balance",
text: "Change your mind -?balance",
side_effects: () => $player_stats.balance -= 1,
target: "no testing subject",
color: "slateblue",
requirement: "balance",
threshold: 1,
},
]>>
<<set _ecard to {title: "Smart Coffee", color: "darkblue", bg_img: "smart coffee_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?money ?stress ?arousal ?sub ?int ?fit ?att</p>
<p>"Let me explain the process. It's simple. You drink the coffee then describe me what you feel. After that you get at least <<print 5*$current_loop.difficulty>>?money, based on your intellegence. You know, the smarter you are the better feedback we get."</p>
<p>"Sounds good for me."</p>
<p>"So, here is your coffee, sir!" Assistant girl giggled. Her confidence seems increased.</p>
<p>I took the cup. I still had doubts, though. Should I really drink it for money?</p>
<</event_passage>><<set $player_stats.bint += 1>>
<<set _dice to random(1,4)>>
<<if _dice is 1>>
<<set $player_stats.bsub += 1>>
<<set $player_stats.arousal += 2>>
<<set $related_phrase to "I also feel more... obedient. And seems like my, ehm, arousal increased. Not too much, but still...">>
<<elseif _dice is 2>>
<<set $player_stats.bint += 1>>
<<set $player_stats.stress += 2>>
<<set $related_phrase to "You know, this time it's all about brain. It's really a smart coffee. From the other hand, I feel a bit more worked out now...">>
<<elseif _dice is 3>>
<<set $player_stats.bfit += 1>>
<<set $player_stats.stress += 2>>
<<set $related_phrase to "I also feel stronger, cool. From the other hand, I feel a bit more worked out now...">>
<<else>>
<<set $player_stats.batt += 1>>
<<set $player_stats.arousal += 2>>
<<set $related_phrase to "I also feel more... attractive? And seems like my, ehm, arousal increased. Not too much, but still...">>
<</if>>
<<set $events.splice(random(3, 5), 0, "feminization calc")>>
<<goto "testing subject">><<set _salary to (5 + $player_stats.int) * $current_loop.difficulty>>
<<set _choices to [
{
text: "Next",
target: "back",
side_effects: () => $player_stats.money += _salary,
color: "green",
},
]>>
<<set _ecard to {title: "Lab Assistant", color: "deepskyblue", bg_img: "smart echo_b.jpg", fg_img: "smart echo.png"}>>
<<event_passage _ecard _choices>>
<p>"Do you feel something? Can you describe that?"</p>
<p>I took some more time to think about it, and then answered.</p>
<p>"I'm sure I got smarter." You said. The assistant marked something in her notebook. "$related_phrase And I feel something else that I can't describe, sorry."</p>
<p>"Don't worry, that's more than enough. Here is your <<print _salary>>?money.
We'll continue improving the formula, so next time, I'll ask you to try this again. See you next time!"</p>
<br>
<p><i>"Lab Assistant" arc with this character comming soon. If you want it to happen sooner, vote for the character you like the most [[here|https://www.patreon.com/posts/character-106693649]]. It's free for all.</i></p>
<</event_passage>><<if $player_stats.bfit gte 10>>
<<if $events[0] is "testing subject precalc">>
<<goto "back">>
<<else>>
<<goto "testing subject precalc">>
<</if>>
<<else>>
<<if $real_man_meeting>>
<<goto "become a real man 3">>
<<else>>
<<goto "become a real man 1">>
<</if>>
<</if>><<set $real_man_meeting to true>>
<<set _choices to [
{
text: "Next",
target: "become a real man 2",
color: "green",
},
]>>
<<set _ecard to {title: "Real Man", color: "deepskyblue", bg_img: "Real Man_b.jpg", fg_img: "Real Man.png"}>>
<<event_passage _ecard _choices>>
<p>"Hey! Hey you! Do you want to become a real man?" A cute girl got closer and asked again. "Sorry, but do you want to become a real man like me?"</p>
<p>"Ehm..." I explored the girl, from top to bottom. "What?"</p>
<p>"Ok, let me explain. You know, in the past, I wasn`t as manly as I am now. People often mistook me for a girl." I got it, it's a boy... "Some even mocked me for my look.
They called me "femboy", "sissy", and some other words that I didn`t even know the meaning. And one day I decided to change that!"
His posture has become more confident.</p><p>"I decided to become a real man!"</p>
<</event_passage>><<set _choices to [
{
text: "Next",
target: "become a real man 3",
color: "green",
},
]>>
<<set _ecard to {title: "Real Man", color: "deepskyblue", bg_img: "Real Man_b.jpg", fg_img: "Real Man.png"}>>
<<event_passage _ecard _choices>>
<p>"I see..." Still confused you continued to listen to his story.</p>
<p>"So I went to the gym, I found the strongest guy there, and I told him that I can do anything he wants to become as strong and masculine as he is.
And look at me now." I looked at his body, it was still cute and maybe even hot, just like a minute ago. "Yeah, I got bigger already! Thanks to him and the time spent in training.
My legs, hips, glutes, all my bottom part is quite big and strong now! The guy from the gym said that it will take some time to improve the top part, though.
But there is a shortcut. If I take these hyper-masculine supplements I can become stronger in no time. One moment, let me show you."</p>
<</event_passage>><<set _choices to [
{
text: "Become a real man",
side_effects() {
$player_stats.bfit += 1;
$player_stats.stress -= 3;
$events.splice(random(3, 6), 0, "feminization calc");
},
target: "become a real man",
color: "green",
},
{
disabled_text: "Not enough ?balance",
text: "Not interested -?balance",
side_effects: () => $player_stats.balance -= 1,
target: "no become a real man",
color: "slateblue",
requirement: "balance",
threshold: 1,
},
]>>
<<set _ecard to {title: "Pink Supplements", color: "purple", bg_img: "pink coffee_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?stress ?fit</p>
<p>The "real man" showed me a pink cup with some liquid inside. "Cute! Don't you think?"</p>
<p>"Ehm... Yes... So what do you want from me?" You asked.</p>
<p>The boy took your hand. "I'm a little worried to take it. So I want you to try it with me, if you don't mind. It's always better doing something together, don't you think?
And I can see that you also want to become stronger. It's said that you get stronger within a few minutes. Visual effect takes place after a while. So what do you think?"</p>
<p> It would be hard to reject such a cute face...</p>
<</event_passage>><<set _ecard to {title: "Real Man", color: "deepskyblue", bg_img: "Real Man_b.jpg", fg_img: "Real Man 2.png"}>>
<<event_passage _ecard setup.ok_choices>>
<p>"Cool! Here, take it." The boy gave me the pink bottle. "Now let's drink it straight to the bottom!"</p>
<p> Both of us started to drink. It was sweet and quite tasty. And as the label said, I started to feel the power almost instantly.</p>
<p> When we finished cute thing infront of me stuck out his tong, waiting for me to tell something.</p>
<p>"Ehm... Good boy." You said.</p>
<p>His eyes flashed. "Do you really think? Thank you so much! It's so cool to hear "boy" from someone, you can't imagine! Seems like it's really working. And I'm already feeling the energy, so I better go and do some more squats. Cya next time!"</p>
<br>
<p><i>"The Real Man" arc with this character coming soon. If you want it to happen sooner, vote for the character you like the most [[here|https://www.patreon.com/posts/character-106693649]]. It's free for all.</i></p>
<</event_passage>><<set _ecard to {title: "Real Man", color: "deepskyblue", bg_img: "Real Man_b.jpg", fg_img: "Real Man.png"}>>
<<event_passage _ecard setup.ok_choices>>
<p>"Eh... So..." Cute face of the real man became sad for a moment, and then back to normal. "Maybe next time then? You seem to be a good person, I would really like to spend some time with you! Cya!"</p>
<br>
<p><i>"The Real Man" arc with this character comming soon. If you want it to happen sooner, vote for the character you like the most [[here|https://www.patreon.com/posts/character-106693649]]. It's free for all.</i></p>
<</event_passage>><<set _current_clothing to Object.keys(setup.all_styles).shuffle()
.map(clty => $player_equipment[clty]).reduce((ans, cur) => ans.fem < cur.fem ? ans : cur)>>
<<set _matching_clothes to setup.all_styles[_current_clothing.place]
.filter(item => item.fem gt _current_clothing.fem and item.id gt 0 and setup.item_not_worn(item))>>
<<if _matching_clothes.length is 0>>
<<goto "back">>
<<else>>
<<set $loot to clone(_matching_clothes.random())>>
<<goto "great stylist 1">>
<</if>><<set $ran_from_gstylist ??= 0>>
<<if $ran_from_gstylist is 0>>
<<set _run_text to "Run away -?balance">>
<<else>>
<<set _run_text to "Can't avoid him forever -" + ($ran_from_gstylist + 1) + "?balance">>
<</if>>
<<set _choices to [
{
text: "Shut up and wait",
target: "stylist makeup calc",
color: "green",
},
{
disabled_text: "Not enough ?balance",
text: _run_text,
side_effects() {
$ran_from_gstylist += 1;
$player_stats.balance -= $ran_from_gstylist;
$player_stats.stress += Math.ceil($ran_from_gstylist / 2);
},
target: "back",
color: "gray",
requirement: "balance",
threshold: 1 + $ran_from_gstylist,
},
]>>
<<set _ecard to {title: "The Great Stylist", color: "purple", bg_img: "stylist echo_b.jpg", fg_img: "stylist echo.png"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?identity ?fem ?stress ?att</p>
<p>"Omg... Darling, what happened to your <<print $loot.place.replaceAll("_", " ")>>?" Quite handsome and hyper stylish guy examines my look.</p>
<p>"Nothing. Why?"</p>
<p>The guy was definitely caught off guard by my question. "You ask why? Girl, don't you want men to fight for you? Don't you want to see them kneel before your beauty?"</p>
<p>"I'm not a g..."</p>
<p>"I don't want to hear your excuses. Every single woman wants to become more beautiful and desired, no matter how deep she borrowed these feelings." He took some tools from his bag and said in a joking tone. "So just shut up and let the Great Stylist do his job."</p>
<</event_passage>><<set $ran_from_gstylist to 0>>
<<set $old_item to $player_equipment.replace_with($loot)>>
<<set $player_stats.batt += 1>>
<<set $player_stats.identity += 1>>
<<set $player_stats.stress -= 2>>
<<if $great_stylist_meeting>>
<<goto "great stylist result">>
<<else>>
<<goto "great stylist 2">>
<</if>><<set $great_stylist_meeting to true>>
<<set _choices to [
{
text: "Next",
target: "great stylist 3",
color: "green",
},
]>>
<<set _ecard to {title: "The Great Stylist", color: "purple", bg_img: "stylist echo_b.jpg", fg_img: "stylist echo.png"}>>
<<event_passage _ecard _choices>>
<p> Every single stylist's move was so precise and confident that my doubts about his "greatness" were dispelled. However, I decided to ask him why he called himself "The Great Stylist".</p>
<p> "Asking again? Darling, you're a bit out of place here, you know." The man answered without the actual answer.</p>
<p> "What do you mean? Here?"</p>
<p> "I mean here, in the loop." Suprised, I suddenly moved, but his gentle hand guided me back to the position stylist needed to continue. "Usually people try to stay neutral and just fit in. But you are not the same. Girl, you really are special."</p>
<p>You couldn't hold any longer.</p>
<p>"Do you know that we are in the loop?"</p>
<</event_passage>><<set _choices to [
{
text: "Next",
target: "great stylist result",
color: "green",
},
]>>
<<set _ecard to {title: "The Great Stylist", color: "purple", bg_img: "stylist echo_b.jpg", fg_img: "stylist echo.png"}>>
<<event_passage _ecard _choices>>
<p>"Yes, sure." He smiled. "Don't be so suprised, or you get wrinkles on your cute forehead. You can find many people here who knows where are they are, or at least starting to understand that. Moreover, some of us are able to move freely between the different loops."</p>
<p>You couldn't believe that there are other people who know everything.</p>
<p>"But tell you, darling, it's the best place in the world. You can try everything you want, you can go wherever you want, and so on. The freedom at its very core." Then the great stylist added. "If you know what to do."</p>
<p>"What should I do?"</p>
<p>"At first, start asking yourself rather than people in the loop. And maybe then you get the answer." He stepped back. "We are done!"</p>
<</event_passage>><<set _ecard to {title: "The Great Stylist", color: "purple", bg_img: "stylist echo_b.jpg", fg_img: "stylist echo.png"}>>
<<event_passage _ecard setup.ok_choices>>
<p>You can see freshly made <<print $loot.place.replaceAll("_", " ")>> in the mirror.</p>
<<equip_tf $old_item $loot>>
<p>"And it's time to say goodbye! I'm out of time." He said and put all the tools back into his bag.</p>
<p>"Wait, but I have so many questions to ask..."</p>
<p>"Don't worry, I believe a girl like you can find all the answers herself." With these words the great stylist has gone.</p>
<br>
<p><i>"The Great Stylist" arc with this character comming soon. If you want it to happen sooner, vote for the character you like the most [[here|https://www.patreon.com/posts/character-106693649]]. It's free for all.</i></p>
<</event_passage>><<set _training_options to {
"sub": {
enemy_index: 0,
bstat: "bsub",
before_txt: "<p>Should I really train submission to succeed? Why being submissive is so important here? It's reasonable to train intellect, fitness, even attractiveness is ok. But what if I want to be dominant?.. Eh...</p><br><p><i>?sub You can improve your core stat here. These SIFA stats make you stronger and are needed to get new cards.</i></p>",
win_txt: "Ehm, I became more submissive. It's good, right?",
lose_txt: "Why on earth being submissive is so difficult? I guess I need to get stronger to push higher...",
/* TODO separate passage? images? idk */
},
"int": {
enemy_index: 1,
bstat: "bint",
before_txt: "<p>Oh, finally I can train my intelligence. It's a bit boring, but it's still better than dancing on the pole.</p><br><p><i>?int You can improve your core stat here. These SIFA stats make you stronger and are needed to get new cards.</i></p>",
win_txt: "It was a great session, I got smarter for sure.",
lose_txt: "The only thing I learned today is that I need to get stronger before I try improving my intellect higher.",
},
"fit": {
enemy_index: 2,
bstat: "bfit",
before_txt: "<p>Ok, it's hard to call me a fan of physical training, but here... I guess I better train my butt.</p><br><p><i>?fit You can improve your core stat here. These SIFA stats make you stronger and are needed to get new cards.</i></p>",
win_txt: "Seems like I became a bit stronger.",
lose_txt: "Gosh, it was a mad idea pushing over my limits. I need to prepare better next time.",
},
"att": {
enemy_index: 3,
bstat: "batt",
before_txt: "<p>Attractiveness? Hm, maybe it's not so pointless here...</p><br><p><i>?att You can improve your core stat here. These SIFA stats make you stronger and are needed to get new cards.</i></p>",
win_txt: "Ok, so it's about smiling and doing cute stuff. I think I'm getting better in that.",
lose_txt: "Yeah, sure, I can't just become attractive. I need to be strong enough for that...",
},
}>>
<<set _core to $player_stats.core_stats>>
<<set _trainable to setup.SIFA.filter(s => _core[s] < 10)>>
<<if _trainable.length gt 0>>
<<set $temp.train to _training_options[_trainable.random()]>>
<<set $enemy to clone(setup.training_enemies[$temp.train.enemy_index])>>
/* TODO copied from battle page; probably could use a function */
<<set $temp.train.card to {
title: $enemy.name,
color: "blue",
bg_img: $enemy.image,
}>>
<<set $enemy.power_rate to $player_stats[$temp.train.bstat] + 1>>
<<goto "train sifa">>
<<else>>
<<goto "new action card choice">>
<</if>><<set _choices to [
{
requirement: $temp.train.bstat,
low_threshold: 10,
disabled_text: "Trained to maximum!",
text: "Train!",
side_effects: () => $back.push("training conclusion"),
target: "battle pre calc",
color: "green",
},
{
text: "Skip training",
target: "back",
color: "gray",
}
]>>
<<event_passage $temp.train.card _choices>>
<p>$temp.train.before_txt</p>
<</event_passage>><<if $battle_won>>
<<set $enemy.power_rate to $player_stats[$temp.train.bstat] + 1>>
<<set $player_stats[$temp.train.bstat] += 1>>
<<event_passage $temp.train.card setup.ok_choices>>
<p>$temp.train.win_txt</p>
<</event_passage>>
<<else>>
<<event_passage $temp.train.card setup.ok_choices>>
<p>$temp.train.lose_txt</p>
<</event_passage>>
<</if>><<set _choices to [
{
disabled_text: "Not enough ?money",
text: "Mind Control",
target: "get clear mind",
color: "darkblue",
requirement: "money",
threshold: 3,
},
{
disabled_text: "Not enough ?money",
text: "Pain Control",
target: "get painkillers",
color: "darkred",
requirement: "money",
threshold: 3,
},
{
text: "Skip +?balance",
side_effects: () => $player_stats.balance += 1,
target: "back",
color: "gray",
},
]>>
<<set _ecard to {title: "Renovation Center", color: "mediumblue", bg_img: "renovation_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?new_card ?money</p>
<p>"Hello. You can get some help with controling negative conditions. You can get some power to clean your bad thoughts in mind control center, and some medication in pain control center."</p>
<p>Do I really need that right now?</p>
<</event_passage>><<set _choices to [
{
text: "Back",
target: "get cleanse card",
color: "gray",
},
{
disabled_text: "Not enough ?money",
text: "Get 1 Card -3?money",
target: "back",
side_effects: () => {
$player_stats.money -= 3;
$player_deck.push(setup.cleanse_cards[0]);
},
color: "darkblue",
requirement: "money",
threshold: 3,
},
{
disabled_text: "Not enough ?money",
text: "Get 2 Cards -7?money",
target: "back",
side_effects: () => {
$player_stats.money -= 7;
$player_deck.push(setup.cleanse_cards[0], setup.cleanse_cards[0]);
},
color: "violet",
requirement: "money",
threshold: 7,
},
{
disabled_text: "Not enough ?money",
text: "Get 3 Cards -11?money",
target: "back",
side_effects: () => {
$player_stats.money -= 11;
$player_deck.push(setup.cleanse_cards[0], setup.cleanse_cards[0], setup.cleanse_cards[0]);
},
color: "orange",
requirement: "money",
threshold: 11,
},
]>>
<<event_passage setup.cleanse_cards[0] _choices>>
<p class="framed-icons">?new_card ?money</p>
<p>Seems like they charge more if I want to get more.</p>
<br>
<i><p>?delete It's a self-destructible card. It will be deleted from your deck after use.</p>
<p>?remove2 It's a card that can remove another card from your deck. In this case you get the extra effect. If you don't have the required card in the deck - description of the card will be changed.</p></i>
<</event_passage>><<set _choices to [
{
text: "Back",
target: "get cleanse card",
color: "gray",
},
{
disabled_text: "Not enough ?money",
text: "Get 1 Card -3?money",
target: "back",
side_effects: () => {
$player_stats.money -= 3;
$player_deck.push(setup.cleanse_cards[1]);
},
color: "darkblue",
requirement: "money",
threshold: 3,
},
{
disabled_text: "Not enough ?money",
text: "Get 2 Cards -7?money",
target: "back",
side_effects: () => {
$player_stats.money -= 7;
$player_deck.push(setup.cleanse_cards[1], setup.cleanse_cards[1]);
},
color: "violet",
requirement: "money",
threshold: 7,
},
{
disabled_text: "Not enough ?money",
text: "Get 3 Cards -11?money",
target: "back",
side_effects: () => {
$player_stats.money -= 11;
$player_deck.push(setup.cleanse_cards[1], setup.cleanse_cards[1], setup.cleanse_cards[1]);
},
color: "orange",
requirement: "money",
threshold: 11,
},
]>>
<<event_passage setup.cleanse_cards[1] _choices>>
<p class="framed-icons">?new_card ?money</p>
<p>Seems like they charge more if I want to get more pills.</p>
<br>
<i><p>?delete It's a self-destructible card. It will be deleted from your deck after use.</p>
<p>?remove2 It's a card that can remove another card from your deck. In this case you get the extra effect. If you don't have the required card in the deck - description of the card will be changed.</p></i>
<</event_passage>><<set $enemy to {name: "Well-Dressed Echo", style: "formal", gender:"male", power_rate: 2}>>
<<set $player_stats.identity to $player_stats.fem>>
<<if $player_stats.identity gte 10>>
<<set $current_loop.max_identity to true>>
<</if>>
<<goto "full identity">><<set _choices to [
{
text: "Take Heavy Dose",
target: "take heavy dose calc",
color: "hotpink",
},
{
disabled_text: "Not enough ?corruption",
text: "Show him how girly you actually are -2?corruption",
target: "full identity sex calc",
color: "red",
requirement: "corruption",
threshold: 2,
},
{
disabled_text: "Not enough ?balance",
text: "Release Echo -?balance",
side_effects() {
$player_stats.balance -= 1;
$back.push("post event battle");
},
target: "battle pre calc",
color: "slateblue",
requirement: "balance",
threshold: 1,
},
]>>
<<set _ecard to {title: "Estrogen", color: "hotpink", bg_img: "estrogen_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?money ?identity ?arousal</p>
<p><<print $enemy.name>> blocked my way.</p>
<p>"Darling, if you're so desperate to be a girl, why don't you take these tablets? Sooth to say, the duty of every individual is to help society to improve. So I can't let you go without a heavy dose of these "improvements"."</p>
<p>For some reason his words hit me really deep, and my ?identity has become the same as my ?fem. However, I still need to choose what to do. These tablets will improve all my skills and will also help to relax a bit. So it doesn't seem too bad.</p>
<p>If I decide to release him, I should be ready for a tough session.</p>
<</event_passage>><<set $player_stats.corruption -= 2>>
<<set $player_stats.money += (10+$player_stats.fem+$player_stats.att)*$current_loop.difficulty>>
<<set $player_stats.batt += 2>>
<<set $player_stats.bsub += 2>>
<<set $player_stats.identity += 3>>
<<set $player_stats.stress -= 2>>
<<if $player_stats.arousal gte 4>>
<<set $player_stats.arousal to 0>>
<<set $player_stats.corruption += 1>>
<<set $player_stats.identity += 2>>
<<set $related_phrase to "I told the $enemy.name that he can use me anyway he wants, but no pills. So he used me quite hard, like I'm a complete whore. It took us just a few minutes untill we came. Then the echo thanked me and gave me my payment.">>
<<else>>
<<set $player_stats.arousal += 4>>
<<set $related_phrase to "I told the $enemy.name that he can use me anyway he wants, but no pills. So he used me quite hard, like I'm a complete whore. It took him just a few minutes untill he came. Then the echo thanked me and gave me the payment I deserved and left me with my raised arousal.">>
<</if>>
<<goto "full identity sex">><<if $player_equipment.body.id gt 8>>
<<set _scene to "hardcore futa_b.jpg">>
<<else>>
<<set _scene to "hardcore trap_b.jpg">>
<</if>>
<<set _ecard to {title: "Hardcore Sex", color: "darkred", bg_img: _scene}>>
<<event_passage _ecard setup.ok_choices>>
<p>$related_phrase</p>
<</event_passage>><<set $player_stats.bfit += 1>>
<<set $player_stats.batt += 1>>
<<set $player_stats.bsub += 1>>
<<set $player_stats.bint += 1>>
<<set $player_stats.stress -= 3>>
<<set $player_stats.arousal -= 3>>
<<set $events.splice(random(2, 4), 0, "feminization calc")>>
<<set $events.splice(random(5, 7), 0, "feminization calc")>>
<<set $events.splice(random(8, 10), 0, "feminization calc")>>
<<goto "back">><<set _choices to [
{
disabled_text: "Not enough ?balance",
text: "Hold On -?balance",
side_effects() {
$player_stats.balance -= 1;
$player_stats.stress -= 1;
},
target: "back",
color: "slateblue",
requirement: "balance",
threshold: 1,
},
{
text: "Pass Out",
target: "pass out calc",
color: "red",
},
]>>
<<set _ecard to {title: "Passing Out", color: "brown", bg_img: "Passing Out_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?money ?identity ?fem ?stress</p>
<p>I... think... I'm passing out...</p>
<</event_passage>><<set _choices to [
{
disabled_text: "Not enough ?corruption",
text: "Calm Down -?corruption",
side_effects() {
$player_stats.corruption -= 1;
$player_stats.arousal -= 1;
},
target: "back",
color: "blueviolet",
requirement: "corruption",
threshold: 1,
},
{
text: "Pass Out",
target: "pass out calc",
color: "red",
},
]>>
<<set _ecard to {title: "Passing Out", color: "brown", bg_img: "Passing Out_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?money ?identity ?fem ?arousal</p>
<p>I... think... I'm passing out...</p>
<</event_passage>><<if $player_stats.stress gte 10>>
<<set $player_stats.stress to 5>>
<<set $related_phrase to "I feel that my stress is much lower now. After passing out right on the floor, strange.">>
<<set $old_item to clone($player_equipment.body)>>
<<set _body_num to $player_equipment.body.id+1>>
<<set _body_num to Math.clamp(_body_num, 0, setup.all_body.body.length-1)>>
<<set $player_equipment.body to clone(setup.all_body.body[_body_num])>>
<<set $loot to clone($player_equipment.body)>>
<<elseif $player_stats.arousal gte 10>>
<<set $player_stats.arousal to 5>>
<<set $related_phrase to "My arousal is lower now. Seems like I had some wet dreams. What is strange that my undies are clean.">>
<<set _random_feminization to ["nails", "hair", "face", "penis"].random()>>
<<set $old_item to clone($player_equipment[_random_feminization])>>
<<if _random_feminization is "penis">>
<<set _body_num to $player_equipment[_random_feminization].id-1>>
<<else>>
<<set _body_num to $player_equipment[_random_feminization].id+1>>
<</if>>
<<set _body_num to Math.clamp(_body_num, 0, setup.all_body[_random_feminization].length-1)>>
<<set $player_equipment[_random_feminization] to clone(setup.all_body[_random_feminization][_body_num])>>
<<set $loot to clone($player_equipment[_random_feminization])>>
<</if>>
<<set $player_stats.identity += 1>>
<<set $player_stats.money -= 10*$current_loop.difficulty>>
<<goto "passed out">><<set _ecard to {title: "Feminization", color: "magenta", bg_img: "Feminization_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p>I woke up. $related_phrase.</p>
<p>But it's not the weirdest thing. Even the fact that I lost <<print 10*$current_loop.difficulty>>?money isn't suprising. It's quite expected actually.</p>
<p>The weirdest thing is that my body has changed. The images of girls in fancy clothes are still flashing in my head. I got feminized!</p>
<p>Now I have <<print $loot.name>>.</p>
<<equip_tf $old_item $loot>>
<</event_passage>><<set $player_stats.balance -= 6>>
<<if $player_stats.bal_cards lt 3>>
<<set $player_stats.bal_cards += 1>>
<<set $player_stats.bal_cards to Math.clamp($player_stats.bal_cards, 1, 3)>>
<<set $loot to clone(setup.balance_cards[$player_stats.bal_cards-1])>>
<<set $related_phrase to "My ?balance was high enough to realize that I can use the power of $loot.name if I really need to release the echo.">>
<<else>>
<<set $player_stats.money += 10*$current_loop.difficulty>>
<<set $player_stats.bint += 1>>
<<set $player_stats.bfit += 1>>
<<set $loot to {title: "Bonus", color: "deepskyblue", bg_img: "lost money_b.jpg"}>>
<<set $related_phrase to "My ?balance was high enough to make me stronger and even get some extra ?money.">>
<</if>>
<<goto "full karma">><<set $player_stats.corruption -= 6>>
<<if $player_stats.cor_cards lt 3>>
<<set $player_stats.cor_cards += 1>>
<<set $player_stats.cor_cards to Math.clamp($player_stats.cor_cards, 1, 3)>>
<<set $loot to clone(setup.corruption_cards[$player_stats.cor_cards-1])>>
<<set $related_phrase to "My ?corruption was high enough to realize that I can use the power of $loot.name if I really need to release the echo.">>
<<else>>
<<set $player_stats.money += 10*$current_loop.difficulty>>
<<set $player_stats.batt += 1>>
<<set $player_stats.bsub += 1>>
<<set $loot to {title: "Bonus", color: "deepskyblue", bg_img: "lost money_b.jpg"}>>
<<set $related_phrase to "My ?corruption was high enough to make me stronger and even get some extra ?money.">>
<</if>>
<<goto "full karma">><<event_passage $loot setup.ok_choices>>
<p>$related_phrase</p>
<</event_passage>>
/* INTRODUCTION start */<<set $charview to 3>>
<<set _choices to [
{
text: "Next",
target: "introduction 2",
color: "green",
},
]>>
<<set _ecard to {title: "Naked", color: "darkblue", bg_img: "naked_b.jpg"}>>
<<event_passage _ecard _choices>>
<p>I woke up in unfamiliar place fully naked... I didn't remember who I am and what happened to me.</p>
<p>I noticed a screen on the wall telling what to do next</p>
<p>"Hello! I know that you don't remember a thing. But don't you worry. At first, let's find something to cover you up. Go to the next room."</p>
<p>Ok, it wasn't a bad idea. And anyway I have no other ideas. Let's go.</p>
<</event_passage>><<set _choices to [
{
text: "Next",
target: "introduction 3",
color: "green",
},
]>>
<<set _ecard to {title: "Drawer", color: "hotpink", bg_img: "drawer_b.jpg"}>>
<<event_passage _ecard _choices>>
<p>"What are you waiting for? Open the drawer and try to find something. Don't you worry, fluf, no one will ever find out that you borrowed something from there."</p>
<</event_passage>><<set _ecard to clone(setup.all_clothes.undies[12])>>
<<run $inv.push(clone(_ecard))>>
<<set _choices to [
{
text: "Next",
target: "introduction 4",
color: "green",
},
]>>
<<event_passage _ecard _choices>>
<p>I managed to find only red panties with the heart on the groin area. It's still better than walking naked.</p>
<p> However, for some weird reason I couldn't wear them. My body just didn't want to do it. Let's check what the screen got to say.</p>
<p>"Yes, you can't wear this cute panties no matter how hard you try. It's because the loop is blocking you from doing that. Just move to the next room, there you can finally wear the panties, as you always wanted."</p>
<p>Loop? What is this person talking about?</p>
<</event_passage>><<set _choices to [
{
text: "Put on the panties, then continue",
target: "introduction 5",
color: "red",
},
]>>
<<set _ecard to {title: "Changing Room", color: "hotpink", bg_img: "women changing room_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?changing_room</p>
<p>"Do you see this icon? If you see such icon in the room that means you can change here.
So you can open your inventory now and wear the panties."</p>
<br>
<p><i>You can open inventory on the left sidebar. To wear an item just click the item you want and then click your current item to swap them.</i></p>
<</event_passage>><<if $player_equipment.undies.id lte 0>>
<<goto "introduction 4">>
<</if>>
<<set _choices to [
{
text: "Next",
target: "introduction 6",
color: "green",
},
]>>
<<set _ecard to {title: "Half Naked", color: "darkblue", bg_img: "half naked_b.jpg"}>>
<<event_passage _ecard _choices>>
<p>"You look adorable in this panties!"</p>
<p>Do they really see me or it's just a setup? I don't see any cameras here...</p>
<p>"Now let's try to make some cash. After all, we saved you, but it costed us a lot. I would like to let you go without paying, fluf. By SIFA company can't save everyone for free, you know."</p>
Oh, great, the debt. I don't event know what happened.
<p> "Your debt is 3000?money in total. But don't you worry, we decided to let you work on it step by step, without pushing yourself too much. 100?money is your first payment. We expect you to pay it after your first loop."</p>
<p>Ok, doesn't sound too much, to be honest.</p>
<p>"Now let's try to earn some cash. Go to the next room."</p>
<</event_passage>><<set _choices to [
{
text: "Relax at the bar",
target: "introduction 7",
color: "green",
},
{
disabled_text: "Not enough ?balance",
text: "Bartender Shift -?balance",
target: "bartender shift calc",
color: "gold",
requirement: "balance",
threshold: 1,
},
]>>
<<set _ecard to {title: "Striptease Bar", color: "blueviolet", bg_img: "striptease bar_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?money ?balance ?stress</p>
<p>Oh no! It's definitely a striptease bar. Don't tell me they gonna force me to dance in this panties for strangers. I'm not a bitch boy or something...</p>
<p>"I could imagine what thoughts you have at the moment, heh. But I keep telling you - don't worry, it's not so bad. You can work here as a bartender, for example. And you fit in just well, heh."</p>
<p>But it doesn't change the fact that I need to work in striptease bar... I think I have no choice anyway...</p>
<p>"But at first, you need to get some balance ?balance points. I think you already mentioned this icon in the room. That means that the room is connected to balance somehow. Try to spend some time at the bar. This time it's free."</p>
<</event_passage>><<set $player_stats.balance += 1>>
<<set _choices to [
{
disabled_text: "Not enough ?money",
text: "Relax at the bar -5?money",
target: "introduction 7",
color: "green",
requirement: "money",
threshold: 5,
},
{
disabled_text: "Not enough ?balance",
text: "Bartender Shift -?balance",
target: "introduction 8",
color: "orange",
requirement: "balance",
threshold: 1,
},
]>>
<<set _ecard to {title: "Striptease Bar", color: "blueviolet", bg_img: "striptease bar_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?money ?balance ?stress</p>
<p>After some time at the bar you felt something changed. Now you can work here.</p>
<p>"Now you can spend your ?balance point to get some cash here."</p>
<</event_passage>><<set $player_stats.money += 10>>
<<set $player_stats.balance -= 1>>
<<set $player_stats.stress += 2>>
<<set _choices to [
{
text: "Look for the next message",
target: "introduction 9",
color: "green",
},
]>>
<<set _ecard to {title: "Bartender Shift", color: "orange", bg_img: "bartender_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?money ?balance</p>
<p>I spent some time at the bar, but this time I was the bartender myself. I can't say it was hard. But doing in half naked is still quite stressful.</p>
<</event_passage>><<set $enemy to clone(setup.regular_enemies[1])>>
<<run $back.push("introduction 10")>>
<<set $current_loop to {
difficulty: 1,
}>>
<<set _choices to [
{
text: "Release the Echo",
side_effects: () => $back.push("post event battle"),
target: "battle pre calc",
color: "darkred",
},
]>>
<<set _ecard to {title: "Gross Echo", color: "darkred", bg_img: "gross echo_b.jpg"}>>
<<event_passage _ecard _choices>>
<p>I were looking for the next message when a fat guy started following me. Thanks god I found the message.</p>
<p>"Now you can start to worry, fluf. You are followed by the echo. We call people like the one following you "echoes", because they are not real people. It's like a ghost, just a trace of a real human being stuck in the loop."</p>
<p>A ghost? What is going on??</p>
<p>"But again, no need to panic. You can release them. To make it possible, you need to bring them to emotions, anyway you want. You have some initial actions to perform, I think it's enough for now. Later you will learn more actions. Remember that each action has different impact on you. Some make you aroused, some increase your stress, and so on."</p>
<</event_passage>><<run $player_deck.push(setup.action_cards[6])>>
<<unset $current_loop>>
<<set _choices to [
{
text: "Start the real game",
target: "loop selection",
color: "green",
},
]>>
<<event_passage setup.action_cards[6] _choices>>
<p>"You are so cool, fluf! You will become a great echo hunter! You know what? I gonna teach you a new skill right now. It's called respite."</p>
<p>I spent some time learning new skill.</p>
<p>"Now you are ready for a real game to start. Just remember what you've learned. And remember about the first payment. Good luck!"</p>
<</event_passage>>
/* INTRODUCTION end */<<set $player_stats.arousal += 2>>
<<set _non_max_tf to []>>
<<for _part range Object.keys(setup.all_body)>>
<<if _part is "penis">>
<<if $player_equipment[_part].id gt 0>>
<<set _non_max_tf.push(_part)>>
<</if>>
<<elseif $player_equipment[_part].id lt setup.all_body[_part].length - 1>>
<<set _non_max_tf.push(_part)>>
<</if>>
<</for>>
<<if _non_max_tf.length is 0>>
/* player has max fem body in all categories... */
/* TODO passage for that? */
<<set $player_stats.identity += 2>>
<<set $player_stats.arousal += 1>>
<<goto "back">>
<</if>>
/* weight by # TFs remaining per category */
<<set _weights to _non_max_tf.map(p => {
if(p === "penis") {
return $player_equipment[p].id;
} else {
return setup.all_body[p].length - 1 - $player_equipment[p].id;
}
})>>
<<set _random_feminization to _non_max_tf[alias_sampler(_weights)()]>>
<<set $old_item to clone($player_equipment[_random_feminization])>>
<<if _random_feminization is "penis">>
<<set _body_num to $player_equipment[_random_feminization].id-1>>
<<else>>
<<set _body_num to $player_equipment[_random_feminization].id+1>>
<</if>>
<<set _body_num to Math.clamp(_body_num, 0, setup.all_body[_random_feminization].length-1)>>
<<set $player_equipment[_random_feminization] to clone(setup.all_body[_random_feminization][_body_num])>>
<<set $loot to clone($player_equipment[_random_feminization])>>
<<switch _random_feminization>>
<<case "penis">>
<<set $related_phrase to "Oh no, my penis has shrunk!">>
<<case "face">>
<<set $related_phrase to "My face has changed. It's even more feminine now.">>
<<case "nails">>
<<set $related_phrase to "My nails have become longer. Not a big deal.">>
<<case "hair">>
<<set $related_phrase to "My hair has grown.">>
<<default>>
<<set $related_phrase to "Something happened to my body.">>
<</switch>>
<<goto "feminization">><<set _ecard to {title: "Feminization", color: "magenta", bg_img: "Feminization_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p>$related_phrase But what caused this to happen?</p>
<p>Now I have <<print $loot.name>>.</p>
<<equip_tf $old_item $loot>>
<</event_passage>><<set _distracted to $player_stats.stress + $player_stats.arousal gte 8>>
<<set _choices to [
{
disabled: $player_deck.length lte 8,
disabled_text: "Your mind is pretty clear",
text: "Clear your mind",
side_effects: () => $back.push(passage()),
target: "remove card selection",
color: "royalblue",
},
{
disabled: not _distracted,
disabled_text: "You are calm enough",
text: "Calm yourself",
/* TODO meditate: calm passage */
side_effects: () => {
$player_stats.stress -= 1;
$player_stats.arousal -= 1;
},
target: "back",
},
{
disabled: $player_stats.identity === $player_stats.fem,
disabled_text: "You are content with your appearance",
text: "Focus on your appearance",
/* TODO meditate: identity passage; give "embrace" card if 10 */
side_effects() {
if($player_stats.identity > $player_stats.fem) {
$player_stats.identity -= 1;
} else {
$player_stats.identity += 1;
}
},
target: "back",
},
{
text: "Move on",
target: "back",
color: "grey",
},
]>>
<<if _distracted>>
<<set _choices[0].disabled to true; _choices[0].disabled_text to "Too distracted">>
<</if>>
<<set _ecard to {title: "Meditation", color: "cyan", bg_img: "yoga_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?new_card ?stress ?arousal ?identity</p>
<p>I wandered into an empty room filled with yoga mats. It's unusually calm here...
Maybe I could take a break and clear my head.
A little bit of extra focus would probably help me deal with these echoes more effectively...</p>
<</event_passage>><<if $back.at(-1) === "get ditz">><<run $back.pop()>><</if>>
<<set _distr_card_amt to $player_deck.filter(card => ActionCard.distr_cards.includes(card.name)).length>>
<<set _stat_distraction to $player_stats.stress + $player_stats.arousal>>
<<set _choices to [
{
disabled: $player_deck.length lte 8,
disabled_text: "Need to Learn more Skills",
text: "Try to forget a Skill",
side_effects: () => $back.push(passage()),
target: "remove card selection",
color: "royalblue",
},
{
disabled: _distr_card_amt lte 0,
disabled_text: "Yor mind is Clear",
text: "Clear your Mind",
/*side_effects: () => $back.push(passage()),*/
target: "meditate focus",
color: "royalblue",
},
{
disabled: _stat_distraction lte 5,
disabled_text: "You are calm enough",
text: "Calm yourself",
/* TODO meditate: calm passage */
side_effects: () => {
$player_stats.stress -= 1;
$player_stats.arousal -= 1;
},
target: "back",
},
{
disabled: $player_stats.identity === $player_stats.fem,
disabled_text: "You are content with your appearance",
text: "Focus on your appearance",
/* TODO meditate: identity passage; give "embrace" card if 10 */
side_effects() {
if($player_stats.identity > $player_stats.fem) {
$player_stats.identity -= 1;
} else {
$player_stats.identity += 1;
}
},
target: "back",
},
{
text: "Move on",
target: "back",
color: "grey",
},
]>>
<<if _distr_card_amt gte 3>>
<<set _choices[0].disabled to true; _choices[0].disabled_text to "Too distracted">>
<<elseif _stat_distraction gte 8>>
<<set _choices[0].side_effects to () => {$back.push("get ditz"); $back.push(passage())}>>
<</if>>
<<set _ecard to {title: "Meditation", color: "cyan", bg_img: "yoga_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?new_card ?stress ?arousal ?identity</p>
<p>I wandered into an empty room filled with yoga mats. It's unusually calm here...
Maybe I could take a break and clear my head.
A little bit of extra focus would probably help me deal with these echoes more effectively...</p>
<</event_passage>><<run $player_deck.push(clone(setup.cleanse_cards[0]))>>
<<event_passage $player_deck.at(-1) setup.ok_choices>>
<p>You feel focused.</p>
<</event_passage>><<run $player_deck.push(clone(setup.punish_cards[3]))>>
<<event_passage $player_deck.at(-1) setup.ok_choices>>
<p>You were too distracted to forget that completely...</p>
<</event_passage>><p>You can remove an action card from your deck here.</p>
<div class="flexbuttons">
<button data-passage="back" class="btn">On second thought, keep my deck as is.</button>
</div>
<div id="deck-inv" class="grid5col">
<<for _idx, _card range $player_deck>><<capture _idx _card>>
<<link "<<action_card _card>>">>
<<set _rm_idx to _idx>>
<<run Dialog.setup("Forget this card?", "autoanim");
Dialog.wiki(Story.get("remove card confirm").processText());
Dialog.open();>>
<</link>>
<</capture>><</for>>
</div><<set _rm_card to $player_deck[_rm_idx]>>
<<action_card _rm_card notilt>>
<div class="flexbuttons">
<<button "Keep it.">><<run Dialog.close()>><</button>>
<<button "Forget it!" "2back">>
<<run $player_deck.splice(_rm_idx, 1)>>
<<run Dialog.close()>>
<</button>>
</div>
<<done>>
<<addclass "#ui-dialog-body button" "btn">>
<<addclass "#ui-dialog-body button:nth-child(2)" "btn-red">>
<</done>>[[back]]<br>
[[battle pre calc][$back.push("battle end test"); $enemy to setup.regular_enemies.random()]]
<<set $newactions ??= setup.action_cards.randomMany(5)>>
/*
<<set _cards to []>>
<<for _c = 0; _c < 5; ++_c>>
<<set _stats to {sub: 0, int: 0, fit: 0, att: 0}>>
<<for _s = 0; _s < _c + 1; ++_s>>
<<set _stats[Object.keys(_stats).random()]++>>
<</for>>
<<run _cards.push({
/* copied the last one from a Mozilla example lol * /
background: ["#6A0000", "#2E3192", "#8F006D", "#176320", "radial-gradient(#e66465, #9198e5)"][_c],
name: "Longer Card Title " + _c,
mana_cost: _stats,
img: "complain_b.jpg",
power: 5 * (_c - 1) + 1,
stat_effects: {obedience: 3 - _c},
description: "Everything is possible, <em>nothing is free.</em>",
rarity_text: ["common", "rare", "epic", "legendary"][(_c + 1) % 4],
})>>
<</for>>
*/
<<set _cards to clone(setup.action_cards.slice(0, 4))>>
<<set _cards[1].description to "It is useful to test what happens with really long descriptions because overflow behavior can be annoying.">>
<<set _cards[2].description to '<span style="font-size: .5em">Yo dawg, I heard you like cards in cards </span><div class="dumbdescr" style="transform: translateZ(5px)"><<action_card _cards[0]>></div>'>>
<div class="grid3col">
<<for _card range _cards.slice(1, 4)>>
<<action_card _card>>
<</for>>
</div>
<p>The following cards were randomly picked at start and *should* stay the same on save/load/passage navigation</p>
<div class="grid5col">
<<for _card range $newactions>>
<<action_card _card>>
<</for>>
</div>
<p>Here are all the cards in the game, by category:</p>
<<for _key range ["action_cards", "balance_cards", "corruption_cards",
"punish_cards", "cleanse_cards", "get_pain_cards", "get_distraction_cards"]>>
<p><<print _key.replaceAll("_", " ")>></p>
<div class="grid5col">
<<for _card range setup[_key]>>
<<action_card _card>>
<</for>>
</div>
<</for>><<set _winnings to 10 * $current_loop.difficulty>>
<<set $consecutive_wins ??= 0>>
<<if $battle_won>>
<<set $consecutive_wins += 1>>
/* TODO better victory (& maybe loss) image */
<<set _ecard to {title: "You won!", color: "deepskyblue", bg_img: "lost money_b.jpg"}>>
<<set $player_stats.money += _winnings>>
<<set _passage to "You managed to release the echo. It left behind " + _winnings + " ?money, neat!">>
<<if $consecutive_wins gte 3>>
/* TODO gte 6 - difficulty or something */
<<set $consecutive_wins to 0>>
<<set _ecard to clone(setup.punish_cards[1])>>
<<run $player_deck.push(_ecard)>>
<<set _passage += "<br>You're feeling great about echo hunting. Maybe too great...">>
<</if>>
<<else>>
<<set _winnings to 10 * $current_loop.difficulty * $game_difficulty>>
<<set $consecutive_wins to 0>>
<<set _ecard to {title: "You lost!", color: "brown", bg_img: "Passing Out_b.jpg"}>>
/* TODO make a new passage since randomness needs a "pre-calc" */
<<if random(1,4) is 1>>
<<set _ecard to clone(setup.punish_cards[0])>>
<<run $player_deck.push(_ecard)>>
<<set _passage to "You lost. The " + $enemy.name + " decided to spank you in retaliation while you were down!">>
<<else>>
<<set $player_stats.money -= _winnings/2>>
<<set _passage to "You lost. While you were passed out, the echo rummaged through your wallet and stole " + (_winnings / 2) + " ?money from you.">>
<</if>>
<</if>>
<<event_passage _ecard setup.ok_choices>>
<p>_passage</p>
<</event_passage>><<unset $battle_won>>
/* Mana setup; copy from stats */
<<set $mana to {}>>
<<for _sifa range setup.SIFA>>
<<set $mana[_sifa] to $player_stats[_sifa]>>
<</for>>
/* Player deck setup */
<<for _card range $player_deck>>
<<set _card.power_modifier to 0>>
<<set _card.turn_power to 0>>
<</for>>
<<set $temp_deck to clone($player_deck).shuffle()>>
<<set $player_hand to $temp_deck.splice(0, 5)>>
<<set $bal_deck to setup.balance_cards.slice(0, $player_stats.bal_cards)>>
<<set $cor_deck to setup.corruption_cards.slice(0, $player_stats.cor_cards)>>
<<set $next_power_multiplier to 0>>
<<set $next_power_addition to 0>>
<<unset $draw_filter>>
<<set _enemy_rate to $enemy?.power_rate ?? 1>>
<<set _loop_diff to $current_loop?.difficulty ?? 1>>
<<set $enemy_power to Math.round(_enemy_rate * 24 *
(_loop_diff + (_loop_diff - 1) * $game_difficulty + $game_difficulty - 1))>>
<<if $enemy?.name.toLowerCase().includes("training")>>
<<set $enemy_power to Math.round(_enemy_rate * 12 * ($game_difficulty + $game_difficulty - 1))>>
<<set $bal_deck to $enemy.bal_cor_cards.shuffle().slice(0, 3)>>
<<set $cor_deck to $enemy.bal_cor_cards.shuffle().slice(0, 3)>>
<</if>>
<<goto "battle page">>/* <p>debug: Go back to <code><<print $back.at(-1)>></code>
by [[winning|back][$battle_won to true]] or [[losing|back][$battle_won to false]]</p> */
<div id="battlediv">
<<include "battle page incl">>
</div>/*
<p>Power target: $enemy_power</p>
<p>all stats: <code style="overflow-wrap: break-word;"><<print JSON.stringify($player_stats.plain_obj)>></code></p>
<p>mana:
<<for _type, _amt range $mana>>
_amt <<print "?" + _type>>,
<</for>>
</p>
<p>bonus add'n: $next_power_addition; bonus mult: $next_power_multiplier</p>
<p>total hand size: $player_hand.length</p>
your hand: <br>
*/
<<set $draw_front to 0>>
<<set $draw_back to 0>>
<<set _top_of_hand to $player_hand.slice(0, 5)>>
<<for _card range _top_of_hand>>
<<run _card.run_pre_play()>>
<</for>>
<<run $bal_deck[0]?.run_pre_play()>>
<<run $cor_deck[0]?.run_pre_play()>>
<<set _playable to _top_of_hand.map(c => c.is_playable)>>
<<set _hand_count to _playable.reduce((acc, cur) => acc + Number(cur), 0)>>
<div class="grid3col" style="gap: 1em; align-items: center; margin-bottom: auto;">
<div class="flexdown" style="width: 80%; margin: auto;">
<<statbar "balance">>
<<if $bal_deck[0]?.is_playable>>
<<playable_action $bal_deck 0>>
<<else>>
/* TODO will require keeping track of the last one if more cards get introduced... */
<<set _thecard to $bal_deck[0] ?? setup.balance_cards[$player_stats.bal_cards - 1]>>
<<action_card _thecard disabled notilt>>
<</if>>
</div>
<div class="flexdown">
<div class="imgstack js-tilt">
<<set _ecard to {
title: $enemy.name,
color: "blue", /* TODO ??? */
bg_img: $enemy.image, /* TODO probably pointing in the wrong dir */
}>>
<<event_card _ecard>>
<span class="enemyhptxt">$enemy_power</span>
</div>
<<if isNaN($enemy_power)>>
<p style="font-size: smaller; text-align: justify;">Oops, the game broke somewhere.
Please save here and report this bug.
For now, we'll let you pick whether you won this fight...</p>
<div class="grid2col">
<button class="btn" data-passage="back" data-setter="$battle_won to true">Win</button>
<button class="btn" data-passage="back" data-setter="$battle_won to false">Lose</button>
</div>
<<elseif _hand_count lt 5>>
<button class="btn" data-passage="back" data-setter="$battle_won to false">Give up?</button>
<</if>>
<<sifa_stats $mana>>
</div>
<div class="flexdown" style="width: 80%; margin: auto;">
<<statbar "corruption">>
<<if $cor_deck[0]?.is_playable>>
<<playable_action $cor_deck 0>>
<<else>>
/* TODO will require keeping track of the last one if more cards get introduced... */
<<set _thecard to $cor_deck[0] ?? setup.corruption_cards[$player_stats.cor_cards - 1]>>
<<action_card _thecard disabled notilt>>
<</if>>
</div>
</div>
<div class="grid5col playerhandbg">
<<for _idx, _card range _top_of_hand>>
<<if _playable[_idx]>>
<<playable_action $player_hand _idx>>
<<else>>
<<action_card _card disabled>>
<</if>>
<</for>>
<<if _top_of_hand.length is 0>>
<p class="gridfilltxt">You've ran out of cards!</p>
<</if>>
</div>
<<if $player_hand.length gt 5>>
<p class="largertext" style="text-align: right; line-height: 1;">
+ <<print $player_hand.length - 5>> card<<print $player_hand.length gt 6 ? "s" : "">> pending</p>
<</if>>
<<done>><<run setup.activate_tilt()>><</done>><p>
<<if $battle_won>>
Congrats, you won!
<<else>>
Oh no, you lost...
<</if>>
</p>
[[back]] * [[Try again?|battle pre calc][$back.push(passage())]]Public Version<a href="https://www.patreon.com/sifagames" target="_blank">
<img src="public/banner_alpha.jpg" class="relfull">
</a>
<br>
<br><<run _choices.push({
text: "Debug/Testing for Sigma patrons!",
target: passage(),
disabled: true,
})>><<if $charview gt 0>>
<div id="avatar"><<include avatar_sidebar>></div>
<<else>>
Continue further to see your character.
<</if>><<set $charview to random(1,3)>>
<a href="https://www.patreon.com/sifagames" target="_blank">
<img @src='"public/banner_right_" + $charview + ".jpg"' style="width: 100%;">
</a>