v6.8.0 "NPC appearance"<br>
<<include TierSubtitle>><<if $charview gt 0>>
/*<code>back: <<print $back>></code>*/
<div id="sidebar-stats">
<<include "sidebar stats">>
</div>
<<if $quest_slots?.size gt 0>>
<p>Current task: Replace clothes:<br>
<<print Array.from($quest_slots).join(", ")>></p>
<</if>>
<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">>
<<run setup.show_dialog("Action Deck", "inv-dialog autoanim", "player deck page")>>
<</button>>
<<else>>
<button disabled>Deck</button>
<</if>>
<<button "Equipment">>
<<run setup.show_dialog("Equipment", "inv-dialog autoanim", "player equipment page")>>
<</button>>
<<if $effects.length gt 0>>
<<button "Effects">>
<<run setup.show_dialog("Effects", "", "player effects dialog")>>
<</button>>
<<else>>
<button disabled>Effects</button>
<</if>>
/*
<<button "Inventory">>
<<run setup.show_dialog("Inventory", "inv-dialog autoanim", "inventory dialog")>>
<</button>>
*/
<div style="grid-column: 1/-1">
<<button "What are these icons?">>
<<run setup.show_dialog("Information", "help-dialog", "information dialog")>>
<</button>>
</div>
</div>
/* end of charview check */
<</if>><div class="flexdown">
<div class="flexbuttons" style="height: 2em;">
<<statnum "money">>
</div>
<div class="flexbuttons" style="height: 2em;"><<statnum "productivity" >> <<statnum "bills">></div>
<div class="flexbuttons" style="height: 2em;">
<span class="statnum statnum-total_energy">
<img class="statnum-img" @src='"img2/icons/energy.svg"'>
<span class="statnum-txt"><<print $player_stats.energy + "/" + $player_stats.max_energy>></span>
</span>
</div>
<div class="flexbuttons" style="height: 2em;"><<statnum "compulsion">> <<statnum "focus">></div>
<<statbar "fem">>
<<statbar "identity_lvl" "identity">>
<div class="flexbuttons" style="height: 2em;"><<statnum "masculine">> <<statnum "feminine">></div>
<div class="flexbuttons" style="height: 2em;">
<span class="statnum statnum-total_tf">
<img class="statnum-img" @src='"img2/icons/tf.svg"'>
<span class="statnum-txt"><<print $player_equipment.total_tf + "/" + $player_equipment.max_total_tf>></span>
</span>
</div>
/*<<statbar "masochism_lvl" "masochism">>
<<statbar "airhead_lvl" "airhead">>*/
</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/XcpMJ3Q7KB]]<<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 setup.add_random_xp = function(is_fem, min = 4, max = 20) {
const stat = is_fem ? "feminine" : "masculine";
$player_stats[stat] += random(min, max);
}>>
<<set setup.reset_debt_timer to function() {
$debt_timer = random(2, 4);
}>>
<<run setup.reset_debt_timer()>><<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 2>>
<<set setup.loops to {
job: {
stat: "productivity",
},
shop: {
stat: "compulsion",
},
training: {
stat: "focus",
},
}>>
<<set setup.event_passages to {}>>
<<for _type, _obj range setup.loops>>
<<set _obj.type to _type>>
<<set _tag to _type + "-loop">>
/* idk if it's even worth doing tag stuff if there's only going to be one... */
<<set setup.event_passages[_tag] to Story.filter(p => p.tags.includes(_tag)).map(p => p.name)>>
<</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 */
[50, 60, 80, 120, 200, 250, 310, 380, 460, 550],
[75, 90, 120, 180, 300, 375, 465, 570, 690, 825],
[100, 120, 160, 240, 400, 500, 620, 760, 920, 1100],
]>>
/* new lobby setup (overwrite) */
<<set setup.payments to [
null,
[3000],
[6000],
[9000],
]>>
<<set setup.goal_fracs to [0, 0.033, 0.133, 0.3]>>
<<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.amount_for_next_frac = function() {
const goal = setup.payments[$game_difficulty][0];
const paid = goal - $debt.payment;
const paid_frac = paid / goal;
const cur_frac_idx = setup.goal_fracs.findLastIndex(f => paid_frac gte f);
if(cur_frac_idx >= setup.goal_fracs.length - 1) {
return 0; /* already at max */
}
const target_paid = Math.ceil(setup.goal_fracs[cur_frac_idx + 1] * goal);
return target_paid - paid;
}>><<set setup.all_body to {
body: [
new EquipItem({name:"Male Body", gender:"male", styles: ["male"], rarity:"common", fem:-8, 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:-7, 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:-4, 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:2, 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:6, 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:9, 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:10, 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:13, 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:17, 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:20, 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:21, 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:16, sub: 4}),
new EquipItem({name:"Tiny Clitty", gender:"female", styles: ["female"], rarity:"legendary", fem:18, sub: 4, fit: 1}),
new EquipItem({name:"Little Winkle", gender:"male", styles: ["unisex"], rarity:"epic", fem:10, sub: 3, int: 0, fit: 1, att: 0}),
new EquipItem({name:"Small Prick", gender:"male", styles: ["unisex"], rarity:"rare", fem:4, sub: 2, int: 0, fit: 1, att: 0}),
new EquipItem({name:"Normal Stick", gender:"male", styles: ["male"], rarity:"common", fem:-2, sub: 0, int: 0, fit: 2, att: 0}),
new EquipItem({name:"Big Tool", gender:"male", styles: ["male"], rarity:"epic", fem:-8, sub: 0, int: 0, fit: 4, att: 0}),
],
face: [
new EquipItem({name:"Masculine Face", gender:"male", styles: ["male"], head:1, rarity:"common", fem:-3, sub: 0, int: 0, fit: 0, att: 0}),
new EquipItem({name:"Boy Face", gender:"male", styles: ["male"], head:2, rarity:"rare", fem:4, sub: 0, int: 0, fit: 0, att: 1}),
new EquipItem({name:"Femboy Face", gender:"male", styles: ["unisex"], head:2, rarity:"epic", fem:11, sub: 0, int: 0, fit: 0, att: 2}),
new EquipItem({name:"Girly Face", gender:"female", styles: ["female"], head:2, rarity:"legendary", fem:18, sub: 0, int: 0, fit: 0, att: 3}),
],
hair: [
new EquipItem({name:"Short Hair", gender:"male", styles: ["male"], ears:"both", rarity:"common", fem:-5, sub: 0, int: 0, fit: 1, att: 0}),
new EquipItem({name:"Medium Hair", gender:"unisex", styles: ["unisex"], ears:"right", rarity:"rare", fem:5, sub: 0, int: 1, fit: 0, att: 1}),
new EquipItem({name:"Long Hair", gender:"female", styles: ["female"], ears:"left", rarity:"epic", fem:15, sub: 1, int: 1, fit: 0, att: 1}),
],
nails: [
new EquipItem({name:"Short Nails", gender:"male", styles: ["male"], rarity:"common", fem:-5, sub: 0, int: 0, fit: 1, att: 0}),
new EquipItem({name:"Long Nails", gender:"female", styles: ["female"], rarity:"rare", fem:5, 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", fem:2, int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["blonde"], styles: ["unisex"], rarity:"epic", fem:2, int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["blue"], styles: ["unisex"], rarity:"epic", fem:2, int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["brown"], styles: ["unisex"], rarity:"epic", fem:2, int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["darkblue"], styles: ["unisex"], rarity:"epic", fem:2, int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["ginger"], styles: ["unisex"], rarity:"epic", fem:2, int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["gray"], styles: ["unisex"], rarity:"epic", fem:2, int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["green"], styles: ["unisex"], rarity:"epic", fem:2, int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["pink"], styles: ["unisex"], rarity:"epic", fem:2, int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["purple"], styles: ["unisex"], rarity:"epic", fem:2, int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["red"], styles: ["unisex"], rarity:"epic", fem:2, int:1, sub:1}),
new EquipItem({name:"Straight Hair", ears: ["no", "no", "no"], colors: ["white"], styles: ["unisex"], rarity:"epic", fem:2, 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", "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", fem:-2, int:2}),
new EquipItem({name:"Subtle Lipstick", gender:"female", colors: ["red"], styles: ["female"], rarity:"rare", fem:-2, att:2}),
new EquipItem({name:"Subtle Lipstick", gender:"female", colors: ["pink"], styles: ["female"], rarity:"rare", fem:-2, sub:2}),
new EquipItem({name:"Bold Lipstick", gender:"female", colors: ["black"], styles: ["female"], rarity:"epic", fem:2, int:3}),
new EquipItem({name:"Bold Lipstick", gender:"female", colors: ["red"], styles: ["female"], rarity:"epic", fem:2, att:3}),
new EquipItem({name:"Bold Lipstick", gender:"female", colors: ["pink"], styles: ["female"], rarity:"epic", fem:2, 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", fem:2, int:1}),
new EquipItem({name:"Nail Polish", gender:"female", colors: ["blue"], styles: ["female"], rarity:"common", fem:-2, 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", fem:-1, fit:1}),
new EquipItem({name:"Toenail Polish", gender:"unisex", colors: ["black"], styles: ["unisex"], rarity:"common", fem:1, int:1}),
new EquipItem({name:"Toenail Polish", gender:"female", colors: ["blue"], styles: ["female"], rarity:"common", fem:-3, att:1}),
new EquipItem({name:"Toenail Polish", gender:"female", colors: ["white"], styles: ["female"], rarity:"common", fem:-1, sub:1}),
new EquipItem({name:"Toenail Polish", gender:"female", colors: ["red"], styles: ["female"], rarity:"rare", fem:-1, sub:2}),
new EquipItem({name:"Toenail Polish", gender:"female", colors: ["pink"], styles: ["female"], rarity:"rare", fem:-1, 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: -1},
unisex: {fem: 1},
female: {fem: 5},
},
mid: {
male: {fem: -2},
unisex: {fem: 1},
female: {fem: 8},
},
big: {
male: {fem: -3},
unisex: {fem: 1},
female: {fem: 11},
},
}>>
<<set _fem += _genpts[_scale]?.[_item.styles]?.fem ?? 0>>
<<set _rarpts to {
common: {fem: 0},
rare: {fem: 0},
epic: {fem: 0},
legendary: {fem: 0},
}>>
<<set _rar to _item.rarity>>
<<set _fem += _rarpts[_rar]?.fem ?? 0>>
<<set _colorpts to {
black: {fem: -2},
blonde: {fem: 1},
blue: {fem: 1},
brown: {fem: -1},
darkblue: {fem: 0},
ginger: {fem: 1},
gray: {fem: 0},
green: {fem: 1},
pink: {fem: 3},
purple: {fem: 2},
red: {fem: 2},
white: {fem: 0},
cyan: {fem: 1},
nocolor: {fem:-1},
transparent:{fem:-1},
}>>
<<for _col range _item.colors>>
<<set _fem += _colorpts?.[_col]?.fem ?? 0>>
<</for>>
<<set _item.base_fem to Math.clamp(_fem, 0, 20)>>
<</for>>
<</widget>><<set setup.all_clothes to {
undies: [
new EquipItem({name:"No Undies", gender: "unisex", colors: ["nocolor"], styles: ["lewd"], covers_slots: {penis: 0}}),
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:"male", colors: ["nocolor"], styles: [], covers_slots: {body: 0}}),
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: [], covers_slots: {undies: 0}}),
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:"Pants", gender:"male", colors: ["black", "brown"], styles: ["formal", "modest"]}),
new EquipItem({name:"Pants", gender:"male", colors: ["blue", "brown", "gold"], styles: ["formal", "modest"]}),
new EquipItem({name:"Pants", gender:"male", colors: ["brown", "black"], styles: ["formal", "modest"]}),
new EquipItem({name:"Pants", gender:"male", colors: ["red", "black"], styles: ["formal", "modest"]}),
new EquipItem({name:"Pants", gender:"male", colors: ["white", "black"], styles: ["formal", "modest"]}),
new EquipItem({name:"Pants", gender:"male", colors: ["white", "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:"High Waisted Pants", gender:"female", colors: ["black", "brown", "gold"], styles: ["formal", "casual"]}),
new EquipItem({name:"High Waisted Pants", gender:"female", colors: ["black", "white", "gold"], styles: ["formal", "casual"]}),
new EquipItem({name:"High Waisted Pants", gender:"female", colors: ["blue", "white", "gold"], styles: ["formal", "casual"]}),
new EquipItem({name:"High Waisted Pants", gender:"female", colors: ["red", "white", "gold"], styles: ["formal", "casual"]}),
new EquipItem({name:"High Waisted Pants", gender:"female", colors: ["white", "black", "gold"], styles: ["formal", "casual"]}),
new EquipItem({name:"High Waisted Pants", gender:"female", colors: ["white", "pink", "gold"], styles: ["formal", "casual"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["black"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["white"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["pink"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["black", "brown", "gold"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["black", "pink", "gold"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["black", "white", "gold"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["brown", "black", "gold"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["brown", "white", "gold"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["pink", "blue", "gold"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["pink", "white", "gold"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["red", "black", "gold"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["red", "white", "gold"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["white", "black", "gold"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["white", "blue", "gold"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["white", "gold"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["white", "pink", "gold"], styles: ["formal"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Skirt", gender:"female", colors: ["black", "brown", "gold"], styles: ["casual", "comfy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Skirt", gender:"female", colors: ["black", "pink", "gold"], styles: ["casual", "comfy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Skirt", gender:"female", colors: ["black", "white", "gold"], styles: ["casual", "comfy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Skirt", gender:"female", colors: ["brown", "black", "gold"], styles: ["casual", "comfy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Skirt", gender:"female", colors: ["brown", "white", "gold"], styles: ["casual", "comfy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Skirt", gender:"female", colors: ["pink", "blue", "gold"], styles: ["casual", "comfy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Skirt", gender:"female", colors: ["pink", "white", "gold"], styles: ["casual", "comfy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Skirt", gender:"female", colors: ["red", "black", "gold"], styles: ["casual", "comfy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Skirt", gender:"female", colors: ["red", "white", "gold"], styles: ["casual", "comfy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Skirt", gender:"female", colors: ["white", "black", "gold"], styles: ["casual", "comfy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Skirt", gender:"female", colors: ["white", "blue", "gold"], styles: ["casual", "comfy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Skirt", gender:"female", colors: ["white", "gold"], styles: ["casual", "comfy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Skirt", gender:"female", colors: ["white", "pink", "gold"], styles: ["casual", "comfy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Mini Skirt", gender:"female", colors: ["black", "brown", "gold"], styles: ["casual", "comfy", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Mini Skirt", gender:"female", colors: ["black", "pink", "gold"], styles: ["casual", "comfy", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Mini Skirt", gender:"female", colors: ["black", "white", "gold"], styles: ["casual", "comfy", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Mini Skirt", gender:"female", colors: ["brown", "black", "gold"], styles: ["casual", "comfy", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Mini Skirt", gender:"female", colors: ["brown", "white", "gold"], styles: ["casual", "comfy", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Mini Skirt", gender:"female", colors: ["pink", "blue", "gold"], styles: ["casual", "comfy", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Mini Skirt", gender:"female", colors: ["pink", "white", "gold"], styles: ["casual", "comfy", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Mini Skirt", gender:"female", colors: ["red", "black", "gold"], styles: ["casual", "comfy", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Mini Skirt", gender:"female", colors: ["red", "white", "gold"], styles: ["casual", "comfy", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Mini Skirt", gender:"female", colors: ["white", "black", "gold"], styles: ["casual", "comfy", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Mini Skirt", gender:"female", colors: ["white", "blue", "gold"], styles: ["casual", "comfy", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Mini Skirt", gender:"female", colors: ["white", "gold"], styles: ["casual", "comfy", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Formal Mini Skirt", gender:"female", colors: ["white", "pink", "gold"], styles: ["casual", "comfy", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Mini Tube Skirt", gender:"female", colors: ["black"], styles: ["formal", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Mini Tube Skirt", gender:"female", colors: ["white"], styles: ["formal", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Mini Tube Skirt", gender:"female", colors: ["pink"], styles: ["formal", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Mini Tube Skirt", gender:"female", colors: ["black", "pink", "gold"], styles: ["formal", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Mini Tube Skirt", gender:"female", colors: ["black", "white", "gold"], styles: ["formal", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Mini Tube Skirt", gender:"female", colors: ["blue", "white", "gold"], styles: ["formal", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Mini Tube Skirt", gender:"female", colors: ["brown", "black", "gold"], styles: ["formal", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Mini Tube Skirt", gender:"female", colors: ["pink", "white", "gold"], styles: ["formal", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Mini Tube Skirt", gender:"female", colors: ["red", "white", "gold"], styles: ["formal", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Mini Tube Skirt", gender:"female", colors: ["white", "black", "gold"], styles: ["formal", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Mini Tube Skirt", gender:"female", colors: ["white", "brown", "gold"], styles: ["formal", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Skirt", gender:"female", colors: ["black", "brown", "gold"], styles: ["formal", "party"], extra: ["skirt"]}),
new EquipItem({name:"Slit Skirt", gender:"female", colors: ["black", "white", "gold"], styles: ["formal", "party"], extra: ["skirt"]}),
new EquipItem({name:"Slit Skirt", gender:"female", colors: ["blue", "brown", "gold"], styles: ["formal", "party"], extra: ["skirt"]}),
new EquipItem({name:"Slit Skirt", gender:"female", colors: ["blue", "white", "gold"], styles: ["formal", "party"], extra: ["skirt"]}),
new EquipItem({name:"Slit Skirt", gender:"female", colors: ["pink", "white", "gold"], styles: ["formal", "party"], extra: ["skirt"]}),
new EquipItem({name:"Slit Skirt", gender:"female", colors: ["red", "white", "gold"], styles: ["formal", "party"], extra: ["skirt"]}),
new EquipItem({name:"Slit Skirt", gender:"female", colors: ["white", "black", "gold"], styles: ["formal", "party"], extra: ["skirt"]}),
new EquipItem({name:"Slit Skirt", gender:"female", colors: ["white", "brown", "gold"], styles: ["formal", "party"], extra: ["skirt"]}),
new EquipItem({name:"Slit Skirt", gender:"female", colors: ["white", "pink", "gold"], styles: ["formal", "party"], extra: ["skirt"]}),
new EquipItem({name:"Slit Mini Skirt", gender:"female", colors: ["black", "brown", "gold"], styles: ["formal", "party", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Mini Skirt", gender:"female", colors: ["black", "white", "gold"], styles: ["formal", "party", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Mini Skirt", gender:"female", colors: ["blue", "white", "gold"], styles: ["formal", "party", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Mini Skirt", gender:"female", colors: ["pink", "white", "gold"], styles: ["formal", "party", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Mini Skirt", gender:"female", colors: ["red", "white", "gold"], styles: ["formal", "party", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Mini Skirt", gender:"female", colors: ["white", "black", "gold"], styles: ["formal", "party", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Mini Skirt", gender:"female", colors: ["white", "blue", "gold"], styles: ["formal", "party", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Mini Skirt", gender:"female", colors: ["white", "brown", "gold"], styles: ["formal", "party", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Slit Mini Skirt", gender:"female", colors: ["white", "pink", "gold"], styles: ["formal", "party", "sexy"], extra: ["skirt"]}),
new EquipItem({name:"Gym Shorts", gender:"unisex", colors: ["black", "white"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"unisex", colors: ["blue", "white"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"unisex", colors: ["green", "white"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"unisex", colors: ["pink", "white"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"unisex", colors: ["red", "black"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"unisex", 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"], extra: ["skirt"]}),
new EquipItem({name:"Seifuku Long Skirt", gender:"female", colors: ["blue"], styles: ["study"], extra: ["skirt"]}),
new EquipItem({name:"Seifuku Long Skirt", gender:"female", colors: ["cyan"], styles: ["study"], extra: ["skirt"]}),
new EquipItem({name:"Seifuku Long Skirt", gender:"female", colors: ["green"], styles: ["study"], extra: ["skirt"]}),
new EquipItem({name:"Seifuku Long Skirt", gender:"female", colors: ["pink"], styles: ["study"], extra: ["skirt"]}),
new EquipItem({name:"Seifuku Long Skirt", gender:"female", colors: ["white"], styles: ["study"], extra: ["skirt"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["black", "red"], styles: ["study", "party", "cute"], extra: ["skirt"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["blue", "brown"], styles: ["study", "party", "cute"], extra: ["skirt"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["blue", "white"], styles: ["study", "party", "cute"], extra: ["skirt"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["cyan"], styles: ["study", "party", "cute"], extra: ["skirt"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["green", "white"], styles: ["study", "party", "cute"], extra: ["skirt"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["pink", "white"], styles: ["study", "party", "cute"], extra: ["skirt"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["red", "white"], styles: ["study", "party", "cute"], extra: ["skirt"]}),
new EquipItem({name:"Seifuku Mini Skirt", gender:"female", colors: ["white", "black"], styles: ["study", "party", "cute"], extra: ["skirt"]}),
new EquipItem({name:"Formal Pants", gender:"unisex", 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: ["skirt", "thick"]}),
new EquipItem({name:"Winter Short Skirt", gender:"female", colors: ["red", "white", "black"], styles: ["comfy", "party", "cute"], extra: ["skirt", "thick"]}),
new EquipItem({name:"Sweatpants", gender:"male", colors: ["black", "white"], styles: ["active", "casual"], extra: ["thick"]}),
new EquipItem({name:"Sweatpants", gender:"male", colors: ["blue", "white"], styles: ["active", "casual"], extra: ["thick"]}),
new EquipItem({name:"Sweatpants", gender:"male", colors: ["green", "white"], styles: ["active", "casual"], extra: ["thick"]}),
new EquipItem({name:"Sweatpants", gender:"male", colors: ["pink", "white"], styles: ["active", "casual"], extra: ["thick"]}),
new EquipItem({name:"Sweatpants", gender:"male", colors: ["red", "white"], styles: ["active", "casual"], extra: ["thick"]}),
new EquipItem({name:"Sweatpants", gender:"male", colors: ["white", "black"], styles: ["active", "casual"], extra: ["thick"]}),
new EquipItem({name:"Sweatpants", gender:"male", colors: ["yellow", "black"], styles: ["active", "casual"], extra: ["thick"]}),
new EquipItem({name:"Tight Sweatpants", gender:"unisex", colors: ["black", "white"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Tight Sweatpants", gender:"unisex", colors: ["blue", "white"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Tight Sweatpants", gender:"unisex", colors: ["green", "white"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Tight Sweatpants", gender:"unisex", colors: ["pink", "white"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Tight Sweatpants", gender:"unisex", colors: ["red", "white"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Tight Sweatpants", gender:"unisex", colors: ["white", "black"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Tight Sweatpants", gender:"unisex", colors: ["yellow", "black"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Leggings Pattern 2", gender:"female", colors: ["black", "pink"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Leggings Pattern 2", gender:"female", colors: ["blue", "black", "white"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Leggings Pattern 2", gender:"female", colors: ["green", "orange"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Leggings Pattern 2", gender:"female", colors: ["pink", "white"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Leggings Pattern 2", gender:"female", colors: ["red", "black"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Leggings Pattern 2", gender:"female", colors: ["white", "blue"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Leggings Pattern 2", gender:"female", colors: ["yellow", "black", "white"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Leggings Pattern 1", gender:"female", colors: ["black", "white"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Leggings Pattern 1", gender:"female", colors: ["blue", "black"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Leggings Pattern 1", gender:"female", colors: ["green", "white"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Leggings Pattern 1", gender:"female", colors: ["pink", "blue"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Leggings Pattern 1", gender:"female", colors: ["red", "white"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Leggings Pattern 1", gender:"female", colors: ["white", "black"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Leggings Pattern 1", gender:"female", colors: ["yellow", "black"], styles: ["active", "casual"], extra: ["tight"]}),
new EquipItem({name:"Light Skirt", gender:"female", colors: ["black", "brown"], styles: ["casual", "cute", "sexy"], extra: ["skirt", "loose"]}),
new EquipItem({name:"Light Skirt", gender:"female", colors: ["blue", "brown"], styles: ["casual", "cute", "sexy"], extra: ["skirt", "loose"]}),
new EquipItem({name:"Light Skirt", gender:"female", colors: ["green", "brown"], styles: ["casual", "cute", "sexy"], extra: ["skirt", "loose"]}),
new EquipItem({name:"Light Skirt", gender:"female", colors: ["orange", "brown"], styles: ["casual", "cute", "sexy"], extra: ["skirt", "loose"]}),
new EquipItem({name:"Light Skirt", gender:"female", colors: ["pink", "brown"], styles: ["casual", "cute", "sexy"], extra: ["skirt", "loose"]}),
new EquipItem({name:"Light Skirt", gender:"female", colors: ["red", "brown"], styles: ["casual", "cute", "sexy"], extra: ["skirt", "loose"]}),
new EquipItem({name:"Light Skirt", gender:"female", colors: ["white", "brown"], styles: ["casual", "cute", "sexy"], extra: ["skirt", "loose"]}),
new EquipItem({name:"Light Skirt", gender:"female", colors: ["yellow", "brown"], styles: ["casual", "cute", "sexy"], extra: ["skirt", "loose"]}),
],
top: [
new EquipItem({name:"No Top", gender:"unisex", colors: ["nocolor"], styles: [], covers_slots: {bra: 0}}),
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:"Tank Top", gender:"unisex", colors: ["green"], styles: ["active"]}),
new EquipItem({name:"Tank Top", gender:"unisex", colors: ["red"], styles: ["active"]}),
new EquipItem({name:"Tank Top", gender:"unisex", colors: ["yellow"], styles: ["active"]}),
new EquipItem({name:"Tank Top", gender:"unisex", colors: ["black", "white"], styles: ["active"]}),
new EquipItem({name:"Tank Top", gender:"unisex", colors: ["blue", "white"], styles: ["active"]}),
new EquipItem({name:"Tank Top", gender:"unisex", colors: ["pink", "white"], styles: ["active"]}),
new EquipItem({name:"Tank Top", gender:"unisex", colors: ["white", "black"], styles: ["active"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["black"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["black", "white"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["blue"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["blue", "pink"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["blue", "white"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["pink"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["pink", "pink"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["pink", "white"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["red"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["red", "black"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["red", "white"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["white"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["white", "black"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["white", "pink"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["black"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["black", "pink"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["black", "white"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["blue"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["blue", "pink"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["blue", "white"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["pink"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["pink", "black"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["pink", "blue"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["pink", "white"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["red"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["red", "black"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["red", "white"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["white"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["white", "black"], styles: ["formal", "sexy"]}),
new EquipItem({name:"Crop Top 2", gender:"female", colors: ["white", "pink"], styles: ["formal", "sexy"]}),
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"]}),
new EquipItem({name:"Bardot T-Shirt", gender:"female", colors: ["black"], styles: ["comfy", "casual", "cute"], extra: ["loose"]}),
new EquipItem({name:"Bardot T-Shirt", gender:"female", colors: ["blue"], styles: ["comfy", "casual", "cute"], extra: ["loose"]}),
new EquipItem({name:"Bardot T-Shirt", gender:"female", colors: ["green"], styles: ["comfy", "casual", "cute"], extra: ["loose"]}),
new EquipItem({name:"Bardot T-Shirt", gender:"female", colors: ["orange"], styles: ["comfy", "casual", "cute"], extra: ["loose"]}),
new EquipItem({name:"Bardot T-Shirt", gender:"female", colors: ["pink"], styles: ["comfy", "casual", "cute"], extra: ["loose"]}),
new EquipItem({name:"Bardot T-Shirt", gender:"female", colors: ["red"], styles: ["comfy", "casual", "cute"], extra: ["loose"]}),
new EquipItem({name:"Bardot T-Shirt", gender:"female", colors: ["white"], styles: ["comfy", "casual", "cute"], extra: ["loose"]}),
new EquipItem({name:"Bardot T-Shirt", gender:"female", colors: ["yellow"], styles: ["comfy", "casual", "cute"], extra: ["loose"]}),
new EquipItem({name:"V-Neck T-Shirt", gender:"male", colors: ["black", "white"], styles: ["comfy", "casual"]}),
new EquipItem({name:"V-Neck T-Shirt", gender:"male", colors: ["blue", "white"], styles: ["comfy", "casual"]}),
new EquipItem({name:"V-Neck T-Shirt", gender:"male", colors: ["green", "orange"], styles: ["comfy", "casual"]}),
new EquipItem({name:"V-Neck T-Shirt", gender:"male", colors: ["orange", "white"], styles: ["comfy", "casual"]}),
new EquipItem({name:"V-Neck T-Shirt", gender:"male", colors: ["pink", "blue"], styles: ["comfy", "casual"]}),
new EquipItem({name:"V-Neck T-Shirt", gender:"male", colors: ["red", "white"], styles: ["comfy", "casual"]}),
new EquipItem({name:"V-Neck T-Shirt", gender:"male", colors: ["white", "red"], styles: ["comfy", "casual"]}),
new EquipItem({name:"V-Neck T-Shirt", gender:"male", colors: ["yellow", "black"], styles: ["comfy", "casual"]}),
],
shoes: [
new EquipItem({name:"No Shoes", gender:"unisex", colors: ["nocolor"], styles: [], covers_slots: {legwear: 0}}),
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", "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", "casual"]}),
new EquipItem({name:"Sneakers", gender:"unisex", colors: ["red", "white"], styles: ["active", "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:"Oxfords", gender:"male", 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"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["black"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["black", "black", "white"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["black", "white"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["blue"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["blue", "black", "white"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["blue", "white"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["green"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["green", "white"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["green", "white", "orange"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["pink"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["pink", "white"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["pink", "white", "blue"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["red"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["red", "black", "white"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["red", "red", "white"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["red", "white"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["white"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["white", "black"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["yellow"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["yellow", "white"], styles: ["active", "casual"]}),
new EquipItem({name:"Cool Sneakers", gender:"unisex", colors: ["yellow", "white", "black"], styles: ["active", "casual"]}),
],
legwear: [
new EquipItem({name:"No Legwear", gender:"male", colors: ["nocolor"], styles: [], covers_slots: {toenail_polish: 0}}),
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:"male", 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", "sexy"], extra: ["transparent"]}),
new EquipItem({name:"Sheer Stockings", gender:"female", colors: ["brown"], styles: ["formal", "sexy"], extra: ["transparent"]}),
new EquipItem({name:"Sheer Stockings", gender:"female", colors: ["blue"], styles: ["formal", "sexy"], extra: ["transparent"]}),
new EquipItem({name:"Sheer Stockings", gender:"female", colors: ["black"], styles: ["formal", "sexy"], extra: ["transparent"]}),
new EquipItem({name:"Sheer Stockings", gender:"female", colors: ["black", "black"], styles: ["formal", "sexy"], extra: ["transparent"]}),
new EquipItem({name:"Sheer Stockings", gender:"female", colors: ["white"], styles: ["formal", "sexy"], extra: ["transparent"]}),
new EquipItem({name:"Sheer Stockings", gender:"female", colors: ["pink"], styles: ["formal", "sexy"], extra: ["transparent"]}),
new EquipItem({name:"Sheer Stockings", gender:"female", colors: ["pink", "pink"], styles: ["formal", "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"]}),
new EquipItem({name:"Gym Socks", gender:"unisex", colors: ["black", "red"], styles: ["active", "comfy"]}),
new EquipItem({name:"Gym Socks", gender:"unisex", colors: ["black", "white"], styles: ["active", "comfy"]}),
new EquipItem({name:"Gym Socks", gender:"unisex", colors: ["blue", "white"], styles: ["active", "comfy"]}),
new EquipItem({name:"Gym Socks", gender:"unisex", colors: ["green", "white"], styles: ["active", "comfy"]}),
new EquipItem({name:"Gym Socks", gender:"unisex", colors: ["pink", "blue"], styles: ["active", "comfy"]}),
new EquipItem({name:"Gym Socks", gender:"unisex", colors: ["pink", "white"], styles: ["active", "comfy"]}),
new EquipItem({name:"Gym Socks", gender:"unisex", colors: ["red", "white"], styles: ["active", "comfy"]}),
new EquipItem({name:"Gym Socks", gender:"unisex", colors: ["white", "black"], styles: ["active", "comfy"]}),
new EquipItem({name:"Gym Socks", gender:"unisex", colors: ["white", "blue"], styles: ["active", "comfy"]}),
new EquipItem({name:"Gym Socks", gender:"unisex", colors: ["white", "green"], styles: ["active", "comfy"]}),
new EquipItem({name:"Gym Socks", gender:"unisex", colors: ["white", "pink"], styles: ["active", "comfy"]}),
new EquipItem({name:"Gym Socks", gender:"unisex", colors: ["white", "red"], styles: ["active", "comfy"]}),
new EquipItem({name:"Gym Socks", gender:"unisex", colors: ["white", "yellow"], styles: ["active", "comfy"]}),
new EquipItem({name:"Gym Socks", gender:"unisex", colors: ["yellow", "black"], styles: ["active", "comfy"]}),
new EquipItem({name:"Knee Socks", gender:"female", colors: ["black"], styles: ["active"]}),
new EquipItem({name:"Knee Socks", gender:"female", colors: ["blue"], styles: ["active"]}),
new EquipItem({name:"Knee Socks", gender:"female", colors: ["green"], styles: ["active"]}),
new EquipItem({name:"Knee Socks", gender:"female", colors: ["pink"], styles: ["active"]}),
new EquipItem({name:"Knee Socks", gender:"female", colors: ["red"], styles: ["active"]}),
new EquipItem({name:"Knee Socks", gender:"female", colors: ["white"], styles: ["active"]}),
new EquipItem({name:"Knee Socks", gender:"female", colors: ["yellow"], styles: ["active"]}),
],
mask: [
new EquipItem({name:"No Mask", gender:"male", 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", "study"], extra: "transparent"}),
new EquipItem({name:"Lexington Glasses", gender:"male", colors: ["red"], styles: ["formal", "study"], extra: "transparent"}),
new EquipItem({name:"Lexington Glasses", gender:"male", colors: ["white"], styles: ["formal", "study"], extra: "transparent"}),
new EquipItem({name:"Lexington Glasses", gender:"male", colors: ["cyan"], styles: ["formal", "study"], extra: "transparent"}),
new EquipItem({name:"Lexington Glasses", gender:"male", colors: ["pink"], styles: ["formal", "study"], extra: "transparent"}),
new EquipItem({name:"Lexington Glasses", gender:"male", colors: ["green"], styles: ["formal", "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"}),
],
outerwear: [
new EquipItem({name:"No Outerwear", gender:"unisex", colors: ["nocolor"], styles: [], covers_slots: {bra: 0}}),
new EquipItem({name:"Winter Coat", gender:"male", colors: ["green", "white"], styles: ["modest", "comfy", "party"]}),
new EquipItem({name:"Winter Coat", gender:"male", colors: ["red", "white"], styles: ["modest", "comfy", "party"]}),
new EquipItem({name:"Winter Cape", gender:"female", colors: ["green", "white"], styles: ["cute", "comfy", "party"]}),
new EquipItem({name:"Winter Cape", gender:"female", colors: ["red", "white"], styles: ["cute", "comfy", "party"]}),
new EquipItem({name:"Armless Jacket", gender:"unisex", colors: ["black", "white"], styles: ["casual", "active"]}),
new EquipItem({name:"Armless Jacket", gender:"unisex", colors: ["blue", "white"], styles: ["casual", "active"]}),
new EquipItem({name:"Armless Jacket", gender:"unisex", colors: ["green", "white"], styles: ["casual", "active"]}),
new EquipItem({name:"Armless Jacket", gender:"unisex", colors: ["orange", "white"], styles: ["casual", "active"]}),
new EquipItem({name:"Armless Jacket", gender:"unisex", colors: ["pink", "white"], styles: ["casual", "active"]}),
new EquipItem({name:"Armless Jacket", gender:"unisex", colors: ["red", "white"], styles: ["casual", "active"]}),
new EquipItem({name:"Armless Jacket", gender:"unisex", colors: ["white", "white"], styles: ["casual", "active"]}),
new EquipItem({name:"Armless Jacket", gender:"unisex", colors: ["yellow", "white"], styles: ["casual", "active"]}),
new EquipItem({name:"Gym Jacket", gender:"female", colors: ["black", "white", "yellow"], styles: ["casual", "active", "sexy"]}),
new EquipItem({name:"Gym Jacket", gender:"female", colors: ["blue", "white", "yellow"], styles: ["casual", "active", "sexy"]}),
new EquipItem({name:"Gym Jacket", gender:"female", colors: ["green", "white", "brown"], styles: ["casual", "active", "sexy"]}),
new EquipItem({name:"Gym Jacket", gender:"female", colors: ["pink", "white", "blue"], styles: ["casual", "active", "sexy"]}),
new EquipItem({name:"Gym Jacket", gender:"female", colors: ["red", "white", "yellow"], styles: ["casual", "active", "sexy"]}),
new EquipItem({name:"Gym Jacket", gender:"female", colors: ["white", "black", "red"], styles: ["casual", "active", "sexy"]}),
new EquipItem({name:"Gym Jacket", gender:"female", colors: ["yellow", "black"], styles: ["casual", "active", "sexy"]}),
],
}>>
/* TODO 'multi' & 'energy' 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>>
/*<<for _prop range _default_zero>>
<<set _cl[_prop] ??= 0>>
<</for>>*/
/* default coverage rules */
<<switch _place>>
<<case "top">>
<<set _cl.covers_slots.bra ??= 75>>
<<case "bra">>
<<set _cl.covers_slots.body ??= 75>>
<<case "bottom">>
<<set _cl.covers_slots.undies ??= 75>>
<<case "undies">>
<<set _cl.covers_slots.penis ??= 75>>
<<case "shoes">>
<<set _cl.covers_slots.legwear ??= 25>>
<<case "legwear">>
<<set _cl.covers_slots.toenail_polish ??= 75>>
/* mask covers nothing */
<</switch>>
<</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 6>>
<<set _item.rarity to 3>>
<<elseif _value gte 5>>
<<set _item.rarity to 2>>
<<elseif _value gte 4>>
<<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:-3, sub:1, int:0, fit:0, att:0},
formal: {fem:-2, sub:0, int:1, fit:0, att:0},
active: {fem:-1, sub:0, int:0, fit:1, att:0},
comfy: {fem:-1, sub:1, int:0, fit:0, att:0},
casual: {fem:0, sub:0, int:0, fit:1, att:0},
study: {fem:1, sub:0, int:1, fit:0, att:0},
party: {fem:1, sub:0, int:0, fit:0, att:1},
cute: {fem:2, sub:0, int:0, fit:0, att:1},
sexy: {fem:3, sub:0, int:0, fit:0, att:1},
lewd: {fem:3, 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:3},
black: {fem:-2},
nocolor: {fem:0},
blue: {fem:0},
brown: {fem:-1},
yellow: {fem:1},
cyan: {fem:1},
green: {fem:0},
white: {fem:1},
red: {fem:2},
multicolor: {fem:2},
gold: {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:2},
thick: {fem:-1},
baggy: {fem:-1},
loose: {fem:1},
transparent: {fem:1},
heels: {fem:2},
highheels: {fem:3},
fake: {fem:1},
skirt: {fem:3},
}>>
<<for _extra range _item.extra>>
<<set _fem += _extrapts?.[_extra]?.fem ?? 0>>
<</for>>
<<set _genpts to {
male: {fem: -1},
unisex: {fem: 1},
female: {fem: 4},
}>>
<<set _fem += _genpts[_item.gender]?.fem ?? 0>>
<<set _item.base_fem to Math.clamp(_fem, 0, 20)>>
<</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,
outerwear: 3,
}>><<set setup.action_cards to {
all_player: {
"take a break_m": new ActionCard({"name": "Take a Break", "power": "0", "rarity": "0", "suit": "refresh", "theme": "Smart", "stat1": "Stress-", "stat2": "Arousal+", }),
"take a break_m+": new ActionCard({"name": "Take a Break+", "power": "-4", "rarity": "1", "suit": "refresh", "theme": "Smart", "stat1": "Stress-", "stat2": "Stress-", "stat3": "Arousal+", descr_effects: [["add_refresh", 1]] }),
"clear mind_m": new ActionCard({"name": "Clear Mind", "power": "-5", "rarity": "2", "suit": "refresh", "theme": "Smart", "stat1": "Stress-", "stat2": "Arousal-", descr_effects: [["add_flow", 2]] }),
"clear mind_m+": new ActionCard({"name": "Clear Mind+", "power": "-8", "rarity": "3", "suit": "refresh", "theme": "Smart", "stat1": "Stress-", "stat3": "Arousal-", "effect_fn": "flow_addhandsize",}),
"apathy_m": new ActionCard({"name": "Apathy", "power": "-1", "rarity": "2", "suit": "refresh", "theme": "Ditz", "stat1": "Arousal-", "stat2": "Stress+", descr_effects: [["add_drain", 1]]}),
"apathy_m+": new ActionCard({"name": "Apathy+", "power": "-2", "rarity": "3", "suit": "refresh", "theme": "Ditz", "stat1": "Arousal-", "stat2": "Arousal-", "stat3": "Stress+", "effect_fn": "drain_addarousal", }),
"lolipop_m": new ActionCard({"name": "Lolipop", "power": "0", "rarity": "0", "suit": "refresh", "theme": "Ditz", "stat1": "Stress-", "stat2": "Arousal+", }),
"lolipop_m+": new ActionCard({"name": "Lolipop+", "power": "-5", "rarity": "1", "suit": "refresh", "theme": "Ditz", "stat1": "Stress-", "stat2": "Stress-", "stat3": "Arousal+", "card+bott": "1", }),
"talk_m": new ActionCard({"name": "Talk", "power": "2", "rarity": "1", "suit": "flow", "theme": "Smart", "stat1": "Stress+", "stat2": "Arousal+", "card+bott": "1", }),
"talk_m+": new ActionCard({"name": "Talk+", "power": "2", "rarity": "2", "suit": "flow", "theme": "Smart", "stat1": "Stress+", "stat2": "Stress+", "stat3": "Arousal+", "card+bott": "2", }),
"calculated move_m": new ActionCard({"name": "Calculated Move", "power": "0", "rarity": "1", "suit": "flow", "theme": "Smart", "stat1": "Stress+", descr_effects: [["add_power_to_next", 4]]}),
"calculated move_m+": new ActionCard({"name": "Calculated Move+", "power": "1", "rarity": "2", "suit": "flow", "theme": "Smart", "stat1": "Stress+", "effect_fn": "next_addthis", }),
"pay attention_m": new ActionCard({"name": "Pay Attention", "power": "2", "rarity": "0", "suit": "flow", "theme": "Smart", "stat1": "Stress+", descr_effects: [["spawn_smart_tokens", 1]]}),
"pay attention_m+": new ActionCard({"name": "Pay Attention+", "power": "3", "rarity": "1", "suit": "flow", "theme": "Smart", "stat1": "Stress+", "stat2": "Stress+", descr_effects: [["spawn_smart_tokens", 2]]}),
"work hard_m": new ActionCard({"name": "Work Hard", "power": "0", "rarity": "2", "suit": "flow", "theme": "Smart", "stat1": "Stress+", "stat2": "Stress+", pre_play_effects: [["multiply_this_power"]]}),
"work hard_m+": new ActionCard({"name": "Work Hard+", "power": "0", "rarity": "3", "suit": "flow", "theme": "Smart", "stat1": "Stress+", "stat2": "Stress+", "stat3": "Stress+", pre_play_effects: [["multiply_this_power", 2]]}),
"play dumb_m": new ActionCard({"name": "Play Dumb", "power": "1", "rarity": "0", "suit": "flow", "theme": "Ditz", "stat1": "Arousal-", "stat2": "Stress+", descr_effects: [["add_drain", -2], ["add_flow", 3]]}),
"play dumb_m+": new ActionCard({"name": "Play Dumb+", "power": "1", "rarity": "1", "suit": "flow", "theme": "Ditz", "stat1": "Arousal-", "stat2": "Stress+", descr_effects: [["add_drain", -4], ["add_flow", 6]]}),
"cheer up_m": new ActionCard({"name": "Cheer Up", "power": "-1", "rarity": "0", "suit": "flow", "theme": "Ditz", "stat1": "Stress-", "stat2": "Arousal+", descr_effects: [["add_power_to_first", 2]]}),
"cheer up_m+": new ActionCard({"name": "Cheer Up+", "power": "-3", "rarity": "1", "suit": "flow", "theme": "Ditz", "stat1": "Stress-", "stat2": "Arousal+", descr_effects: [["add_power_to_first", 4]]}),
"no time to think_m": new ActionCard({"name": "No Time to Think", "power": "1", "rarity": "0", "suit": "drain", "theme": "Smart", "stat1": "Arousal-", "stat2": "Stress+", descr_effects: [["add_drain", 3], ["add_flow", -2]]}),
"no time to think_m+":new ActionCard({"name": "No Time to Think+", "power": "1", "rarity": "1", "suit": "drain", "theme": "Smart", "stat1": "Arousal-", "stat2": "Stress+", descr_effects: [["add_drain", 6], ["add_flow", -3]]}),
"complain_m": new ActionCard({"name": "Complain", "power": "2", "rarity": "0", "suit": "drain", "theme": "Smart", "stat1": "Arousal-", "stat2": "Stress+", }),
"complain_m+": new ActionCard({"name": "Complain+", "power": "1", "rarity": "1", "suit": "drain", "theme": "Smart", "stat1": "Arousal-", "stat2": "Arousal-", "stat3": "Stress+", }),
"lip biting_m": new ActionCard({"name": "Lip Biting", "power": "2", "rarity": "1", "suit": "drain", "theme": "Ditz", "stat1": "Arousal+", "stat2": "Stress+", "card+bott": "1", }),
"lip biting_m+": new ActionCard({"name": "Lip Biting+", "power": "2", "rarity": "2", "suit": "drain", "theme": "Ditz", "stat1": "Arousal+", "stat2": "Stress+", "stat3": "Stress+", "card+bott": "2", }),
"loose pants_m": new ActionCard({"name": "Loose Pants", "power": "2", "rarity": "1", "suit": "drain", "theme": "Ditz", "stat1": "Arousal+", descr_effects: [["spawn_ditz_tokens", 1]] }),
"loose pants_m+": new ActionCard({"name": "Loose Pants+", "power": "3", "rarity": "2", "suit": "drain", "theme": "Ditz", "stat1": "Arousal+", "stat2": "Arousal+", descr_effects: [["spawn_ditz_tokens", 2]] }),
"high five_m": new ActionCard({"name": "High Five", "power": "1", "rarity": "2", "suit": "drain", "theme": "Ditz", "stat1": "Stress-", "stat2": "Arousal+", descr_effects: [["add_drain", 1]] }),
"high five_m+": new ActionCard({"name": "High Five+", "power": "-3", "rarity": "3", "suit": "drain", "theme": "Ditz", "stat1": "Stress-", "stat2": "Arousal+", "stat3": "Arousal+", "effect_fn": "drain_addhandsize", }),
"make a scene_m": new ActionCard({"name": "Make a Scene", "power": "-1", "rarity": "2", "suit": "drain", "theme": "Ditz", "stat1": "Arousal+", "stat2": "Arousal+", descr_effects: [["trigger_drain_if_good", 2]]}),
"make a scene_m+": new ActionCard({"name": "Make a Scene+", "power": "-1", "rarity": "3", "suit": "drain", "theme": "Ditz", "stat1": "Arousal+", "stat2": "Arousal+", "stat3": "Arousal+", descr_effects: [["trigger_drain_if_good", 3]]}),
"hug_m": new ActionCard({"name": "Hug", "power": "0", "rarity": "1", "suit": "burst", "theme": "Smart", "stat1": "Stress-", "stat2": "Arousal+", "stat3": "Arousal+", "card+bott": "1", }),
"hug_m+": new ActionCard({"name": "Hug+", "power": "-1", "rarity": "2", "suit": "burst", "theme": "Smart", "stat1": "Stress-", "stat2": "Arousal+", "card+bott": "1", }),
"respite_m": new ActionCard({"name": "Respite", "power": "-3", "rarity": "1", "suit": "refresh", "theme": "Fitness", "stat1": "Stress-", "effect_fn": "burst_keep", }),
"respite_m+": new ActionCard({"name": "Respite+", "power": "-4", "rarity": "2", "suit": "refresh", "theme": "Fitness", "stat1": "Stress-", "stat2": "Arousal-", "effect_fn": "burst_keep", }),
"deep breath_m": new ActionCard({"name": "Deep Breath", "power": "-4", "rarity": "0", "suit": "refresh", "theme": "Fitness", "stat1": "Stress-", "stat2": "Stress-", tfs: {fem: "deep breath_f"}, }),
"deep breath_m+": new ActionCard({"name": "Deep Breath+", "power": "-6", "rarity": "1", "suit": "refresh", "theme": "Fitness", "stat1": "Stress-", "stat2": "Stress-", "effect_fn": "burst_keep", descr_effects: [["add_drain", 1], ["add_flow", 1]], tfs: {fem: "deep breath_f+"}, }),
"deep breath_f": new ActionCard({"name": "Deep Breath", "power": "-4", "rarity": "0", "suit": "refresh", "theme": "Fitness", "stat1": "Arousal-", "stat2": "Arousal-", "is_fem": "true", tfs: {masc: "deep breath_m"}, }),
"deep breath_f+": new ActionCard({"name": "Deep Breath+", "power": "-6", "rarity": "1", "suit": "refresh", "theme": "Fitness", "stat1": "Arousal-", "stat2": "Arousal-", "effect_fn": "burst_keep", descr_effects: [["add_drain", 1], ["add_flow", 1]], "is_fem": "true", tfs: {masc: "deep breath_m+"}, }),
"get massage_m": new ActionCard({"name": "Get Massage", "power": "3", "rarity": "1", "suit": "flow", "theme": "Fitness", "stat1": "Stress-", "stat2": "Arousal+", "stat3": "Arousal+", descr_effects: [["add_flow", 1]] }),
"get massage_m+": new ActionCard({"name": "Get Massage+", "power": "3", "rarity": "2", "suit": "flow", "theme": "Fitness", "stat1": "Stress-", "stat2": "Arousal+", "stat3": "Arousal+", "effect_fn": "flow_rmvstress", descr_effects: [["add_flow", 5]] }),
"stretching_m": new ActionCard({"name": "Stretching", "power": "0", "rarity": "2", "suit": "drain", "theme": "Fitness", "stat1": "Stress+", "stat2": "Arousal+", descr_effects: [["draw_drain", 5]] }),
"stretching_m+": new ActionCard({"name": "Stretching+", "power": "-3", "rarity": "3", "suit": "drain", "theme": "Fitness", "stat1": "Stress+", "stat2": "Arousal+", descr_effects: [["mult_drain", 2], ["add_flow", -4]] }),
"special move_m": new ActionCard({"name": "Special Move", "power": "0", "rarity": "2", "suit": "burst", "theme": "Fitness", "stat1": "Arousal-", "stat2": "Stress+", "stat3": "Stress+", descr_effects: [["add_burst", 1]]}),
"special move_m+": new ActionCard({"name": "Special Move+", "power": "-2", "rarity": "3", "suit": "burst", "theme": "Fitness", "stat1": "Arousal-", "stat2": "Stress+", "effect_fn": "burst_addstress", }),
"toned legs_m": new ActionCard({"name": "Toned Legs", "power": "0", "rarity": "2", "suit": "burst", "theme": "Fitness", "stat1": "Arousal+", descr_effects: [["spawn_fitness_tokens", 1]] }),
"toned legs_m+": new ActionCard({"name": "Toned Legs+", "power": "0", "rarity": "3", "suit": "burst", "theme": "Fitness", "stat1": "Arousal+", "stat2": "Stress+", descr_effects: [["spawn_fitness_tokens", 2]] }),
"smart thought_m": new ActionCard({"name": "Smart Thought", "power": "0", "rarity": "0", "suit": "token", "theme": "Smart", descr_effects: [["add_mod_to_hand", 1], ["add_flow", -2]]}),
"wise thought_m": new ActionCard({"name": "Wise Thought", "power": "0", "rarity": "0", "suit": "token", "theme": "Smart", "stat1": "Stress+", "stat2": "Stress+", descr_effects: [["trigger_flow_if_good"]]}),
"ditzy thought_m": new ActionCard({"name": "Ditzy Thought", "power": "-2", "rarity": "0", "suit": "token", "theme": "Ditz", "stat1": "Arousal+", descr_effects: [["trigger_drain_if_good"]]}),
"flex muscles_m": new ActionCard({"name": "Flex Muscles", "power": "1", "rarity": "0", "suit": "token", "theme": "Fitness", "stat1": "Stress+", "effect_fn": "burst_keep", }),
"seeing things_f": new ActionCard({"name": "Seeing Things", "power": "0", "rarity": "2", "gender": "Female", "suit": "status", "theme": "Ditz", "stat1": "TF+", "stat2": "Stress+", "stat3": "Arousal+", descr_effects: [["add_flow", 8], ["draw_back", 1]] }),
"unusual gift_f": new ActionCard({"name": "Unusual Gift", "power": "0", "rarity": "2", "gender": "Female", "suit": "status", "theme": "Ditz", "stat1": "Identity+", "stat2": "Stress+", "stat3": "Arousal+", descr_effects: [["add_drain", 8], ["draw_back", 1]] }),
"embarrassed_f": new ActionCard({"name": "Embarrassed", "power": "0", "rarity": "2", "gender": "Female", "suit": "status", "theme": "Ditz", "stat1": "Arousal+", "stat2": "Stress+", "stat3": "Identity+", descr_effects: [["emb_id"],], "card+bott": "1", }),
"embarrassed_tf": new ActionCard({"name": "Embarrassed", img: "embarrassed_f_b.jpg", "power": "0", "rarity": "2", "gender": "Female", "suit": "status", "theme": "Ditz", "stat1": "Arousal+", "stat2": "Stress+", "stat3": "TF+", descr_effects: [["emb_tf"],], "card+bott": "1", }),
"feminization_f": new ActionCard({"name": "Feminization", "power": "0", "rarity": "2", "gender": "Female", "suit": "status", "theme": "Ditz", "stat1": "Arousal+", "stat2": "TF+", "stat3": "Identity+", descr_effects: [["feminization"], ["add_refresh", 3]], }),
},
all_enemy: {
"arousal suppressants_f": new ActionCard({"name": "Arousal Suppressants", "power": "0", "rarity": "2", "gender": "Female", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", "stat2": "TF+", pre_play_effects: [["add_turn_power_times_arousal", -2]], descr_effects: [["add_arousal", -5]]}),
"relaxation chair_f": new ActionCard({"name": "Relaxation Chair", "power": "0", "rarity": "2", "gender": "Female", "suit": "enemy", "theme": "Smart", "stat1": "Energy-", "stat2": "Identity+", pre_play_effects: [["add_turn_power_times_stress", -2]], descr_effects: [["add_stress", -5]]}),
"not alone_m": new ActionCard({"name": "Not Alone", "power": "0", "rarity": "1", "gender": "Male", "suit": "enemy", "theme": "Smart", "stat1": "Energy-", pre_play_effects: [["add_turn_power_times_stress", -2]], "effect_fn": "stress_reset_effect", }),
"bigger than mine_m": new ActionCard({"name": "Bigger than Mine", "power": "0", "rarity": "1", "gender": "Male", "suit": "enemy", "theme": "Smart", "effect_fn": "stress_reset_effect", }),
"post workout fuel_m": new ActionCard({"name": "Post Workout Fuel", "power": "0", "rarity": "3", "gender": "Male", "suit": "enemy", "theme": "Smart", "effect_fn": "arousal_reset_effect", }),
"suck some milk_m": new ActionCard({"name": "Suck some Milk", "power": "0", "rarity": "3", "gender": "Male", "suit": "enemy", "theme": "Smart", "effect_fn": "arousal_reset_effect", }),
"exhausted_m": new ActionCard({"name": "Exhausted", "power": "0", "rarity": "1", "gender": "Male", "suit": "enemy", "theme": "Smart", descr_effects: [["add_stress", -5]]}),
"spread wide_m": new ActionCard({"name": "Spread Wide", "power": "0", "rarity": "3", "gender": "Male", "suit": "enemy", "theme": "Smart", descr_effects: [["add_arousal", -10], ["add_stress", -5]]}),
"lick or suck_f": new ActionCard({"name": "Lick or Suck", "power": "0", "rarity": "2", "gender": "Female", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", "effect_fn": "stress_reset_effect", }),
"flirt gone wild_f": new ActionCard({"name": "Flirt gone Wild", "power": "0", "rarity": "2", "gender": "Female", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", "stat2": "Energy-", pre_play_effects: [["add_turn_power_times_arousal", 2]], descr_effects: [["add_arousal", -10], ["add_stress", -5]]}),
"trick or treat_m": new ActionCard({"name": "Trick or Treat", "power": "0", "rarity": "3", "gender": "Male", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", "effect_fn": "stress_reset_effect", }),
"rabbit hole_m": new ActionCard({"name": "Rabbit Hole", "power": "0", "rarity": "3", "gender": "Male", "suit": "enemy", "theme": "Ditz", descr_effects: [["add_arousal", -10], ["add_stress", -5]]}),
"big orange pumpkin_m": new ActionCard({"name": "Big Orange Pumpkin", "power": "0", "rarity": "3", "gender": "Male", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", "effect_fn": "stress_reset_effect", }),
"deep magic_m": new ActionCard({"name": "Deep Magic", "power": "0", "rarity": "3", "gender": "Male", "suit": "enemy", "theme": "Ditz", descr_effects: [["add_arousal", -10], ["add_stress", -5]]}),
"blue spell_m": new ActionCard({"name": "Blue Spell", "power": "0", "rarity": "1", "gender": "Male", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", descr_effects: [["add_arousal", -4], ["add_stress", 2]] }),
"pink spell_f": new ActionCard({"name": "Pink Spell", "power": "0", "rarity": "2", "gender": "Female", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", descr_effects: [["add_arousal", 2], ["add_stress", -4]] }),
"eehh_m": new ActionCard({"name": "Eehh?!", "power": "0", "rarity": "3", "gender": "Male", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", descr_effects: [["add_arousal", -2], ["add_stress", 2]]}),
"cute little things_f": new ActionCard({"name": "Cute Little Things", "power": "0", "rarity": "3", "gender": "Female", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", descr_effects: [["add_arousal", -2], ["add_stress", 4]] }),
"size check_f": new ActionCard({"name": "Size Check", "power": "0", "rarity": "2", "gender": "Female", "suit": "enemy", "theme": "Ditz", descr_effects: [["add_arousal", 2], ["add_stress", 2]] }),
"creamy inside_f": new ActionCard({"name": "Creamy Inside", "power": "0", "rarity": "2", "gender": "Female", "suit": "enemy", "theme": "Ditz", "stat1": "Energy+", descr_effects: [["add_arousal", 2], ["add_stress", 4]] }),
"suggestive look_m": new ActionCard({"name": "Suggestive Look", "power": "0", "rarity": "1", "gender": "Male", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", descr_effects: [["add_arousal", 2], ["add_stress", -2]] }),
"my turn_m": new ActionCard({"name": "My Turn", "power": "0", "rarity": "1", "gender": "Male", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", descr_effects: [["add_arousal", 4], ["add_stress", -4]] }),
"all in_m": new ActionCard({"name": "All In", "power": "0", "rarity": "3", "gender": "Male", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", "stat2": "Energy-", descr_effects: [["add_arousal", 2], ["add_stress", -10]] }),
"always together_f": new ActionCard({"name": "Always Together", "power": "0", "rarity": "2", "gender": "Female", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", "stat2": "Energy-", "stat3": "Energy-", descr_effects: [["add_arousal", -8], ["add_stress", -8]] }),
"what is it_f": new ActionCard({"name": "What is It", "power": "0", "rarity": "3", "gender": "Female", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", descr_effects: [["add_arousal", -2], ["add_stress", 2]] }),
"the best sits_f": new ActionCard({"name": "The Best Sits", "power": "0", "rarity": "2", "gender": "Female", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", descr_effects: [["add_arousal", -2], ["add_stress", 4]] }),
"just the tip_f": new ActionCard({"name": "Just the Tip", "power": "0", "rarity": "2", "gender": "Female", "suit": "enemy", "theme": "Ditz", descr_effects: [["add_arousal", 2], ["add_stress", 2]] }),
"good boy_f": new ActionCard({"name": "Good Boy", "power": "0", "rarity": "3", "gender": "Female", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", descr_effects: [["add_arousal", -8], ["add_stress", 4]] }),
"high desire_m": new ActionCard({"name": "High Desire", "power": "0", "rarity": "1", "gender": "Male", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", descr_effects: [["add_arousal", 2], ["add_stress", -2]] }),
"just a lick_m": new ActionCard({"name": "Just a Lick", "power": "0", "rarity": "1", "gender": "Male", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", descr_effects: [["add_arousal", 4], ["add_stress", -4]] }),
"long way down_m": new ActionCard({"name": "Long Way Down", "power": "0", "rarity": "3", "gender": "Male", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", "stat2": "Energy-", descr_effects: [["add_arousal", 2], ["add_stress", -10]] }),
"salty outcum_m": new ActionCard({"name": "Salty Outcum", "power": "0", "rarity": "3", "gender": "Male", "suit": "enemy", "theme": "Ditz", "stat1": "Energy-", "stat2": "Energy-", descr_effects: [["add_arousal", -8], ["add_stress", -4]] }),
},
}>>
/* Gender flip every *male* player card & add them back to all_player
* (female cards are excluded; assumed to either be unique or manually def'd masc variant) */
<<set _all_player to setup.action_cards.all_player>>
<<for _id, _card range _all_player>>
<<set _card.id to _id>>
<<if not _card.is_fem>>
<<set _fid to _card.id.replace(/m(\+?)$/, "f$1")>>
<<if ndef _all_player[_fid]>>
<<set _fcard to clone(_card)>>
<<set _fcard.id to _fid>>
<<set _fcard.is_fem to true>>
/* let them TF into each other */
<<set _fcard.tfs.masc to _id>>
<<set _card.tfs.fem to _fid>>
<<set _all_player[_fid] to _fcard>>
<</if>>
<</if>>
<</for>>
<<for _id, _card range setup.action_cards.all_enemy>>
<<set _card.id to _id>>
<</for>>
/* Add upgrade paths by ID */
<<for _id, _card range setup.action_cards.all_player>>
<<if not _id.endsWith("+")>>
<<if def setup.action_cards.all_player[_id + "+"]>>
<<set _card.tfs.upgrade to _id + "+">>
<</if>>
<</if>>
<</for>>
/* hacks for "length" for debug screen */
<<run Object.defineProperty(_all_player, "length", {
get() { return Object.values(this).length; },
enumerable: false,
})>>
<<run Object.defineProperty(setup.action_cards.all_enemy, "length", {
get() { return Object.values(this).length; },
enumerable: false,
})>>
/* flat list categories */
<<set setup.action_cards.player_drops to Object.values(setup.action_cards.all_player)
.filter(c => not ["token", "neutral", "status"].includes(c.suit))>>
<<set setup.action_cards.player_token to Object.values(setup.action_cards.all_player)
.filter(c => c.suit === "token")>>
<<set setup.starter_deck to [
"complain_f",
"complain_m",
"lolipop_m",
"pay attention_f",
"pay attention_m",
"take a break_f"
].map(cid => setup.action_cards.all_player[cid]).sort(setup.card_name_compare)>>
<<set $player_deck to setup.starter_deck.map(card => clone(card).combat_reset())>>
/*
<<set setup.starting_deck_choices to {
burst: [0, 0, 0, 15, 6, 6, 4, 4],
drain: [21, 21, 25, 25, 6, 6, 17, 4],
flow: [19, 6, 8, 8, 0, 0, 4, 4],
balanced: [6, 6, 21, 0, 0, 17, 4, 4],
}>>
<<set setup.starting_deck_choices_f to {}>>
<<for _dk, _cids range setup.starting_deck_choices>>
<<set setup.starting_deck_choices[_dk] to
_cids.map(cid => setup.action_cards.all_player[cid]).sort(setup.card_name_compare)>>
<<set setup.starting_deck_choices_f[_dk] to setup.starting_deck_choices[_dk]
.map(card => card.get_gender_flipped_copy())>>
<</for>>
*/
<<set setup.id_to_enemy_card to function(id) {
return clone(setup.action_cards.all_enemy[id]).enemy_reset();
}>>/* different set of enemies for different loops, e.g. "Regular", "Halloween", etc. */
<<set setup.enemies to {
regular: [
{
name: "Lina",
target: "regular person",
color: "royalblue",
fg_img: "npc",
features: "casual sexy female",
max_progression: 6,
prog_thresholds: [60, 120, 180, 240, 320, 400, 500],
cutscenes: [
[5, "mc_elf_blow"],
[3, "mc_elf_oral"],
[0, null],
],
left_decks: [
["relaxation chair_f", ],
["exhausted_m", "relaxation chair_f", ],
["exhausted_m", "relaxation chair_f", ],
["exhausted_m", "the best sits_f", "relaxation chair_f", ],
["exhausted_m", "the best sits_f", "relaxation chair_f", ],
["exhausted_m", "the best sits_f", "just the tip_f", "relaxation chair_f", ],
["exhausted_m", "the best sits_f", "just the tip_f", "relaxation chair_f", ],
],
right_decks: [
["arousal suppressants_f" ],
["arousal suppressants_f", ],
["high desire_m", "arousal suppressants_f", ],
["high desire_m", "just a lick_m", "arousal suppressants_f", ],
["high desire_m", "just a lick_m", "suck some milk_m", "arousal suppressants_f", ],
["high desire_m", "just a lick_m", "suck some milk_m", "long way down_m", "arousal suppressants_f", ],
["high desire_m", "just a lick_m", "suck some milk_m", "long way down_m", "spread wide_m", "arousal suppressants_f", ],
],
},
{
name: "Meme Analyst Shift",
target: "meme job",
color: "mediumvioletred",
bg_img: "meme analyst_b.jpg",
left_decks: [["relaxation chair_f"]],
right_decks: [["arousal suppressants_f"]],
},
{
name: "Stylist",
target: "stylist encounter",
color: "chocolate",
fg_img: "auto",
features: "casual stylish male",
max_progression: 4,
prog_thresholds: [50, 150, 250],
img_ids: [0, 1, 1, 2, 3],
left_decks: [
[ "relaxation chair_f" ],
[ "relaxation chair_f" ],
[ "relaxation chair_f", "lick or suck_f" ],
[ "relaxation chair_f", "lick or suck_f" ],
[ "relaxation chair_f", "lick or suck_f" ],
],
right_decks: [
[ "arousal suppressants_f" ],
[ "arousal suppressants_f" ],
[ "arousal suppressants_f" ],
[ "arousal suppressants_f" ],
[ "arousal suppressants_f", "flirt gone wild_f" ],
],
},
{
name: "Shin",
target: "training encounter",
color: "purple",
fg_img: "npc",
features: "active modest femboy",
max_progression: 6,
prog_thresholds: [40, 80, 120, 180, 240, 320, 400],
cutscenes: [
[5, "mc_rudy_ride"],
[3, "mc_rudy_oral"],
[0, null],
],
left_decks: [
[ "relaxation chair_f" ],
[ "not alone_m", "relaxation chair_f" ],
[ "not alone_m", "relaxation chair_f" ],
[ "not alone_m", "bigger than mine_m", "relaxation chair_f" ],
[ "not alone_m", "bigger than mine_m", "relaxation chair_f" ],
[ "not alone_m", "bigger than mine_m", "size check_f", "relaxation chair_f" ],
[ "not alone_m", "bigger than mine_m", "size check_f", "creamy inside_f", "relaxation chair_f" ],
],
right_decks: [
[ "arousal suppressants_f" ],
[ "arousal suppressants_f" ],
[ "suggestive look_m", "arousal suppressants_f" ],
[ "suggestive look_m", "arousal suppressants_f" ],
[ "suggestive look_m", "post workout fuel_m", "arousal suppressants_f" ],
[ "suggestive look_m", "post workout fuel_m", "my turn_m", "arousal suppressants_f" ],
[ "suggestive look_m", "post workout fuel_m", "my turn_m", "all in_m", "arousal suppressants_f" ],
],
},
],
halloween: [
{
name: "Linumin the Wizard",
target: "final round",
color: "fuchsia",
fg_img: "auto",
features: "cosplay female",
power_rate: 4,
max_progression: 6,
prog_thresholds: [50, 100, 150, 200, 250],
img_ids: [0, 0, 0, 0, 0, 0, 0],
left_decks: [
[ "relaxation chair_f" ],
[ "relaxation chair_f" ],
[ "relaxation chair_f" ],
[ "relaxation chair_f" ],
[ "relaxation chair_f", "exhausted_m" ],
[ "relaxation chair_f", "exhausted_m" ],
[ "big orange pumpkin_m", "exhausted_m", "relaxation chair_f" ]
],
right_decks: [
[ "arousal suppressants_f" ],
[ "arousal suppressants_f" ],
[ "arousal suppressants_f", "suck some milk_m" ],
[ "arousal suppressants_f", "suck some milk_m" ],
[ "arousal suppressants_f", "suck some milk_m" ],
[ "arousal suppressants_f", "suck some milk_m" ],
[ "deep magic_m", "suck some milk_m", "spread wide_m", "arousal suppressants_f" ],
],
},
{
name: "Shinko the Rabbit",
target: "final round",
color: "royalblue",
fg_img: "auto",
features: "cosplay femboy",
power_rate: 4,
max_progression: 6,
prog_thresholds: [50, 100, 150, 200, 250],
img_ids: [0, 0, 0, 0, 0, 0, 0],
left_decks: [
[ "relaxation chair_f" ],
[ "relaxation chair_f" ],
[ "relaxation chair_f", "not alone_m" ],
[ "relaxation chair_f", "not alone_m" ],
[ "relaxation chair_f", "not alone_m", "bigger than mine_m" ],
[ "relaxation chair_f", "not alone_m", "bigger than mine_m" ],
[ "trick or treat_m", "not alone_m", "bigger than mine_m", "relaxation chair_f" ],
],
right_decks: [
[ "arousal suppressants_f" ],
[ "arousal suppressants_f" ],
[ "arousal suppressants_f" ],
[ "arousal suppressants_f" ],
[ "arousal suppressants_f" ],
[ "arousal suppressants_f" ],
[ "rabbit hole_m", "post workout fuel_m", "arousal suppressants_f" ],
],
},
],
xmas: [
{
name: "Rudy the Santa",
target: "final round",
color: "fuchsia",
fg_img: "auto",
features: "xmas femboy",
power_rate: 2,
max_progression: 9,
prog_thresholds: [40, 80, 120, 160, 200, 300, 400, 500, 700],
img_ids: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
left_decks: [
[ "blue spell_m" ],
[ "blue spell_m" ],
[ "blue spell_m" ],
[ "blue spell_m", "eehh_m" ],
[ "blue spell_m", "eehh_m" ],
[ "blue spell_m", "eehh_m", "cute little things_f" ],
[ "blue spell_m", "eehh_m", "cute little things_f", "size check_f" ],
[ "blue spell_m", "eehh_m", "cute little things_f", "size check_f", "creamy inside_f" ],
[ "blue spell_m", "eehh_m", "cute little things_f", "size check_f", "creamy inside_f" ],
[ "blue spell_m", "eehh_m", "cute little things_f", "size check_f", "creamy inside_f" ]
],
right_decks: [
[ "pink spell_f" ],
[ "pink spell_f" ],
[ "pink spell_f" ],
[ "pink spell_f" ],
[ "pink spell_f", "suggestive look_m" ],
[ "pink spell_f", "suggestive look_m" ],
[ "pink spell_f", "suggestive look_m", "my turn_m" ],
[ "pink spell_f", "suggestive look_m", "my turn_m", "all in_m" ],
[ "pink spell_f", "suggestive look_m", "my turn_m", "all in_m", "always together_f" ],
[ "pink spell_f", "suggestive look_m", "my turn_m", "all in_m", "always together_f" ]
]
},
{
name: "Sylphy the Elf",
target: "final round",
color: "fuchsia",
fg_img: "auto",
features: "xmas female",
power_rate: 2,
max_progression: 9,
prog_thresholds: [40, 80, 120, 160, 200, 300, 400, 500, 700],
img_ids: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
left_decks: [
[ "blue spell_m" ],
[ "blue spell_m" ],
[ "blue spell_m" ],
[ "blue spell_m", "what is it_f" ],
[ "blue spell_m", "what is it_f" ],
[ "blue spell_m", "what is it_f", "the best sits_f" ],
[ "blue spell_m", "what is it_f", "the best sits_f", "just the tip_f" ],
[ "blue spell_m", "what is it_f", "the best sits_f", "just the tip_f", "good boy_f" ],
[ "blue spell_m", "what is it_f", "the best sits_f", "just the tip_f", "good boy_f" ],
[ "blue spell_m", "what is it_f", "the best sits_f", "just the tip_f", "good boy_f" ]
],
right_decks: [
[ "pink spell_f" ],
[ "pink spell_f" ],
[ "pink spell_f" ],
[ "pink spell_f" ],
[ "pink spell_f", "high desire_m" ],
[ "pink spell_f", "high desire_m" ],
[ "pink spell_f", "high desire_m", "just a lick_m" ],
[ "pink spell_f", "high desire_m", "just a lick_m", "long way down_m" ],
[ "pink spell_f", "high desire_m", "just a lick_m", "long way down_m", "salty outcum_m" ],
[ "pink spell_f", "just a lick_m", "just a lick_m", "long way down_m", "salty outcum_m" ]
]
},
],
}>>
<<set $enemy_progression to {}>>
<<for _type, _grp range setup.enemies>>
<<set $enemy_progression[_type] to []>>
<<for _id, _enm range _grp>>
<<set _enm.id ??= _id>>
<<set _enm.type ??= _type>>
<<if _enm.fg_img is "auto">>
<<set _enm.bg_img ??= _enm.name.toLowerCase() + "_" + _enm.features.toLowerCase() + "_b.jpg">>
<<else>>
<<set _enm.bg_img ??= _enm.name.toLowerCase() + "_b.jpg">>
<</if>>
<<set _enm.max_progression ??= 0>>
<<set $enemy_progression[_type][_enm.id] to 0>>
<<set _enm.power_rate ??= 1>> /* TODO already set by default in battle precalc, remove? */
<</for>>
<</for>>
/* TODO set 'baseline' NPC items... */
<<set $npc_items to {
regular: [
new NPCEquipment({
model: "lina_shy",
accessory: setup.npc_items.lina_shy.accessory[1],
bottom: setup.npc_items.lina_shy.bottom[1],
bra: setup.npc_items.lina_shy.bra[1],
head: setup.npc_items.lina_shy.head[0],
legwear: setup.npc_items.lina_shy.legwear[0],
shoes: setup.npc_items.lina_shy.shoes[1],
top: setup.npc_items.lina_shy.top[1],
undies: setup.npc_items.lina_shy.undies[1],
}),
null,
null,
new NPCEquipment({
model: "shin_cheerful",
accessory: setup.npc_items.shin_cheerful.accessory[1],
bottom: setup.npc_items.shin_cheerful.bottom[1],
bra: setup.npc_items.shin_cheerful.bra[0],
hair_back: setup.npc_items.shin_cheerful.hair_back[0],
hair_front: setup.npc_items.shin_cheerful.hair_front[0],
head: setup.npc_items.shin_cheerful.head[0],
legwear: setup.npc_items.shin_cheerful.legwear[0],
shoes: setup.npc_items.shin_cheerful.shoes[1],
top: setup.npc_items.shin_cheerful.top[1],
undies: setup.npc_items.shin_cheerful.undies[1],
}),
],
}>>
<<set setup.difficulties to [
{
value: 1,
text: "Very Easy",
color: "green",
},
{
value: 2,
text: "Easy",
color: "seagreen",
},
{
value: 3,
text: "Normal",
color: "darkkhaki",
},
{
value: 4,
text: "Hard",
color: "chocolate",
},
{
value: 5,
text: "Very Hard",
color: "darkred",
},
]>>/* all of the "body" slots are covered automatically by PlayerEquipment */
<<set $player_equipment to new PlayerEquipment({
hairstyle: setup.all_styles.hairstyle[3],
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[4],
bra: setup.all_clothes.bra[0],
legwear: setup.all_clothes.legwear[3],
mask: setup.all_clothes.mask[0],
top: setup.all_clothes.top[78],
shoes: setup.all_clothes.shoes[23],
bottom: setup.all_clothes.bottom[5],
outerwear: setup.all_clothes.outerwear[0],
})>>
<<set $player_perm_equip to clone($player_equipment)>>
<<set $player_stats to new PlayerStats()>>
<<set $inv to new PlayerInventory()>>
<<set $effects to []>>
<<set $combat_stats to {
drain_base: 0,
drain_per_card: 1,
drain_decay: 2,
drain_min: -99,
flow_base: 0,
flow_per_card: 1,
flow_decay: 2,
flow_min: -99,
burst_base: 0,
burst_per_card: 1,
refresh_base: 2,
refresh_per_card: 1,
refresh_min: 1
}>><<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]]>>
<<raw_statbar _wis_icon _wis_stat>>
<</widget>>
<<widget "raw_statbar">>
/* 0: icon + CSS class (statbar-)
* 1: value */
<<set _wis_icon to _args[0]>>
<<set _wis_stat to _args[1]>>
<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), -99, 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 "effect_stats">>
<div class="grid4col" style="margin: auto;">
<<for _wis_ce range setup.card_effects>>
<<statnum _wis_ce $bat_effects>>
<</for>>
/*<<statnum "tf">>*/
</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 _layer gte 3>>
/* outerwear */
<img @src='"img2/char/clothes/outerwear/" + _char.outerwear.name + "/" + "".concat(... _char.outerwear.colors) + "/b" + _char.body.boobs + "h" + _char.body.hips + "w" + _char.body.waist + "s" + _char.body.shoulders + _svg'>
<</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">
/*L:_weq_card.lewd;
<<if Object.keys(_weq_card.covers_slots).length > 0>>
C: <<print JSON.stringify(_weq_card.covers_slots)>>
<</if>>*/
</div>
<img @src='"img2/gear/" + _rarity_text + ".svg"' class="equipgridrarity">
<span class="equipgridfem">
<<set _color to "equipgridfemtext">>
<<if _fem gte $player_equipment[_weq_card.place].fem ?? 5>>
<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">
<<set _wac_theme to "">>
<<if _wac_card.theme isnot "">>
<<set _wac_theme to "?" + _wac_card.theme.toLowerCase()>>
<</if>>
<span class="cardgridtitle"><<= _wac_theme>> _wac_card.name</span>
/*<span class="cardgridcost">
<<if setup.card_effects.includes(_wac_card.suit)>>
<img @src='"img2/icons/" + _wac_card.suit + ".svg"'>
<<elseif _wac_card.suit === "enemy">>
<img src="img2/icons/corruption.svg"> TODO placeholder image
<</if>>
guess this could be removed...
</span>*/
</div>
<<if _wac_card.suit !== "neutral">>
<img class="cardgrid-suit" @src='"img2/actions/" + _wac_card.suit + ".svg"'>
<</if>>
<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">
<<set _wac_gender to "male.svg">>
<<if _wac_card.is_fem>>
<<set _wac_gender to "female.svg">>
<</if>>
<img class="cardgridbg" @src='"img2/actions/" + _wac_gender'>
<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>>
<<for _type, _qty range _wac_card.stat_effects>>
<<for _i = 0; _i < Math.abs(_qty); ++_i>>
<span class="cardgridicon">
<img src="img2/actions/status1.svg">
<<set _wac_is_bad to _qty gt 0>>
/*if setup.skill_stats.includes(_type)*/
<<if _type is "energy">>
<<set _wac_is_bad to not _wac_is_bad>>
<</if>>
<<if _wac_is_bad>>
<img src="img2/actions/negative.svg">
<<else>>
<img src="img2/actions/positive.svg">
<</if>>
<<if _qty gt 0>>
<span class="cardgridicon-sign">+</span>
<</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>>
</div>
<div class="cardgriddesc">
<<print _wac_card.description>>
/*
<<if _wac_card.side_effects.draw_front gt 0>>
<<set _wac_pl to _wac_card.side_effects.draw_front gt 1 ? "cards" : "card">>
?card_front: draw _wac_card.side_effects.draw_front _wac_pl
<</if>>
<<if _wac_card.side_effects.draw_back gt 0>>
<<set _wac_pl to _wac_card.side_effects.draw_back gt 1 ? "cards" : "card">>
?card_back: draw _wac_card.side_effects.draw_back _wac_pl
<</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 playable_action>>
/* args[0] is an array of cards usable in action_card widget, typically $bat_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. */
<<set _wpa_played to _deck.splice(_idx, 1)[0].run_effect()>>
<<if not _wpa_played.self_destruct>>
<<set $bat_dump.push(_wpa_played)>>
<</if>>
<<if $enemy_power lte 0>>
<<set $battle_won to true>>
<<goto "battle end">>
<<else>>
<<replace "#battlediv">><<include "battle page incl">><</replace>>
<<replace "#sidebar-stats">><<include "sidebar stats">><</replace>>
<</if>>
<</link>>
<</capture>>
<</widget>>
<<widget "card_grid">>
/* first arg is an array of action cards. */
<div class="grid5col">
<<for _wcg_card range _args[0]>>
<<action_card _wcg_card>>
<</for>>
</div>
<<done>><<run setup.activate_tilt()>><</done>>
<</widget>>
<<widget "card_tf">>
/* args: 0, 1: two ActionCards, before & after. */
<div class="itemtfgrid">
<<action_card _args[0]>>
<img alt="has become" src="img2/icons/green_arrow.svg">
<<action_card _args[1]>>
</div>
<</widget>><div style="line-height: 1">
<h1 style="margin-top: 0">Icon Reference</h1>
</div>
<h2 style="line-height: 1">Story Statistics</h2>
<ul>
<li>?energy Energy. You have to stay awake somehow! Many actions use energy, and you'll need to rest on occasion to replenish it.</li>
<li>?money Money. Makes the world go 'round.</li>
<li>?bills Upkeep costs. If you want to be able to rest undisturbed, be ready to pay up.</li>
</ul>
<p>These stats relate to your femininity:</p>
<ul>
<li>?fem Femininity of your appearance. This is an average score from all of your cosmetics, clothing, and body parts.</li>
<li>?identity Identity. This represents how feminine your thoughts and actions are. Raises more slowly than other stats.<br>
Mismatching with your appearance leads to embarrassment...</li>
<li>?tf Transformation. Some events or cards may have transformative effects. Leads to body changes.</li>
</ul>
<p>These stats relate to other mental states:</p>
<ul>
<li>?stress Stress. Stay calm! You can't have more than 10 stress, which might prevent you from playing cards that add more stress.</li>
<li>?arousal Arousal. Stay focused! You can't have more than 10 arousal, which might prevent you from playing cards that add more arousal.</li>
<li>?productivity Productivity. Leads to more income while working and more difficult combat (everywhere).</li>
<li>?focus Focus. Mainly used while training to upgrade your action deck.</li>
<li>?compulsion Compulsion. Causes prices to rise while shopping. Shop 'til you drop?</li>
</ul>
<h2 style="line-height: 1">Card Effects</h2>
<ul>
<li>?enemy These cards end your turn in combat, triggering Refresh, Flow, and Drain effects afterward. These cards often manipulate Stress and Arousal and cost energy.</li>
<li>?refresh Refresh: At the end of your turn, you discard your entire hand and draw as many cards as your Refresh value. It resets to $combat_stats.refresh_base (the value can be changed during the game).</li>
<li>?flow Flow: after cards are drawn by Refresh, distribute a persistent power bonus equal to Flow between all the cards in hand (from left to right), then Flow decreases by half of its value.</li>
<li>?drain Drain: The enemy's health is reduced by the Drain value at the end of the turn, then Drain decreases by half of its value.</li>
<li>?burst Burst: Temporarily increases the power of the next card you play. Playing any other card type resets Burst to 0.</li>
<li>?token Token cards are destroyed when they are played or when combat ends; they do not recirculate into your deck.</li>
<li>?status Status cards can be played only once per battle, but are not deleted from your deck.</li>
<li>?card_back Draw X cards then place them at the end of your hand. (You can only choose to play a card between first 5 cards in your hand.)</li>
<li>?card_front Draw X cards into your hand to the front (so you can play it straight away)</li>
</ul>
<h2 style="line-height: 1">Rarity Icons</h2>
<p>Each card gives experience based on its rarity:</p>
<ul style="columns: 2">
<li>?feminine Feminine experience</li>
<li>?masculine Masculine experience</li>
</ul>
<p>These describe the relative value of equipment items and cards:</p>
<ul style="columns: 4">
<<for _i, _icon range setup.rarities.slice(0, 4)>>
<li><<print "?" + _icon>> _icon (<<print _i + 1>> XP) </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">>
<<run setup.replace_dialog("Inventory", "inv-dialog autoanim", "inventory dialog")>>
<</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", "outerwear"]>>
<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>
/*
<<set _seen_items to Array.from($player_equipment.seen_items).map(s => s.replaceAll("_", " ")).sort()>>
<p>You were last seen by $player_equipment.last_seen_by and they noticed your <<print _seen_items.slice(0, -1).join(", ")>>, and <<print _seen_items.at(-1)>>.</p>
<<set _stat_info to $player_equipment.stat_info>>
<p>If everything is seen, you would have fem: _stat_info.all.fem_avg and lewd: _stat_info.all.lewd_avg</p>
<p>If as few items as possible are seen, you would have fem: _stat_info.few.fem_avg and lewd: _stat_info.few.lewd_avg</p>
*/
/* 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">>
<<run setup.replace_dialog("Equipment", "inv-dialog autoanim", "player equipment page")>>
<</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>><<run $player_deck.sort(setup.card_name_compare)>>
/* TODO let player sort in other ways... */
<p>This is your deck of actions.</p>
<div id="deck-inv" class="grid5col">
<<for _card range $player_deck>>
<<action_card _card.combat_reset()>>
<</for>>
</div>
<<done>><<run setup.activate_tilt()>><</done>><<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>><<run $effects.sort(setup.effect_fns.sort_by_dur_asc)>>
<h2>Current Combined Effects</h2>
<h3>At the end of your turns in combat</h3>
<<set _cf to setup.effect_fns.get_combat($effects)>>
<ul>
<<for _eff range ["burst", "refresh", "drain", "flow"]>>
<<set _v to _cf[_eff] ?? 0>>
<<if _v gt 0>>
<<set _v = "+" + _v>>
<</if>>
<li>_v <<print "?" + _eff>></li>
<</for>>
</ul>
/*
<h3>Until they wear off</h3>
<ul>
<li>+<<print $effects.filter(e => e.type is "productivity").reduce((a, e) => a + e.value, 0)>> ?productivity</li>
</ul>
*/
<h2>Individual Effects</h2>
<<set _last_dur to -Infinity>>
<ul>
<<for _eff range $effects>>
<<if _eff.duration gt _last_dur>>
<h3>Until you rest _eff.duration more time<<print _eff.duration !== 1 ? "s" : "">></h3>
<<set _last_dur to _eff.duration>>
<</if>>
<li><<print setup.effect_fns.to_string(_eff)>></li>
<</for>>
</ul><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>All characters depicted in this work are over 21 years old.
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><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.</p>
<p class="largertext">Also, please try playing the game without cheating. Remember, there's a difficulty select;
if that isn't enough, please let us know what you like to tinker with on Discord (link in the sidebar) so we can balance the game better. Thanks!</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|clothes check][$back.push(passage())]]</li>
<li>[[Change your deck|cards check][$back.push(passage())]]</li>
<li>[[See all cards|action cards test][$back.push(passage())]]</li>
<li>[[Test combat|combat test][$back.push(passage())]]</li>
<li>[[See animations|anim list][$back.push(passage())]]</li>
<li>[[Reset 'temp' (unlock & reset lobby)|back][$temp = {}]]</li>
/*
<li>[[event test]]</li>
<li>[[event card 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>
<br>
<<statbar "stress">>
<<statbar "arousal">>
<div class="flexbuttons">
<<button "+5 ?money" "test starting page">><<set $player_stats.money+=5>><</button>>
<<button "+5 ?bills" "test starting page">><<set $player_stats.bills+=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 "+100 ?masculine" "test starting page">><<set $player_stats.masculine += 100>><</button>>
<<button "+100 ?feminine" "test starting page">><<set $player_stats.feminine += 100>><</button>>
<<button "+10 ?energy" "test starting page">><<set $player_stats.energy += 10>><</button>>
<<button "+1% ?identity" "test starting page">><<set $player_stats.identity += 1>><</button>>
<<button "+1 ?productivity" "test starting page">><<set $player_stats.productivity += 1>><</button>>
<<button "+1 ?focus" "test starting page">><<set $player_stats.focus += 1>><</button>>
<<button "+1 ?compulsion" "test starting page">><<set $player_stats.compulsion += 1>><</button>>
</div>
<div class="flexbuttons">
<<button "-5 ?money" "test starting page">><<set $player_stats.money-=5>><</button>>
<<button "-5 ?bills" "test starting page">><<set $player_stats.bills-=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 "-100 ?masculine" "test starting page">><<set $player_stats.masculine -= 100>><</button>>
<<button "-100 ?feminine" "test starting page">><<set $player_stats.feminine -= 100>><</button>>
<<button "-10 ?energy" "test starting page">><<set $player_stats.energy -= 10>><</button>>
<<button "-1% ?identity" "test starting page">><<set $player_stats.identity -= 1>><</button>>
<<button "-1 ?productivity" "test starting page">><<set $player_stats.productivity -= 1>><</button>>
<<button "-1 ?focus" "test starting page">><<set $player_stats.focus -= 1>><</button>>
<<button "-1 ?compulsion" "test starting page">><<set $player_stats.compulsion -= 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>*/<p class="largertext">You can change your character's appearance here. Beware minor spoilers for your character's look.</p>
<p class="largertext">Also, please keep in mind that this game was designed with a masculine start in mind; the game may be more difficult if you pick a lot of feminine items.</p>
<<button "Finalize character & start!" "back">><</button>>
<ul>
<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|clothes check][$back.push(passage())]]</li>
</ul><<set setup.animations to Object.keys(setup.spine_uris)
.filter(path => path.endsWith("skel"))
.map(p => p.slice(0, p.lastIndexOf(".")))>>
[[back]]
<ul>
<<for _anim range setup.animations>>
<<capture _anim>>
<li>[[_anim|play animation][$temp.anim to _anim; $back.push(passage())]]</li>
<</capture>>
<</for>>
</ul><<set _anim_idx to 0>>
<<set _sequences to setup.animation_sequences[$temp.anim] ?? []>>
<div id="anim"></div>
<div id="anim-controls" class="flexbuttons">
<<set _nxt to "Next (" + (_anim_idx + 1) + "/" + _sequences.length + ")">>
<<button _nxt>>
<<set _anim_idx += 1>>
<<if (def _main_anim) and _anim_idx lt _sequences.length>>
<<for _a range _sequences[_anim_idx]>>
<<run _main_anim.animationState.addAnimation(0, _a.name, _a.loop, 0)>>
<</for>>
<<if _anim_idx lt _sequences.length - 1>>
<<set _nxt to "Next (" + (_anim_idx + 1) + "/" + _sequences.length + ")">>
<<replace "#next-anim">>_nxt<</replace>>
<<else>>
<<replace "#next-anim">>Finish<</replace>>
<<remove "#skip-anim">>
<</if>>
<<else>>
<<goto "back">>
<</if>>
<</button>>
<button id="skip-anim" class="btn" style="background: gray" data-passage="back">Skip ⏭</button>
</div>
<<done>><<script>>
$('#anim-controls > button:nth-child(1)').prop("id", "next-anim");
setup.show_animation(variables().temp.anim);
<</script>><</done>><<button "Back" "back">><</button>>
<br>
<<for _key, _cards range setup.all_body>><<capture _key, _cards>>
<<set _key to _key.replaceAll("_", " ") + " (" + _cards.length + " items)" + "<br>">>
<<linkreplace _key>>
<<print _key>>
<div class="grid5col">
<<for _card range _cards>><<capture _card>>
<a data-passage=passage() data-setter="$player_equipment.replace_with(_card)">
<<equip_card _card>>
</a>
<</capture>><</for>>
</div>
/*<<done>><<run setup.activate_tilt()>><</done>>*/
<</linkreplace>>
<</capture>><</for>><<button "Back" "back">><</button>>
<br>
<<for _key, _cards range setup.all_styles>><<capture _key, _cards>>
<<set _key to _key.replaceAll("_", " ") + " (" + _cards.length + " items)" + "<br>">>
<<linkreplace _key>>
<<print _key>>
<div class="grid5col">
<<for _card range _cards>><<capture _card>>
<a data-passage=passage() data-setter="$player_equipment.replace_with(_card)">
<<equip_card _card>>
</a>
<</capture>><</for>>
</div>
/*<<done>><<run setup.activate_tilt()>><</done>>*/
<</linkreplace>>
<</capture>><</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 _key, _cards range setup.all_clothes>><<capture _key, _cards>>
<<set _key to _key.replaceAll("_", " ") + " (" + _cards.length + " items)" + "<br>">>
<<linkreplace _key>>
<<print _key>>
<div class="grid5col">
<<for _card range _cards>><<capture _card>>
<a data-passage=passage() data-setter="$player_equipment.replace_with(_card)">
<<equip_card _card>>
</a>
<</capture>><</for>>
</div>
/*<<done>><<run setup.activate_tilt()>><</done>>*/
<</linkreplace>>
<</capture>><</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.all_player>><<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.enemies.regular.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 _wcb_btn to _args[0]>>
<<set _wcb_disable to false>>
<<set _wcb_text to _wcb_btn.text>>
<<set _wcb_target to _wcb_btn.target>>
<<if def _wcb_btn.requirement>>
<<set _req to $player_stats[_wcb_btn.requirement]>>
<<if (def _wcb_btn.threshold) and (ndef _wcb_btn.low_threshold)>>
/* only regular threshold */
<<if not (_req >= _wcb_btn.threshold)>>
<<set _wcb_disable to true>>
<<set _wcb_text to _wcb_btn.disabled_text ?? _wcb_text>>
<</if>>
/* otherwise met, nothing to do */
<<elseif (ndef _wcb_btn.threshold) and (def _wcb_btn.low_threshold)>>
/* only low threshold */
<<if _req < _wcb_btn.low_threshold>>
<<set _wcb_target to _wcb_btn.low_wcb_target ?? _wcb_target>>
<<set _wcb_text to _wcb_btn.low_wcb_text ?? _wcb_text>>
<<else>>
<<set _wcb_disable to true>>
<<set _wcb_text to _wcb_btn.disabled_text ?? _wcb_text>>
<</if>>
<<elseif (def _wcb_btn.threshold) and (def _wcb_btn.low_threshold)>>
/* low & high threshold. Test high, then low... */
<<if not (_req >= _wcb_btn.threshold)>>
/* high not met, try low */
<<if _req < _wcb_btn.low_threshold>>
/* low met */
<<set _wcb_target to _wcb_btn.low_wcb_target ?? _wcb_target>>
<<set _wcb_text to _wcb_btn.low_wcb_text ?? _wcb_text>>
<<elseif def _wcb_btn.mid_wcb_target>>
/* neither met, but there's a fallback... */
<<set _wcb_target to _wcb_btn.mid_wcb_target>>
<<set _wcb_text to _wcb_btn.mid_wcb_text ?? _wcb_text>>
<<else>>
/* neither met, no fallback */
<<set _wcb_disable to true>>
<<set _wcb_text to _wcb_btn.disabled_text ?? _wcb_text>>
<</if>>
<</if>>
/* else high is OK, use regular text & target */
<</if>>
/* else both are missing, do nothing */
<<elseif _wcb_btn.disabled>>
<<set _wcb_text to _wcb_btn.disabled_text ?? _wcb_text>>
<</if>>
<<if _wcb_disable or _wcb_btn.disabled is true>>
<button class="btn" disabled>_wcb_text</button>
<<else>>
<<capture _wcb_btn>>
<button data-setter="_wcb_btn.side_effects?.()" @data-passage="_wcb_target" class="btn" @style='"background: " + _wcb_btn.color'>_wcb_text</button>
<</capture>>
<</if>>
<</widget>>
<<widget "event_choices">>
/* Args:
* 0: object for event_card widget
* 1: array of "button" objects for player choices, see choice_btn widget */
<div class="flexdown">
<div class="event-container js-tilt"><<event_card _args[0]>></div>
<<for _choice range _args[1]>>
<<choice_btn _choice>>
<</for>>
</div>
<</widget>>
<<widget "event_passage" container>>
/* Args:
* 0, 1: same as event_choices (card, choices)
* _contents: passage text */
<div class="grid2col">
<div><<print _contents>></div>
<<event_choices _args[0] _args[1]>>
</div>
<</widget>>
<<widget "choice_passage">>
/* Args:
* 0: Array of objects for event_card widget
* 1: Nested array of button objects for each choice
[[1st card choices], [2nd card choices], [etc]]
* both inputs should have the same length */
<<if _args[0].length !== _args[1].length>>
<p>choice_passage args didn't match up. this is a bug we can't recover from easily, sorry.</p>
<<else>>
<<set _wcp_gclass to "grid" + _args[0].length + "col">>
<div @class="_wcp_gclass">
<<for _wcp_i, _wcp_card range _args[0]>>
<<event_choices _wcp_card _args[1][_wcp_i]>>
<</for>>
</div>
<</if>>
<</widget>>
<<widget "event_card">>
/* First arg is an object with properties:
* title: of the card
* name: OPTIONAL fallback for 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
* Second arg is OPTIONAL enemy power
*/
<<set _wev_card to _args[0]>>
<<if ndef _wev_card>>
<div class="eventcard">
<img class="eventcard-static" style="background: orange" src="img2/events/static.svg">
<div class="eventcard-title">[Missing]</div>
<span style="grid-row: 2; font-size: 8cqh; margin: 1em;">
An event card belongs here but it was null or undefined.
Please save here and report this bug.
</span>
</div>
<<elseif _wev_card.is_equip_item>>
<<equip_card _wev_card>>
<<elseif _wev_card.is_action_card>>
<<action_card _wev_card.combat_reset() notilt>>
<<else>>
<div class="eventcard">
<<set _wev_card.color ??= "black">>
<img class="eventcard-static" @style='"background: " + _wev_card.color' src="img2/events/static.svg">
<div class="eventcard-title"><<print _wev_card.title ?? _wev_card.name>></div>
<<if _wev_card.fg_img isnot "npc">>
<img class="eventcard-art-bg" @src='"img2/events/images/" + _wev_card.bg_img.toLowerCase()'>
<<if def _wev_card.fg_img>>
<<if _wev_card.fg_img is "auto">>
/* card is assumed to be an enemy using linear progression system */
<<set _prog to _wev_card.img_ids[$enemy_progression[_wev_card.type][_wev_card.id] ?? 0]>>
<<set _wev_fg to `img2/events/images/${_wev_card.name.toLowerCase()}_${_wev_card.features}_${_prog}_f.png`>>
<<else>>
<<set _wev_fg to "img2/events/images/" + _wev_card.fg_img.toLowerCase()>>
<</if>>
<img class="eventcard-art" @src="_wev_fg">
<</if>>
<<else>>
/* card is assumed to be an enemy using NPC equipment system */
<<set _wev_equip to $npc_items[_wev_card.type][_wev_card.id]>>
<img class="eventcard-art-bg" @src='_wev_equip.bg.img_path'>
<div class="eventcard-art imgstack">
<<print _wev_equip.render()>>
</div>
<</if>>
<<if def _args[1]>>
<span class="enemyhptxt">_args[1]</span>
<</if>>
</div>
<</if>>
<</widget>>/* newer ver. is in lobby.twee */
<<if $back.at(-1) is "lobby">>
<<run $back.pop(); $back.push("autosave lobby");>>
<</if>>
/* maybe a better name is "loop event calc"? */
<<set $events to []>>
<<set _uniques to clone(setup.event_passages["unique-event"]).shuffle()>>
<<set _last_break to null>>
<<set _next_break to null>>
/* each "wave" should not have duplicates but repeats may happen otherwise */
<<for _i = 0; _i < 20; ++_i>>
<<set _wave to clone(setup.event_passages["six-five"]).shuffle()>>
/* TODO maybe something involving weighted randomness instead? */
/* alternate work/unique */
/*
<<if _i % 2 is 0>>
<<run _wave.push(setup.event_passages["work-event"].random())>>
<<else>>
<<run _wave.push(_uniques.pop())>>
<</if>>
<<run _wave.push(...setup.event_passages["event"].randomMany(4))>>
<<run _wave.shuffle()>>
/* at wave end, always have a 'break', but not the same break as prev. * /
<<for _next_break === _last_break>>
<<set _next_break to setup.event_passages["break-event"].random()>>
<</for>>
<<run _wave.push(_next_break)>>
<<set _last_break to _next_break>>
*/
<<run $events.push(... _wave)>>
<</for>>
<<set $player_perm_equip to clone($player_equipment)>>
<<run $player_equipment.reset_body_chg()>>
/* TODO passage to introduce TFs? */
<<goto "next event">><<set $temp to {}>>
/* TODO TF change "over time" */
<<set _chg_items to $player_equipment.recent_chg_body_items()>>
<<if _chg_items.length > 0>>
<<set $temp.chg_items to _chg_items>>
<<set _event to "recent body tf">>
/* (removed the leading < because sugarcube is weird with comments)
elseif $player_stats.identity gte 10 and (not $current_loop.max_identity)>>
<<set _event to "full identity">>
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>><<set $player_stats.stress to 0>>
<<set $player_stats.arousal to 0>>
<<set _ecard to {title: "Welcome Back", color: "green", bg_img: "Men Changing Room_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p>Welcome back from the $current_loop.type loop.</p>
<</event_passage>>
<<unset $current_loop>>
/* TODO maybe just <include> the lobby here? idk *//* 'back' should point to the lobby around here... */
<<unset $current_loop>>
<<set $loop_choices to []>>
<<set _old_equip to clone($player_equipment)>>
<<set $extra_body_restores to 0>>
<<set $player_stats.stress to 0>>
<<set $player_stats.arousal to 0>>
<<set $player_deck to setup.starter_deck.map(card => clone(card).combat_reset())>>
/* Rewind NPC progression by 1 step */
<<for _type, _progs range $enemy_progression>>
<<for _idx, _prog range _progs>>
<<set _progs[_idx] to Math.max(0, _prog - 1)>>
<</for>>
<</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 setup.ok_choices>>
<p>Welcome back.</p>
<p>Your connection with the loop weakened, so your progress with the people inside has regressed by a point:</p>
<h2 style="margin: auto;">Relationship Progress</h2>
<ul>
/* TODO w/ multiple loop types, use that choice here instead of 'regular' */
<<set _ltype to "regular">>
<<for _idx, _prog range $enemy_progression[_ltype]>>
<<set _enm to setup.enemies[_ltype][_idx]>>
<<if _enm.max_progression gt 0>>
<li>_enm.name: _prog/_enm.max_progression</li>
<</if>>
<</for>>
</ul>
<p>Unfortunately, you'll also need to start with a new deck of actions on your next loop, as well.</p>
<p>You've changed since you were last here:</p>
<div class="itemtfgrid">
<div class="imgstack">
<img src="img2/char/other/charbg.svg">
<<render_char 2 "" $player_perm_equip>>
</div>
<img alt="has transformed into" src="img2/icons/green_arrow.svg">
<div class="imgstack">
<img src="img2/char/other/charbg.svg">
<<render_char 2>>
</div>
</div>
/* TODO show overall TF, stats stuff? */
<</event_passage>>
/*<<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. Unfortunately, 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 the lobby|lobby]]
<</if>>/* go back, after discarding the top */
<<run $back.pop()>>
<<goto "back">><<set setup.npc_test ??= 0>>
<div class="grid2col">
/* <<set _ecard to {title: "test event", color: "blue", fg_img: "testnpc_f.png", bg_img: "testnpc_b.jpg"}>> */
<<set _ecard to setup.enemies.regular[setup.npc_test]>>
<div class="js-tilt">
<<event_card _ecard>>
</div>
<div class="grid2col">
[[lina|event card test][setup.npc_test = 0]]
[[shin|event card test][setup.npc_test = 3]]
[[randomize|event card test][$npc_items.regular[setup.npc_test].randomize()]]
[[back]]
</div>
</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>>
/* v6.5 events */<<if $events.length gt 0>>
<<set $temp.echoices to setup.enemies.regular.randomMany(2)>>
<<set $temp.difficulties to setup.difficulties.randomMany(2)>>
<<else>>
<<set _difficulties to [
{
value: 5,
text: "Very Hard",
color: "darkred",
},
{
value: 5,
text: "Very Hard",
color: "darkred",
},
]>>
<<set $temp.echoices to setup.enemies.halloween.randomMany(2)>>
<<set $temp.difficulties to _difficulties.randomMany(2)>>
<</if>>
<<goto "regular event decision">><<set _btns to []>>
<<set _sugarcube_capture_doesnt_work to function(i) {return function() {
$enemy = $temp.echoices[i];
}}>>
<<for _idx, _enemy range $temp.echoices>>
<<set _enemy.difficulty to $temp.difficulties[_idx].value>> /* TODO or store elsewhere? */
<<set _btns.push([{
text: $temp.difficulties[_idx].text + " " + _enemy.name,
target: _enemy.target,
side_effects: _sugarcube_capture_doesnt_work(_idx),
color: $temp.difficulties[_idx].color,
}])>>
<</for>>
<<choice_passage $temp.echoices _btns>><<set _target2 to $enemy.name + " win">>
<<set _path to "img2/npc/regular/"+$enemy.name.toLowerCase()+"_"+$enemy.features+"_bottom_0.jpg">>
<<set _choices to [
{
text: "Last Round!",
target: "battle pre calc",
side_effects: () => $back.push(_target2),
color: "green",
},
]>>
<div class="flexdown">
<p class="largertext" style="text-align: center;"><i>You can make the battle easier by undressing Shin or Lina.</i></p>
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img @src=_path class="eventimg">
</div><<if $battle_won>>
<<set _choices to [
{
text: "Ok",
target: "Linumin the Wizard win 2",
color: "green",
},
]>>
<div class="flexdown">
<p class="largertext" style="text-align: center;">$enemy.name was quite impressed by my actions, so she showed me very big pumpkin. From the bottom the view was especially astonishing.</p>
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/linumin the wizard_cosplay female_bottom_1.jpg' class="eventimg">
</div>
<<else>>
<<set _choices to [
{
text: "Ok",
target: "back",
color: "green",
},
]>>
<div class="flexdown">
<p class="largertext" style="text-align: center;">$enemy.name wasn't impressed by my actions.</p>
<br>
<p class="largertext" style="text-align: center;">i>You should try to undress her before the last round, so it would be easier to impress her.</i></p>
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/linumin the wizard_cosplay female_bottom_0.jpg' class="eventimg">
</div>
<</if>><<set _choices to [
{
text: "Her bedroom",
target: "Linumin the Wizard win 3",
color: "green",
},
]>>
<div class="flexdown">
<p class="largertext" style="text-align: center;">Then the Wizard removed her clothes and asked me if I'd like to check a special pumpkin in her bedroom. Hm, pumpkins...</p>
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/linumin the wizard_cosplay female_bottom_2.jpg' class="eventimg">
</div><p class="largertext" style="text-align: center;"><i>Happy Halloween! If you like the artworks, consider subscribing to [[Onebrushman|https://www.patreon.com/onebrushman]] not just to see the artworks or comics early, but also to find some extras.</i></p>
<<set _choices to [
{
text: "Ok",
target: "back",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/linumin the wizard_cosplay female_bottom_3.jpg' class="eventimg">
</div><<if $battle_won>>
<<set _choices to [
{
text: "Ok",
target: "Shinko the Rabbit win 2",
color: "green",
},
]>>
<div class="flexdown">
<p class="largertext" style="text-align: center;">$enemy.name was quite impressed by my actions, so he shared some sweets with me. I chose the bigger candy. It was warm and pulsing, though.</p>
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/shinko the rabbit_cosplay femboy_bottom_1.jpg' class="eventimg">
</div>
<<else>>
<<set _choices to [
{
text: "Ok",
target: "back",
color: "green",
},
]>>
<div class="flexdown">
<p class="largertext" style="text-align: center;">$enemy.name wasn't impressed by my actions.</p>
<br>
<p class="largertext" style="text-align: center;"><i>You should try to undress Shin before the last round, so it would be easier to impress him.</i></p>
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/shinko the rabbit_cosplay femboy_bottom_0.jpg' class="eventimg">
</div>
<</if>><<set _choices to [
{
text: "His bedroom",
target: "Shinko the Rabbit win 3",
color: "green",
},
]>>
<div class="flexdown">
<p class="largertext" style="text-align: center;">Then the Rabbit removed his clothes and said that there are more sweets in his bedroom. I like sweets...</p>
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/shinko the rabbit_cosplay femboy_bottom_2.jpg' class="eventimg">
</div><p class="largertext" style="text-align: center;"><i>Happy Halloween! If you like the artworks, consider subscribing to [[Onebrushman|https://www.patreon.com/onebrushman]] not just to see the artworks or comics early, but also to find some extras.</i></p>
<<set _choices to [
{
text: "Ok",
target: "back",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/shinko the rabbit_cosplay femboy_bottom_3.jpg' class="eventimg">
</div>/*precalc: <<set $enemy to clone(setup.enemies.regular.random())>>*/
<<set _choices to [
{
text: "Ask her nicely",
target: "battle pre calc",
side_effects: () => $back.push("post regular battle precalc"),
color: "darkred",
},
]>>
<<if $enemy_progression[$enemy.type][$enemy.id] lt 5 >>
<<run _choices.push(
{
disabled: $player_stats.masculine lt 150,
disabled_text: "Need 150 ?masculine",
text: "Convince her to undress - 150 ?masculine",
side_effects: () => {
$player_stats.masculine -= 150;
$back.push("post regular battle precalc");
$back.push("battle end");
},
target: "npc progression",
color: "darkblue",
}
)>>
<<else>>
<<run _choices.push(
{
disabled: $player_stats.masculine lt 300,
disabled_text: "Need 300 ?masculine",
text: "Ask her to remove panties - 300 ?masculine",
side_effects: () => {
$player_stats.masculine -= 300;
$back.push("post regular battle precalc");
$back.push("battle end");
},
target: "npc progression",
color: "darkblue",
}
)>>
<</if>>
<<event_passage $enemy _choices>>
<p>"Hey! Do you need clothes? I can share some, but only if you ask me niiice~!"</p>
<br>
<p>?new_card <i>You can get new clothes if you win.</i></p>
<br>
<i><p>You can skip the battle phase by spending ?masculine points. You should try it at least once :) </p>
<p>In the future updates this option will be blocked if you don't look masculine enough or don't follow some specific conditions.
Also, I will add more progressions for some characters (or for all of them). </p></i>
<</event_passage>><<if $battle_won>>
/* Award random clothing items to pick from. TODO fancier RNG */
<<set $temp.clothing to Object.values(setup.all_clothes).flat()
.filter(setup.item_not_worn)
.randomMany(3)>>
<<else>>
/* Remove a random worn item, starting with 'outerwear' */
<<set _slots to ["bottom", "top", "shoes", "mask"].shuffle()>>
<<set _under to ["undies", "bra", "legwear"].shuffle()>>
<<run _slots.push(... _under)>>
<<for _slot range _slots>>
<<if $player_equipment[_slot].id isnot 0>>
<<set $temp.clothing to $player_equipment.replace_with(setup.all_clothes[_slot][0])>>
<<break>>
<</if>>
<</for>>
<</if>>
<<goto "post regular battle">><<if $battle_won>>
<p class="largertext">$enemy.name gave me 3 items to choose from.</p>
<p class="largertext">"You can keep one of these. Only one!"</p>
<div class="grid3col" style="gap: 2em;">
<<for _idx, _card range $temp.clothing>><<capture _idx, _card>>
<div class="flexdown">
<<equip_card _card>>
<<button "Wear this" "back">>
/*<<run $player_equipment.wear_and_keep_old(_card)>>*/
<<run $player_equipment.replace_with(_card)>>
<</button>>
/*
<<button "Keep in inventory" "back">>
<<run $inv.push(_card)>>
<</button>>
*/
</div>
<</capture>><</for>>
</div>
<<else>>
<<set _ecard to {title: "You lost!", color: "brown", bg_img: "Passing Out_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<<if def $temp.clothing>>
<p class="largertext">$enemy.name stole some of your clothes!</p>
<<equip_tf $temp.clothing $player_equipment[$temp.clothing.place]>>
<<else>>
<p class="largertext">$enemy.name would have stolen some of your clothes, if you were wearing any...</p>
<</if>>
<</event_passage>>
<</if>><<set _choices to [
{
text: "Analyse Memes",
target: "battle pre calc",
side_effects: () => $back.push("meme job end"),
color: "darkred",
},
]>>
<<set _ecard to {title: "Meme Factory", color: "purple", bg_img: "meme analyst_b.jpg"}>>
<<event_passage _ecard _choices>>
<p>Meme Factory?? What kind of bizarre workplaces will I run into next...</p>
<p>There was a sign in the window advertising that they were always hiring temp analysts. The ad implied that being ditzier paid well, strange...</p>
<</event_passage>>/* no precalc since this is all deterministic */
<<set _theme_bonus to $player_deck.reduce((acc, card) => {
if(card.theme.toLowerCase() === "smart") {
return acc + 1;
} else if(card.theme.toLowerCase() === "ditz") {
return acc + 2;
} else {
return acc;
}
}, 0)>>
<<set _salary to 20 + _theme_bonus>>
<<if $battle_won>>
<<set _combats to $current_loop.combat_count ?? 0>>
<<set _diff to $enemy.difficulty - 1>>
/* each combat gives +0.5%, each diff gives +5% */
<<set $player_stats.money += Math.round(_salary * (1 + ((_combats / 200) + (_diff / 20))))>>
<<set _passage to "Well, that was interesting. I got a few laughs in, and while that was dumb, I feel oddly smarter, too? Regardless, I got paid " + _salary + " ?money, so that might be worth doing again.">>
<<else>>
<<set $player_stats.money -= _salary>>
<<set _passage to "I couldn't keep up with the endless stream of memes. I can't help but feel extra dumb for that... Oh, I lost " + _salary + " ?money too!">>
<</if>>
<<event_passage $enemy setup.ok_choices>>
<p>_passage</p>
<</event_passage>><<set _choices to [
{
text: "Prove yourself!",
target: "battle pre calc",
side_effects: () => $back.push("stylist battle precalc"),
color: "darkred",
},
]>>
<<if $enemy_progression[$enemy.type][$enemy.id] lt 3 >>
<<run _choices.push(
{
disabled: $player_stats.feminine lt 200,
disabled_text: "Need 200 ?feminine",
text: "Flirt with Stylist - 200 ?feminine",
side_effects: () => {
$player_stats.feminine -= 200;
$back.push("stylist battle precalc");
$back.push("battle end");
},
target: "npc progression",
color: "darkviolet",
}
)>>
<<else>>
<<run _choices.push(
{
disabled: $player_stats.feminine lt 400,
disabled_text: "Need 400 ?feminine",
text: "Seduce Stylist - 400 ?feminine",
side_effects: () => {
$player_stats.feminine -= 400;
$back.push("stylist battle precalc");
$back.push("battle end");
},
target: "npc progression",
color: "darkviolet",
}
)>>
<</if>>
<<event_passage $enemy _choices>>
<p>I wandered into a room resembling a salon. The only furnishing in the room was a lone chair.</p>
<p>"Oh, a new customer!" A guy walked in.</p>
<p>Seems like I can't proceed without playing my role. And I think Stylist noticed my doubts.</p>
<p>"If you think you look good enough - you need to prove that. Otherwise, I'll show you why people call me Stylist!"</p>
<br>
<p>?new_card <i>You can get new cosmetics if you win.</i></p>
<br>
<i><p>You can skip the battle phase by spending ?feminine points. You should try it at least once :) </p>
<p>In the future updates this option will be blocked if you don't look masculine enough or don't follow some specific conditions.
Also, I will add more progressions for some characters (or for all of them). </p></i>
<</event_passage>><<if $battle_won>>
/* no filter other than "not worn," allow 'removal' */
<<set _droplist to Object.values(setup.all_styles).flat().filter(setup.item_not_worn)>>
<<set $temp.choices to _droplist.randomMany(3)>>
<<else>>
/* filter "heavier" cosmetics */
<<set _droplist to Object.values(setup.all_styles).flat()
.filter(item => item.fem gt 8 and setup.item_not_worn(item))>>
/* and try to increase fem of cosmetics if possible */
<<set _gt_worn to _droplist.filter(item => item.fem gt $player_equipment[item.place].fem)>>
<<if _gt_worn.length gte 2>>
<<set _droplist to _gt_worn>>
<</if>>
<<set $temp.choices to _droplist.randomMany(2)>>
<</if>>
<<goto "stylist battle">><<if $battle_won>>
<p>"Ok, ok, you can leave. But if you're interested, I could still fix you up..." Stylist explained his ideas:</p>
<div class="grid3col" style="gap: 2em;">
<<for _card range $temp.choices>><<capture _card>>
<a data-passage="back" data-setter="$player_equipment.replace_with(_card)">
<<equip_card _card>>
</a>
<</capture>><</for>>
</div>
/* TODO consesquences, disabling...? */
<div class="flexbuttons">
<button class="btn btn-red" data-passage="back">Ignore these and move on</button>
</div>
<<else>>
<p>"Well, now relax and let the Stylist do his job!"</p>
<div class="grid2col" style="width: 75%; gap: 2em;">
<<for _card range $temp.choices>><<capture _card>>
<a data-passage="back" data-setter="$player_equipment.replace_with(_card)">
<<equip_card _card>>
</a>
<</capture>><</for>>
</div>
<</if>>/* TODO choice to upgrade "for free" but with side effect? */
<<set _choices to [
{
text: "Train!",
target: "battle pre calc",
side_effects: () => $back.push("post training precalc"),
color: "darkred",
},
]>>
<<if $enemy_progression[$enemy.type][$enemy.id] lt 5 >>
<<run _choices.push(
{
disabled: $player_stats.masculine lt 100 or $player_stats.feminine lt 50,
disabled_text: "Need 100 ?masculine and 50 ?feminine",
text: "Train like a real man - 100 ?masculine 50 ?feminine",
side_effects: () => {
$player_stats.masculine -= 100;
$player_stats.feminine -= 50;
$back.push("post training precalc");
$back.push("battle end");
},
target: "npc progression",
color: "darkblue",
}
)>>
<<else>>
<<run _choices.push(
{
disabled: $player_stats.masculine lt 400,
disabled_text: "Need 400 ?masculine",
text: "Train like a superhuman - 400 ?masculine",
side_effects: () => {
$player_stats.masculine -= 400;
$back.push("post training precalc");
$back.push("battle end");
},
target: "npc progression",
color: "darkblue",
}
)>>
<</if>>
<<event_passage $enemy _choices>>
<p>"So, you wish to become stronger and be a real man, like me? I knew my manliness would attract new customers!"</p>
<p>Well, she is quite cute for a man. Ehm, HE!.. is cute...? Anyway, being stronger would be helpful, so I nodded.</p>
<p>"Well, you came to the right place! Let's train like real men!"</p>
<br>
<p>?new_card <i>You can upgrade a card in your deck if you win.</i></p>
<br>
<i><p>You can skip the battle phase by spending ?masculine points. You should try it at least once :) </p>
<p>In the future updates this option will be blocked if you don't look masculine enough or don't follow some specific conditions.
Also, I will add more progressions for some characters (or for all of them). </p></i>
<</event_passage>><<run $player_deck.forEach(c => c.combat_reset())>>
/* figure out which cards can be upgraded... */
<<set $temp.card_upgrades to $player_deck.sort(setup.card_name_compare).map(card => {
return setup.action_cards.all_player[card.tfs.upgrade]?.combat_reset() ?? null;
})>>
<<goto "card upgrade selection">><p>Pick a card to upgrade:</p>
<div class="grid5col">
<<for _idx, _card range $player_deck>><<capture _idx _card>>
<<if $temp.card_upgrades[_idx] isnot null>>
<<link "<<action_card _card>>">>
<<set _up_idx to _idx>>
<<run setup.show_dialog("Upgrade this card?", "autoanim", "upgrade card confirm")>>
<</link>>
<<else>>
<<action_card _card disabled notilt>>
<</if>>
<</capture>><</for>>
</div>
<div class="flexbuttons">
<button data-passage="back" class="btn">Change nothing and move on</button>
</div><<set _old_card to $player_deck[_up_idx]>>
<<set _new_card to $temp.card_upgrades[_up_idx]>>
/*<<card_tf _old_card _up_ch.up>> hardcoded width here so the dialog isn't tiny...*/
<div class="itemtfgrid" style="width: 40em;">
<<action_card _old_card>>
<img alt="upgrades to" src="img2/icons/green_arrow.svg">
<<action_card _new_card>>
</div>
<div class="flexbuttons">
<<if _new_card !== null>>
<<button "Upgrade!" "back">>
<<run $player_deck.splice(_up_idx, 1, clone(_new_card))>>
<<run Dialog.close()>>
<</button>>
<<else>>
<button class="btn" disabled>Upgrade!</button>
<</if>>
<<button "Not this card...">><<run Dialog.close()>><</button>>
</div>
<<done>>
<<addclass "#ui-dialog-body button" "btn">>
<<addclass "#ui-dialog-body button:nth-child(2)" "btn-red">>
<</done>><<set $battle_won to true>>
<<if $enemy_progression[$enemy.type][$enemy.id] lt $enemy.max_progression>>
<<set $enemy_progression[$enemy.type][$enemy.id] += 1>>
<<if $enemy.name is "Shin">>
<<set $enemy_progression.halloween[1] += 1>>
<</if>>
<<if $enemy.name is "Lina">>
<<set $enemy_progression.halloween[0] += 1>>
<</if>>
<</if>>
<<set _target to $enemy.name + " " + $enemy.type + " " + $enemy_progression[$enemy.type][$enemy.id]>>
<<goto _target>>
/* Shin progression */<<set _choices to [{
text: "OK",
target: "Shin regular 1 part 2",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>"Wow! You are a real man!" Shin said while removing his T-shirt. Then a short pause and realization. "Aaah! Don't look!"</p>
<p>It was too late. The real man infront of me was wearing a pink female sports bra!</p>
<p>"It isn't what you think!" He was shaking hands nervously. "It's these stupid supplements for muscles. After taking them my nipples got very sensitive... So I asked
Lina to help me with that somehow..."</p>
<p>What kind of supplements it is?..</p>
<p>"... So she gave me this cute bra. I mean cool bra! Not cute! It works just fine! And I can... could hide it under my T-shirt... Untill now."</p>
<</event_passage>><<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>"Don't worry, man. Many people get even more problems after taking steroids. So your price isn't that big." I tried to calm Shin down. "And I don't think Lina could have given you something manly. She's a girl after all."
<p>"Yeah, you are right!" The smile returned to his cute face. "I think the supplements already working. My bottom is quite strong already, and I think my chest got bigger a bit. Just need to work on my hands more."</p>
<p>"You know, I'm still worried about something. Why on earth you decided to take your T-shirt off?"</p>
<p>Seems like the question wasn't that easy to answer.</p>
<p>"I don't know... Just after you showed me your manlines I got the overwhelming desire to remove it. Maybe it's a sign that the bond between us became stronger,
like between real men! And real man don't hide stuff from each other, right?"</p>
<p>"Right." I agreed. But I don't think it's the actual reason.</p>
<</event_passage>><<set _choices to [
{
text: "Ok",
target: "Shin regular 2 part 2",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/shin_active modest femboy_bottom_1.jpg' class="eventimg">
</div><<set _choices to [{
text: "OK",
target: "Shin regular 2 part 3",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>I was getting dressed in the locker room when Shin just came in. His cute face turned red immediately.</p>
<p>"Sorry!" He shouted with the closed eyes.</p>
<p>"Relax, dude. We are both male after all." He opened the eyes, but just for a moment. "... So it's ok to be naked in a public locker room, lol. How old are you, 12?"</p>
<p>He finally opened his eyes.</p>
<p>"I'm 21! Here is my ID." Ok, Shin is't really that good with sarcasm. "So it's ok for real men to be naked infront of each other?"</p>
<p>What kind of question it is?..</p>
<p>"Ehm... Yes? I don't see a problem."</p>
<p>"I see... Well, see you next time!" He's gone. Seems like he needs some time to process new info.</p>
<</event_passage>><<set _card to clone(setup.action_cards.all_enemy[2])>>
<<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage _card _choices>>
<p><i>Thinking about everything that happened you realized that you can use this info later when you meet Shin.</i></p>
<</event_passage>><<set _choices to [{
text: "OK",
target: "Shin regular 3 part 2",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>I were pushing hard again when suddenly Shin ducked under the barbell.</p>
<p>"Agrh!" Shin tried to make it sound fierce but failed. Then in one fluid motion, his shorts came off, tossed aside. "I'm also going to push today! Like a real man!"</p>
<p>With these words Shin started forcing himself through the squats. Only then I realized that under the shorts he had striped panties!</p>
<p>In silence I waited for Shin to finish. It was hard not to pay close attention to his squat technique. When the man wearing panties finished I asked.</p>
<p>"Ehm, sorry, but what was that? And... why are you wearing panties?"</p>
<p>Shin's gone pale this time.</p>
<p>"Panties?.." He slowly looked down. "NAAAAW!" He rushed to the dressing room.</p>
<p>What the hell is going on here?</p>
<</event_passage>><<set _choices to [{
text: "OK",
target: "Shin regular 3 part 3",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>I finished the training alone and went to the dressing room to find the lost friend. Shin was sitting there, still pale.</p>
<p>"Hey!" Awkward silence. "You know, in the place like that wearing panties is quite normal. I think I have some in my collection, haha."</p>
<p>"Ah... Don't worry, it's not about panties." Bele sighed. "My shorts are ruined now. Do you know how hard it is to get manly clothes here?"</p>
<p>Well, it's quite hard.</p>
<p>"From my point of view, there is no much difference between the shorts you wore and panties, to be honest." I wasn't even lying. The shorts were quite hot. "And you ruined them during this "act" of yours, right? So I thought you wanted to do that."</p>
<p>"Maybe you're right, they are quite manly. I'd been watching some vids about russian soldiers. They were looking so manly ripping their clothes appart and leaving striped tank tops. So I decided to try that myself..."</p>
<p>Watching men taking off their clothes isn't that manly, though. And when tanks tops became panties?..</p>
<</event_passage>><<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>"... So I came to Lina and asked something with blue stripes..."</p>
<p>"Let me guess: and she couldn't find anything but these panties." You tried to finish your friend's sentence.</p>
<p>"Yep! How did you know? Have you been taking clothes from her too?"</p>
<p>"Yep, sometimes..." Then I changed the topic. "So what you gonna do?"</p>
<p>"For now I gonna just keep the panties. I feel like a real man when wearing them. And they are very comfortable."</p>
<p>"Cool! At least they are not pink, heh."</p>
<p>"Yeah..." Did Shin just got upset because of this fact? "Thanks, I'll be going now!"</p>
<p>"No problems."</p>
<</event_passage>><<set _choices to [
{
text: "Ok",
target: "Shin regular 4 part 2",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/shin_active modest femboy_bottom_2.jpg' class="eventimg">
</div><<set _choices to [{
text: "OK",
target: "Shin regular 4 part 3",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>Seems like Shin isn't that worried to use public changing room anymore. However, seeing a cute figure in female panties and sports bra there wasn't that easy.
Especially this time, after a cool workout. So when Shin bent over to take something from the floor I couldn't hold it anymore.</p>
<p>"Wow..." Shin just froze in place staring at my boner.</p>
<p>"It just happens sometimes after a hard workout, you know." Trying to explain everything I made it even more awkward. "You know, muscles are getting pumped. All the muscles, if you know what I mean."</p>
<p>"Yeah, no worries. We are men, we know each other! Happens to me all the time."</p>
<p>Shin pointed at his panties where I could hardly find anything "special".</p>
<p>"I see..." I should go jerk off asap.</p>
<</event_passage>><<set _card to clone(setup.action_cards.all_enemy[3])>>
<<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage _card _choices>>
<p><i>Thinking about everything that happened you realized that you can use this info later when you meet Shin.</i></p>
<</event_passage>><<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>This time Shin showed up without sports bra and without any top clothes.</p>
<p>"What happened again?" I asked waiting to hear another story.</p>
<p>"Nothing special, just my panties and bra didn't fit each other, so I fixed that."</p>
<p>"By removing bra?"</p>
<p>Shin looked at me like it was me who acted odd.</p>
<p>"Do you think taking off the panties would have been a better option?"</p>
<p>"Ehm, no?"</p>
<p>"I thought the same. Let's start the workout already."</p>
<p>He's definitely not in the mood today.</p>
<</event_passage>>/* temporary override */
<<set $enemy.fg_img to "shin_active modest femboy_2_f.png">>
<<set _choices to [{
text: "What happened?",
target: "Shin regular 6 part 2",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>"Ok, it's time to show the word what a real man can do!" I said and started a very intense workout.</p>
<p>Shin supported me with everything he could, so I won't spend time on preparing and can just keep pushing.</p>
<p>"Man, you're awesome!" Shin said when I finished the workout. "Though, I need some time to finish my own workout. Don't worry and go have some rest."</p>
<p>"Ok, thanks mate!"</p>
<p>After such workout I decided to spend a bit more time in the shower. When I finished something unexpected happened.</p>
<</event_passage>><<set _choices to [
{
text: "Ok",
target: "Shin regular 6 part 3",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/shin_active modest femboy_bottom_3.jpg' class="eventimg">
</div>/* back to 'normal' */
<<set $enemy.fg_img to "auto">>
<<set _choices to [{
text: "Ok",
target: "Shin regular 6 part 4",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>"What was that for?"</p>
<p>Shin blushed.</p>
<p>"Actually I had other pans. But you were so manly today, I thought I can support you a bit more with this tension..." He looked at my prick. "...After all, we are men, we should stick together. Maybe one day you can help me too."</p>
<p>"Yeah, I would like to..." This workout went even better than I thought</p>
<p>"So let me know if you ever need a hand from a real man! For now I better go hit the showers."</p>
<p>"Thanks bro! And thanks to your manly hands too!"</p>
<p>With a smile, Shin went to the showers, looking quite happy.</p>
<</event_passage>><<set _card to clone(setup.action_cards.all_enemy[4])>>
<<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage _card _choices>>
<p><i>Thinking about everything that happened you realized that you can use it later when you meet Shin.</i></p>
<</event_passage>>
/* end of Shin progression */
/* Lina progression */<<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>I convinced Lina that she would get more clients if she took off her top.</p>
<</event_passage>><<set _choices to [
{
text: "Ok",
target: "Lina regular 2 part 2",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/lina_casual sexy female_bottom_1.jpg' class="eventimg">
</div><<set _card to clone(setup.action_cards.all_enemy[5])>>
<<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage _card _choices>>
<p>I tried to convince Lina to remove some clothes but she just sucked me off.</p>
<p>"Sorry, you're just too cute today to let you go without a small reward." The only thing she said.</p>
<br>
<p><i>Thinking about everything that happened you realized that you can use this info later when you meet $enemy.name.</i></p>
<</event_passage>><<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>I convinced Lina that she would get more clients if she romoved her shorts.</p>
<</event_passage>><<set _choices to [
{
text: "Ok",
target: "Lina regular 4 part 2",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/lina_casual sexy female_bottom_2.jpg' class="eventimg">
</div><<set _card to clone(setup.action_cards.all_enemy[6])>>
<<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage _card _choices>>
<p>I tried to convince Lina to remove some clothes but she was so exhausted that she couldn't move a muscle.</p>
<p>"Sorry, hun. I had a workout with Shin today, so I think I will just continue slowly diyng here." I asked about Shin. "Yeah, this cute soul helps me with training in exchange of some clothes."</p>
<br>
<p><i>Thinking about everything that happened you realized that you can use this info later when you meet $enemy.name again.</i></p>
<</event_passage>><<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>I convinced Lina that she would get more clients if she romoved her bra.</p>
<</event_passage>><<set _choices to [{
text: "Check the Pillows",
target: "Lina regular 6 part 2",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>I convinced Lina that she would get more clients if she romoved her panties.</p>
<p>"I gonna do that if you also remove yours" She said.</p>
<p>Well, without any hesitation I pulled my underwear aside. She followed me.</p>
<p>"Ehm... You know, I just bought some new pillows. They are quite... white... and puffy. Do you want to check them in my bedroom?"</p>
<p>Actually, I'm quite interested in checking the pillows from time to time. So I agreed.</p>
<</event_passage>><<set _choices to [
{
text: "Ok",
target: "Lina regular 6 part 3",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/lina_casual sexy female_bottom_3.jpg' class="eventimg">
</div><<set _card to clone(setup.action_cards.all_enemy[7])>>
<<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage _card _choices>>
<p><i>Thinking about everything that happened you realized that you can try that later when you meet $enemy.name again.</i></p>
<</event_passage>>
/* end of Lina progression */
/* Stylist progression */<<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>Stylist removed his pants after I flirted with him.</p>
<</event_passage>><<set _choices to [
{
text: "Ok",
target: "Stylist regular 2 part 2",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/regular male stylist 1.jpg' class="eventimg">
</div><<set _card to clone(setup.action_cards.all_enemy[8])>>
<<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage _card _choices>>
<p>I tried to flirt with Stylist but he showed his lollipop in my mouth instead.</p>
<p>"Let the master work please." He whispered in my ear.</p>
<br>
<p><i>Thinking about everything that happened you realized that you can use this later when you meet $enemy.name again.</i></p>
<</event_passage>><<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>Stylist removed his top after I flirted with him.</p>
<</event_passage>><<set _choices to [{
text: "Flirt gone Wild",
target: "Stylist regular 4 part 2",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>Stylist removed his undies after I flirted with him.</p>
<p>"You know, you should know what might happen if you keep flirting with a man."</p>
<p>"What might happen?" I kept flirting.</p>
<p>"Your flirt can go wild."</p>
<p>"Oh my... I think it's happening right now..." With these words I touched his huge dick.</p>
<p>Ok, I definitely crossed the line, I'm seducing him now.</p>
<p>"So, are you going to show me how wild it can be?" Seems like I gonna have sex today, yay!</p>
<</event_passage>><<set _choices to [
{
text: "Ok",
target: "Stylist regular 4 part 3",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/regular male stylist 2.jpg' class="eventimg">
</div><<set _card to clone(setup.action_cards.all_enemy[9])>>
<<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage _card _choices>>
<p><i>Thinking about everything that happened you realized that you can try this later when you meet $enemy.name again.</i></p>
<</event_passage>>
/* v6.5 events end */<<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;
}
})
>>
<<if _current_clothing.id is 0>>
/* No clothes? Get TF'd! */
<<goto "feminization calc">>
<<else>>
<<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 _current_clothing.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>>
<</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: 1,
},
{
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 process_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?fem ?stress ?new_card ?airhead</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 $related_phrase to "During the session I could watch some girl's stuff, like style collections, makeup tips and such.">>
<<run $player_deck.push(clone(setup.punish_cards[3]))>>
<<set $player_stats.airhead += 1>>
<<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 8 and setup.item_not_worn(item))>>
<<set $loot to _droplist.random()>>
<<set $old_item to $player_equipment.replace_with($loot)>>
<<goto "new cosmetics">><<set $related_phrase to "During the session I could watch some ultra girl's stuff, I think some fancy style collections, makeup tips and maybe something else. Everything was so shiny and... pink? So it was extra hard to focus on something specific.">>
<<set $player_stats.airhead += 3>>
<<run $player_deck.push(clone(setup.punish_cards[3]))>>
<<run $player_deck.push(clone(setup.punish_cards[3]))>>
<<set $player_stats.corruption -= 1>>
<<set $player_stats.stress -= 2>>
<<set _droplist to Object.values(setup.all_styles).flat()
.filter(item => item.fem gt 8 and setup.item_not_worn(item))>>
<<set $loot to _droplist.random()>>
<<set $old_item to $player_equipment.replace_with($loot)>>
<<goto "new cosmetics">><<event_passage setup.punish_cards[3] setup.ok_choices>>
<p>A robotic voice told me to sit down and relax. $related_phrase 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">><<set _brainwashed to false>>
<<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 3>>
<<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"}>>
<<run $player_deck.push(clone(setup.punish_cards[3]))>>
<<run $player_deck.push(clone(setup.punish_cards[3]))>>
<<set $player_stats.airhead += 2>>
<<set _brainwashed to true>>
<<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>
<<if _brainwashed>>
<p>After watching brainwashing porn I feel a bit ditzy.</p>
<div class="bigcard">
<<action_card setup.punish_cards[3]>>
</div>
<</if>>
<</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 $salary 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 += $salary>>
<<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 $salary>>?money.
I can still change the clothes in the private room.</p>
<</event_passage>><<set $salary to Math.round(((($player_stats.sub + $player_stats.fit + $player_stats.att + $player_stats.fem) / 2)+10) * $current_loop.difficulty)>>
<<set $player_stats.money += $salary>>
<<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 $salary>>?money.
I can still change the clothes in the private room.</p>
<</event_passage>><<set _choices to [
{
text: "Take the Money +?corruption",
side_effects() {
$player_stats.corruption += 1;
$player_stats.money += random(4,8) * $current_loop.difficulty;
},
target: "back",
color: "green",
},
{
text: "Skip the Money +?balance",
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</p>
<p>I spotted some ?money on the floor. Should I take it or just skip?</p>
<</event_passage>><<set $loss to Math.clamp(10 * $current_loop.difficulty, 0, $player_stats.money)>>
<<set _choices to [
{
disabled: not ($player_stats.corruption gt 0 and $player_stats.bint gt 2),
disabled_text: "I'm not smart enough for a smart move",
text: "Calculated Move -?corruption",
side_effects: () => {
$player_stats.airhead -= 1;
$player_stats.corruption -= 1;
$player_stats.money += $loss/2;
},
target: "calculated move",
color: "darkblue",
},
{
disabled: not ($player_stats.balance gt 0 and ($player_stats.int is 0 or $player_stats.airhead gte 3)),
disabled_text: "I'm not dumb enough to play dumb",
text: "Play Dumb -?balance",
side_effects: () => {
$player_stats.airhead += 2;
$player_stats.balance -= 1;
$player_stats.money += $loss;
},
target: "play dumb",
color: "magenta",
},
{
text: "Return the Money +?balance",
side_effects: () => $player_stats.balance += 1,
target: "back",
color: "royalblue",
},
]>>
<<if $player_stats.corruption is 0 and _choices[0].disabled>><<set _choices[0].disabled_text to "Not enough ?corruption">><</if>>
<<if $player_stats.balance is 0 and _choices[1].disabled>><<set _choices[1].disabled_text to "Not enough ?balance">><</if>>
<<set _ecard to {title: "Lost Money", color: "royalblue", bg_img: "lost money_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?money ?new_card</p>
<p>I spotted some $loss ?money on the floor. Without thinking to much I just grabbed it.</p>
<p>After just a minute or so I met a girl. She asked me about the money. What should I do?</p>
<</event_passage>><<run $player_deck.push(clone(setup.action_cards[16]))>>
<<event_passage setup.action_cards[16] setup.ok_choices>>
<p class="framed-icons">?new_card</p>
<p>I explained the girl that eventhough I found the money she most likely lost, but I still can't be sure that it's her money.</p>
<p>"What if you're lying?"</p>
<p>"I'm not lying, I swear!" Girl was about to burst in tears.</p>
<p>"You see, what if I meet someone else in the next room who is looking for that money too. I just can't be sure. Try to see my point. It isn't that hard to find something on the floor in this place. Are you sure I found your money?"</p>
<p>"I... I don't know..."</p>
<p>"But don't worry, I've got an idea. Yeah, I'm taking a risk... But anyway, I think it might be your money. So what do you say if we cut it in half. One half goes to you and I keep another half in case the money isn't yours."</p>
<p>Her face became brighter.</p>
<p>"Yeah, I think a half would be enough for them. Thanks!"</p>
<</event_passage>><<run $player_deck.push(clone(setup.punish_cards[9]))>>
<<event_passage setup.punish_cards[9] setup.ok_choices>>
<p class="framed-icons">?new_card</p>
<p>"Money?"</p>
<p>"Yes..."</p>
<p>"$loss in cash?"</p>
<p>"Yeah! Exactly $loss." Girl was ready to hug you right here.</p>
<p>"Sorry, I haven't seen anything like that." I cut her happy thougts.</p>
<p>"But..."</p>
<p>"Sorry, I need to go. If I see something I let you know."</p>
<p>Oh, I better hurry up, almost got caught here. Think what you say, idiot.</p>
<</event_passage>><<run $player_deck.push(clone(setup.punish_cards[4]))>>
<<set _choices to [
{
text: "Ok",
side_effects: () => $player_stats.stress += 1,
target: "back",
color: "green",
},
{
disabled: not ($player_stats.corruption gt 0 and ($player_equipment.bottom.id is 0 or $player_equipment.bottom.extra.includes("skirt"))),
disabled_text: "It's good that my undies are well covered",
text: "Oops, Silly Me! -?corruption",
side_effects: () => {
$player_stats.airhead += 2;
$player_stats.corruption -= 1;
$player_stats.stress += Math.round((8 - $player_stats.airhead_lvl) / 2)
},
target: "oops silly me",
color: "magenta",
},
]>>
<<if $player_stats.corruption is 0 and _choices[1].disabled>><<set _choices[1].disabled_text to "Not enough ?corruption">><</if>>
<<set _ecard to {title: "Tripped Over", color: "darkslategray", bg_img: "trip over_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?new_card ?stress</p>
<p>Ouch! I tripped over. My butt hurts... People around think that I'm a clumsy fool.</p>
<div class="bigcard">
<<action_card setup.punish_cards[4]>>
</div>
<</event_passage>><<run $player_deck.push(clone(setup.punish_cards[10]))>>
<<event_passage setup.punish_cards[10] setup.ok_choices>>
<p class="framed-icons">?new_card</p>
<p>I'm sure now they think that I'm an airhead clumsy bimbo...</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 _choices to [
{
text: "Ok",
side_effects: () => $player_stats.stress += 1,
target: "back",
color: "green",
},
{
disabled: not ($player_stats.balance gt 0 and $player_stats.bfit gte 4),
disabled_text: "I need to improve ?fit to catch the thief",
text: "Cath the Thief! -?balance",
side_effects: () => {
$player_stats.masochism += 2;
$player_stats.balance -= 1;
$player_stats.stress += Math.round((8 - $player_stats.airhead_lvl) / 2)
},
target: "butt slam",
color: "darkred",
},
]>>
<<if $player_stats.balance is 0 and _choices[1].disabled>><<set _choices[1].disabled_text to "Not enough ?balance">><</if>>
<<set _ecard to {title: "Pickpocket", color: "brown", bg_img: "pickpocket_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?money ?new_card</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 _loss to Math.clamp(10 * $current_loop.difficulty, 0, $player_stats.money)>>
<<set $player_stats.money += _loss>>
<<run $player_deck.push(clone(setup.punish_cards[7]))>>
<<event_passage setup.punish_cards[7] setup.ok_choices>>
<p class="framed-icons">?new_card ?money</p>
<p>I was running like never before. In no time I could see the thief. He turned to me in surprise. Maybe from the fact that I was after him, or because of my supersonic speed.</p>
<p>Yeah, slowing down was not an option anymore. I was so angry that I missed the fact that the floor was tilted.</p>
<p>My legs were already struggling to keep me from falling. I gonna bump hard into this fucking thief. But if I gonna bump I better do that smart. So I jumped a little and turned by back to him.</p>
<p>My butt slammed the hell out of this dude... So he fainted. Yeah, I also got some pain, but at least I got my cash back, and a little extra for the troubles he caused.</p>
<</event_passage>><<set $enemy to clone(setup.enemies.regular.random())>>
<<goto "regular enemy encounter">><<include "regular enemy encounter precalc">><<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 $enemy to clone(setup.enemies.regular[2])>>
<<set $enemy.power_rate to 2>>
<<set _choices to [
{
text: "Fight the Pain",
side_effects: () => $back.push("spanked conclusion"),
target: "battle pre calc",
color: "darkred",
},
{
disabled: not ($player_stats.balance gt 0 and ($player_equipment.top.id is 0 and $player_equipment.bra.id is 0 and $player_equipment.body.boobs gt 0)),
disabled_text: "It's good that my boobs are covered",
text: "High-Five -?balance",
side_effects: () => {
$player_stats.airhead += 2;
$player_stats.balance -= 1;
$player_stats.stress += Math.round((8 - $player_stats.airhead_lvl) / 2);
},
target: "high five",
color: "magenta",
},
{
text: "It hurts already, I better go",
target: "back",
side_effects: () => {
$player_deck.push(clone(setup.punish_cards[4]));
},
color: "gray",
}
]>>
<<if $player_equipment.body.boobs is 0 and _choices[1].disabled>><<set _choices[1].disabled_text to "I don't even have boobs">><</if>>
<<if $player_stats.balance is 0 and _choices[1].disabled>><<set _choices[1].disabled_text to "Not enough ?balance">><</if>>
<<set _ecard to {title: "Spanked", color: "brown", bg_img: "spanked_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?stress ?new_card</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, when I opened them, I saw a handsome guy looking down at me. His eyes were drilling my chest trying to see what's hidden there. My hands moved automatically to the chest trying to get some extra protection.</p>
<p> I can fight the pain and embarrassment, engage and show him that such stuff is nothing for me. It won't be easy, though.</p>
<p><<if $player_equipment.top.id is 0 and $player_equipment.bra.id is 0 and $player_equipment.body.boobs gt 0>>Like reading my mind, the guy said. "If you want to show me how strong you are - just give me a five. I'm sure it's nothing for you." He raised his hand.<</if>></p>
<p>Something tells me that if I just go the pain would become even stronger...</p>
<div class="flexdown" style="width: 60%; margin: auto;">
<<action_card setup.punish_cards[4]>>
</div>
<</event_passage>><<run $player_deck.push(clone(setup.punish_cards[11]))>>
<<event_passage setup.punish_cards[11] setup.ok_choices>>
<p class="framed-icons">?new_card</p>
<p>I am strong! I should prove that no matter what it takes! Even if it's just a high-five.</p>
<p>"Here, take it!" I clapped his hand.</p>
<p>At this moment his mouth spread into a wide grin, and eyes were focused on nothing but on my naked boob that wasn't covered anymore.</p>
<p>"You are strong. And perky, hah!" With these words he's gone.</p>
<p>I'm acting like some airhead bimbo...</p>
<</event_passage>><<if $battle_won>>
<<set $player_stats.balance += 1>>
<<set $player_stats.money += 5 * $current_loop.difficulty>>
<<set _ecard to {title: "Good Job", color: "darkgreen", bg_img: "good job_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p>Great! No more pain, and I even got some cash.</p>
<</event_passage>>
<<else>>
<<run $player_deck.push(clone(setup.punish_cards[4]))>>
<<run $player_deck.push(clone(setup.punish_cards[4]))>>
<<set $player_stats.arousal += 2>>
<<event_passage setup.punish_cards[4] setup.ok_choices>>
<p>It wasn't a smart move. Now I get spanked even more...</p>
<</event_passage>>
<</if>><<set $player_stats.balance += 1>>
<<set $player_stats.arousal += 1>>
<<set _choices to [
{
disabled: not ($player_stats.corruption gt 0 and $player_stats.batt gte 3),
disabled_text: "Need more ?att",
text: "Make a Scene -?corruption",
side_effects: () => {
$player_stats.airhead += 1;
$player_stats.corruption -= 1;
$player_stats.stress -= 1;
},
target: "make a scene",
color: "magenta",
},
{
text: "Let him go",
target: "back",
color: "gray",
}
]>>
<<if $player_stats.corruption is 0 and _choices[1].disabled>><<set _choices[1].disabled_text to "Not enough ?corruption">><</if>>
<<set _ecard to {title: "A Fall", color: "brown", bg_img: "a fall_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?arousal ?new_card ?money</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.</p>
<</event_passage>><<set _loss to Math.clamp(($player_stats.att+$player_stats.airhead_lvl+$player_stats.fem)*$current_loop.difficulty*0.5, 0, $player_stats.money)>>
<<set $player_stats.money += _loss>>
<<run $player_deck.push(clone(setup.punish_cards[8]))>>
<<event_passage setup.punish_cards[8] setup.ok_choices>>
<p class="framed-icons">?new_card</p>
<p>The hardest part was to start crying. Everything else wasn't that hard for me. After all, tears are the strongest weapon of women. Wait, I'm not a girl... am I?</p>
<p>Anyway, thanks to my attractiveness and emty head I even got _loss ?money from the poor guy.</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 _weights to setup.SIFA.map(s => (10 - _core[s]) * 2)>>
<<if _weights.some(w => w gt 0)>>
<<set $temp.train to _training_options[setup.SIFA[alias_sampler(_weights)()]]>>
<<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>>/* Go to "train sifa" randomly instead, more likely if SIFA stats are super low */
<<if random(0, Math.min(...Object.values($player_stats.core_stats))) lte 2>>
<<goto "train sifa precalc">>
<<else>>
<<set $enemy to clone(setup.training_enemies[4])>>
<<set $enemy.power_rate to $player_stats.masochism_lvl + 1>>
<<set $temp.enemy_card to {
title: $enemy.name,
color: "blue",
bg_img: $enemy.image,
}>>
/* card drop chances (rare, epic, legendary) */
<<set _ml to $player_stats.masochism_lvl>>
<<set $temp.drop_chances to [
95 - (_ml * 5),
5 + (_ml * 3),
2 * _ml,
]>>
<<set _choices to [
{
text: "Train!",
side_effects: () => $back.push("train maso end precalc"),
target: "battle pre calc",
color: "green",
},
{
text: "Skip training",
target: "back",
color: "gray",
}
]>>
<<event_passage $temp.enemy_card _choices>>
<p class="framed-icons">?new_card</p>
<p>Seems like I could train for masochism related skills here. I wonder if that's worth it...</p>
<br>
<p><i>If you succeed, you'll get a new card with these probabilities:</i></p>
<p style="text-align: center">?rare $temp.drop_chances[0]% / ?epic $temp.drop_chances[1]% / ?legendary $temp.drop_chances[2]%</p>
<p><i>Improve your ?masochism to make rarer cards more likely.</i></p>
<</event_passage>>
<</if>><<if $battle_won>>
<<set $player_stats.masochism += 2>>
/* pick an index based on drop chances */
<<set _rarity to alias_sampler($temp.drop_chances)()>>
/* since there's exactly 1 pain card for each rarity in order,
just pick one of those directly */
<<set $temp.card to setup.punish_cards.slice(5, 8)[_rarity]>>
<<run $player_deck.push(clone($temp.card))>>
<<set $temp.passage to "Somehow, this hurts, and yet... I seem to enjoy it? Well, I got another action for it, at least.">>
<<else>>
<<set $player_stats.masochism += 4>>
<<set $temp.card to $temp.enemy_card>>
<<set $temp.passage to "Ow, ow, owwwwwwww... Is this sort of training really worth it? Maybe I should try to get stronger in other ways, first.">>
/* TODO other consequences? */
<</if>>
<<goto "train maso end">><<event_passage $temp.card setup.ok_choices>>
<p>$temp.passage</p>
<</event_passage>><<set $enemy to clone(setup.training_enemies[5])>>
<<set $temp.enemy_card to {
title: $enemy.name,
color: "darkred",
bg_img: $enemy.image,
}>>
<<set _choices to [
{
text: "Submissive Shift",
side_effects: () => $back.push("submissive shift end precalc"),
target: "battle pre calc",
color: "darkred",
},
{
text: "Skip",
target: "back",
color: "gray",
}
]>>
<<set _ecard to {title: "BDSM Club", color: "darkred", bg_img: "BDSM Club_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?money ?masochism ?stress ?arousal</p>
<br>
<p>BDSM Club, sure... Why not... </p>
<p>I noticed a sign in the window. It said that they're always looking for submissives, and they pay well. They'll pay even more the higher my masochism is.</p>
<</event_passage>><<set _salary to Math.round(((($player_stats.bsub + $player_stats.batt + $player_stats.fem) / 3)+$player_stats.masochism_lvl+10) * $current_loop.difficulty)>>
<<set $player_stats.stress += 8 - $player_stats.masochism_lvl>>
<<set $player_stats.arousal += $player_stats.masochism_lvl - 4>>
<<if $player_stats.stress gte 10>>
<<set $player_stats.stress to 9>>
<</if>>
<<if $player_stats.arousal gte 10>>
<<set $player_stats.arousal to 9>>
<</if>>
<<if $battle_won>>
<<set $player_stats.bsub += 1>>
<<set $player_stats.money += _salary>>
<<set $player_stats.masochism += 2>>
<<set $temp.card to {title: "Submissive Shift", color: "darkred", bg_img: "Submissive Shift_b.jpg"}>>
<<set $temp.passage to "Everything went well. Yeah, it's not the experience I thought it'd be, but I got " + _salary + " ?money, cool.">>
<<else>>
<<set _salary to Math.round(_salary / 3)>>
<<set $player_stats.money += _salary>>
<<set $player_stats.masochism += 3>>
<<set $temp.passage to "Ok, that wasn't the best experience of my life, but it wasn't the worst either... And I got " + _salary + " ?money. Only one small issue... Everything <em>hurts like hell!</em>">>
<<set $temp.card to setup.punish_cards[4]>>
<<run $player_deck.push(clone($temp.card))>>
<</if>>
<<goto "submissive shift end">><<event_passage $temp.card setup.ok_choices>>
<p>$temp.passage</p>
<</event_passage>><<set $enemy to clone(setup.training_enemies[6])>>
<<set $temp.enemy_card to {
title: $enemy.name,
color: "purple",
bg_img: $enemy.image,
}>>
<<set _choices to [
{
text: "Analyse Memes",
side_effects: () => $back.push("meme shift end precalc"),
target: "battle pre calc",
color: "darkred",
},
{
text: "Skip",
target: "back",
color: "gray",
}
]>>
<<set _ecard to {title: "Meme Analysis Offices", color: "purple", bg_img: "meme analyst_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?money ?airhead ?stress ?arousal</p>
<br>
<p>Meme Analysis Offices? What kind of bizarre workplaces will I run into next...</p>
<p>There was a sign in the window advertising that they were always hiring temp analysts. The ad implied that being ditzier paid well, strange...</p>
<</event_passage>><<set _salary to Math.round(
((($player_stats.bsub + $player_stats.bint + $player_stats.fem) / 3) +
$player_stats.airhead_lvl + 10) * $current_loop.difficulty
)>>
<<set $player_stats.arousal += 7 - $player_stats.airhead_lvl>>
<<set $player_stats.stress += $player_stats.airhead_lvl - 4>>
<<if $player_stats.stress gte 10>>
<<set $player_stats.stress to 9>>
<</if>>
<<if $player_stats.arousal gte 10>>
<<set $player_stats.arousal to 9>>
<</if>>
<<if $battle_won>>
<<set $player_stats.bint += 1>>
<<set $player_stats.money += _salary>>
<<set $player_stats.airhead += 2>>
<<set $temp.card to $temp.enemy_card>>
<<set $temp.passage to "Well, that was interesting. I got a few laughs in, and while that was dumb, I feel oddly smarter, too? Regardless, I got paid " + _salary + " ?money, so that might be worth doing again.">>
<<else>>
<<set _salary to Math.round(_salary / 3)>>
<<set $player_stats.money += _salary>>
<<set $player_stats.airhead += 3>>
<<set $temp.passage to "I couldn't keep up with the endless stream of memes. I can't help but feel extra dumb for that... In any case, I got paid " + _salary + " ?money.">>
<<set $temp.card to setup.punish_cards[3]>>
<<run $player_deck.push(clone($temp.card))>>
<</if>>
/* Reusing the other 'end' b/c it works the same */
<<goto "submissive shift end">><<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>>/*[instant-event] */
/* TODO basically all text/art here is placeholder */
<<if $player_stats.identity gte $player_stats.fem and random(0, $game_difficulty) isnot 0>>
/* skip this event */
<<goto "back">>
<<else>>
<<if $player_stats.identity gt $player_stats.fem>>
<<set $player_stats.identity -= 1>>
<<set _passage to "You feel more masculine.">>
<<elseif $player_stats.identity lt $player_stats.fem>>
<<set $player_stats.identity += 1>>
<<set _passage to "You feel more feminine.">>
<<else>>
/* equal */
<<set $player_stats.stress -= 1>>
<<set _passage to "You feel comfortable in your body.">>
<</if>>
<<set _ecard to {title: "Reflection", color: "green", bg_img: "good_couch_shift_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p>_passage</p>
<</event_passage>>
<</if>>/* TODO doesn't account for reversal... fuck it just always use 'fem'
<<set _is_fem_tf to $temp.chg_items.some(it => it.id > $player_equipment[it.place].id)>>
*/
/* TODO Use the 'related phrase' stuff from `feminization calc`?
Need to reliably detect which direction change was in though... */
/* TODO separate calc passage for this? */
<<if random(1, 2) is 1>>
<<set _ecard to setup.action_cards.all_player["feminization_f"]>>
<<set $player_deck.push(clone(_ecard))>>
<<else>>
<<set _ecard to {title: "Feminization", color: "magenta", bg_img: "Feminization_b.jpg"}>>
<</if>>
<<run $player_equipment.reset_body_chg()>>
<<event_passage _ecard setup.ok_choices>>
<p>I noticed <<= $temp.chg_items.length > 1 ? "some" : "one">> of my body parts changed.</p>
<<for _item range $temp.chg_items>>
<<equip_tf _item $player_equipment[_item.place]>>
<</for>>
<</event_passage>>/* no need for precalc since there's no randomness */
<<set $enemy to clone(setup.enemies.regular[2]); $enemy.power_rate to 2>>
<<set $player_stats.identity to $player_stats.fem>>
<<if $player_stats.identity gte 10>>
<<set $current_loop.max_identity to true>>
<</if>>
<<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 $temp.first_lobby to true>>
<<set _choices to [
{
text: "Briefing",
target: "introduction 2",
color: "green",
},
]>>
<<set _ecard to {title: "Just a Guy", color: "darkblue", bg_img: "just a guy_b.jpg", fg_img: "just a guy_f.png"}>>
<<event_passage _ecard _choices>>
<p>The world’s a mess. The crisis hit hard, and it didn’t stop. Millions of people (me included) lost everything. No money, no future, just trying to get by.
<p>But then something crazy happened. I got picked for this experimental program run by SIFA Corp. They’re one of the last companies actually trying to fix things instead of just surviving. Their plan? To make a place where people can live and take care of themselves using something they call The Loop. It’s got something to do with quantum tech or whatever. I don’t really get how it works, but they say if it does, nobody will ever have to struggle like this again.</p>
<p>After signing a ton of NDAs and paperwork, I ended up here. Some massive underground facility where they’re starting the first tests. Honestly, I don’t know what’s about to happen, but if this works… it could change everything.</p>
<</event_passage>><<set _choices to [
{
text: "Keep Listening",
target: "introduction 3",
color: "green",
},
]>>
<<set _ecard to {title: "Scientist", color: "darkblue", bg_img: "scientist_b.jpg", fg_img: "scientist_f.png"}>>
<<event_passage _ecard _choices>>
<p>A woman who seems to be in charge steps forward and starts the briefing for our group. There are only ten of us here, including me.</p>
<p>“You will be participating in our latest research project. If everything goes as planned, you may very well become heroes in the future,” she says in this calm, professional tone.</p>
<p>A hero? Sure, sounds nice, but honestly, I’m just interested in, you know, "living" for now.</p>
<p>“For the initial phase, you will not be interacting with each other. This is to ensure your individual statistics remain uncontaminated. However, this arrangement may change as we progress.”</p>
<p>Great. Sounds like I’m going to be stuck alone, probably pedaling a bike all day to power some machine and get some food for that. "The Loop", huh. Whatever that really means. Then again, even that might be better than trying to scrape by on the surface.</p>
<</event_passage>><<set _choices to [
{
text: "Next",
target: "introduction 4",
color: "green",
},
]>>
<<set _ecard to {title: "Scientist", color: "darkblue", bg_img: "scientist_b.jpg", fg_img: "scientist_f.png"}>>
<<event_passage _ecard _choices>>
<p>“You’ll each be assigned your own rooms where you can spend your free time. Food, water, and other essentials are included, along with access to shops and training grounds. However, these are not free — you will be required to pay your bills daily.”</p>
<p>Ok, fair enough.</p>
<p>“To cover your expenses, you’ll need to work. For this group, we have only one job available: Gift Packing. The idea is simple — we take items from The Loop and send them as gifts to the public. This helps improve our reputation and show people that The Loop is real and functional.”</p>
<p>She coughed lightly before continuing.</p>
<p>“The primary goal of this research is to determine how much an individual can earn here. To that end, your bills may be raised occasionally to motivate you to work harder. Additionally, if you fail to pay your bills, we may initiate certain stimulation scenarios to encourage participation.”</p>
<p>Well, sounds good enough to me.</p>
<</event_passage>><<set _choices to [
{
text: "Yes",
target: "autosave lobby",
color: "green",
},
]>>
<<include "IntroExtra">>
<<set _ecard to {title: "Just a Guy", color: "darkblue", bg_img: "just a guy_b.jpg", fg_img: "just a guy_f.png"}>>
<<event_passage _ecard _choices>>
<p>The woman set aside her tablet and looked at us. “Guys, one last thing. This place isn’t like anywhere else. We’ve received a lot of data suggesting that being here changes people—their habits, preferences, and sometimes even their physical appearance. These changes seem to be connected to the actions you take. So, be mindful of your choices.”</p>
<p>What is she talking about? Sure, my preferences might change—I mean, I won’t have to scrape by just to survive anymore. That’s a given.</p>
<p>She asked us to wait until we were called for a final check. Eventually, it was my turn.</p>
<p>“Male. 24 years old. Not married. No kids. No relatives. Not employed. If that’s right, you can proceed to your room.”</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.enemies.regular[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])>>
<<run $player_deck.push(... $player_deck)>> */
<<set $temp.first_lobby to true>>
<<unset $current_loop>>
<<set _choices to [
{
text: "Start the real game",
target: "autosave lobby",
color: "green",
},
]>>
/* FIXME <<event_passage setup.action_cards[6] _choices>>*/
<<event_passage $player_deck[0] _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>>
<<run $player_equipment.add_tf_points_randomly(BodySlot._pts_per_chg)>>
<<goto "back">><<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">>
<<else>>
/* 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">>
<</if>><<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>><<if $back.at(-1) === "get ditz">><<run $back.pop()>><</if>>
<<set _distr_card_amt to $player_deck.filter(card => card.name === "Ditzy Thought").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: "Your 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 _stat_distraction + _distr_card_amt gte 10>>
<<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 setup.show_dialog("Forget this card?", "autoanim", "remove card confirm")>>
<</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>><<button "Back" "back">><</button>>
<br>
/*
<<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.all_player.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>
<<set $newactions ??= setup.action_cards.all_player.randomMany(5)>>
<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, _cards range setup.action_cards>><<capture _key, _cards>>
<<set _key to _key.replaceAll("_", " ") + " (" + _cards.length + " cards)" + "<br>">>
<<linkreplace _key>>
<<print _key>>
<div class="grid5col">
<<for _card range _cards>>
<<action_card _card>>
<</for>>
</div>
<<done>><<run setup.activate_tilt()>><</done>>
<</linkreplace>>
<</capture>><</for>><<button "Back" "back">><</button>>
<ul>
<<for _cat range setup.enemies>>
<<for _enemy range _cat>><<capture _enemy>>
<<set _txt to "Fight " + _enemy.name>>
<li>[[_txt|battle pre calc][$back.push("battle end test"); $enemy to _enemy]]</li>
<</capture>><</for>>
<</for>>
</ul>/* Given $enemy.difficulty, set $temp.new_cards to an array of 3 random cards, weighted by rarity */
/* TODO weighting or whatever for different enemies */
<<set _drops to clone(setup.action_cards.player_drops)>>
/*
<<set setup.card_rarity_weights ??= [
[80, 20, 0, 0],
[50, 40, 10, 0],
[20, 40, 30, 10],
[0, 30, 50, 20],
[0, 10, 60, 30],
]>>
<<set _rar_weights to setup.card_rarity_weights[$enemy.difficulty - 1]>>
*/
<<set _rar_weights to [40, 30, 20, 10]>>
<<set _weights to _drops.map(c => {
let w = _rar_weights[c.combat_reset().rarity] ?? 10;
if(c.name.includes("+")) { /* if upgraded... */
w /= 2;
}
return w;
})>>
<<set $temp.new_cards to []>>
<<set _count to Math.clamp($player_stats.focus, 1, 15)>>
<<for _x = 0; _x < _count; _x++>>
<<set _idx to alias_sampler(_weights)()>>
<<set $temp.new_cards.push(_drops.splice(_idx, 1)[0])>>
<<set _weights.splice(_idx, 1)>>
<</for>>
<<run $temp.new_cards.sort(setup.card_name_compare)>>
<<goto "card selection">>/* menu for choices from $temp.new_cards (via precalc), then go back */
<p class="largertext">You must add one of these actions to your deck:</p>
<<set _grid to "grid" + Math.clamp($temp.new_cards.length, 3, 5) + "col">>
<div @class="_grid">
<<for _card range $temp.new_cards>><<capture _card>>
<a data-passage="back" data-setter="$player_deck.push(clone(_card))">
<<action_card _card notilt>>
</a>
<</capture>><</for>>
</div>
/*
<div class="flexbuttons">
<button class="btn btn-red" data-passage="back" data-setter="$player_equipment.add_tf_points_randomly(1)">
Skip adding card for +1 ?tf
</button>
</div>
*/<<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[3])>>
<<run $player_deck.push(_ecard)>>
<<set _passage += "<br>I felt great about echo hunting. But that changed. Suddenly I felt ditzy. What is this place doing to me?">>
<</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[4])>>
<<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>>/*<<run $player_equipment.update_perception($enemy.name)>>*/
<<set $bat_effects to clone($combat_stats)>>
/* Copy '_base' effects to their normal ones */
<<for _suit range setup.card_effects>>
<<set $bat_effects[_suit] to $bat_effects[_suit + "_base"]>>
<</for>>
/* Add in player "buffs" (effects) */
<<for _stat, _val range setup.effect_fns.get_combat($effects)>>
<<set $bat_effects[_stat] += _val>>
<</for>>
/* Set "player damage" stats here too-- these don't take effect until combat ends */
<<set $bat_effects.max_energy to Math.min(10, $player_stats.energy)>>
<<set $bat_effects.energy to $bat_effects.max_energy>>
<<set $bat_effects.tf to 0>>
<<set $bat_effects.exhausted to []>>
/* Player deck setup */
<<set $bat_stock to clone($player_deck).filter(x => x !== null && x !== undefined)>>
<<for _card range $bat_stock>>
<<run _card.combat_reset()>>
<</for>>
/* Embarrassed cards */
<<set _emb to $player_stats.fem - $player_stats.identity_lvl>>
<<if _emb gt 0>>
<<set _emb_card to setup.action_cards.all_player["embarrassed_f"].combat_reset()>>
<<else>>
<<set _emb_card to setup.action_cards.all_player["embarrassed_tf"].combat_reset()>>
<</if>>
/* each point is worth 10% of the deck in card count
e.g. with deck size of 10, 1 point -> add 1 emb. card */
/*
<<set _emb_count to Math.ceil((Math.abs(_emb) / 10) * $bat_stock.length)>>
<<for _i = 0; _i < _emb_count; _i++>>
<<run $bat_stock.push(clone(_emb_card))>>
<</for>>
*/
<<if random(1, 10) lt Math.abs(_emb)>>
<<run $bat_stock.push(clone(_emb_card))>>
<</if>>
<<set $bat_hand to $bat_stock.pluckMany($bat_effects.refresh)>>
<<set $bat_dump to []>>
/* Other combat vars */
<<set $next_power_multiplier to 0>>
<<set $next_power_addition to 0>>
<<unset $draw_filter, $battle_won>>
/* Enemy setup */
<<set _enemy_rate to $enemy.power_rate ?? 1>>
<<set _enemy_diff to $enemy.difficulty ?? 1>>
/*
<<set _enemy_rate += ($current_loop?.combat_count ?? 0) * 0.2>> */
<<set _loop_diff to $current_loop?.difficulty ?? 1>>
<<set $enemy_power to Math.round((_enemy_rate * _enemy_diff) * (5 + $player_stats.productivity))>>
/* save enemy power for later calc... */
<<set $temp.enemy_power to $enemy_power>>
/* TODO combine all the battle vars into one object... */
<<set $temp.deck_idx to $enemy_progression?.[$enemy.type]?.[$enemy.id] ?? 0>>
<<set $bal_deck to $enemy.left_decks[$temp.deck_idx].map(setup.id_to_enemy_card)>>
<<set $cor_deck to $enemy.right_decks[$temp.deck_idx].map(setup.id_to_enemy_card)>>
<<goto "battle page">>/* <p>debug: Go back to <code><<print $back.at(-1)>></code>
by [[winning|battle end][$battle_won to true]] or [[losing|battle end][$battle_won to false]]</p> */
<div id="battlediv">
<<include "battle page incl">>
</div>
<<done>>
<<if not hasVisited("battle end")>>
<<run setup.battle_tutorial()>>
<</if>>
<</done>>/*
<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: $bat_hand.length</p>
your hand: <br>
*/
<<set _top_of_hand to $bat_hand.slice(0, 5)>>
<<for _card range _top_of_hand>>
<<run _card.run_pre_play()>>
<</for>>
<<if $bal_deck.length is 0>>
<<set $bal_deck to $enemy.left_decks[$temp.deck_idx].map(setup.id_to_enemy_card)>>
<</if>>
<<run $bal_deck[0].run_pre_play()>>
<<if $cor_deck.length is 0>>
<<set $cor_deck to $enemy.right_decks[$temp.deck_idx].map(setup.id_to_enemy_card)>>
<</if>>
<<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)>>
<button id="helpbtn" style="position: absolute;">Combat Help</button>
<div class="grid3col" style="gap: 1em; align-items: center; margin-bottom: auto;">
<div class="flexdown" style="width: 80%; margin: auto;">
<<if $bal_deck[0].is_playable>>
<<playable_action $bal_deck 0>>
<<else>>
<<action_card $bal_deck[0] disabled notilt>>
<</if>>
<<statbar "stress">>
</div>
<div class="flexdown">
<<event_card $enemy $enemy_power>>
<<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="battle end" data-setter="$battle_won to true">Win</button>
<button class="btn" data-passage="battle end" data-setter="$battle_won to false">Lose</button>
</div>
<<else>>
<<effect_stats>>
<</if>>
<<raw_statbar "energy" $bat_effects.energy>>
/*<<if ($enemy.capped_stat ?? "energy") is "energy">>
<p>Energy for this fight: $bat_effects.energy / $bat_effects.max_energy</p>
<<else>>
<p>Your Energy: $player_stats.energy / $player_stats.max_energy</p>
<</if>>
<<if $enemy.capped_stat is "tf">>
<p>TF: $bat_effects.tf / 10</p>
<</if>>*/
</div>
<div class="flexdown" style="width: 80%; margin: auto;">
<<if $cor_deck[0].is_playable>>
<<playable_action $cor_deck 0>>
<<else>>
<<action_card $cor_deck[0] disabled notilt>>
<</if>>
<<statbar "arousal">>
</div>
</div>
<div class="grid5col playerhandbg">
<<for _idx, _card range _top_of_hand>>
<<if _playable[_idx]>>
<<playable_action $bat_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>
/* 1 card pending, 2 cards pending, etc.
<<set _btn_txt to `+ ${$bat_hand.length - 5} card${$bat_hand.length gt 6 ? "s" : ""} pending`>> */
<<set _btn_stock to `Stock (${$bat_stock.length})`>>
<<set _btn_hand to `Hand (${$bat_hand.length})`>>
<<set _btn_dump to `Dump (${$bat_dump.length})`>>
<<set _btn_exhaust to `Exhausted (${$bat_effects.exhausted.length})`>>
<div id="deck-mgmt" class="flexbuttons">
<<button _btn_stock>>
<<run setup.show_dialog("Current Stock", "inv-dialog autoanim", "stock dialog")>>
<</button>>
<<if $bat_hand.length gt 5>>
<<button _btn_hand>>
<<run setup.show_dialog("Current Hand", "inv-dialog autoanim", "hand dialog")>>
<</button>>
<<else>>
<button disabled>_btn_hand</button>
<</if>>
<<button _btn_dump>>
<<run setup.show_dialog("Current Dump", "inv-dialog autoanim", "dump dialog")>>
<</button>>
<<if $bat_effects.exhausted.length gt 0>>
<<button _btn_exhaust>>
<<run setup.show_dialog("Exhausted Cards", "inv-dialog autoanim", "exhaust dialog")>>
<</button>>
<</if>>
<<if _hand_count lt 5>>
/* TODO what if it's a TF fight...? meh */
<<set _gu_cost to Math.round($bat_effects.energy / 2)>>
<button class="btn btn-red" data-passage="battle end" data-setter="$battle_won to false; $bat_effects.energy -= _gu_cost">Give up? -<<print _gu_cost>> ?energy</button>
<</if>>
</div>
<<done>>
<<run setup.activate_tilt()>>
<<run $("#helpbtn").ariaClick(setup.battle_tutorial)>>
<</done>>/* This passage is for "pre-calc" things after all battles */
/* cleanup deck & other battle vars */
<<set $player_deck to $bat_stock.concat($bat_hand, $bat_dump, $bat_effects.exhausted)
.filter(card => card !== null && card !== undefined && card.suit !== "token")
.map(card => card.combat_reset())
.sort(setup.card_name_compare)>>
<<unset $bat_stock, $bat_hand, $bat_dump, $bal_cards, $cor_cards, $draw_filter, $mana>>
/* Apply "damage" to long-term stats */
<<run $player_equipment.add_tf_points_randomly($bat_effects.tf)>>
<<set $temp.tf to $bat_effects.tf>>
<<set $temp.energy_lost to $bat_effects.max_energy - $bat_effects.energy>>
<<set $player_stats.energy -= $temp.energy_lost>>
<<if $player_stats.energy lte 0>>
/* If the player is out, go through normal consequences from end of $back, then kick player out */
<<run $back.splice(-1, 0, "battle energy loss")>>
<</if>>
<<set $player_stats.stress -= 10>>
<<set $player_stats.arousal -= 10>>
<<unset $bat_effects>>
<<goto "battle review">>/* TODO show stat changes...? */
<<if $battle_won>>
<<set _ecard to clone($enemy)>>
<<set _ecard.title to "You won!">>
/* Enemy progression stuff */
<<set _new_npc to $enemy.fg_img is "npc">>
<<set _ty to $enemy.type>>
<<set _id to $enemy.id>>
<<set $temp.enemy_prog to $enemy_progression[_ty][_id]>>
<<set _any_prog to $temp.enemy_power gte $enemy.prog_thresholds[$temp.enemy_prog]>>
<<set $temp.new_prog to _any_prog and $temp.enemy_prog lt $enemy.max_progression>>
<<if _any_prog and _new_npc>>
<<run $back.push("npc progression calc")>>
<</if>>
<<if $temp.new_prog>>
<<set $enemy_progression[_ty][_id] += 1>>
<</if>>
<<event_passage _ecard setup.ok_choices>>
<p class="largertext">
You won the fight against $enemy.name.
<<if $temp.new_prog and not _new_npc>>
They seem... different than when you last saw them.
<</if>>
</p>
<p class="largertext">
<<if $temp.energy_lost isnot 0>>
You spent $temp.energy_lost energy.
<</if>>
<<if $temp.tf is 0>>
<<if $enemy.capped_stat is "tf">>
You managed to avoid further body transformation.
<</if>>
/* else say nothing */
<<else>>
You were transformed by <<statnum "tf" $temp>> during the fight.
<</if>>
</p>
<<if _any_prog and _new_npc>>
<p class="largertext">
$enemy.name is getting your attention...
</p>
<</if>>
<</event_passage>>
<<else>>
<<set _ecard to {title: "You lost!", color: "brown", bg_img: "Passing Out_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p class="largertext">
You lost the fight against $enemy.name.
<<if $temp.energy_lost isnot 0>>
You lost $temp.energy_lost energy.
<</if>>
<<if $temp.tf isnot 0>>
You got transformed by <<statnum "tf" $temp>> as a result.
<</if>>
</p>
<</event_passage>>
<</if>><<set _npc_items to $npc_items[$enemy.type][$enemy.id]>>
<<set _alts to _npc_items.get_all_alternatives()>>
/* prevent the "quest item" accessory from being changed early */
<<if $temp.enemy_prog lt $enemy.max_progression>>
<<set _alts to _alts.filter(item => not (item.slot === "accessory" && item.id === 0))>>
<</if>>
<<set $temp.npc_alts to _alts.pluckMany(3)>>
<<goto "npc progression choice">><<set _npc_items to $npc_items[$enemy.type][$enemy.id]>>
<<set _choices to []>>
<<set _sfx to function(i) {return function() {
_npc_items.replace_item($temp.npc_alts[i]);
}}>>
<<for _idx, _item range $temp.npc_alts>>
<<if _item.id is 0>>
<<set _txt to "Remove " + _npc_items[_item.slot].name + " (" + _item.slot + ")">>
<<else>>
<<set _txt to "Wear " + _item.name + " (" + _item.slot + ")">>
<</if>>
<<run _choices.push({
text: _txt,
target: "npc progression chg",
side_effects: _sfx(_idx),
})>>
<</for>>
<<if not $temp.new_prog>>
<<run _choices.push({
text: "Change nothing",
target: "back",
color: "gray",
})>>
<</if>>
<<event_passage $enemy _choices>>
<p>$enemy.name offered to change their outfit for you.</p>
<</event_passage>><<set _choices to [
{
text: "Move on",
target: "back",
},
]>>
<<set _anim to $enemy.cutscenes.find(cs => $temp.enemy_prog gte cs[0])[1]>>
<<if _anim isnot null>>
<<set _choices[0].text to "Ignore them and move on">>
<<run _choices.unshift({
text: "Have some fun with " + $enemy.name,
color: "pink",
target: "play animation",
side_effects: () => $temp.anim = _anim,
})>>
<</if>>
<<event_passage $enemy _choices>>
<p>Your eyes linger on $enemy.name's new look.
<<if _anim isnot null>>
They take notice and beckon you closer...
<</if>>
</p>
<</event_passage>><<set _ecard to {title: "Passing out...", color: "brown", bg_img: "Passing Out_b.jpg"}>>
<<set _choices to [
{
text: "Back to the lobby...",
target: "autosave lobby",
color: "darkred",
},
]>>
<<event_passage _ecard _choices>>
<p>Since you ran out of energy, you passed out...</p>
<</event_passage>><p>This is your stock of cards. Whenever you draw cards, they are randomly selected from this set.</p>
<p>If you run out, it will be repopulated from
<<link "your previously played cards (the dump)">>
<<run setup.replace_dialog("Current Dump", "inv-dialog autoanim", "dump dialog")>>
<</link>>.</p>
<<if $bat_stock.length gt 0>>
<<card_grid $bat_stock>>
<<else>>
<div class="grid2col">
<p class="gridfilltxt">You have no cards in your stock; this will repopulate next time you draw cards.</p>
</div>
<</if>><p>This is your current hand of drawn cards. Only the first 5 cards here are able to be played,
but some card effects could interact with any of these.</p>
<<card_grid $bat_hand>><p>This is your "dump," the set of cards you have previously played. After you run out of cards in
<<link "your stock">>
<<run setup.replace_dialog("Current Stock", "inv-dialog autoanim", "stock dialog")>>
<</link>>,
these cards will be moved back to the stock.</p>
<<if $bat_dump.length gt 0>>
<<card_grid $bat_dump>>
<<else>>
<div class="grid2col">
<p class="gridfilltxt">You have no cards in your dump right now; play some cards!</p>
</div>
<</if>><p>These cards are "exhausted," meaning they cannot be played again until the next combat.</p>
<<if $bat_effects.exhausted.length gt 0>>
<<card_grid $bat_effects.exhausted>>
<<else>>
<div class="grid2col">
<p class="gridfilltxt">You have not exhausted any cards</p>
</div>
<</if>><p>
<<if $battle_won>>
Congrats, you won!
<<else>>
Oh no, you lost...
<</if>>
</p>
[[back]] * [[Try again?|battle pre calc][$back.push(passage())]]/* this is the "root" of the game so reset $back, just in case */
<<set $back to [passage()]>>
<<set _choices to [
{
text: "Dive into the Loop",
target: "loop selection",
color: "green",
},
/*
{
text: "Recreation Room",
target: "lobby relaxation",
color: "royalblue",
},
{
text: "Reverse Store",
target: "lobby appearance",
color: "darkblue",
},
*/
{
text: "Your Room",
target: "player room",
color: "purple",
},
/*
{
text: "Skill Training",
target: "lobby skills",
color: "purple",
},
{
text: "Financial Office",
target: "lobby debt",
color: "darkorange",
},*/
{
text: "Game Difficulty",
target: "game difficulty",
color: "darkred",
},
]>>
<<if $temp.first_lobby>>
<<run _choices.splice(1, 1)>>
<</if>>
/*<<for _c range _choices>>
<<set _c.side_effects to () => $back.push(passage())>>
<</for>>*/
<<include ChangingRoomExtra>>
<<include LobbyBanner>>
<<set _hints to [
"Training and Shopping can improve your power a lot. During training you can remove unwanted action cards and add better cards to improve your strategy. Shopping can provide temporary effects to your battle stats.",
"Characters become stronger with higher ?productivity. ?focus and ?compulsion don't make them stronger.",
"?compulsion makes prices higher while shopping. Though with higher ?compulsion you have more chances to find the clothing you need.",
"?focus makes prices higher while training. Though with higher ?focus you have more chances to find action cards you want.",
"Try to keep ?productivity high enough to earn money easily but low enough to still be able to defeat characters.",
"Effects don't change if you replace clothes with something else--if you buy different 'bottom' clothing 3 times in a row, you'll still gain 3 effects.",
"The only way to remove effects gained during shopping is to wait for them to expire on their own. They decay whenever you rest in your room.",
"Bonus Battle Stats (?refresh ?flow ?drain ?burst) that you usually get in the shop are added each turn ?enemy during Battle Phase. So +4 ?burst bonus effect from the shop gives you +4 ?burst each turn (?enemy) during Battle Phase.",
"New cards, decks, characters, jobs, etc. will be added in future updates!",
"You can click your character on the left sidebar to switch between visibility layers (naked/underwear/clothes)",
"During Battle Phase, try to keep ?stress and ?arousal as low as possible. You never know what cards you'll get next turn.",
"Using ?feminine actions gives you ?feminine experience points. Using ?masculine actions gives ?masculine experience points. The amount of points is based on rarity of the card: ?common ?rare ?epic ?legendary.",
"You don't <em>have</em> to play your ?feminine cards; you could just ignore them. That may make it harder to win fights, though, especially at the beginning of the game.",
"If your ?fem and ?identity don't match exactly, then some Embarassed cards might be shuffled into your deck right before the Battle Phase. You'll get more of them the bigger the difference is between ?fem and ?identity.",
/*"The number of Embarassed cards is +10% from total number of cards in your hand for each point of difference between ?fem and ?identity. So if you have 20 cards in your deck and 5 points of difference between ?fem and ?identity then 10 embarassed cards gonna be shuffled in.",*/
"If you struggle too much - consider training more. You can get new cards by winning against Characters during training. High ?focus can help with getting the actions you want.",
"If you think you can't win during the Battle Phase - you can give up early. This way you can still save half of energy left for the battle. For example, if you spent 2 energy points and gave up - you lose 6 energy in total (2+8/2) (would have lost 10 otherwise).",
"Some Characters are stronger not just from having more Hit Points, but from having more negative end-turn ?enemy cards.",
"Upgrading cards is important, but not all the times. Sometimes combinations of upgraded card + not upgraded are quite strong.",
"Token (?token ) and Status (?status) cards both can be used only once per battle. Though ?token cards are removed from the deck after use or after the battle, while ?status cards stay in your deck untill you remove them via training.",
"Consider upgrading your room if you have some extra ?money. It might help a lot.",
"?status action cards are usually quite strong, but usually have effect on your ?identity or ?tf. Though, sometimes it's better to use them to avoid even worse consequences.",
"If you can't pay your bills - you can pay it off by working a night shift.",
"?focus and ?compulsion refresh daily, so it might be wise to visit training and shopping loops daily.",
"With the higher ?focus you are more likely to get better cards when Training.",
"Every night the Loop changes you based on your experience. So learn to control your Experience gain. Mostly it's based on the cards in your deck. Choices in the Loop also give you a bit of experience.",
]>>
<div class="grid2col">
<div>
<a href="https://www.patreon.com/sifagames" target="_blank">
<div id="anim" style="width: 100%; aspect-ratio: 4 / 1;"></div>
</a>
<p style="font-size: smaller">This banner uses our new animation tech! If it doesn't work, please try updating your browser. You need something with OpenGL support!</p>
<a href="https://www.patreon.com/posts/122353149" target="_blank">
<p style="font-size: bigger">Changelog</p>
</a>
<br>
<i>
<<if $temp.first_lobby>>
<p>After you travel back from your first loop, you'll have more options here, but for now, let's get started! Dive into the loop!</p>
<<else>>
<p>Hint:</p>
<p><<print _hints.random()>></p>
<</if>>
</i>
</div>
<div class="flexdown">
<h1 class="eventtitle">Lobby</h1>
<img src="img2/events/images/lobby_b.jpg" class="eventimg">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
</div>
</div>
<<done>>
<<run setup.show_animation("banner_xmas")>>
<</done>><<goto "lobby">><<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>Current difficulty - <b><<print _difficulties[$game_difficulty]>></b></p>
<br>
<p>You can change game difficulty here. At the moment, it only affects the amount of power your cards have in combat.</p><p>It's not balanced that well, so don't be afraid to switch it if you're feeling too much pain, or not enough.</p>
<</event_passage>><<set _choices to [
{
requirement: "energy",
threshold: 10,
disabled_text: "Need more ?energy to work",
text: "Gift Packing Job",
target: "start loop",
side_effects: () => $current_loop = clone(setup.loops.job),
},
{
requirement: "compulsion",
threshold: 1,
disabled_text: "Need more ?compulsion to go shopping",
text: "Shopping",
target: "start loop",
side_effects: () => $current_loop = clone(setup.loops.shop),
},
{
requirement: "focus",
threshold: 1,
disabled_text: "Need more ?focus to train",
text: "Training",
target: "start loop",
side_effects: () => $current_loop = clone(setup.loops.training),
},
{
text: "Back to lobby",
color: "gray",
target: "back",
},
]>>
/*
<<if $player_stats.energy lt 6>>
<<for _i = 0; _i < 3; ++_i>>
<<set _choices[_i].disabled to true>>
<</for>>
<</if>>
*/
<<set _ecard to {title: "Staging Room", color: "hotpink", bg_img: "Women Changing Room_b.jpg"}>>
<<event_passage _ecard _choices>>
/* if $temp.first_lobby>>
<p>You don't have any funding at the moment, so you should start with earning some!</p>
<p><strong>Entering any loop costs 5 ?energy.</strong> You'll want more than that in the loop itself;
but you have plenty to start now.</p>
else>> */
<p>Earn ?money by working in the job loop. You'll need money to rest and buy upgrades elsewhere.</p>
<p>Buy new clothes and gain useful effects in the shopping loop.</p>
<p>Get better cards and improve your deck in the training loop.</p>
/* <p><strong>Entering any loop costs 5 ?energy.</strong> You'll want more than that in the loop itself;
make sure you rest in [[your room|player room]] sometimes!</p>
/if>> */
<</event_passage>>/* aka loop event calc. Autosave when we eventually come back */
<<if $back.at(-1) is "lobby">>
<<run $back.pop(); $back.push("autosave lobby");>>
<</if>>
/* <<set $player_stats.energy -= 5>> */
/* TODO maybe we want some kind of interruption events, but until then... */
<<set $events to new Array(25)>>
<<run $events.fill(setup.event_passages[$current_loop.type + "-loop"][0])>>
/*<<set $player_perm_equip to clone($player_equipment)>>*/
/* assume that we showed TFs from lobby/etc */
<<run $player_equipment.reset_body_chg()>>
<<goto "next event">><<set _body_orig to true>>
<<for _bslot range Object.keys(setup.all_body)>>
<<if _bslot isnot "penis">>
<<if $player_equipment[_bslot].id isnot 0>>
<<set _body_orig to false>>
<<break>>
<</if>>
<<else>>
<<if $player_equipment[_bslot].id isnot setup.all_body.penis.at(-1).id>>
<<set _body_orig to false>>
<<break>>
<</if>>
<</if>>
<</for>>
<<set _choices to [
{
disabled: _body_orig,
disabled_text: "Body is in original state.",
text: "Body Restoration",
target: "body restore",
color: "darkblue",
},
/*
{
text: "Cosmetic Alteration",
target: "cosmetic restore",
color: "purple",
}, */
{
text: "Back",
target: "back",
color: "gray",
},
]>>
<div class="grid2col">
<div>
<p>Various items can be found in this room. However, they say I should be interested only in Masculinization potions for now.</p>
<br>
<p><i>Later more stuff would be added that you can buy here.</i></p>
</div>
<div class="flexdown">
<h1 class="eventtitle">Reverse Store</h1>
<img src="img2/events/images/restoration_b.jpg" class="eventimg">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
</div>
</div><<set _restore_options to []>>
<<set $temp.extra_body_restores ??= 0>>
<<for _bslot range Object.keys(setup.all_body)>>
<<set _old_id to $player_equipment[_bslot].id>>
<<if _bslot isnot "penis">>
<<if _old_id gt 0>>
<<run _restore_options.push({
new: setup.all_body[_bslot][_old_id - 1],
past_prev: _old_id lte $player_perm_equip[_bslot].id,
})>>
<</if>>
<<else>>
<<if _old_id lt setup.all_body.penis.at(-1).id>>
<<run _restore_options.push({
new: setup.all_body[_bslot][_old_id + 1],
past_prev: _old_id gte $player_perm_equip[_bslot].id,
})>>
<</if>>
<</if>>
<</for>>
/* for whatever reason it doesn't like capturing stuff in side effects,
so here's a weird workaround for that nonsense */
<<set _sfx to function(idx) { return function() {
const re = _restore_options[idx];
$player_stats.money -= _choices[idx].threshold;
$player_equipment.replace_with(re.new);
if(re.past_prev) { $temp.extra_body_restores += 1; }
}}>>
<<set _choices to []>>
<<set _base_cost to 50>>
<<for _idx, _re range _restore_options>>
<<set _threshold to _base_cost>>
<<if _re.past_prev>>
<<set _threshold *= 2 + $temp.extra_body_restores>>
<</if>>
<<run _choices.push({
requirement: "money",
threshold: _threshold,
disabled_text: "Can't afford " + _re.new.place + " restoration (" + _threshold + "?money)",
text: "Restore " + _re.new.place + " for " + _threshold + "?money",
target: "body restore",
side_effects: _sfx(_idx),
})>>
<</for>>
<<run _choices.push({
text: "Back",
target: "back",
color: "gray",
})>>
<<set _ecard to {title: "Masculinization", color: "darkblue", bg_img: "masculinization_b.jpg"}>>
<<event_passage _ecard _choices>>
<<if _restore_options.length is 0>>
<p>"Hmm, you look like you're in exactly the same state as you arrived at this place.
Can't say the same about others..."</p>
<p>Yeah, I can imagine why...</p>
<p>"Well, there's not much we can do for you here, so why not move on?" The woman continued sorting papers.</p>
<<else>>
<p>"Ah, have you come in to "fix" yourself?
You know, you'd have an easier time getting out of here if you just accepted these small changes..." The woman said inspecting my body.</p>
Why is she mocking me? At least show me the prices...
<p>"Ghm, In any case, we can help you return to the form you first entered this place with."</p>
<p>Then "the best supporter who doesn't work for money" opened a box with the blue potions and their prices.</p>
<p>"Ah! Just to note, it's way easier for us, and cheaper for you, if you revert changes right after the loop. Otherwise... Well, the changes become more permanent."</p>
<p>Then she explained me the options.</p>
<<for _re range _restore_options>>
<<equip_tf $player_equipment[_re.new.place] _re.new>>
<<if _re.past_prev>>
<p><i>*at additional cost</i></p>
<</if>>
<</for>>
<</if>>
<</event_passage>>TODO cosmetics
[[back]]/* TODO passages for each choice */
<<set _choices to [
{
requirement: "money",
threshold: 20,
disabled_text: "Can't afford a regular stay",
text: "Rent a relaxation room for men 20?money",
color: "Dark Blue",
target: "back",
side_effects: () => {
$player_stats.stress = 0;
$player_stats.arousal = 0;
$player_stats.money -= 20;
},
},
{
text: "Use a relaxation room for women",
color: "magenta",
target: "back",
side_effects: () => {
$player_stats.stress = 0;
$player_stats.arousal = 0;
$player_stats.identity += 1;
$player_stats.airhead += 3;
$player_deck.push(clone(setup.punish_cards[3]));
$player_deck.push(clone(setup.punish_cards[3]));
},
},
{
text: "Back",
target: "back",
color: "gray",
},
]>>
<<if $player_stats.stress is 0 and $player_stats.arousal is 0>>
<<run _choices.shift(); _choices[0].disabled = true; _choices[0].disabled_text to "No need to relax">>
<</if>>
<div class="grid2col">
<div>
<p>"Hello." I approached the keeper. "Can I get some me time here?"</p>
<p>"Greetings! You can use one of these rooms." He waved his hand showing the doors.
"However, our Male section is busy at the moment, so we charge 20 for that. Female section is still free to use. Just don't forget to lock the door."</p>
<p>I wonder if it happened because girls section is 10 times bigger. Anyway, I need that if I want to relax before the next loop.</p>
</div>
<div class="flexdown">
<h1 class="eventtitle">Recreation Rooms</h1>
<img src="img2/events/images/relaxation_b.jpg" class="eventimg">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
</div>
</div>TODO - skill training--card add/remove
[[back]]<<set $temp.payment ??= 0>>
<<set _max_pmt to Math.min($player_stats.money, $debt.payment)>>
<<set _choices to [
{
requirement: "money",
threshold: 1,
disabled_text: "I have no money",
text: "Pay specified amount",
color: "blue",
target: "payment check",
side_effects: () => {
const pmt = Math.clamp(Math.floor($temp.payment), 0, _max_pmt);
$debt.payment -= pmt;
$player_stats.money -= pmt;
},
},
{
requirement: "money",
threshold: 1,
disabled_text: "I have no money",
text: "Pay as much as possible",
color: "green",
target: "payment check",
side_effects: () => {
$debt.payment -= _max_pmt;
$player_stats.money -= _max_pmt;
},
},
{
text: "Back",
target: "back",
color: "gray",
},
]>>
<<if $player_stats.money lt 1>>
<<run _choices.shift()>>
<</if>>
<<set _next_goal to setup.amount_for_next_frac()>>
<div class="grid2col">
<div>
<p>"Ah, here to pay your debt, right?" The secretary did something on her computer.
"You currently owe ?money<<print $debt.payment>>.
<<if _next_goal gt 0>>We'll let you try venturing into more difficult loops
after you pay another ?money<<print _next_goal>> toward your debt..<</if>>"</p>
<<if _next_goal gt 0>>
<p>"What is the problem to let me do it straight away?
After all, I can get money faster this way."</p>
<p>She sighed. "You know, rules are made not just to make your life harder.
We don't want to see some airhead bimbo returned instead of yourself."</p>
<p>"Ok, thanks I guess..." I mumbled.</p>
<</if>>
<p>"So, how much are you willing to part with? You can write any number on the tablet infront of you.
Also, don't get smart with us: we don't take decimals or negative payments."</p>
<br>
<<numberbox "$temp.payment" _max_pmt autofocus>>
</div>
<div class="flexdown">
<h1 class="eventtitle">Financial Office</h1>
<img src="img2/events/images/office_b.jpg" class="eventimg">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
</div>
</div>
<<done>><<script>>
$("#numberbox-temppayment")
.attr("min", 0)
.attr("max", temporary().max_pmt)
.attr("step", 1)
.attr("style", "width: 100%; background: black;");
<</script>><</done>><<if $debt.payment lte 0>>
<<set $debt.payment to 0>>
<<set _ecard to {title: "Debt Paid!", color: "blue", bg_img: "Men Changing Room_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p>You paid all the money, which means that you won!
Unfortunately, Sifa was too lazy to write much of an ending.
But we're still working on the game, and we have plenty of materials prepared for further updates.
Please keep an eye on us online, and feel free to give us feedback!
Thanks for your time, you're awesome!</p>
<</event_passage>>
<<else>>
<<goto "back">>
<</if>><<set _choices to [
{
text: "Back to Lobby",
target: "back",
color: "gray",
},
]>>
<<set _deck_cost to 100>>
<<set _ecard to {title: "Changing Room", color: "hotpink", bg_img: "Women Changing Room_b.jpg"}>>
<<event_passage _ecard _choices>>
<<if $player_stats.masculine gt _deck_cost or $player_stats.feminine gt _deck_cost>>
<p>You can pick an alternate starting deck here for the cost of some experience:</p>
<<else>>
<p>Once you have more experience, you can buy an alternate starting deck. For now, start with the standard deck.</p>
<</if>>
<div class="grid2col">
<<for _name, _cards range setup.starting_deck_choices>><<capture _name, _cards>>
<div class="flexdown">
<h2 style="margin: auto; text-align: center">
<<print _name[0].toUpperCase() + _name.slice(1)>> starter deck
</h2>
<div class="flexbuttons">
<<set _btxt to _deck_cost + " ?masculine">>
<<if $player_stats.masculine gte _deck_cost>>
<<button _btxt>>
<<set _cost_type to "masculine">>
<<set _dcards to _cards.map(c => c.combat_reset())>>
<<run setup.show_dialog("Confirm start", "autoanim", "deck selection dialog")>>
<</button>>
<<else>>
<button class="btn" disabled>_btxt</button>
<</if>>
<<set _btxt to _deck_cost + " ?feminine">>
<<if $player_stats.feminine gte _deck_cost>>
<<button _btxt>>
<<set _cost_type to "feminine">>
<<set _dcards to setup.starting_deck_choices_f[_name].map(c => c.combat_reset())>>
<<run setup.show_dialog("Confirm start", "autoanim", "deck selection dialog")>>
<</button>>
<<else>>
<button class="btn" disabled>_btxt</button>
<</if>>
</div>
</div>
<</capture>><</for>>
</div>
<div class="flexbuttons">
<<button "Use the free standard deck">>
<<set _cost_type to null>>
/* player's deck was already reset, so just use it. Lets the cheat menus work. */
<<set _dcards to $player_deck.map(c => c.combat_reset())>>
<<run setup.show_dialog("Confirm start", "autoanim", "deck selection dialog")>>
<</button>>
</div>
<<include ChangingRoomExtra2>>
<</event_passage>><<if _cost_type isnot null>>
<<set _cbtn to "Pay & start!">>
<p>For _deck_cost <<print "?" + _cost_type>>, you can start with these cards:</p>
<<else>>
<<set _cbtn to "Start!">>
<p>You can start with these cards for free:</p>
<</if>>
<div class="grid4col" style="width: 45em;">
<<for _c_card range _dcards>>
<<action_card _c_card>>
<</for>>
</div>
<div class="flexbuttons">
<<button _cbtn "start loop">>
<<if _cost_type isnot null>>
<<set $player_stats[_cost_type] -= _deck_cost>>
<</if>>
<<set $player_deck to clone(_dcards)>>
<<run Dialog.close()>>
<</button>>
<<button "Look at the other decks?">><<run Dialog.close()>><</button>>
</div>
<<done>>
<<addclass "#ui-dialog-body button" "btn">>
<<run setup.activate_tilt()>>
<</done>>/* TODO dyanmic cost, warn player if can't afford, low benefit, etc. */
<<set _choices to [
{
text: "Rest: -" + $player_stats.bills + "?money",
target: "rest animation choice",
color: $player_stats.bills gt $player_stats.money ? "red" : "green",
},
{
text: "Room Upgrades",
side_effects: () => $back.push(passage()),
target: "room upgrades",
color: "lightblue",
},
{
text: "Back",
target: "back",
color: "gray",
},
]>>
<div class="grid2col">
<div>
<p>You can rest to restore energy here, but you'll need to pay upkeep fees ?bills afterward.
If you can't afford them, you'll have to work off the debt as soon as you're done resting.</p>
<<include "room stats">>
</div>
<div class="flexdown">
<h1 class="eventtitle">Your Room</h1>
<img src="img2/events/images/the bedroom of love_b.jpg" class="eventimg">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
</div>
</div><p class="largertext">For the current state of your room, when you rest, the following stats will change:</p>
<ul class="largertext">
<li>Your maximum ?energy will become <<print $player_stats.get_room_stat("max_energy")>></li>
<li>
You will gain <<print $player_stats.get_room_stat("energy_restore")>> ?energy and
<<print $player_stats.get_room_stat("prod_bonus")>> ?productivity.
</li>
<li>
Your ?focus will become <<print $player_stats.get_room_stat("focus_bonus")>> and
your ?compulsion will become <<print $player_stats.get_room_stat("comp_bonus")>>.
</li>
<<if $effects.length gt 0>>
<li>Extra combat stats gained while shopping may expire--see the menu in the sidebar.</li>
<</if>>
</ul><<set _choices to []>>
<<set _sugarcube_capture_doesnt_work to function(stat, cost) {return function() {
$player_stats["room_" + stat] += 1;
$player_stats.money -= cost;
$player_stats.bills += (cost / 10);
}}>>
<<for _stat, _info range PlayerStats.room_upgrades>>
<<set _current to $player_stats["room_" + _stat]>>
/* <<set _cost to _info.tier_cost * (_current + 1)>> */
<<set _cost to _info.tier_cost>>
<<if _current lt _info.cap>>
<<run _choices.push({
disabled: _cost gt $player_stats.money,
text: _info.text + ", -" + _cost + "?money, +" + _cost/10 + "?bills",
side_effects: _sugarcube_capture_doesnt_work(_stat, _cost),
target: "room upgrades",
})>>
<</if>>
<</for>>
<<run _choices.push({
text: "Back",
target: "back",
color: "gray",
})>>
<div class="grid2col">
<div>
<<if _choices.length gt 1>>
<p>You can buy upgrades for your room here. They increase your upkeep costs ?bills,
so don't buy them unless you can afford it!</p>
<<else>>
<p class="largertext">You've acquired all the room upgrades; congratulations!</p>
<</if>>
<<include "room stats">>
</div>
<div class="flexdown">
<h1 class="eventtitle">Room Upgrades</h1>
<img src="img2/events/images/the bedroom of love_b.jpg" class="eventimg">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
</div>
</div>/* remember, these are backwards vs. the order they actually play out */
<<set _backex to ["player rest reflect", "player rest calc", "tf loop calc"]>>
<<set setup.rest_thresholds ??= [
setup.enemies.regular[3].cutscenes.find(cs => cs[1] === "mc_rudy_oral")[0],
setup.enemies.regular[3].cutscenes.find(cs => cs[1] === "mc_rudy_ride")[0],
setup.enemies.regular[0].cutscenes.find(cs => cs[1] === "mc_elf_oral")[0],
setup.enemies.regular[0].cutscenes.find(cs => cs[1] === "mc_elf_blow")[0],
]>>
/* TODO not sure how 'direct' we should be with these choices */
<<set _choices to [
{
text: "Enjoy yourself +5 ?productivity",
side_effects() {
$temp.anim = "mc_solo";
$back.push(... _backex);
$player_stats.productivity += 5;
},
target: "play animation",
},
{
disabled: $enemy_progression.regular[3] lt setup.rest_thresholds[0],
disabled_text: "Shin isn't interested",
text: "Invite Shin +10 ?productivity",
side_effects() {
$temp.anim = "mc_rudy_oral";
$back.push(... _backex);
$player_stats.productivity += 10;
},
target: "play animation",
},
{
disabled: $enemy_progression.regular[3] lt setup.rest_thresholds[1],
disabled_text: "Shin isn't interested in a sleepover",
text: "Invite Shin to stay the night +15 ?productivity",
side_effects() {
$temp.anim = "mc_rudy_ride";
$back.push(... _backex);
$player_stats.productivity += 15;
},
target: "play animation",
},
{
disabled: $enemy_progression.regular[0] lt setup.rest_thresholds[2],
disabled_text: "Lina isn't interested",
text: "Invite Lina +10 ?productivity",
side_effects() {
$temp.anim = "mc_elf_oral";
$back.push(... _backex);
$player_stats.productivity += 10;
},
target: "play animation",
},
{
disabled: $enemy_progression.regular[0] lt setup.rest_thresholds[3],
disabled_text: "Lina isn't interested in a sleepover",
text: "Invite Lina to stay the night +15 ?productivity",
side_effects() {
$temp.anim = "mc_elf_blow";
$back.push(... _backex);
$player_stats.productivity += 15;
},
target: "play animation",
},
{
disabled: $enemy_progression.regular[3] lt setup.rest_thresholds[1] or
$enemy_progression.regular[0] lt setup.rest_thresholds[3],
disabled_text: "Shin & Lina aren't interested in a sleepover",
text: "Invite Shin & Lina to stay the night +25 ?productivity",
side_effects() {
$temp.anim = "mc_rudy_elf";
$back.push(... _backex);
$player_stats.productivity += 25;
},
target: "play animation",
},
{
text: "Back",
target: "back",
color: "gray",
},
]>>
<div class="grid2col">
<div>
<p>You could have someone join you for some <em>evening activities</em> before you go to sleep...</p>
<br>
<i><p>Hint: Progress with Characters to unlock spending time with them; you can improve ?productivity by doing so.
You can progress by winning against stronger versions of the characters.
Characters become stronger from higher ?productivity and from their difficulty level (red buttons are most difficult).
You will often notice changes in a character's look when you progress.
Characters also use more end-turn cards the more you progress. (Progress will not decrease, even if you lose.)</p></i>
</div>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
</div>
</div>/* TODO reset stress/arousal here instead of "loop end"?
Room upgrades that worsen that but reduce upkeep?
IDK, there's a lot that could be done to stats here... */
<<set $player_stats.max_energy to $player_stats.get_room_stat("max_energy")>>
<<set $player_stats.energy += $player_stats.get_room_stat("energy_restore")>>
<<set $player_stats.productivity += $player_stats.get_room_stat("prod_bonus")>>
<<set $player_stats.focus to $player_stats.get_room_stat("focus_bonus")>>
<<set $player_stats.compulsion to $player_stats.get_room_stat("comp_bonus")>>
<<set $effects to setup.effect_fns.decay($effects)>>
<<if $player_stats.money gte $player_stats.bills>>
<<set $player_stats.money -= $player_stats.bills>>
<<goto "upkeep quest calc">>
/* advance timer if can afford; increase bills if enough successful payments
<<set $debt_timer -= 1>>
<<run $back.push("upkeep quest calc")>>
<<if $debt_timer lte 0>>
<<run setup.reset_debt_timer()>>
<<set $player_stats.bills += PlayerStats._base_stats.bills.default>>
<<goto "player bill increase">>
<<else>>
<<goto "back">>
<</if>>
*/
<<else>>
/* <<run setup.reset_debt_timer()>> */
/* Using $temp.bills such that we can re-use upkeep check with a different debt (e.g fines) */
<<set $temp.bills to $player_stats.bills>>
<<goto "player upkeep check">>
<</if>><div class="grid2col">
<div>
<p>You noticed a sign posted on the outside of your door:</p>
<p><i>"Due to economic inflation, your upkeep costs have been increased to $player_stats.bills ?money."</i></p>
</div>
<div class="flexdown">
<h1 class="eventtitle">Your Room</h1>
<img src="img2/events/images/the bedroom of love_b.jpg" class="eventimg">
<<choice_btn setup.ok_choices[0]>>
</div>
</div><<set $temp.upkeep_visits ??= 0>>
<<set $temp.upkeep_visits += 1>>
<<if $player_stats.money gte $temp.bills>>
<<set $player_stats.money -= $temp.bills>>
<<set $temp.upkeep_visits to 0>>
<<goto "back">>
<<else>>
<<set _tf_choices to {
all: {weight: 2, choices: 5, pluck: 1},
}>>
<<set $temp.choices to setup.loop_choices(_tf_choices, 2)>>
<<if $temp.upkeep_visits lt 10>>
<<goto "player upkeep work">>
<<else>>
<<goto "upkeep debt forgiveness">>
<</if>>
<</if>><<set $player_stats.money -= $temp.bills>>
<<set $temp.upkeep_visits to 0>>
<<set _ecard to {title: "Working Off Debt", color: "pink", bg_img: "striptease show_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p>Despite your remaining debt, you seem to have been working long enough for the staff not to care anymore.</p>
<p>You're free to go, for now...</p>
<</event_passage>><<set _cash to (1 + $player_stats.fem) * (1 + $player_stats.identity_lvl)>>
<<set $temp.ecard to {title: "Working Off Debt", color: "pink", bg_img: "striptease show_b.jpg"}>>
<<set _all_choices to {
all: [
{
text: "Clothing Modelling:<br>" + _cash + " ?money, -2 ?energy",
side_effects() {
$player_stats.money += _cash;
$player_stats.energy -= 2;
$back.push("player upkeep check");
},
target: "upkeep clothes",
},
{
text: "Cosmetics Testing:<br>" + _cash + " ?money, -2 ?energy",
side_effects() {
$player_stats.money += _cash;
$player_stats.energy -= 2;
$back.push("player upkeep check");
},
target: "upkeep cosmetics",
},
{
text: "Occupational \"Training\":<br>" + _cash + " ?money, -2 ?energy, +2% ?identity",
side_effects() {
$player_stats.money += _cash;
$player_stats.energy -= 2;
$player_stats.identity += 2;
},
target: "player upkeep check",
},
{
text: "Drug Testing:<br>" + _cash + " ?money, -2 ?energy, 2 ?tf",
side_effects() {
$player_stats.money += _cash;
$player_stats.energy -= 2;
$player_equipment.add_tf_points_randomly(2);
},
target: "player upkeep check",
},
{
disabled: $player_deck.every(c => !c.can_flip_gender_to(true)),
text: "Convert a random action to ?feminine:<br>" + _cash + " ?money, -2 ?energy, 2 ?tf",
side_effects() {
$player_stats.money += _cash;
$player_stats.energy -= 2;
$temp.to_fem = true;
$back.push("player upkeep check");
},
target: "tf loop card flip",
},
],
}>>
<<set _choices to $temp.choices.map(c => _all_choices[c.cat][c.i])>>
<<event_passage $temp.ecard _choices>>
<p class="largertext">You still owe <<print $temp.bills - $player_stats.money>>?money in upkeep fees.
Please choose from these tasks to make up your debt:</p>
<</event_passage>>/* pick something not worn but at least as fem */
<<set _droplist to Object.values(setup.all_styles).flat()
.filter(item => item.fem gte $player_equipment[item.place].fem and setup.item_not_worn(item))>>
<<set $temp.old to $player_equipment.replace_with(_droplist.random())>>
<<goto "upkeep cosmetics result">><<event_passage $temp.ecard setup.ok_choices>>
<p class="largertext">You had a flurry of cosmetics applied, but one of them stuck around:</p>
<<equip_tf $temp.old $player_equipment[$temp.old.place]>>
<</event_passage>><<set _droplist to Object.values(setup.all_clothes).flat()
.filter(item => item.id isnot 0
and item.fem gte $player_equipment[item.place].fem
and setup.item_not_worn(item))>>
<<set $temp.old to $player_equipment.replace_with(_droplist.random())>>
<<goto "upkeep clothes result">><<event_passage $temp.ecard setup.ok_choices>>
<p class="largertext">You were made to try on way too many clothes and ended up stuck with something new:</p>
<<equip_tf $temp.old $player_equipment[$temp.old.place]>>
<</event_passage>>/* this is a calc passage... */
<<set _chg_items to $player_equipment.recent_chg_body_items()>>
<<if _chg_items.length > 0>>
<<set $temp.chg_items to _chg_items>>
<<run $back.push("player rest review")>>
<<goto "recent body tf">>
<<else>>
<<goto "player rest review">>
<</if>><<set _ecard to {title: "Waking Up", color: "white", bg_img: "the bedroom of love_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<p>You've changed since you last rested:</p>
<div class="itemtfgrid">
<div class="imgstack">
<img src="img2/char/other/charbg.svg">
<<render_char 2 "" $player_perm_equip>>
</div>
<img alt="has transformed into" src="img2/icons/green_arrow.svg">
<div class="imgstack">
<img src="img2/char/other/charbg.svg">
<<render_char 2>>
</div>
</div>
<</event_passage>>
<<set $player_perm_equip to clone($player_equipment)>><<set _tf_choices to {
all: {weight: 2, choices: 7, pluck: 1},
}>>
<<set $temp.choices to setup.loop_choices(_tf_choices, 2)>>
<<set $temp.tf_loop_visits ??= 0>>
<<set $temp.tf_loop_visits += 1>>
<<if $temp.tf_loop_visits gte 10>>
<<set $temp.tf_loop_visits to 0>>
<<goto "back">>
<<else>>
<<goto "tf loop choice">>
<</if>><<set _body_slots to $player_equipment.sorted_body_slots>>
<<set $temp.min_body to _body_slots[0]>>
<<set $temp.max_body to _body_slots.at(-1)>>
<<set _is_naked to Object.keys(setup.all_clothes).map(k => $player_equipment[k])
.every(c => c.id === 0)>>
<<set $temp.ecard to {title: "Strange Dreams", color: "purple", bg_img: "Feminization_b.jpg"}>>
<<set _all_choices to {
all: [
{
disabled: $temp.min_body.tf_points >= $temp.min_body.max_tf ||
$player_stats.feminine < 100,
text: "+10 ?tf to " + $temp.min_body.place + ": 100 ?feminine",
side_effects() {
$player_equipment.add_tf_points_to_part(10, $temp.min_body.place);
$player_stats.feminine -= 100;
},
target: "tf loop calc",
},
{
disabled: $temp.max_body.tf_points <= 0 ||
$player_stats.masculine < 100,
text: "-5 ?tf to " + $temp.max_body.place + ": 100 ?masculine",
side_effects() {
$player_equipment.add_tf_points_to_part(-5, $temp.max_body.place);
$player_stats.masculine -= 100;
},
target: "tf loop calc",
},
{
disabled: $player_stats.identity >= 100 || $player_stats.feminine < 50,
text: "+1% ?identity: 50 ?feminine",
side_effects() {
$player_stats.identity += 1;
$player_stats.feminine -= 50;
},
target: "tf loop calc",
},
{
disabled: $player_stats.identity <= 0 || $player_stats.masculine < 100,
text: "-1% ?identity: 50 ?masculine",
side_effects() {
$player_stats.identity -= 1;
$player_stats.masculine -= 100;
},
target: "tf loop calc",
},
{
disabled: $player_stats.feminine < 50 || $player_deck.every(c => c.is_fem),
text: "Convert a random action to ?feminine: 50 ?feminine",
side_effects() {
$player_stats.feminine -= 50;
$temp.to_fem = true;
$back.push("tf loop calc");
},
target: "tf loop card flip",
},
{
disabled: $player_stats.masculine < 100 || $player_deck.every(c => !c.is_fem),
text: "Convert a random action to ?masculine: 50 ?masculine",
side_effects() {
$player_stats.masculine -= 100;
$temp.to_fem = false;
$back.push("tf loop calc");
},
target: "tf loop card flip",
},
{
disabled: _is_naked || $player_stats.feminine < 100,
text: "Lose an article of clothing: 100 ?feminine",
side_effects() {
$player_stats.feminine -= 100;
$back.push("tf loop calc");
},
target: "tf loop clothing loss",
},
/* todo disabled, delete?
{
disabled: _is_naked || $player_stats.feminine < 200,
text: "Lose an article of clothing: 200 ?feminine",
side_effects() {
$player_stats.feminine -= 200;
$back.push("tf loop calc");
},
target: "tf loop clothing loss",
},*/
],
}>>
<<set _choices to $temp.choices.map(c => _all_choices[c.cat][c.i])>>
<<if _choices.every(c => c.disabled)>>
<<run _choices.push({
text: "Wake up!",
side_effects: () => $temp.tf_loop_visits = 0,
color: "green",
target: "back",
})>>
<</if>>
<<event_passage $temp.ecard _choices>>
<p>While you rest, you have strange dreams about your recent experiences.
They seem unusually real...</p>
<</event_passage>>/* "TF" a random card based on $temp.to_fem */
<<run $player_deck.shuffle()>>
<<set _idx to $player_deck.findIndex(c => c.can_flip_gender_to($temp.to_fem))>>
<<if _idx isnot -1>>
<<set $temp.old to $player_deck[_idx]>>
<<set $temp.new to $temp.old.get_gender_flipped_copy()>>
<<set $player_deck[_idx] to $temp.new>>
/* else no cards match, hopefully we prevented this before visiting here */
<</if>>
<<run $player_deck.sort(setup.card_name_compare)>>
<<goto "tf loop card flip result">><<set _ecard to $temp.ecard ?? {title: "Strange Dreams", color: "purple", bg_img: "Feminization_b.jpg"}>>
<<set _fem to $temp.to_fem ? "feminine" : "masculine">>
<<event_passage _ecard setup.ok_choices>>
<<if def $temp.old>>
<p class="largertext">Your thoughts have shifted to be a bit more <<print _fem>>...</p>
<<card_tf $temp.old $temp.new>>
<<else>>
/* TODO something more...? */
<p class="largertext">Strange... all of your cards were already <<print _fem>>...</p>
<</if>>
<</event_passage>>/* Remove a random worn item, starting with 'outerwear' */
<<set _slots to ["bottom", "top", "shoes", "mask"].shuffle()>>
<<set _under to ["undies", "bra", "legwear"].shuffle()>>
<<run _slots.push(... _under)>>
<<for _slot range _slots>>
<<if $player_equipment[_slot].id isnot 0>>
<<set $temp.clothing to $player_equipment.replace_with(setup.all_clothes[_slot][0])>>
<<break>>
<</if>>
<</for>>
<<goto "tf loop clothing loss result">><<set _ecard to $temp.ecard ?? {title: "Strange Dreams", color: "purple", bg_img: "Feminization_b.jpg"}>>
<<event_passage _ecard setup.ok_choices>>
<<if def $temp.clothing>>
<p class="largertext">You lost some of your clothes!</p>
<<equip_tf $temp.clothing $player_equipment[$temp.clothing.place]>>
<<else>>
<p class="largertext">You would have lost some of your clothes, if you were wearing any...</p>
<</if>>
<</event_passage>><<set $temp.missing_items to $quest_slots ?? new Set()>>
<<set $temp.quest_passed to $temp.missing_items.size is 0>>
<<if not $temp.quest_passed>>
<<set $temp.missing_items to Array.from($temp.missing_items)>>
<<set $temp.bills to Math.round($player_stats.bills * 0.15)>>
<<run $back.push("player upkeep check")>>
<</if>>
<<set _req_slots to Object.keys(setup.all_clothes).filter(k => k isnot "mask" and k isnot "outerwear")>>
<<set $quest_slots to new Set(
_req_slots.map(s => $player_equipment[s])
.filter(c => c.id === 0)
.map(c => c.place)
)>>
<<set $temp.any_unworn to $quest_slots.size gt 0>>
<<if not $temp.any_unworn>>
<<set $quest_slots.add(_req_slots.random())>>
<</if>>
<<goto "new upkeep quest">><<set _mi to $temp.missing_items>>
<<set _qf to not $temp.quest_passed>>
<<set _qi to Array.from($quest_slots)>>
<<set _ecard to {title: "New Demands", color: "darkblue", bg_img: "scientist_b.jpg", fg_img: "scientist_f.png"}>>
<<event_passage _ecard setup.ok_choices>>
<<if _qf>>
<p>I see you failed to do anything about your
<<if _mi.length gte 3>>
<<print _mi.slice(0, -1).join(", ")>>, or <<print _mi.at(-1)>>,
<<elseif _mi.length is 2>>
<<print _mi[0]>> or <<print _mi[1]>>,
<<else>>
<<print _mi[0]>>,
<</if>>
how disappointing. Unfortunately, I'll have to fine you $temp.bills ?money for that, due immediately.
<<if $player_stats.money lt $temp.bills>>
...You can't afford it? Well then, you can begin working off that fine as soon as you leave!
<</if>>
</p><br>
<</if>>
<<if $temp.any_unworn>>
<p>
<<if _qf>>Anyway.<</if>>
<b>
I see you are failing to wear any
<<if _qi.length gte 3>>
<<print _qi.slice(0, -1).join(", ")>>, or <<print _qi.at(-1)>>.
<<elseif _qi.length is 2>>
<<print _qi[0]>> or <<print _qi[1]>>.
<<else>>
<<print _qi[0]>>.
<</if>>
</b></p>
<p>Have you no decency?</p>
<<else>>
<p>
<<if _qf>>Anyway.<</if>>
<b>
Your _qi[0] looks hideous, and you should replace it.
</b></p>
<div style="width: 40%; margin: auto"><<equip_card $player_equipment[_qi[0]]>></div>
<</if>>
<p>If you don't address that by the time I see you again,
I'll be forced to issue you a fine<<if _qf>> yet again<</if>>.
Please take better care of your appearance.</p>
<</event_passage>>/* point to this in "start loop" passage/events array */
<<set _job_choices to {
npc: {weight: 2, choices: 5, pluck: 1},
cash: {weight: 4, choices: 4, pluck: 1},
card: {weight: 3, choices: 2, pluck: 1},
luck: {weight: 1, choices: 2, pluck: 1},
boss: {weight: 2, choices: 2, pluck: 1},
}>>
<<set _choices to setup.loop_choices(_job_choices, 2)>>
/* filter out npc & boss */
<<set $temp.choices to []>>
<<set $temp.npcs to []>>
<<set $temp.boss to []>>
<<for _c range _choices>>
<<switch _c.cat>>
<<case "npc">>
/* just push the difficulty. if we need more elaborate enemy rng do it here */
<<run $temp.npcs.push(clone(setup.difficulties[_c.i]))>>
<<case "boss">>
<<run $temp.boss.push(clone(setup.difficulties[_c.i + 3]))>>
<<default>>
<<run $temp.choices.push(_c)>>
<</switch>>
<</for>>
<<set $temp.random_cash to [
{prod: random(0, 4), energy: random(4, 16)},
{prod: random(2, 8), energy: random(0, 10)},
]>>
<<goto "job loop choice">>/* start with NPCs, if we have them. TODO not exactly sure which ones to use */
<<set _card_grps to []>>
<<set _choice_grps to []>>
<<set _cash to "+" + $player_stats.productivity + " ?money">>
<<if $temp.boss.length gt 0>>
<<set _card_grps.push(setup.enemies.regular[0])>>
<<set _boss_choices to []>>
<<set _ugh to function(i) {return function() {
$enemy = setup.enemies.regular[0];
$enemy.difficulty = i;
$back.push("job boss postcalc");
}}>>
<<for _diff range $temp.boss>>
<<set _boss_choices.push({
requirement: "energy",
threshold: 10,
disabled_text: "Need at least 10 ?energy",
text: "Work under close supervision +5 ?productivity",
color: _diff.color,
side_effects: _ugh(_diff.value),
target: "battle pre calc",
})>>
<</for>>
<<set _boss_choices.push({
requirement: "energy",
threshold: 6,
disabled_text: "Not enough ?energy to avoid them",
text: "Avoid them: -5 ?energy, +2 ?productivity",
side_effects() {
$player_stats.energy -= 5;
$player_stats.productivity += 2;
setup.add_random_xp(true);
},
color: "orchid",
target: "back",
})>>
<<set _choice_grps.push(_boss_choices)>>
<</if>>
<<if $temp.npcs.length gt 0>>
<<set _card_grps.push(setup.enemies.regular[3])>>
<<set _npc_choices to []>>
<<set _ugh to function(i) {return function() {
$enemy = setup.enemies.regular[3];
$enemy.difficulty = i;
$back.push("job npc postcalc");
}}>>
<<for _diff range $temp.npcs>>
<<set _npc_choices.push({
text: _diff.text + ", Win: +" + _diff.value + " ?productivity",
color: _diff.color,
side_effects: _ugh(_diff.value),
target: "battle pre calc",
})>>
<</for>>
<<set _choice_grps.push(_npc_choices)>>
<</if>>
<<set _rcash to $temp.random_cash.map(rc =>
`Work: ${_cash}, -${rc.prod} ?productivity, -${rc.energy} ?energy`
)>>
<<set _all_choices to {
cash: [
{
requirement: "energy",
threshold: 11,
disabled_text: "Too little ?energy to work",
text: "Work Hard: " + _cash + ", -2 ?productivity, -10 ?energy",
side_effects() {
$player_stats.money += $player_stats.productivity;
$player_stats.productivity -= 2;
$player_stats.energy -= 10;
setup.add_random_xp(false);
},
target: "back",
},
{
requirement: "energy",
threshold: 6,
disabled_text: "Too little ?energy to work",
text: "Sloppy Work: " + _cash + ", -5 ?productivity, -5 ?energy",
side_effects() {
$player_stats.money += $player_stats.productivity;
$player_stats.productivity -= 5;
$player_stats.energy -= 5;
setup.add_random_xp(true);
},
color: "orchid",
target: "back",
},
{
requirement: "energy",
threshold: $temp.random_cash[0].energy + 1,
disabled_text: "Too little ?energy to work",
text: _rcash[0],
side_effects() {
$player_stats.money += $player_stats.productivity;
$player_stats.productivity -= $temp.random_cash[0].prod;
$player_stats.energy -= $temp.random_cash[0].energy;
setup.add_random_xp(false);
},
target: "back",
},
{
requirement: "energy",
threshold: $temp.random_cash[1].energy + 1,
disabled_text: "Too little ?energy to work",
text: _rcash[1],
side_effects() {
$player_stats.money += $player_stats.productivity;
$player_stats.productivity -= $temp.random_cash[1].prod;
$player_stats.energy -= $temp.random_cash[1].energy;
setup.add_random_xp(false);
},
target: "back",
},
],
card: [
{
requirement: "energy",
threshold: 6,
disabled_text: "Too little ?energy to work on a special line",
text: "Pack Special Gifts: " + _cash + ", -2 ?productivity, -5 ?energy, chance to get Unusual Gift action",
side_effects() {
$player_stats.money += $player_stats.productivity;
$player_stats.productivity -= 2;
$player_stats.energy -= 5;
setup.add_random_xp(true);
},
color: "orchid",
target: "job stress card",
},
{
requirement: "energy",
threshold: 3,
disabled_text: "Too little ?energy to work in tasting area",
text: "Sweets Tasting: " + _cash + ", -5 ?productivity, -2 ?energy, chance to get Seeing Things action",
side_effects() {
$player_stats.money += $player_stats.productivity;
$player_stats.productivity -= 5;
$player_stats.energy -= 2;
setup.add_random_xp(true);
},
color: "orchid",
target: "job arousal card",
},
],
luck: [
{
disabled: $player_stats.energy gte $player_stats.max_energy,
disabled_text: "Snack break: but no need for more energy...",
text: "Snack break: +5 ?energy",
side_effects() {
$player_stats.energy += 5;
setup.add_random_xp(true);
},
color: "orchid",
target: "back",
},
{
text: "Spark of inspiration: +2 ?productivity",
side_effects() {
$player_stats.productivity += 2;
},
target: "back",
},
],
}>>
<<if random(1, 6) isnot 1>>
<<set _all_choices.card[0].target to "back">>
<<set _all_choices.card[1].target to "back">>
<</if>>
<<set _choices to $temp.choices.map(c => _all_choices[c.cat][c.i])>>
<<set _choices.push({
text: "Leave work early",
color: "grey",
side_effects() {
$events = [];
},
target: "back",
})>>
<<if $temp.choices.some(c => c.cat is "card")>>
<<set _card_grps.push({title: "What's next?", color: "gray", bg_img: "slacking off_b.jpg"})>>
<<elseif $temp.choices.some(c => c.cat is "luck")>>
<<set _card_grps.push({title: "A brief respite", color: "gray", bg_img: "short break_b.jpg"})>>
<<else>>
<<set _card_grps.push({title: "Working", color: "gray", bg_img: "pack gifts_b.jpg"})>>
<</if>>
<<set _choice_grps.push(_choices)>>
<<choice_passage _card_grps _choice_grps>><<set _prod to $player_stats.productivity>>
<<if $battle_won>>
/*
<<set $player_stats.money += _prod>>*/
<<set $player_stats.productivity += 5>>
<<set _passage to "Due to your success with " + $enemy.name + ", you gained 5 ?productivity." >>
<<else>>
/* <<set $player_stats.money -= _prod>>*/
<<set $player_stats.productivity -= $enemy.difficulty>>
<<set _passage to "Due to your failure with " + $enemy.name + ", you lost " +
$enemy.difficulty + " ?productivity." >>
<</if>>
<<event_passage $enemy setup.ok_choices>>
<<print _passage>>
<</event_passage>><<if $battle_won>>
<<set $player_stats.productivity += $enemy.difficulty>>
<<set _passage to "Due to your success with " + $enemy.name + ", you gained " +
$enemy.difficulty + " ?productivity." >>
<<else>>
<<set $player_stats.productivity -= $enemy.difficulty>>
<<set _passage to "Due to your failure with " + $enemy.name + ", you lost " +
$enemy.difficulty + " ?productivity." >>
<</if>>
<<event_passage $enemy setup.ok_choices>>
<<print _passage>>
<</event_passage>><<set _card to setup.action_cards.all_player["unusual gift_f"]>>
<<set $player_deck.push(clone(_card))>>
<<event_passage _card setup.ok_choices>>
<p>Some of the gifts you're wrapping look strange...</p>
<</event_passage>><<set _card to setup.action_cards.all_player["seeing things_f"]>>
<<set $player_deck.push(clone(_card))>>
<<event_passage _card setup.ok_choices>>
<p>What kind of sweets do they make here...?</p>
<</event_passage>>/* TODO For future upgrades, just add to weights (and choices-- acts weird if not enough choices vs. weight)
* e.g. pop: {weight: 2 + upgrade, choices: 2 + upgrade, pluck: 1} */
<<set _shop_choices to {
pop: {weight: 2, choices: 2, pluck: 1},
gen: {weight: 4, choices: 4, pluck: 1},
don: {weight: 1, choices: 1, pluck: 1},
cos: {weight: 1, choices: 1, pluck: 1},
}>>
/* npc: {weight: 1, choices: 3, pluck: 1}, */
<<set _choices to setup.loop_choices(_shop_choices, 3)>>
/* separate out npc vs. others */
<<set $temp.npc_diff to null>>
<<set $temp.choices to []>>
<<set _cpool to Object.values(setup.all_clothes).flat()>>
/* Bias for more masc/fem items-- increases as compulsion goes down; range 1-2 */
<<set _bias_wt to 2 - ($player_stats.compulsion / $player_stats.get_room_stat("comp_bonus"))>>
<<for _c range _choices>>
<<switch _c.cat>>
<<case "npc">>
/* just set the difficulty. if we need more elaborate enemy rng do it here */
<<set $temp.npc_diff to setup.difficulties[_c.i + 2]>>
<<case "pop">>
/* Positive effect. Bias more fem over time.
* Also bias toward clothing required by quest. */
<<set _weights to _cpool.map(item => {
let wt = 1;
if(item.fem > $player_equipment[item.place].fem) {
wt = _bias_wt;
}
if($quest_slots?.has(item.place)) {
wt *= 5;
}
return wt;
})>>
<<set _idx to alias_sampler(_weights)()>>
<<run $temp.choices.push({
txt: "Buy Popular Wear:",
item: _cpool.splice(_idx, 1)[0],
effect: setup.effect_fns.gen_pos_arr(),
cost: 5 + 2 * $player_stats.compulsion,
})>>
<<case "gen">>
/* Mixed effect, pure random. */
<<run $temp.choices.push({
txt: "Buy General Wear:",
item: _cpool.pluck(),
effect: setup.effect_fns.gen_pair(),
cost: 5 + 2 * $player_stats.compulsion,
})>>
<<case "don">>
/* Negative effect. Bias more masc over time.
* Also bias toward clothing required by quest. */
<<set _weights to _cpool.map(item => {
let wt = 1;
if(item.fem < $player_equipment[item.place].fem) {
wt = _bias_wt;
}
if($quest_slots?.has(item.place)) {
wt *= 5;
}
return wt;
})>>
<<set _idx to alias_sampler(_weights)()>>
<<run $temp.choices.push({
txt: "Buy from Thrift Shop:",
item: _cpool.splice(_idx, 1)[0],
effect: setup.effect_fns.gen_neg_arr(),
cost: 5 + 2 * $player_stats.compulsion,
})>>
<<case "cos">>
/* cosmetics -- assumed at most 1, otherwise need to move next to clothes */
<<set _cos_pool to Object.values(setup.all_styles).flat()
.filter(setup.item_not_worn)>>
/* TODO weigh more fem w/ compulsion? */
<<run $temp.choices.push({
txt: "Visit the Salon:",
item: _cos_pool.pluck(),
/* tilt rng a bit to be more likely to be good
effect: setup.effect_fns.gen_pair(2, 5, 0, 3), */
effect: setup.effect_fns.gen_pos_arr(),
cost: 5 + 2 * $player_stats.compulsion,
})>>
<</switch>>
<</for>>
<<if $player_stats.compulsion gt 0>>
<<goto "shop loop choice">>
<<else>>
<<set $events to []>>
<<goto "back">>
<</if>><<set _card_grps to []>>
<<set _choice_grps to []>>
<<if $temp.npc_diff isnot null>>
<<set $enemy to setup.enemies.regular[0]>>
<<set $enemy.difficulty to $temp.npc_diff.value>>
<<set _card_grps.push($enemy)>>
<<set _choice_grps.push([{
text: $temp.npc_diff.text + ", Win: -" + $temp.npc_diff.value + " ?compulsion",
color: $temp.npc_diff.color,
side_effects: () => $back.push("shop npc postcalc"),
target: "battle pre calc",
}])>>
<</if>>
/* clothing choices */
<<set _fx to function(i) {return function() {
const c = $temp.choices[i];
$player_stats.compulsion -= 1;
$player_stats.money -= c.cost;
$player_equipment.replace_with(c.item);
$effects.push(...c.effect);
}}>>
<<for _i, _choice range $temp.choices>>
<<if not setup.item_not_worn(_choice.item)>>
/* item *is* worn, make it free */
<<set _choice.cost to 0>>
<</if>>
<<set _card_grps.push(_choice.item)>>
<<set _txt to _choice.txt + "<br>">>
<<if _choice.cost gt 0>>
<<set _txt += "-" + _choice.cost + " ?money, ">>
<</if>>
<<set _txt += "-1 ?compulsion">>
<<if _choice.effect.length gt 0>>
<<set _txt += ",<br>+Effects: " + setup.effect_fns.pair_to_string(_choice.effect)>>
<<else>>
<<set _txt += "<br>(No extra effects.)">>
<</if>>
<<set _choice_grps.push([{
requirement: "money",
threshold: _choice.cost,
text: _txt,
side_effects: _fx(_i),
target: "back",
}])>>
<<if $quest_slots?.has(_choice.item.place)>>
/* Doing this here b/c I forget the default button color and think 'undefined' breaks it */
<<set _choice_grps.at(-1)[0].color to "purple">>
<</if>>
<</for>>
<<choice_passage _card_grps _choice_grps>>
/* fixed choices */
/* <<set _card_grps.push({title: "Shopping", color: "pink", bg_img: "pink coffee_b.jpg"})>> */
<<set _fixed_choices to [
{
requirement: "compulsion",
threshold: 2,
text: "Look for something else: -1 ?compulsion",
color: "green",
side_effects: () => $player_stats.compulsion -= 1,
target: "back",
},
{
text: ($player_stats.compulsion gte 2 ? "Leave and stop shopping:" : "Done shopping for now...") + " -1 ?compulsion",
color: "grey",
side_effects() {
$events = [];
$player_stats.compulsion -= 1;
},
target: "back",
},
]>>
<div class="flexdown" style="margin: auto; width: 50%;">
<<for _choice range _fixed_choices>>
<<choice_btn _choice>>
<</for>>
</div><<if $battle_won>>
<<set $player_stats.compulsion -= $enemy.difficulty>>
<<set _passage to "Due to your success with " + $enemy.name +
", you calmed down and reduced your ?compulsion by " + $enemy.difficulty + ".">>
<<else>>
/* TODO not worth the effort to move to a calc passage... */
<<set _eff to []>>
<<for _eff.length is 0>>
<<set _eff to setup.effect_fns.gen_neg_arr()>>
<</for>>
<<set $effects.push(... _eff)>>
<<set _passage to "Due to your failure with " + $enemy.name + ", you gained a negative effect: " +
setup.effect_fns.pair_to_string(_eff)>>
<</if>>
<<event_passage $enemy setup.ok_choices>>
<<print _passage>>
<</event_passage>><<set _train_choices to {
add: {weight: 18, choices: 18, pluck: 1},
remove: {weight: 2, choices: 2, pluck: 1},
upgrade: {weight: 1, choices: 1, pluck: 1},
}>>
<<set _choices to setup.loop_choices(_train_choices, 3).map(c => c.cat)>>
<<set _rm_count to _choices.filter(c => c === "remove").length>>
<<set _card_count to _choices.filter(c => c === "add").length>>
<<if _rm_count gt 1>>
<<set _card_count += _rm_count - 1>>
<</if>>
<<set $temp.remove to _rm_count gt 0>>
/* if upgrade weight increased, copy pattern of _rm_count instead (extras +cards) */
<<set $temp.upgrade to _choices.includes("upgrade")>>
<<set $temp.new_cards to []>>
<<set _drops to clone(setup.action_cards.player_drops)>>
/*
<<set setup.card_rarity_weights ??= [
[80, 20, 0, 0],
[50, 40, 10, 0],
[20, 40, 30, 10],
[0, 30, 50, 20],
[0, 10, 60, 30],
]>>
<<set $temp.rar_weights to setup.card_rarity_weights[$enemy.difficulty - 1]>>
*/
<<set $temp.rar_weights to [
60 - 1.50 * $player_stats.focus,
35 - 1.00 * $player_stats.focus,
5 + 1.50 * $player_stats.focus,
0 + 1.00 * $player_stats.focus,
]>>
<<set _weights to _drops.map(c => {
let w = $temp.rar_weights[c.combat_reset().rarity] ?? 10;
if(c.name.includes("+")) { /* if upgraded... */
w /= 2;
}
return w;
})>>
<<for _x = 0; _x < _card_count; _x++>>
<<set _idx to alias_sampler(_weights)()>>
<<set $temp.new_cards.push(_drops.splice(_idx, 1)[0])>>
<<set _weights.splice(_idx, 1)>>
<</for>>
<<run $temp.new_cards.sort(setup.card_name_compare)>>
<<if $player_stats.focus gt 0>>
<<goto "training loop choice">>
<<else>>
<<set $events to []>>
<<goto "back">>
<</if>><p>Probability with $player_stats.focus ?focus : ?common $temp.rar_weights[0]% ?rare $temp.rar_weights[1]% ?epic $temp.rar_weights[2]% ?legendary $temp.rar_weights[3]%</p>
<<set _card_grps to []>>
<<set _choice_grps to []>>
<<set _cost to $player_stats.focus * 4 + 8>>
<<set _addfx to function(i) { return function() {
$player_stats.money -= _cost;
$player_stats.focus -= 1;
$player_deck.push(clone($temp.new_cards[i]));
}}>>
<<for _i, _new_card range $temp.new_cards>>
<<run _card_grps.push(_new_card)>>
<<run _choice_grps.push([{
requirement: "money",
threshold: _cost,
text: "Learn " + _new_card.name + "<br>-" + _cost + " ?money, -1 ?focus",
side_effects: _addfx(_i),
target: "back",
}])>>
<</for>>
<<set _other_choices to []>>
<<if $temp.remove>>
/* removal goes "2back" on confirm, regular back on skip.
it's dumb, but pushing an extra "back" makes them go to the same dest. */
<<set _rm_fem to random(0, 1) is 1>>
<<run _choice_grps.push([{
requirement: "money",
threshold: _cost,
disabled_text: "Not enough ?money to forget a card",
text: "Forget a card<br>-" + _cost +" ?money, -1 ?focus",
side_effects() {
$back.push("back");
$player_stats.money -= _cost;
$player_stats.focus -= 1;
setup.add_random_xp(_rm_fem);
},
color: _rm_fem ? "orchid" : undefined,
target: "remove card selection",
}])>>
<<set _card_grps.push({title: "Relaxation", color: "brown", bg_img: "take a break_b.jpg"})>>
<</if>>
<<if $temp.upgrade>>
<<set _up_fem to random(0, 1) is 1>>
<<run _choice_grps.push([{
requirement: "money",
threshold: _cost,
disabled_text: "Not enough ?money to upgrade a card",
text: "Upgrade a card<br>-" + _cost +" ?money, -1 ?focus",
side_effects() {
$player_stats.money -= _cost;
$player_stats.focus -= 1;
setup.add_random_xp(_up_fem);
},
color: _up_fem ? "orchid" : undefined,
target: "card upgrade precalc",
}])>>
<<if _up_fem>>
<<set _card_grps.push({title: "Practice", color: "brown", bg_img: "practice_b.jpg"})>>
<<else>>
<<set _card_grps.push({title: "Preparation", color: "brown", bg_img: "preparation_b.jpg"})>>
<</if>>
<</if>>
<<choice_passage _card_grps _choice_grps>>
<<set _fixed_choices to [
{
requirement: "focus",
threshold: 2,
text: "Continue training: -1 ?focus",
color: "green",
side_effects: () => $player_stats.focus -= 1,
target: "back",
},
{
text: ($player_stats.focus gte 2 ? "Leave and stop training:" : "Done training for now...") + " -1 ?focus",
color: "grey",
side_effects() {
$events = [];
$player_stats.focus -= 1;
},
target: "back",
},
]>>
<div class="flexdown" style="margin: auto; width: 50%;">
<<for _choice range _fixed_choices>>
<<choice_btn _choice>>
<</for>>
</div><<set _train_choices to {
npc: {weight: 2, choices: 3, pluck: 1},
mind: {weight: 4, choices: 2, pluck: 1},
medi: {weight: 2, choices: 4, pluck: 1},
relax: {weight: 1, choices: 2, pluck: 1},
}>>
<<set _choices to setup.loop_choices(_train_choices, 2)>>
/* filter out npc */
<<set $temp.choices to []>>
<<set $temp.npcs to []>>
<<for _c range _choices>>
<<switch _c.cat>>
<<case "npc">>
<<run $temp.npcs.push(clone(setup.difficulties[_c.i + 2]))>>
<<default>>
<<run $temp.choices.push(_c)>>
<</switch>>
<</for>>
<<set $temp.focus_costs to [random(3, 9), random(6, 18)]>>
<<goto "deprecated training loop choice">><<set _card_grps to []>>
<<set _choice_grps to []>>
<<if $temp.npcs.length gt 0>>
<<set _card_grps.push(setup.enemies.regular[3])>>
<<set _npc_choices to []>>
<<set _ugh to function(i) {return function() {
$enemy = setup.enemies.regular[3],
$enemy.difficulty = i;
$back.push("train npc postcalc");
}}>>
<<for _diff range $temp.npcs>>
/* diff 2, 3, 4 -> focus 4, 3, 2 */
<<set _foc_cost to 6 - _diff.value>>
<<set _npc_choices.push({
requirement: "focus",
threshold: _foc_cost,
disabled_text: "Not enough ?focus to learn new action",
text: "Learn new action (" + _diff.text + ")<br>Win: Choose 1 action from " +
Math.clamp($player_stats.focus, 1, 15) + ", -" + _foc_cost + " ?focus",
color: _diff.color,
side_effects: _ugh(_diff.value),
target: "battle pre calc",
})>>
<</for>>
<<set _npc_choices.push({
requirement: "energy",
threshold: 6,
disabled_text: "Not enough ?energy to ignore them",
text: "Ignore them: -5 ?energy, +1 ?focus",
side_effects() {
$player_stats.energy -= 5;
$player_stats.focus += 1;
setup.add_random_xp(true);
},
color: "orchid",
target: "back",
})>>
<<set _choice_grps.push(_npc_choices)>>
<</if>>
<<set _all_choices to {
mind: [
{
requirement: "energy",
threshold: $temp.focus_costs[0] + 1,
disabled_text: "Too little ?energy to prepare mentally",
text: "Prepare Mentally: -" + $temp.focus_costs[0] + " ?energy, +1 ?focus",
side_effects() {
$player_stats.energy -= $temp.focus_costs[0];
$player_stats.focus += 1;
setup.add_random_xp(true);
},
color: "orchid",
target: "back",
},
{
requirement: "energy",
threshold: $temp.focus_costs[1] + 1,
disabled_text: "Too little ?energy to practice",
text: "Practice: -" + $temp.focus_costs[1] + " ?energy, +2 ?focus",
side_effects() {
$player_stats.energy -= $temp.focus_costs[1];
$player_stats.focus += 2;
setup.add_random_xp(false);
},
target: "back",
},
],
medi: [
{
requirement: "focus",
threshold: 2,
disabled_text: "Not enough ?focus to rethink",
text: "Rethink: Convert ?feminine action into ?masculine -2 ?focus",
side_effects() {
$player_stats.focus -= 2;
$temp.convert_fem = false;
setup.add_random_xp(false);
},
target: "training card convert",
},
{
text: "Rethink: Convert ?masculine action into ?feminine",
side_effects() {
$temp.convert_fem = true;
setup.add_random_xp(true);
},
color: "orchid",
target: "training card convert",
},
/* removal goes "2back" on confirm, regular back on skip.
it's dumb, but pushing an extra "back" makes them go to the same dest. */
{
requirement: "focus",
threshold: 3,
disabled_text: "Not enough ?focus to forget a card",
text: "Forget a card: -3 ?focus",
side_effects() {
$back.push("back");
$player_stats.focus -= 3;
setup.add_random_xp(true);
},
color: "orchid",
target: "remove card selection",
},
{
requirement: "focus",
threshold: 3,
disabled_text: "Not enough ?focus to forget a card",
text: "Forget a card: -3 ?focus",
side_effects() {
$back.push("back");
$player_stats.focus -= 3;
setup.add_random_xp(false);
},
target: "remove card selection",
},
{
requirement: "focus",
threshold: 3,
disabled_text: "Not enough ?focus to upgrade a card",
text: "Upgrade a card: -3 ?focus",
side_effects() {
$player_stats.focus -= 3;
setup.add_random_xp(false);
},
target: "card upgrade precalc",
},
],
relax: [
{
text: "Short Break: +5 ?energy",
side_effects() {
$player_stats.energy += 5;
setup.add_random_xp(true);
},
color: "orchid",
target: "back",
},
{
text: "Moment of clarity: +1 ?focus",
side_effects() {
$player_stats.focus += 1;
setup.add_random_xp(false);
},
target: "back",
},
],
}>>
<<set _choices to $temp.choices.map(c => _all_choices[c.cat][c.i])>>
/*
<<set _choices.push({
requirement: "energy",
threshold: 6,
disabled_text: "Too tired to even think...",
text: "Scattered thoughts: -5 ?energy",
side_effects() {
$player_stats.energy -= 5;
},
target: "back",
})>> */
<<set _choices.push({
text: "Leave training early: -3 ?focus",
color: "grey",
side_effects() {
$player_stats.focus -= 3;
$events = [];
},
target: "back",
})>>
<<if $temp.choices.some(c => c.cat is "relax")>>
<<set _card_grps.push({title: "Relaxation", color: "brown", bg_img: "take a break_b.jpg"})>>
<<elseif $temp.choices.some(c => c.cat is "medi")>>
<<set _card_grps.push({title: "Practice", color: "brown", bg_img: "practice_b.jpg"})>>
<<else>>
<<set _card_grps.push({title: "Preparation", color: "brown", bg_img: "preparation_b.jpg"})>>
<</if>>
<<set _choice_grps.push(_choices)>>
<<choice_passage _card_grps _choice_grps>><<if $battle_won>>
<<set _foc_cost to 6 - $enemy.difficulty>>
<<set $back.push("train npc focus calc")>>
<<set $back.push("card selection precalc")>>
<<set _passage to "Your training with " + $enemy.name + " went well. You spent " +
_foc_cost + " ?focus to train, but you'll get a new action card...">>
<<else>>
<<set $player_stats.focus += 1>>
<<set _passage to "Your training with " + $enemy.name + " went poorly. Despite this, you are slightly more focused. (+1 ?focus)">>
<</if>>
<<event_passage $enemy setup.ok_choices>>
<<print _passage>>
<</event_passage>>/* it's dumb, but the focus cost is deducted *after* the new card */
<<set $player_stats.focus -= 6 - $enemy.difficulty>>
<<goto "back">><p>Pick a card to convert to <<print $temp.convert_fem ? "?feminine" : "?masculine">>:</p>
<div class="grid5col">
<<for _idx, _card range $player_deck>><<capture _idx _card>>
<<if _card.can_flip_gender_to($temp.convert_fem)>>
<<link "<<action_card _card>>">>
<<set _up_idx to _idx>>
<<run setup.show_dialog("Convert this card?", "autoanim", "convert card confirm")>>
<</link>>
<<else>>
<<action_card _card disabled notilt>>
<</if>>
<</capture>><</for>>
</div>
<div class="flexbuttons">
<button data-passage="back" class="btn">Change nothing and move on</button>
</div><<set _old_card to $player_deck[_up_idx]>>
<<set _new_card to _old_card.get_gender_flipped_copy()>>
/*<<card_tf _old_card _up_ch.up>> hardcoded width here so the dialog isn't tiny...*/
<div class="itemtfgrid" style="width: 40em;">
<<action_card _old_card>>
<img alt="upgrades to" src="img2/icons/green_arrow.svg">
<<action_card _new_card>>
</div>
<div class="flexbuttons">
<<button "Convert!" "back">>
<<run $player_deck.splice(_up_idx, 1, clone(_new_card))>>
<<run Dialog.close()>>
<</button>>
<<button "Not this card...">><<run Dialog.close()>><</button>>
</div>
<<done>>
<<addclass "#ui-dialog-body button" "btn">>
<<addclass "#ui-dialog-body button:nth-child(2)" "btn-red">>
<</done>>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: "Cheat Room for Sigma patrons!",
target: passage(),
disabled: true,
})>><br>
<div>
<a href="https://www.patreon.com/sifagames" target="_blank">
<img src="public/banner_nsfw.jpg" class="relfull">
</a>
</div>
<i>*all the artworks that could be NSFW are NSFW</i><<run _choices.push({
text: "Character creation available for patrons!",
target: passage(),
disabled: true,
})>><<if $charview gt 0>>
<div id="avatar"><<include avatar_sidebar>></div>
<<else>>
Continue further to see your character.
<</if>><div class="imgstack">
<img src="img2/char/other/charbg.svg">
<<render_char 1 "" $player_equipment.to_render()>>
</div>