v6.5.0 "Combat Refocus"<br>
<<include TierSubtitle>><<if $charview gt 0>>
/* TODO a stat display for this? */
<<if $events.length gt 0>>
<p><<print $events.length>> events left</p>
<</if>>
/*<code>back: <<print $back>></code>*/
<div id="sidebar-stats">
<<include "sidebar stats">>
</div>
<br>
/*
<<if Story.get(passage()).tags.includes("dressing")>>
<p class="framed-icons" style="font-size: smaller">You can change clothes here. ?changing_room</p>
<</if>>
*/
<div class="grid2col" 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>>
/*
<<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>>/*<<set _statbar_stats to ["balance", "corruption", "identity", "fem", "stress", "arousal"]>>*/
<<set _statbar_stats to ["stress", "arousal", "fem"]>>
<div class="flexdown">
<div class="flexbuttons" style="height: 2em;">
<<statnum "money">>
</div>
<<for _stat range _statbar_stats>>
<<statbar _stat>>
<</for>>
<div class="flexbuttons" style="height: 2em;"><<statnum "masculine" $exp_stats>> <<statnum "feminine" $exp_stats>></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/sZqtvENVXp]]<<include "body cards init">>
<<include "style cards init">>
<<include "clothing cards init">>
<<include "char init">>
<<include "view boxes init">>
<<include "action cards init">>
<<include "enemy init">>
<<include "functions init">>
<<include "other init">><<set setup.matches_current_loop to function(item) {
return (item.id gt 0) and
(item.rarity lt $current_loop.difficulty) and
item.styles.some(st => $current_loop.event_styles.has(st)) and
item.colors.some(cl => $current_loop.event_colors.has(cl));
}>>
<<set setup.items_matching_current_loop to function(category, ...places) {
let droplist = [];
const items = setup["all_" + category];
for(const place of places) {
droplist.push(...items?.[place]?.filter(setup.matches_current_loop));
}
return droplist;
}>>
<<set setup.matches_difficulty to function(item) {
return (item.id gt 0) and
(item.rarity lt $current_loop.difficulty);
}>>
<<set setup.items_matching_difficulty to function(category, ...places) {
let droplist = [];
const items = setup["all_" + category];
for(const place of places) {
droplist.push(...items?.[place]?.filter(setup.matches_difficulty));
}
return droplist;
}>>
<<set setup.item_not_worn to function(item) {
return not item.is_equal($player_equipment[item.place]);
}>>
<<set setup.payment_adjust to function(old_diff, new_diff) {
if(old_diff === new_diff) {
return;
}
$debt.payment = Math.max(0, Math.round(setup.payments[new_diff][$debt.index] - (setup.payments[old_diff][$debt.index] - $debt.payment)));
}>>
/* given an array of items, return a list with numeric weights for each item
* where carrying *fewer* items in a category weights it higher */
<<set setup.weight_items_by_carried to function(item_list) {
const quants = $inv.quantities();
let max_quant = 0;
for(const place in quants) {
if($player_equipment[place].id !== 0) {
quants[place] += 1;
}
max_quant = Math.max(max_quant, quants[place]);
}
max_quant += 1; /* so every answer is at least 1 */
for(const place in quants) {
quants[place] = max_quant - quants[place];
}
return item_list.map((item) => quants[item.place] ?? 1);
}>><<set $back to []>>
<<set $temp to {}>>
<<set $complete_difficulty to 0>>
<<set $loop_choices to []>>
<<set $events to []>>
<<set $charview to 0>>
<<set $debug_passages to new Set()>>
<<set $game_difficulty to 1>>
<<set setup.event_passages to {}>>
<<for _tag range ["event", "break-event", "unique-event", "work-event", "six-five"]>>
<<set setup.event_passages[_tag] to Story.lookup("tags", _tag).map(p => p.title)>>
<</for>>
/*<<set setup.event_passages.all to Array.from(new Set(Object.values(setup.event_passages).flat()))>>*/
<<set setup.ok_choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<set setup.payments to [
null, /* so we count from 1 */
[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:0, 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:2, 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:6, 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:10, 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:14, 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:22, 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:26, 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:28, 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:32, 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:40, 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:44, 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:46, 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:25, sub: 4}),
new EquipItem({name:"Tiny Clitty", gender:"female", styles: ["female"], rarity:"legendary", fem:26, sub: 4, fit: 1}),
new EquipItem({name:"Little Winkle", gender:"male", styles: ["unisex"], rarity:"epic", fem:18, sub: 3, int: 0, fit: 1, att: 0}),
new EquipItem({name:"Small Prick", gender:"male", styles: ["unisex"], rarity:"rare", fem:11, sub: 2, int: 0, fit: 1, att: 0}),
new EquipItem({name:"Normal Stick", gender:"male", styles: ["male"], rarity:"common", fem:5, sub: 0, int: 0, fit: 2, att: 0}),
new EquipItem({name:"Big Tool", gender:"male", styles: ["male"], rarity:"epic", fem:0, sub: 0, int: 0, fit: 4, att: 0}),
],
face: [
new EquipItem({name:"Masculine Face", gender:"male", styles: ["male"], head:1, rarity:"common", fem:0, sub: 0, int: 0, fit: 0, att: 0}),
new EquipItem({name:"Boy Face", gender:"male", styles: ["male"], head:2, rarity:"rare", fem:7, sub: 0, int: 0, fit: 0, att: 1}),
new EquipItem({name:"Femboy Face", gender:"male", styles: ["unisex"], head:2, rarity:"epic", fem:15, sub: 0, int: 0, fit: 0, att: 2}),
new EquipItem({name:"Girly Face", gender:"female", styles: ["female"], head:2, rarity:"legendary", fem:24, sub: 0, int: 0, fit: 0, att: 3}),
],
hair: [
new EquipItem({name:"Short Hair", gender:"male", styles: ["male"], ears:"both", rarity:"common", fem:0, sub: 0, int: 0, fit: 1, att: 0}),
new EquipItem({name:"Medium Hair", gender:"unisex", styles: ["unisex"], ears:"right", rarity:"rare", fem:10, sub: 0, int: 1, fit: 0, att: 1}),
new EquipItem({name:"Long Hair", gender:"female", styles: ["female"], ears:"left", rarity:"epic", fem:20, sub: 1, int: 1, fit: 0, att: 1}),
],
nails: [
new EquipItem({name:"Short Nails", gender:"male", styles: ["male"], rarity:"common", fem:0, sub: 0, int: 0, fit: 1, att: 0}),
new EquipItem({name:"Long Nails", gender:"female", styles: ["female"], rarity:"rare", fem:10, 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"], styles: ["female"], rarity:"epic", fem:3, 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: 0},
unisex: {fem: 3},
female: {fem: 7},
},
mid: {
male: {fem: 0},
unisex: {fem: 4},
female: {fem: 9},
},
big: {
male: {fem: 0},
unisex: {fem: 5},
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: -1},
blonde: {fem: 2},
blue: {fem: 2},
brown: {fem: -1},
darkblue: {fem: 0},
ginger: {fem: 1},
gray: {fem: 0},
green: {fem: 1},
pink: {fem: 3},
purple: {fem: 3},
red: {fem: 2},
white: {fem: 1},
cyan: {fem: 1},
nocolor: {fem:0},
transparent:{fem:0},
}>>
<<for _col range _item.colors>>
<<set _fem += _colorpts?.[_col]?.fem ?? 0>>
<</for>>
<<set _item.base_fem to Math.clamp(_fem, 0, 20)>>
<</for>>
<</widget>><<set setup.all_clothes to {
undies: [
new EquipItem({name:"No Undies", gender: "unisex", colors: ["nocolor"], styles: ["lewd"]}),
new EquipItem({name:"Boxers", gender: "male", colors: ["black", "white"], styles: ["formal", "modest"]}),
new EquipItem({name:"Boxers", gender: "male", colors: ["blue", "white"], styles: ["formal", "modest"]}),
new EquipItem({name:"Boxers", gender: "male", colors: ["white", "pink"], styles: ["formal", "modest"]}),
new EquipItem({name:"Boxers", gender: "male", colors: ["red", "white"], styles: ["formal", "modest"]}),
new EquipItem({name:"Boxers", gender: "male", colors: ["pink", "cyan"], styles: ["formal", "modest"]}),
new EquipItem({name:"Briefs", gender: "unisex", colors: ["black"], styles: ["active"]}),
new EquipItem({name:"Briefs", gender: "unisex", colors: ["blue"], styles: ["active"]}),
new EquipItem({name:"Briefs", gender: "unisex", colors: ["white"], styles: ["active"]}),
new EquipItem({name:"Briefs", gender: "unisex", colors: ["red"], styles: ["active"]}),
new EquipItem({name:"Briefs", gender: "unisex", colors: ["pink"], styles: ["active"]}),
new EquipItem({name:"Heart Thongs", gender: "female", colors: ["green", "white"], styles: ["comfy", "party", "cute"]}),
new EquipItem({name:"Heart Thongs", gender: "female", colors: ["red", "white"], styles: ["comfy", "party", "cute"]}),
new EquipItem({name:"Heart Boxers", gender: "male", colors: ["green", "white"], styles: ["comfy", "party", "cute"]}),
new EquipItem({name:"Heart Boxers", gender: "male", colors: ["red", "white"], styles: ["comfy", "party", "cute"]}),
new EquipItem({name:"Thongs", gender: "female", colors: ["black"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Striped Panties", gender: "unisex", colors: ["black", "pink"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Striped Panties", gender: "unisex", colors: ["white", "cyan"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Striped Panties", gender: "unisex", colors: ["multicolor"], styles: ["study", "party"]}),
new EquipItem({name:"Striped Panties", gender: "unisex", colors: ["cyan", "pink", "white"], styles: ["study", "party"]}),
new EquipItem({name:"Heart Panties", gender: "female", colors: ["black", "red"], styles: ["casual", "cute"]}),
new EquipItem({name:"Heart Panties", gender: "female", colors: ["blue", "red"], styles: ["casual", "cute"]}),
new EquipItem({name:"Heart Panties", gender: "female", colors: ["cyan", "white"], styles: ["casual", "cute"]}),
new EquipItem({name:"Heart Panties", gender: "female", colors: ["green", "red"], styles: ["casual", "cute"]}),
new EquipItem({name:"Heart Panties", gender: "female", colors: ["pink", "red"], styles: ["casual", "cute"]}),
new EquipItem({name:"Heart Panties", gender: "female", colors: ["red", "black"], styles: ["casual", "cute"]}),
new EquipItem({name:"Heart Panties", gender: "female", colors: ["white", "red"], styles: ["casual", "cute"]}),
new EquipItem({name:"Lace Panties", gender: "female", colors: ["black"], styles: ["casual", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Panties", gender: "female", colors: ["white"], styles: ["casual", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Panties", gender: "female", colors: ["blue"], styles: ["casual", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Panties", gender: "female", colors: ["green"], styles: ["casual", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Panties", gender: "female", colors: ["pink"], styles: ["casual", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Panties", gender: "female", colors: ["red"], styles: ["casual", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Retro Panties", gender: "female", colors: ["black"], styles: ["formal", "comfy", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Retro Panties", gender: "female", colors: ["white"], styles: ["formal", "comfy", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Retro Panties", gender: "female", colors: ["blue"], styles: ["formal", "comfy", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Retro Panties", gender: "female", colors: ["green"], styles: ["formal", "comfy", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Retro Panties", gender: "female", colors: ["pink"], styles: ["formal", "comfy", "sexy"], extra: ["lace"]}),
new EquipItem({name:"Lace Retro Panties", gender: "female", colors: ["red"], styles: ["formal", "comfy", "sexy"], extra: ["lace"]}),
],
bra: [
new EquipItem({name:"No Bra", gender:"male", colors: ["nocolor"], styles: []}),
new EquipItem({name:"Beginners Bra", gender:"unisex", colors: ["black"], styles: ["study", "comfy"]}),
new EquipItem({name:"Beginners Bra", gender:"unisex", colors: ["red"], styles: ["study", "comfy"]}),
new EquipItem({name:"Beginners Bra", gender:"unisex", colors: ["white"], styles: ["study", "comfy"]}),
new EquipItem({name:"Beginners Bra", gender:"unisex", colors: ["pink"], styles: ["study", "comfy"]}),
new EquipItem({name:"Beginners Bra", gender:"unisex", colors: ["blue"], styles: ["study", "comfy"]}),
new EquipItem({name:"Crop Cami", gender:"female", colors: ["black"], styles: ["modest"]}),
new EquipItem({name:"Crop Cami", gender:"female", colors: ["blue"], styles: ["modest"]}),
new EquipItem({name:"Crop Cami", gender:"female", colors: ["white"], styles: ["modest"]}),
new EquipItem({name:"Crop Cami", gender:"female", colors: ["red"], styles: ["modest"]}),
new EquipItem({name:"Crop Cami", gender:"female", colors: ["pink"], styles: ["modest"]}),
new EquipItem({name:"Sports Bra", gender:"unisex", colors: ["black"], styles: ["active", "comfy"], extra: ["tight"]}),
new EquipItem({name:"Sports Bra", gender:"unisex", colors: ["blue"], styles: ["active", "comfy"], extra: ["tight"]}),
new EquipItem({name:"Sports Bra", gender:"unisex", colors: ["green"], styles: ["active", "comfy"], extra: ["tight"]}),
new EquipItem({name:"Sports Bra", gender:"unisex", colors: ["pink", "white"], styles: ["active", "comfy"], extra: ["tight"]}),
new EquipItem({name:"Sports Bra", gender:"unisex", colors: ["red"], styles: ["active", "comfy"], extra: ["tight"]}),
new EquipItem({name:"Sports Bra", gender:"unisex", colors: ["white", "black"], styles: ["active", "comfy"], extra: ["tight"]}),
new EquipItem({name:"Push-Up Bra", gender:"female", colors: ["black"], styles: ["casual", "cute"]}),
new EquipItem({name:"Push-Up Bra", gender:"female", colors: ["blue"], styles: ["casual", "cute"]}),
new EquipItem({name:"Push-Up Bra", gender:"female", colors: ["white"], styles: ["casual", "cute"]}),
new EquipItem({name:"Push-Up Bra", gender:"female", colors: ["red"], styles: ["casual", "cute"]}),
new EquipItem({name:"Push-Up Bra", gender:"female", colors: ["pink"], styles: ["casual", "cute"]}),
new EquipItem({name:"Heart Bra", gender:"female", colors: ["green", "white"], styles: ["party", "cute", "sexy"]}),
new EquipItem({name:"Heart Bra", gender:"female", colors: ["red", "white"], styles: ["party", "cute", "sexy"]}),
new EquipItem({name:"Lace Bra", gender:"female", colors: ["black", ], styles: ["formal", "sexy"], extra: ["lace", "transparent"]}),
new EquipItem({name:"Lace Bra", gender:"female", colors: ["blue"], styles: ["formal", "sexy"], extra: ["lace", "transparent"]}),
new EquipItem({name:"Lace Bra", gender:"female", colors: ["green"], styles: ["formal", "sexy"], extra: ["lace", "transparent"]}),
new EquipItem({name:"Lace Bra", gender:"female", colors: ["pink"], styles: ["formal", "sexy"], extra: ["lace", "transparent"]}),
new EquipItem({name:"Lace Bra", gender:"female", colors: ["red"], styles: ["formal", "sexy"], extra: ["lace", "transparent"]}),
new EquipItem({name:"Lace Bra", gender:"female", colors: ["white"], styles: ["formal", "sexy"], extra: ["lace", "transparent"]}),
new EquipItem({name:"Strapless Bra", gender:"female", colors: ["black"], styles: ["casual", "party", "sexy"]}),
],
bottom: [
new EquipItem({name:"No Bottom", gender:"unisex", colors: ["nocolor"], styles: []}),
new EquipItem({name:"Pants", gender:"male", colors: ["black"], styles: ["formal", "modest"]}),
new EquipItem({name:"Pants", gender:"male", colors: ["white"], styles: ["formal", "modest"]}),
new EquipItem({name:"Pants", gender:"male", colors: ["pink"], styles: ["formal", "modest"]}),
new EquipItem({name:"High Waisted Pants", gender:"female", colors: ["black"], styles: ["formal", "casual"]}),
new EquipItem({name:"High Waisted Pants", gender:"female", colors: ["white"], styles: ["formal", "casual"]}),
new EquipItem({name:"High Waisted Pants", gender:"female", colors: ["pink"], styles: ["formal", "casual"]}),
new EquipItem({name:"Tube Skirt", gender:"female", colors: ["black"], styles: ["formal"], 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:"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:"Gym Shorts", gender:"female", colors: ["black", "white"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"female", colors: ["blue", "white"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"female", colors: ["green", "white"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"female", colors: ["pink", "white"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"female", colors: ["red", "black"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Gym Shorts", gender:"female", colors: ["white", "black"], styles: ["active", "comfy", "sexy"]}),
new EquipItem({name:"Denim Shorts", gender:"unisex", colors: ["black"], styles: ["casual", "party"]}),
new EquipItem({name:"Denim Shorts", gender:"unisex", colors: ["blue"], styles: ["casual", "party"]}),
new EquipItem({name:"Denim Shorts", gender:"unisex", colors: ["green"], styles: ["casual", "party"]}),
new EquipItem({name:"Denim Shorts", gender:"unisex", colors: ["white"], styles: ["casual", "party"]}),
new EquipItem({name:"Denim Shorts", gender:"unisex", colors: ["red"], styles: ["casual", "party"]}),
new EquipItem({name:"Denim Shorts", gender:"unisex", colors: ["pink"], styles: ["casual", "party"]}),
new EquipItem({name:"Seifuku Pants", gender:"male", colors: ["black"], styles: ["study"]}),
new EquipItem({name:"Seifuku Pants", gender:"male", colors: ["blue"], styles: ["study"]}),
new EquipItem({name:"Seifuku Pants", gender:"male", colors: ["cyan"], styles: ["study"]}),
new EquipItem({name:"Seifuku Pants", gender:"male", colors: ["green"], styles: ["study"]}),
new EquipItem({name:"Seifuku Pants", gender:"male", colors: ["pink"], styles: ["study"]}),
new EquipItem({name:"Seifuku Pants", gender:"male", colors: ["white"], styles: ["study"]}),
new EquipItem({name:"Seifuku Long Skirt", gender:"female", colors: ["black"], styles: ["study"], 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:"female", colors: ["black"], styles: ["formal", "study", "party"]}),
new EquipItem({name:"Winter Pants", gender:"male", colors: ["green", "white"], styles: ["comfy", "party"], extra: ["thick"]}),
new EquipItem({name:"Winter Pants", gender:"male", colors: ["red", "white"], styles: ["comfy", "party"], extra: ["thick"]}),
new EquipItem({name:"Winter Short Skirt", gender:"female", colors: ["green", "white", "black"], styles: ["comfy", "party", "cute"], extra: ["skirt", "thick"]}),
new EquipItem({name:"Winter Short Skirt", gender:"female", colors: ["red", "white", "black"], styles: ["comfy", "party", "cute"], extra: ["skirt", "thick"]}),
],
top: [
new EquipItem({name:"No Top", gender:"unisex", colors: ["nocolor"], styles: []}),
new EquipItem({name:"T-Shirt", gender:"male", colors: ["black"], styles: ["active", "casual"]}),
new EquipItem({name:"T-Shirt", gender:"male", colors: ["white"], styles: ["active", "casual"]}),
new EquipItem({name:"T-Shirt", gender:"male", colors: ["pink"], styles: ["active", "casual"]}),
new EquipItem({name:"Tank Top", gender:"unisex", colors: ["pink"], styles: ["active"]}),
new EquipItem({name:"Tank Top", gender:"unisex", colors: ["black"], styles: ["active"]}),
new EquipItem({name:"Tank Top", gender:"unisex", colors: ["white"], styles: ["active"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["white"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["black"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["red"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Crop Top", gender:"female", colors: ["pink"], styles: ["formal", "comfy"]}),
new EquipItem({name:"Light Shirt", gender:"unisex", colors: ["black", "red"], styles: ["modest", "study"], extra: ["baggy"]}),
new EquipItem({name:"Light Shirt", gender:"unisex", colors: ["cyan"], styles: ["modest", "study"], extra: ["baggy"]}),
new EquipItem({name:"Light Shirt", gender:"unisex", colors: ["white", "blue", "red"], styles: ["modest", "study"], extra: ["baggy"]}),
new EquipItem({name:"Light Shirt", gender:"unisex", colors: ["white", "green"], styles: ["modest", "study"], extra: ["baggy"]}),
new EquipItem({name:"Light Shirt", gender:"unisex", colors: ["white", "pink", "red"], styles: ["modest", "study"], extra: ["baggy"]}),
new EquipItem({name:"Light Shirt", gender:"unisex", colors: ["yellow", "black"], styles: ["modest", "study"], extra: ["baggy"]}),
new EquipItem({name:"Sailor Shirt", gender:"unisex", colors: ["black", "red"], styles: ["study", "cute"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Shirt", gender:"unisex", colors: ["cyan"], styles: ["study", "cute"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Shirt", gender:"unisex", colors: ["white", "blue", "red"], styles: ["study", "cute"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Shirt", gender:"unisex", colors: ["white", "green"], styles: ["study", "cute"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Shirt", gender:"unisex", colors: ["white", "pink", "red"], styles: ["study", "cute"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Shirt", gender:"unisex", colors: ["yellow", "black"], styles: ["study", "cute"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Crop Top", gender:"female", colors: ["black", "red"], styles: ["study", "party", "sexy"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Crop Top", gender:"female", colors: ["cyan"], styles: ["study", "party", "sexy"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Crop Top", gender:"female", colors: ["white", "blue", "red"], styles: ["study", "party", "sexy"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Crop Top", gender:"female", colors: ["white", "green"], styles: ["study", "party", "sexy"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Crop Top", gender:"female", colors: ["white", "pink", "red"], styles: ["study", "party", "sexy"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Crop Top", gender:"female", colors: ["white", "red"], styles: ["study", "party", "sexy"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Sailor Crop Top", gender:"female", colors: ["yellow", "black"], styles: ["study", "party", "sexy"], extra: ["loose", "baggy"]}),
new EquipItem({name:"Vest", gender:"male", colors: ["red", "yellow", "white"], styles: ["active", "party"]}),
new EquipItem({name:"Vest", gender:"male", colors: ["green", "yellow", "white"], styles: ["active", "party"]}),
new EquipItem({name:"Blouse", gender:"female", colors: ["green", "white", "red"], styles: ["comfy", "party", "cute"]}),
new EquipItem({name:"Blouse", gender:"female", colors: ["red", "white", "green"], styles: ["comfy", "party", "cute"]}),
],
shoes: [
new EquipItem({name:"No Shoes", gender:"unisex", colors: ["nocolor"], styles: []}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["black"], styles: ["formal"]}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["black", "red"], styles: ["formal"]}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["cyan"], styles: ["formal"]}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["green"], styles: ["formal"]}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["pink"], styles: ["formal"]}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["pink", "black"], styles: ["formal"]}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["red", "black"], styles: ["formal"]}),
new EquipItem({name:"Formal Shoes", gender:"male", colors: ["white", "black"], styles: ["formal"]}),
new EquipItem({name:"Sneakers", gender:"unisex", colors: ["black", "white"], styles: ["active", "party", "casual"]}),
new EquipItem({name:"Sneakers", gender:"unisex", colors: ["cyan", "white"], styles: ["active", "casual"]}),
new EquipItem({name:"Sneakers", gender:"unisex", colors: ["green", "white"], styles: ["active", "casual"]}),
new EquipItem({name:"Sneakers", gender:"unisex", colors: ["pink", "white"], styles: ["active", "party", "casual"]}),
new EquipItem({name:"Sneakers", gender:"unisex", colors: ["red", "white"], styles: ["active", "party", "casual"]}),
new EquipItem({name:"Sneakers", gender:"unisex", colors: ["white"], styles: ["active", "casual"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["black", "red"], styles: ["study", "comfy"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["black"], styles: ["study", "comfy"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["cyan"], styles: ["study", "comfy"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["green"], styles: ["study", "comfy"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["pink", "white"], styles: ["study", "comfy"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["pink"], styles: ["study", "comfy"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["red"], styles: ["study", "comfy"]}),
new EquipItem({name:"Loafers", gender:"unisex", colors: ["white"], styles: ["study", "comfy"]}),
new EquipItem({name:"Womens Oxfords", gender:"female", colors: ["brown", "black"], styles: ["formal", "study", "party"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["black", "black"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["cyan"], styles: ["study", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["green"], styles: ["study", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["pink"], styles: ["study", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["pink", "black"], styles: ["study", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["pink", "white"], styles: ["study", "party", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["red"], styles: ["study", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["white"], styles: ["study", "cute"]}),
new EquipItem({name:"Mary Janes", gender:"female", colors: ["white", "black"], styles: ["study", "cute"]}),
new EquipItem({name:"Winter Boots", gender:"male", colors: ["black"], styles: ["modest", "party"]}),
new EquipItem({name:"Winter Boots", gender:"male", colors: ["green", "white"], styles: ["modest", "party"]}),
new EquipItem({name:"Winter Boots", gender:"male", colors: ["red", "white"], styles: ["modest", "party"]}),
new EquipItem({name:"Winter Heels", gender:"female", colors: ["green", "white"], styles: ["party", "cute"], extra: ["highheels"]}),
new EquipItem({name:"Winter Heels", gender:"female", colors: ["red", "white"], styles: ["party", "cute"], extra: ["highheels"]}),
],
legwear: [
new EquipItem({name:"No Legwear", gender:"unisex", colors: ["nocolor"], styles: []}),
new EquipItem({name:"Long Socks", gender:"male", colors: ["white", "green"], styles: ["formal", "modest"]}),
new EquipItem({name:"Long Socks", gender:"male", colors: ["white", "red"], styles: ["formal", "modest"]}),
new EquipItem({name:"Ankle Socks", gender:"unisex", colors: ["white"], styles: ["active", "casual"]}),
new EquipItem({name:"Small Bow Stockings", gender:"female", colors: ["brown", "green", "white"], styles: ["party", "cute"], extra: ["transparent"]}),
new EquipItem({name:"Small Bow Stockings", gender:"female", colors: ["brown", "red", "white"], styles: ["party", "cute"], extra: ["transparent"]}),
new EquipItem({name:"Stockings", gender:"female", colors: ["brown", "black"], styles: ["formal", "casual", "sexy"], extra: ["transparent"]}),
new EquipItem({name:"Seifuku Thigh Highs", gender:"female", colors: ["black", "red"], styles: ["study", "party", "comfy"]}),
new EquipItem({name:"Seifuku Thigh Highs", gender:"female", colors: ["blue", "brown"], styles: ["study", "comfy"]}),
new EquipItem({name:"Seifuku Thigh Highs", gender:"female", colors: ["cyan", "white"], styles: ["study", "comfy"]}),
new EquipItem({name:"Seifuku Thigh Highs", gender:"female", colors: ["green", "white"], styles: ["study", "comfy"]}),
new EquipItem({name:"Seifuku Thigh Highs", gender:"female", colors: ["pink", "white"], styles: ["study", "party", "comfy"]}),
new EquipItem({name:"Seifuku Thigh Highs", gender:"female", colors: ["white", "blue"], styles: ["study", "party", "comfy"]}),
new EquipItem({name:"Seifuku Thigh Highs", gender:"female", colors: ["red", "white"], styles: ["study", "comfy"]}),
],
mask: [
new EquipItem({name:"No Mask", gender:"unisex", colors: ["nocolor"], styles: []}),
new EquipItem({name:"Santas Beard", gender:"male", colors: ["white"], styles: ["party", "party", "party"], extra: ["fake"]}),
new EquipItem({name:"Lexington Glasses", gender:"male", colors: ["black"], styles: ["formal", "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"}),
],
}>>
/* TODO 'multi' & 'hp' property for clothes? */
<<set _default_zero to ["fem", "sub", "int", "fit", "att"]>>
<<for _place, _list range setup.all_clothes>>
<<for _id, _cl range _list>>
<<set _cl.id to _id>>
<<set _cl.place to _place>>
<<set _cl.extra ??= []>>
<<for _prop range _default_zero>>
<<set _cl[_prop] ??= 0>>
<</for>>
<</for>>
<<clothesstatgen _list>>
<<clothesraritygen _list>>
<</for>><<widget "clothesraritygen">>
<<for _item range _args[0]>>
<<set _value to _item.colors.length+_item.styles.length>>
<<if _item.rarity is 0>>
<<if _value gte 5>>
<<set _item.rarity to 3>>
<<elseif _value gte 4>>
<<set _item.rarity to 2>>
<<elseif _value gte 3>>
<<set _item.rarity to 1>>
<<else>>
<<set _item.rarity to 0>>
<</if>>
<</if>>
<</for>>
<</widget>>
<<widget "clothesstatgen">>
<<set _scale to _args[1]>>
<<for _item range _args[0]>>
<<set _fem to _item.fem ?? 0>>
<<set _stylepts to {
modest: {fem:-2, sub:1, int:0, fit:0, att:0},
formal: {fem:-1, sub:0, int:1, fit:0, att:0},
active: {fem:0, sub:0, int:0, fit:1, att:0},
comfy: {fem:-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:0},
nocolor: {fem:0},
blue: {fem:1},
brown: {fem:-1},
yellow: {fem:1},
cyan: {fem:1},
green: {fem:1},
white: {fem:2},
red: {fem:2},
multicolor: {fem:2},
}>>
<<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},
}>>
<<for _extra range _item.extra>>
<<set _fem += _extrapts?.[_extra]?.fem ?? 0>>
<</for>>
<<set _genpts to {
male: {fem: 0},
unisex: {fem: 4},
female: {fem: 8},
}>>
<<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,
}>><<set setup.action_cards to {
all_player: [
new ActionCard({"name": "Complain", "power": "4", "rarity": "0", "suit": "burst", "theme": "Smart", "stat1": "Stress+", "unique_effects": "<i>?burst Burst effect ?burst <br> The next card gets one-time-bonus to power equal to ?burst counters</i>", }),
new ActionCard({"name": "Complain+", "power": "3", "rarity": "1", "suit": "burst", "theme": "Smart", "stat1": "Stress+", "stat2": "Stress+", "card+bott": "1", }),
new ActionCard({"name": "No Time to Think", "power": "2", "rarity": "2", "suit": "drain", "theme": "Smart", "stat1": "Arousal-", "stat2": "Stress+", "unique_effects": "Add as much ?drain as ?flow<br>Reset ?flow", "effect_fn": "complain_effect", }),
new ActionCard({"name": "No Time to Think+", "power": "-2", "rarity": "3", "suit": "drain", "theme": "Smart", "stat1": "Arousal-", "stat2": "Stress+", "stat3": "Stress+", "unique_effects": "Add as much ?drain as ?flow", "effect_fn": "complain_plus_effect", }),
new ActionCard({"name": "Take a Break", "power": "-4", "rarity": "1", "suit": "refresh", "theme": "Smart", "stat1": "Stress-", "unique_effects": "<i>?refresh Refresh effect ?refresh <br> Each turn draw the same number of cards as ?refresh counters you have</i>", }),
new ActionCard({"name": "Take a Break+", "power": "-5", "rarity": "2", "suit": "refresh", "theme": "Smart", "stat1": "Stress-", "stat2": "Arousal+", "card+bott": "1", }),
new ActionCard({"name": "Talk", "power": "3", "rarity": "0", "suit": "flow", "theme": "Smart", "stat1": "Stress+", "stat2": "Arousal+", "card+bott": "1", }),
new ActionCard({"name": "Talk+", "power": "1", "rarity": "1", "suit": "flow", "theme": "Smart", "stat1": "Stress+", "card+bott": "1", }),
new ActionCard({"name": "Calculated Move", "power": "2", "rarity": "1", "suit": "flow", "theme": "Smart", "stat1": "Stress+", "stat2": "Stress+", "unique_effects": "Next card gets power bonus equal to ?flow", "effect_fn": "calculated_move_effect", }),
new ActionCard({"name": "Calculated Move+", "power": "2", "rarity": "2", "suit": "flow", "theme": "Smart", "stat1": "Stress+", "stat2": "Stress+", "unique_effects": "Add power of this card to the 1st card", "effect_fn": "calculated_move_plus_effect", }),
new ActionCard({"name": "Pay Attention", "power": "3", "rarity": "1", "suit": "flow", "theme": "Smart", "stat1": "Stress+", "unique_effects": "Create ?smart ?token token in hand", "effect_fn": "pay_attention_effect", }),
new ActionCard({"name": "Pay Attention+", "power": "3", "rarity": "2", "suit": "flow", "theme": "Smart", "stat1": "Stress+", "stat2": "Stress+", "unique_effects": "Create 3 ?smart ?token tokens in hand", "effect_fn": "pay_attention_plus_effect", }),
new ActionCard({"name": "Clear Mind", "power": "-2", "rarity": "2", "suit": "flow", "theme": "Smart", "stat1": "Stress-", "stat2": "Arousal+", "unique_effects": "Get as much ?flow as cards in hand", "effect_fn": "clear_mind_effect", }),
new ActionCard({"name": "Clear Mind+", "power": "-2", "rarity": "3", "suit": "flow", "theme": "Smart", "stat1": "Stress-", "stat2": "Arousal+", "stat3": "Arousal+", "unique_effects": "Double ?flow", "effect_fn": "clear_mind_plus_effect", }),
new ActionCard({"name": "Smart Thought", "power": "0", "rarity": "0", "suit": "token", "theme": "Smart", "unique_effects": "-1 ?flow<br>Temporary add +2 to all cards in hand", "effect_fn": "smart_thought_effect", }),
new ActionCard({"name": "Oops, Silly Me", "power": "1", "rarity": "1", "suit": "burst", "theme": "Ditz", "stat1": "Arousal-", "unique_effects": "-1 ?drain<br>+1 ?burst", "effect_fn": "silly_me_effect", }),
new ActionCard({"name": "Oops, Silly Me+", "power": "2", "rarity": "2", "suit": "burst", "theme": "Ditz", "stat1": "Arousal-", "stat2": "Stress+", "unique_effects": "-1 ?drain<br>+2 ?burst", "effect_fn": "silly_me_plus_effect", }),
new ActionCard({"name": "Lolipop", "power": "-6", "rarity": "2", "suit": "refresh", "theme": "Ditz", "stat1": "Stress-", "unique_effects": "+2 ?drain", "effect_fn": "lolipop_effect", }),
new ActionCard({"name": "Lolipop+", "power": "-10", "rarity": "3", "suit": "refresh", "theme": "Ditz", "stat1": "Stress-", "stat2": "Arousal+", "card+bott": "2", "unique_effects": "+2 ?drain<br>", "effect_fn": "lolipop_effect", }),
new ActionCard({"name": "Play Dumb", "power": "2", "rarity": "0", "suit": "flow", "theme": "Ditz", "stat1": "Arousal-", "stat2": "Stress+", "unique_effects": "<i>?flow Flow effect ?flow <br> Each turn cards in hand get perma-bonus to power equal to ?flow counters</i>", }),
new ActionCard({"name": "Play Dumb+", "power": "1", "rarity": "1", "suit": "flow", "theme": "Ditz", "stat1": "Stress+", "card+bott": "1", }),
new ActionCard({"name": "Apathy", "power": "0", "rarity": "0", "suit": "drain", "theme": "Ditz", "stat1": "Arousal-", "unique_effects": "<i>?drain Drain effect ?drain <br> Each turn deal as much damage as ?drain counters you have</i>", }),
new ActionCard({"name": "Apathy+", "power": "-1", "rarity": "1", "suit": "drain", "theme": "Ditz", "stat1": "Arousal-", "stat2": "Stress+", "card+bott": "1", }),
new ActionCard({"name": "Lip Biting", "power": "2", "rarity": "1", "suit": "drain", "theme": "Ditz", "stat1": "Arousal+", "unique_effects": "Trigger ?drain", "effect_fn": "ditzy_thought_effect", }),
new ActionCard({"name": "Lip Biting+", "power": "1", "rarity": "2", "suit": "drain", "theme": "Ditz", "stat1": "Arousal+", "stat2": "Stress+", "card+bott": "1", "unique_effects": "Trigger ?drain<br>", "effect_fn": "ditzy_thought_effect", }),
new ActionCard({"name": "Loose Pants", "power": "4", "rarity": "1", "suit": "drain", "theme": "Ditz", "stat1": "Arousal+", "unique_effects": "Create ?ditz ?token token in hand", "effect_fn": "loose_pants_effect", }),
new ActionCard({"name": "Loose Pants+", "power": "2", "rarity": "2", "suit": "drain", "theme": "Ditz", "stat1": "Arousal+", "stat2": "Arousal+", "unique_effects": "Create 3 ?ditz ?token tokens in hand", "effect_fn": "loose_pants_plus_effect", }),
new ActionCard({"name": "High Five", "power": "2", "rarity": "2", "suit": "drain", "theme": "Ditz", "stat1": "Arousal+", "stat2": "Arousal+", "unique_effects": "Get as much ?drain as cards in hand", "effect_fn": "high_five_effect", }),
new ActionCard({"name": "High Five+", "power": "2", "rarity": "3", "suit": "drain", "theme": "Ditz", "stat1": "Arousal+", "stat2": "Arousal+", "stat3": "Stress+", "unique_effects": "Double ?drain", "effect_fn": "high_five_plus_effect", }),
new ActionCard({"name": "Ditzy Thought", "power": "0", "rarity": "0", "suit": "token", "theme": "Ditz", "unique_effects": "Trigger ?drain", "effect_fn": "ditzy_thought_effect", }),
],
all_enemy: [
new ActionCard({"name": "Arousal Suppressants", "power": "0", "rarity": "0", "gender": "Female", "suit": "enemy", "theme": "Ditz", "stat1": "TF+", "unique_effects": "<<power_is -2>> * ?arousal<br>-5 ?arousal", "pre_play_fn": "arousal_supp_pre", "effect_fn": "arousal_lower5_effect", }),
new ActionCard({"name": "Relaxation Chair", "power": "0", "rarity": "0", "gender": "Female", "suit": "enemy", "theme": "Smart", "stat1": "TF+", "unique_effects": "<<power_is -2>> * ?stress<br>-5 ?stress", "pre_play_fn": "relaxation_chair_pre", "effect_fn": "stress_lower5_effect", }),
new ActionCard({"name": "Not Alone", "power": "0", "rarity": "1", "gender": "Male", "suit": "enemy", "theme": "Smart", "stat1": "TF+", "unique_effects": "<<power_is -2>> * ?stress<br>-10 ?stress", "pre_play_fn": "relaxation_chair_pre", "effect_fn": "stress_reset_effect", }),
new ActionCard({"name": "Bigger than Mine", "power": "0", "rarity": "2", "gender": "Male", "suit": "enemy", "theme": "Smart", "unique_effects": "-10 ?stress", "effect_fn": "stress_reset_effect", }),
new ActionCard({"name": "Post Workout Fuel", "power": "0", "rarity": "3", "gender": "Male", "suit": "enemy", "theme": "Smart", "unique_effects": "-10 ?arousal", "effect_fn": "arousal_reset_effect", }),
new ActionCard({"name": "Suck some Milk", "power": "0", "rarity": "1", "gender": "Male", "suit": "enemy", "theme": "Smart", "unique_effects": "-10 ?arousal", "effect_fn": "arousal_reset_effect", }),
new ActionCard({"name": "Exhausted", "power": "0", "rarity": "2", "gender": "Male", "suit": "enemy", "theme": "Smart", "unique_effects": "-5 ?stress", "effect_fn": "stress_lower5_effect", }),
new ActionCard({"name": "Spread Wide", "power": "0", "rarity": "3", "gender": "Male", "suit": "enemy", "theme": "Smart", "unique_effects": "-10 ?arousal<br>-5 ?stress", "effect_fn": "arousal_reset_stress_lower5_effect", }),
new ActionCard({"name": "Lick or Suck", "power": "0", "rarity": "1", "gender": "Female", "suit": "enemy", "theme": "Ditz", "stat1": "TF+", "unique_effects": "-10 ?stress", "effect_fn": "stress_reset_effect", }),
new ActionCard({"name": "Flirt gone Wild", "power": "0", "rarity": "3", "gender": "Female", "suit": "enemy", "theme": "Ditz", "stat1": "TF+", "stat2": "TF+", "unique_effects": "<<power_is 2>> * ?arousal<br>-10 ?arousal<br>-5 ?stress", "pre_play_fn": "arousal_x2_increase_pre", "effect_fn": "arousal_reset_stress_lower5_effect", }),
],
}>>
/* Gender flip every card & add them back to all_player */
<<set _gflip_cards to []>>
<<for _card range setup.action_cards.all_player>>
<<run _gflip_cards.push(clone(_card).flip_gender())>>
<</for>>
<<run setup.action_cards.all_player.push(... _gflip_cards)>>
<<set setup.action_cards.player_drops to setup.action_cards.all_player
.filter(c => c.suit !== "token")>>
<<set setup.action_cards.player_normal to setup.action_cards.player_drops
.filter(c => !c.name.includes("+"))>>
<<set setup.action_cards.player_upgrade to setup.action_cards.player_drops
.filter(c => c.name.includes("+"))>>
<<set setup.action_cards.player_token to setup.action_cards.all_player
.filter(c => c.suit === "token")>>
<<set setup.starter_deck to [0, 30, 4, 34, 19, 49, 21, 51]
.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 => clone(card).flip_gender())>>
<</for>>
<<set setup.id_to_enemy_card to function(id) {
return clone(setup.action_cards.all_enemy[id]).enemy_reset();
}>><<set setup.action_cards to [
new ActionCard({"name": "Apologize", "power": "8", "color": "Red", "rarity": "0", "sub-": "1", "stat1": "Stress+", }),
new ActionCard({"name": "Talk", "power": "8", "color": "Blue", "rarity": "0", "int-": "1", "stat1": "Arousal+", }),
new ActionCard({"name": "Slap", "power": "8", "color": "Green", "rarity": "0", "fit-": "1", "stat1": "Stress+", }),
new ActionCard({"name": "Flirt", "power": "8", "color": "Purple", "rarity": "0", "att-": "1", "stat1": "Arousal+", }),
new ActionCard({"name": "Meditate", "power": "5", "color": "Red", "rarity": "1", "sub-": "2", "stat1": "Stress-", "card+bott": "1", }),
new ActionCard({"name": "Take a Break", "power": "5", "color": "Blue", "rarity": "1", "int-": "2", "stat1": "Stress-", "card+bott": "1", }),
new ActionCard({"name": "Respite", "power": "5", "color": "Green", "rarity": "1", "fit-": "2", "stat1": "Stress-", "card+bott": "1", }),
new ActionCard({"name": "Freshen Up", "power": "5", "color": "Purple", "rarity": "1", "att-": "2", "stat1": "Stress-", "card+bott": "1", }),
new ActionCard({"name": "Apathy", "power": "17", "color": "Red", "rarity": "2", "sub-": "2", "stat1": "Arousal-", "stat2": "Arousal-", "unique_effects": "<<power_is 17>> - ?arousal", "pre_play_fn": "subt_arousal_pre", }),
new ActionCard({"name": "Cheer Up", "power": "17", "color": "Blue", "rarity": "2", "int-": "2", "stat1": "Stress-", "stat2": "Arousal-", "unique_effects": "<<power_is 17>> - ?stress", "pre_play_fn": "subt_stress_pre", }),
new ActionCard({"name": "Embrace Masculinity", "power": "19", "color": "Green", "rarity": "2", "fit-": "2", "stat1": "Arousal-", "stat2": "Stress+", "unique_effects": "<<power_is 19>> - ?identity", "pre_play_fn": "subt_identity_pre", }),
new ActionCard({"name": "Embrace Femininity", "power": "9", "color": "Purple", "rarity": "2", "att-": "2", "stat1": "Stress-", "stat2": "Arousal+", "unique_effects": "<<power_is 9>> + ?fem", "pre_play_fn": "add_fem_pre", }),
new ActionCard({"name": "Obey", "power": "11", "color": "Red", "rarity": "3", "sub-": "3", "stat1": "Stress-", "stat2": "Arousal+", "stat3": "Arousal+", "unique_effects": "<<power_is 11>> + ?sub", "pre_play_fn": "add_mana_sub_pre", }),
new ActionCard({"name": "Complain", "power": "12", "color": "Blue", "rarity": "3", "int-": "3", "stat1": "Stress+", "stat2": "Stress+", "unique_effects": "<<power_is 12>> + ?int", "pre_play_fn": "add_mana_int_pre", }),
new ActionCard({"name": "Special Move", "power": "11", "color": "Green", "rarity": "3", "fit-": "3", "stat1": "Arousal-", "stat2": "Stress+", "stat3": "Stress+", "unique_effects": "<<power_is 11>> + ?fit", "pre_play_fn": "add_mana_fit_pre", }),
new ActionCard({"name": "Seduction", "power": "12", "color": "Purple", "rarity": "3", "att-": "3", "stat1": "Arousal+", "stat2": "Arousal+", "unique_effects": "<<power_is 12>> + ?att", "pre_play_fn": "add_mana_att_pre", }),
new ActionCard({"name": "Calculated Move", "power": "4", "color": "Blue", "rarity": "1", "int-": "1", "unique_effects": "1st card in hand gets <<power_is 4>>", "effect_fn": "calculated_effect", }),
]>>
<<set setup.balance_cards to [
new ActionCard({"balance-": 1, "name": "Awkward Silence", "power": 13, "color": "Blue", "rarity": 1, "stat1": "Arousal-", "int+": 2, "fit+": 2, "card+top": 2, }),
new ActionCard({"balance-": 1, "name": "Friendly Talk", "power": 17, "color": "Blue", "rarity": 2, "stat1": "Stress-", "stat2": "Arousal-", "int+": 3, "fit+": 3, "card+top": 3, }),
new ActionCard({"balance-": 1, "name": "Friendzone", "power": 21, "color": "Blue", "rarity": 3, "stat1": "Stress-", "stat2": "Stress-", "stat3": "Arousal-", "int+": 4, "fit+": 4, "card+top": 4, }),
]>>
<<set setup.corruption_cards to [
new ActionCard({"corruption-": 1, "name": "Get Closer", "power": 21, "color": "Purple", "rarity": 1, "stat1": "Arousal+", "sub+": 3, "att+": 3, "card+top": 2, }),
new ActionCard({"corruption-": 1, "name": "Blowjob", "power": 26, "color": "Purple", "rarity": 2, "stat1": "Stress+", "stat2": "Arousal+", "sub+": 4, "att+": 4, "card+top": 3, }),
new ActionCard({"corruption-": 1, "name": "Hardcore", "power": 31, "color": "Purple", "rarity": 3, "stat1": "Stress+", "stat2": "Arousal+", "stat3": "Arousal+", "sub+": 5, "att+": 5, "card+top": 4, }),
]>>
<<set setup.punish_cards to [
new ActionCard({"name": "Spanked", "power": "0", "color": "Red", "rarity": "1", "theme": "Pain", "sub-": "2", "stat1": "Masochism+", "stat2": "Stress+", "card+bott": "2", "unique_effects": "?delete<br><<power_is 0>> - ?sub", "pre_play_fn": "spanked_pre", "effect_fn": "delete_self_effect", }),
new ActionCard({"name": "Boredom", "power": "0", "color": "Blue", "rarity": "1", "theme": "Ditz", "int-": "2", "stat1": "Airhead+", "stat2": "Arousal+", "card+bott": "1", "unique_effects": "?delete<br><<power_is 0>> - ?int", "pre_play_fn": "boredom_pre", "effect_fn": "delete_self_effect", }),
new ActionCard({"name": "Stiff Muscles", "power": "0", "color": "Green", "rarity": "1", "theme": "Pain", "fit-": "2", "stat1": "Masochism+", "stat2": "Stress+", "card+bott": "1", "unique_effects": "?delete<br><<power_is 0>> - ?fit", "pre_play_fn": "stiff_muscles_pre", "effect_fn": "delete_self_effect", }),
new ActionCard({"name": "Ditzy Thought", "power": "-5", "color": "Purple", "rarity": "0", "theme": "Ditz", "att-": "1", "stat1": "Airhead+", "stat2": "Arousal+", "stat3": "Stress-", "card+top": "1", "unique_effects": "?delete", "effect_fn": "delete_self_effect", }),
new ActionCard({"name": "Feel the Pain", "power": "-5", "color": "Red", "rarity": "0", "theme": "Pain", "sub-": "1", "stat1": "Masochism+", "stat2": "Stress+", "stat3": "Arousal-", "card+top": "1", "unique_effects": "?delete", "effect_fn": "delete_self_effect", }),
new ActionCard({"name": "Lip Biting", "power": "-1", "color": "Purple", "rarity": "1", "theme": "Pain", "att-": "1", "stat1": "Masochism+", "stat2": "Stress+", "card+bott": "1", "unique_effects": "Discard 1st card in hand", "effect_fn": "lip_biting_effect", }),
new ActionCard({"name": "No Pain No Gain", "power": "-1", "color": "Green", "rarity": "2", "theme": "Pain", "fit-": "1", "stat1": "Masochism+", "unique_effects": "Next card gets <<power_is -1>>", "pre_play_fn": "npng_pre", "effect_fn": "npng_effect", }),
new ActionCard({"name": "Butt Slam", "power": "3", "color": "Green", "rarity": "3", "theme": "Pain", "fit-": "2", "stat1": "Masochism+", "stat2": "Stress+", "stat3": "Arousal+", "unique_effects": "?strike <br><i>double the power</i>", "pre_play_fn": "double_self_pre", }),
new ActionCard({"name": "Make a Scene", "power": "-5", "color": "Purple", "rarity": "1", "theme": "Ditz", "att-": "1", "stat1": "Airhead+", "stat2": "Arousal+", "card+top": "2", "unique_effects": "Next card gets <<power_is 4>>", "effect_fn": "make_scene_effect", }),
new ActionCard({"name": "Play Dumb", "power": "-5", "color": "Purple", "rarity": "1", "theme": "Ditz", "int-": "1", "att-": "1", "stat1": "Airhead+", "card+top": "3", "unique_effects": "?new_card <b>Ditzy Thought</b>", "effect_fn": "play_dumb_effect", }),
new ActionCard({"name": "Oops, silly me", "power": "-2", "color": "Purple", "rarity": "2", "theme": "Ditz", "sub-": "1", "att-": "1", "stat1": "Airhead+", "stat2": "Masochism+", "stat3": "Stress+", "card+top": "1", "unique_effects": "1st card gets <<power_is ?hand_size>>", "effect_fn": "silly_me_effect", }),
new ActionCard({"name": "High-Five", "power": "-5", "color": "Purple", "rarity": "3", "theme": "Ditz", "att-": "2", "stat1": "Airhead+", "stat2": "Arousal+", "card+top": "2", "unique_effects": "<<power_is -5>> + <<power_is ?hand_size>><br>?strike", "pre_play_fn": "high_five_pre", }),
]>>
/* change name now that image is set correctly */
<<set setup.punish_cards[10].name to '"Oops, silly me!"'>>
/* TODO painkillers is duplicated b/c we decided to make all of them "no delete" variant */
<<set setup.cleanse_cards to [
new ActionCard({"name": "Clear Mind", "power": "11", "color": "Blue", "rarity": "2", "int-": "1", "att-": "1", "stat1": "Arousal-", "stat2": "Airhead-", "card+bott": "2", "unique_effects": "?remove2 1 <b>Ditzy Thought</b><br>?delete chance from ?airhead", "pre_play_fn": "clear_mind_pre", "effect_fn": "clear_mind_effect", }),
new ActionCard({"name": "Painkillers", "power": "11", "color": "Green", "rarity": "2", "int-": "1", "fit-": "1", "stat1": "Stress-", "stat2": "Masochism-", "card+bott": "2", "unique_effects": "?remove2 1 <b>Feel the Pain</b>", "pre_play_fn": "painkiller_nd_pre", "effect_fn": "painkiller_nd_effect", }),
new ActionCard({"name": "Painkillers", "power": "11", "color": "Green", "rarity": "2", "int-": "1", "fit-": "1", "stat1": "Stress-", "card+bott": "2", "unique_effects": "?remove2 1 <b>Feel the Pain</b>", "pre_play_fn": "painkiller_nd_pre", "effect_fn": "painkiller_nd_effect", }),
]>>
<<set setup.get_pain_cards to [
new ActionCard({"name": "Try Hard", "power": "0", "color": "Green", "rarity": "1", "stat1": "Stress+", "int+": "3", "fit+": "3", "card+top": "2", "unique_effects": "?new_card <b>Feel the Pain</b>", "effect_fn": "try_hard_effect", }),
new ActionCard({"name": "Helping Hand", "power": "0", "color": "Red", "rarity": "1", "theme": "Pain", "stat1": "Arousal+", "sub+": "3", "fit+": "3", "card+top": "2", "unique_effects": "?new_card <b>Feel the Pain</b>", "effect_fn": "helping_hand_effect", }),
]>>
/* TODO: Remove when 3+ cards exist for this */
<<run setup.get_pain_cards.push(... clone(setup.get_pain_cards))>>
<<set setup.get_distraction_cards to [
new ActionCard({"name": "Pay Attention", "power": "0", "color": "Blue", "rarity": "1", "stat1": "Stress+", "int+": "3", "att+": "3", "card+top": "2", "unique_effects": "?new_card <b>Boredom</b>", "effect_fn": "pay_attention_effect", }),
new ActionCard({"name": "Play Dumb", "power": "0", "color": "Purple", "rarity": "1", "theme": "Ditz", "stat1": "Arousal+", "sub+": "3", "att+": "3", "card+top": "2", "unique_effects": "?new_card <b>Ditzy Thought</b>", "effect_fn": "play_dumb_effect", }),
]>>
/* TODO: Remove when 3+ cards exist for this */
<<run setup.get_distraction_cards.push(... clone(setup.get_distraction_cards))>>
<<set setup.meme_shift_cards to [
new ActionCard({"name": "Pay Attention", "power": "0", "color": "Blue", "rarity": "1", "stat1": "Stress+", "int+": "3", "att+": "3", "card+top": "2", "unique_effects": "?new_card <b>Boredom</b>", "effect_fn": "pay_attention_effect", }),
new ActionCard({"name": "Play Dumb", "power": "0", "color": "Purple", "rarity": "1", "theme": "Ditz", "stat1": "Arousal+", "sub+": "3", "att+": "3", "card+top": "2", "unique_effects": "?new_card <b>Ditzy Thought</b>", "effect_fn": "play_dumb_effect", }),
new ActionCard({"name": "Ditzy Thought", "power": "-5", "color": "Purple", "rarity": "0", "theme": "Ditz", "stat1": "Airhead+", "stat2": "Arousal+", "stat3": "Stress-", "card+top": "2",}),
new ActionCard({"name": "Cheer Up", "power": "7", "color": "Blue", "rarity": "2", "stat1": "Stress-", "stat2": "Airhead+", "card+bott": "2", "unique_effects": "<<power_is 7>> - ?stress", "pre_play_fn": "subt_stress_pre", }),
]>>
<<set $player_deck to [
setup.action_cards[0],
setup.action_cards[1],
setup.action_cards[2],
setup.action_cards[3],
]>>
/*<<set $player_deck to clone(setup.action_cards)>>*//* different set of enemies for different loops, e.g. "Regular", "Halloween", etc. */
<<set setup.enemies to {
regular: [
{
name: "Bubblegum",
target: "regular person",
color: "fuchsia",
fg_img: "auto",
max_progression: 6,
img_ids: [0, 1, 1, 2, 2, 3, 4],
left_decks: [
[1],
[1],
[1],
[1],
[1, 6],
[1, 6],
[1, 6],
],
right_decks: [
[0],
[0],
[0, 5],
[0, 5],
[0, 5],
[0, 5],
[0, 5, 7],
],
},
{
name: "Meme Analyst Shift",
target: "meme job",
color: "mediumvioletred",
bg_img: "meme analyst_b.jpg",
left_decks: [[1]],
right_decks: [[0]],
},
{
name: "Stylist",
target: "stylist encounter",
color: "chocolate",
fg_img: "auto",
max_progression: 4,
img_ids: [0, 1, 1, 2, 3],
left_decks: [
[1],
[1],
[1, 8],
[1, 8],
[1, 8],
],
right_decks: [
[0],
[0],
[0],
[0],
[0, 9],
],
},
{
name: "Blue Belle",
target: "training encounter",
color: "royalblue",
fg_img: "auto",
max_progression: 6,
img_ids: [0, 1, 1, 2, 2, 3, 4],
left_decks: [
[1],
[1],
[1, 2],
[1, 2],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
],
right_decks: [
[0],
[0],
[0],
[0],
[0],
[0],
[0, 4],
],
},
]
}>>
<<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>>
<<set _enm.bg_img ??= _enm.name.toLowerCase() + "_b.jpg">>
<<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>>
<<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[12],
bra: setup.all_clothes.bra[23],
legwear: setup.all_clothes.legwear[5],
mask: setup.all_clothes.mask[0],
top: setup.all_clothes.top[0],
shoes: setup.all_clothes.shoes[0],
bottom: setup.all_clothes.bottom[0],
})>>
<<set $player_perm_equip to clone($player_equipment)>>
<<set $player_stats to new PlayerStats()>>
<<set $player_stats.cor_cards to 1; $player_stats.bal_cards to 1>>
<<set $inv to new PlayerInventory()>>
<<set $combat_stats to {
drain_base: 0,
drain_per_card: 1,
drain_decay: 1,
drain_min: 0,
flow_base: 0,
flow_per_card: 1,
flow_decay: 1,
flow_min: 0,
burst_base: 0,
burst_per_card: 1,
refresh_base: 3,
refresh_per_card: 1,
}>>
<<set $exp_stats to {
feminine: 0,
masculine: 0,
}>><<widget "statbar">>
/* args[0] is expected to be a value in PlayerStats e.g. fem, stress... one of the ones capped at 10
* args[1] is an optional icon name (uses 0 otherwise) */
<<set _wis_icon to _args[1] ?? _args[0]>>
<<set _wis_stat to $player_stats[_args[0]]>>
<span @class='"statbar statbar-" + _wis_icon'>
<img class="statbar-icon" @alt="_args[0]" @src='"img2/icons/" + _wis_icon + ".svg"'>
<<for _i = 1; _i lte 10; ++_i>>
<<set _wis_class to "statbar-block">>
<<if _wis_stat gte _i>>
<<set _wis_class += " statbar-block-on">>
<</if>>
<span @class="_wis_class">
<<if _i is _wis_stat>>
<<print _i>>
<<elseif (_i is 1 and _wis_stat lt 1) or (_i is 10 and _wis_stat gt 10)>>
/* first block should have lte 1, last block has gte 10 */
<<print _wis_stat>>
<</if>>
</span>
<</for>>
</span>
<</widget>>
<<widget "raw_stat_num">>
/* args:
* 0: icon name (path in icons dir), also becomes extra class name
* 1: display value-- rendered literally; no safety precautions.
* 2: add'l CSS classes to apply after statnum instead of defaults */
<<set _wrsn_classes to _args[2] ?? "statnum-" + _args[0]>>
<span @class='"statnum " + _wrsn_classes'>
<img class="statnum-img" @alt="_args[0]" @src='"img2/icons/" + _args[0] + ".svg"'>
<span class="statnum-txt"><<print _args[1]>></span>
</span>
<</widget>>
<<widget "statnum">>
/* args:
* 0: icon name & key in lookup object (usually $player_stats)
* 1: OPTIONAL lookup object, defaults to PlayerStats */
<<set _wisn_icon to _args[0]>>
<<set _wisn_value to (_args[1] ?? $player_stats)[_args[0]]>>
<<if typeof _wisn_value isnot "number">>
<<set _wisn_value to "??">>
<<else>>
<<set _wisn_value to Math.clamp(Math.round(_wisn_value), -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>>
/* head */
<img @src='"img2/char/body/other/" + _char.face.head + _svg'>
/* makeup svg */
<img @src='"img2/char/styles/makeup/" + _char.makeup.name + "/" + "".concat(... _char.makeup.colors) + "/" + _char.face.id + _svg'>
/* lipstick svg */
<img @src='"img2/char/styles/lipstick/" + _char.lipstick.name + "/" + "".concat(... _char.lipstick.colors) + "/" + _char.face.id + _svg'>
/* front hair & ears */
<img @src='"img2/char/styles/hair/" + _char.hairstyle.name + "/" + "".concat(... _char.hairstyle.colors) + "/" + _char.hair.id + "/f" + _svg'>
<img @src='"img2/char/styles/hair/ears_" + _char.hairstyle.ears[_char.hair.id] + _svg'>
/* face */
<img @src='"img2/char/body/face/" + _char.face.id + _svg'>
/* mask */
<<if _layer gte 1>>
<img @src='"img2/char/clothes/mask/" + _char.mask.name + "/" + "".concat(... _char.mask.colors) + _svg'>
<</if>>
</div>
<</widget>><<widget equip_card>>
/* _args[0] is expected to be an EquipItem.
* Also, note that in widgets, using a common name like _card can accidentally overwrite stuff :\ */
<<set _weq_card to _args[0]>>
<<if _weq_card is undefined or _weq_card is null>>
<<run $debug_passages.add(passage())>>
<div class="equipgrid">
<img src="img2/gear/static2.svg" class="equipgridbg" style='background: orange'>
<span style="grid-row: 2; font-size: 8cqh; margin: 1em;">
An equipment card belongs here but it was null or undefined.
Please save here and report this bug.
</span>
</div>
<<else>>
<<set _rarity_text to _weq_card.rarity_text>>
<<if _rarity_text is "unique">>
<<set _rarity_text to "legendary">>
<</if>>
/* patches for new equipment card style */
<<switch _rarity_text>>
<<case "rare">>
<<set _bg to "deepskyblue">>
<<case "epic">>
<<set _bg to "blueviolet">>
<<case "legendary">>
<<set _bg to "orange">>
<<default>> /* common */
<<set _bg to "gray">>
<</switch>>
<<set _fem to _weq_card.fem>>
<div class="equipgrid">
<img src="img2/gear/static2.svg" class="equipgridbg" @style='"background: " + _bg'>
<div class="equipgridheader">
<span class="equipgridtitle">_weq_card.name</span>
<span class="equipgridstyles">
<<for _style range _weq_card.styles>>
<<if def $current_loop?.bonuses?.styles?.[_style]>>
<<set _weq_bnscls to "loop-bonus">>
<<else>>
<<set _weq_bnscls to "">>
<</if>>
<img @class="_weq_bnscls" @src='"img2/gear/style/" + _style + ".svg"'>
<</for>>
</span>
</div>
<div class="equipgridart">
<<render_char setup.equip_layers[_weq_card.place] setup.svg_views[_weq_card.place]
$player_equipment.with_alt_equip(_weq_card)>>
</div>
<img src="img2/gear/frame.svg" class="equipgridbg" style="z-index: 10">
<div class="equipgridinfo">
<div class="equipgriddesc">
/*<<for _sifa range setup.SIFA>>
<<for _num to 1; _num lte _weq_card[_sifa]; _num++>>
<<if _num gt _weq_card["base_" + _sifa]>>
<<set _weq_bnscls to "loop-bonus">>
<<else>>
<<set _weq_bnscls to "">>
<</if>>
<img @class="_weq_bnscls" @src='"img2/icons/" + _sifa + ".svg"'>
<</for>>
<</for>>*/
</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/status.svg">
<<set _wac_is_bad to _qty gt 0>>
<<if setup.skill_stats.includes(_type)>>
<<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>
/*<h2>SIFA Statistics</h2>*/
</div>
/*<p>These are the main statistics representing your character's abilities.
They affect your ability to play cards in combat and are used for some skill checks.
You have a set of "core" SIFA stats that can be increased by training,
but your cosmetics, clothing, and body also contribute to your SIFA stats.</p>
<ul style="columns: 4">
<li>?sub Submissiveness</li>
<li>?int Intelligence</li>
<li>?fit Fitness</li>
<li>?att Attractiveness</li>
</ul>*/
<h2 style="line-height: 1">Story Statistics</h2>
<ul>
<li>?money Money. Makes the world go 'round. (For now, the only use of money is to reverse body transformation.)</li>
</ul>
/*<p>These stats relate to your karma. You can gain and lose points from story events,
and you can spend karma to play special cards in combat.</p>
<ul style="columns: 2">
<li>?balance Balance</li>
<li>?corruption Corruption</li>
</ul>*/
<p>These stats relate to your femininity:</p>
<ul>
<li>?fem Femininity of your appearance.
All of your cosmetics, clothing, and body parts contribute to this score (body tends to have the most impact).
Every 2 points also gives +1 to power of female cards and -1 to power of male cards.
At 0 femininity you get +5 to male cards and +0 to female cards.</li>
/*<li>?identity Identity. This represents how feminine your thoughts and actions are.</li>*/
<li>?tf Transformation. Usually gained during combat, but some events may also 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, so at some point you might not be able to use cards that give stress.</li>
/*<li>?masochism Masochism. Enjoying the pain? Raises slower than other stats.</li>*/
<li>?arousal Arousal. Stay focused! You can't have more than 10 arousal, so at some point you might not be able to use cards that give arousal.</li>
/*<li>?airhead Airheadedness. Maybe you don't need to think too much... Raises slower than other stats.</li>*/
</ul>
<h2 style="line-height: 1">Card Effects</h2>
<ul>
<li>?enemy Enemy cards end your turn in combat, triggering Refresh, Flow, and Drain effects afterward. These cards usually decrease Stress and Arousal.</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 3 (without upgrades).</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 1.</li>
<li>?drain Drain: The enemy's health is reduced by the Drain value at the end of the turn, then Drain decreases by 1.</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>?card_back Draw cards then place them at the end of your hand (you can use only first 5 cards in hand)</li>
<li>?card_front Draw cards into your hand to the front. New cards are available immediately.</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"]>>
<div id="changeable-equip" class="grid5col">
<<for _slot range _r_slots>><<capture _slot>>
<<set _item to $player_equipment[_slot]>>
<div class="flexdown" style="row-gap: 0;">
<div style="width: 60%">
<<if _item.id isnot 0>>
<<equipment_type_icon "green" _slot>>
<<else>>
<<equipment_type_icon "red" _slot>>
<</if>>
</div>
/*
<<if _can_change and _item.id isnot 0>>
<a data-passage="passage()"
data-setter="$inv.push(clone($player_equipment[_slot])); $player_equipment[_slot] to clone(setup.all_clothes[_slot][0]);">
<<equip_card _item>>
</a>
<<else>>
<<equip_card _item>>
<</if>>
*/
<<equip_card _item>>
</div>
<</capture>><</for>>
</div>
/* Body & Style items (not changeable) */
<<set _slots to ["hair", "face", "body", "nails", "penis",
"hairstyle", "makeup", "lipstick", "nail_polish", "toenail_polish"]>>
<div class="grid5col">
<<for _slot range _slots>>
<<set _item to $player_equipment[_slot]>>
<div class="flexdown" style="row-gap: 0;">
<div style="width: 60%"> <<equipment_type_icon "green" _slot>> </div>
<<equip_card _item>>
</div>
<</for>>
</div>
/* end width hack */
</div>
<<done>><<script>>
const SCV = variables();
const TMP = temporary();
if(TMP.can_change) {
$('#changeable-equip .equipgrid').each((idx, el) => {
/* tie the element back to the slot... */
const slot = TMP.r_slots[idx];
const jqel = $(el);
if(SCV.player_equipment[slot].id !== 0) {
/* TODO use <a> tags like a normal person (messes w/ hierarchy) */
jqel.css('cursor', 'pointer');
jqel.ariaClick((event) => {
SCV.inv.push(clone(SCV.player_equipment[slot]));
SCV.player_equipment[slot] = clone(setup.all_clothes[slot][0]);
const parent = jqel.parent();
jqel.remove();
/* fix label color above */
parent.find('img').addClass("btn-red").removeClass("btn-green");
/* add replacement card */
parent.wiki('<<equip_card $player_equipment["' + slot + '"]>>');
/* redraw avatar (TODO: on dialog close instead?) */
$('#avatar').empty().wiki("<<include avatar_sidebar>>");
});
}
});
}
<</script>><</done>><<set _can_change to Story.get(passage()).tags.includes("dressing")>>
<<set _delete_items to false>>
<<for _idx, _item range $inv>>
<<set _item.inv_idx to _idx>>
<</for>>
<<if $inv.is_empty>>
<p class="largertext">Your inventory is empty...</p>
<<else>>
/* TODO should probably be a setup var. see also: Object.keys(setup.all_clothes) */
<<set _first_place to $inv.first_category>>
<div id="inv-seln" class="flexbuttons" style="gap: 0.15em;">
<<for _place, _items range $inv>>
<<if _items.length gt 0>>
<<set _color to _place is _first_place ? "green" : "red">>
<a @data-place="_place"><<equipment_type_icon _color _place>></a>
<</if>>
<</for>>
<<if not passage().startsWith("introduction")>>
<button id="deletebtn" class="btn btn-delete togglebtn">Delete Items</button>
<</if>>
</div>
<div id="inv-items">
<<inventory_group _first_place>>
</div>
<</if>>
<<done>><<script>>
const SCV = variables();
const TMP = temporary();
$('#inv-seln a').each((_, el) => {
const jqel = $(el);
jqel.ariaClick((ev) => {
const place = jqel[0].dataset.place;
delete TMP.inv_swap;
TMP.delete_items = false;
delbtn.removeClass("toggle-on");
$('#inv-items').empty().wiki("<<inventory_group '" + place + "'>>");
$('#inv-seln a .btn-green').addClass("btn-red").removeClass("btn-green");
jqel.children().first().addClass("btn-green").removeClass("btn-red");
});
});
const delbtn = $('#deletebtn');
delbtn.ariaClick((ev) => {
const item_area = $('#inv-items .grid4col');
const worn = $('#inv-items .flexdown').first();
TMP.delete_items = !TMP.delete_items;
$('#inv-notice').empty().wiki("<<inventory_notice>>");
delete TMP.inv_swap;
$('#inv-items .cardselect').removeClass(setup.card_select_classes);
if(TMP.delete_items) {
delbtn.addClass("toggle-on");
item_area.addClass("warning-bg");
worn.hide();
} else {
delbtn.removeClass("toggle-on");
item_area.removeClass("warning-bg");
worn.show();
}
});
<</script>><</done>><<widget "inventory_notice">>
/* no args, but reads _can_change and _delete_items */
<<if not _delete_items>>
Click any two items to swap them, for organization.
<<if _can_change>>
This includes your currently worn equipment, to change.
<br>(You can remove worn clothing from
<<link "the equipment page">>
<<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>><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.
By the way, you can use your browser's search feature (usually Ctrl/Cmd + F) to find specific items.</p>
/* [[Text|Link][Setter]] */
/* Most "events" should return here */
/*<<run $back.push(passage())>>*/
<ul>
<li>[[Go back|back]]</li>
<li>[[Change your body|body check][$back.push(passage())]]</li>
<li>[[Change your styles (cosmetics)|styles check][$back.push(passage())]]</li>
<li>[[Change your clothes (beware: lag)|clothes check][$back.push(passage())]]</li>
<li>[[Change your deck|cards check][$back.push(passage())]]</li>
<li>[[See all cards/combat test|action cards test][$back.push(passage())]]</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>
<div class="flexbuttons">
<<button "+5 ?money" "test starting page">><<set $player_stats.money+=5>><</button>>
<<button "+1 ?stress" "test starting page">><<set $player_stats.stress+=1>><</button>>
<<button "+1 ?arousal" "test starting page">><<set $player_stats.arousal+=1>><</button>>
<<button "+100 ?masculine" "test starting page">><<set $exp_stats.masculine += 100>><</button>>
<<button "+100 ?feminine" "test starting page">><<set $exp_stats.feminine += 100>><</button>>
</div>
<div class="flexbuttons">
<<button "-5 ?money" "test starting page">><<set $player_stats.money-=5>><</button>>
<<button "-1 ?stress" "test starting page">><<set $player_stats.stress-=1>><</button>>
<<button "-1 ?arousal" "test starting page">><<set $player_stats.arousal-=1>><</button>>
<<button "-100 ?masculine" "test starting page">><<set $exp_stats.masculine -= 100>><</button>>
<<button "-100 ?feminine" "test starting page">><<set $exp_stats.feminine -= 100>><</button>>
</div>
/*
<br>
<p>and now, for some stat blocks:</p>
<<for _stat range PlayerEquipment._stats.concat(PlayerStats._stats)>>
<<statbar _stat>>
<</for>>
<p>and for the numeric versions:</p>
<<for _stat range PlayerEquipment._stats.concat(PlayerStats._stats, ["money"])>>
<<statnum _stat>>
<</for>>
<p>sifa stats (at full passage width)</p>
<<sifa_stats>>
*/
/*
<br>
<<set _shirts to ["img/test/shirt.svg", "img/test/b4h3w3s3.svg"]>>
<div class="grid5col">
<<for _shirt range _shirts>>
<span>uncolored: <<include _shirt>></span>
<span>blue: <span class="item-blue"><<include _shirt>></span></span>
<span>green: <span class="item-green"><<include _shirt>></span></span>
<</for>>
</div>*/<<set _svg_passages to Story.lookup("tags", "svg").map(p => p.title).slice(0, 10)>>
<div class="grid5col" style="background: grey;">
<<for _svgpsg range _svg_passages>>
<div>
<code><<print _svgpsg>></code>
<<include _svgpsg>>
</div>
<</for>>
</div><<button "Back" "back">><</button>>
<br>
<<for _j to 0; _j lt Object.keys(setup.all_body).length; _j++>>
<<set _place to Object.keys(setup.all_body)[_j]>>
<<print _place>>
<<set _items_at_place to clone(setup.all_body[_place])>>
/*<<set _drop_items to _items_at_place.filter(item => item.rarity.includes("common") or item.rarity.includes("rare") or item.rarity.includes("epic") or item.rarity.includes("legendary"))>>*/
<div class="cards5" style="gap: 0.25em">
<<for _card range _items_at_place>>
<<capture _card>>
<a data-passage=passage() data-setter="$player_equipment[_card.place] to _card">
<<equip_card _card>>
</a>
<</capture>>
<</for>>
</div>
<</for>><<button "Back" "back">><</button>>
<br>
<<for _j to 0; _j lt Object.keys(setup.all_styles).length; _j++>>
<<set _place to Object.keys(setup.all_styles)[_j]>>
<<print _place>>
<<set _items_at_place to clone(setup.all_styles[_place])>>
/*<<set _drop_items to _items_at_place.filter(item => item.rarity.includes("common") or item.rarity.includes("rare") or item.rarity.includes("epic") or item.rarity.includes("legendary"))>>*/
<div class="cards5" style="gap: 0.25em">
<<for _card range _items_at_place>>
<<capture _card>>
<a data-passage=passage() data-setter="$player_equipment[_card.place] to _card">
<<equip_card _card>>
</a>
<</capture>>
<</for>>
</div>
<</for>><<button "Back" "back">><</button>><br>
/*
<<set _styles to {}; _rarities to {}>>
<<set _stats to {min: Infinity, max: -Infinity, sum: 0}>>
<<set _sifa_stats to {}>>
<<for _sifa range setup.SIFA>>
<<set _sifa_stats[_sifa] to clone(_stats)>>
<</for>>
<<set _count to 0>>
<<for _i range setup.all_clothes>>
<<for _k range _i>>
<<set _count++>>
<<for _st range _k.styles>>
<<set _styles[_st] to (_styles[_st] ?? 0) + 1>>
<</for>>
<<set _rarities[_k.rarity] to (_rarities[_k.rarity] ?? 0) + 1>>
<<for _sifa range setup.SIFA>>
<<set _k_stat to _k[_sifa] ?? 0>>
<<set _sifa_stats[_sifa].sum += _k_stat>>
<<set _sifa_stats[_sifa].min to Math.min(_sifa_stats[_sifa].min, _k_stat)>>
<<set _sifa_stats[_sifa].max to Math.max(_sifa_stats[_sifa].max, _k_stat)>>
<</for>>
<</for>>
<</for>>
<<for _sifa, _stat range _sifa_stats>>
<<set _stat.avg to (_stat.sum / _count).toPrecision(5)>>
<</for>>
<p>Counts: (total items: _count)</p>
<<set _pr_st to []>>
<<for _ty, _val range _styles>>
<<run _pr_st.push(_ty + " <img style='height: 1em' src='img2/gear/style/" + _ty + ".svg'>: " + _val)>>
<</for>>
<p><<print _pr_st.join(" | ")>></p>
<<set _pr_st to []>>
<<for _ty, _val range _rarities>>
<<run _pr_st.push(_ty + " <img style='height: 1em' src='img2/gear/" + _ty + ".svg'>: " + _val)>>
<</for>>
<p><<print _pr_st.join(" | ")>></p>
<p>SIFA stats:</p>
<<for _sifa, _stat range _sifa_stats>>
<p><<print _sifa + ": " + JSON.stringify(_stat)>></p>
<</for>>
*/
<<for _j to 0; _j lt Object.keys(setup.all_clothes).length; _j++>>
<<set _place to Object.keys(setup.all_clothes)[_j]>>
<<print _place>>
<<set _items_at_place to clone(setup.all_clothes[_place])>>
/*<<set _drop_items to _items_at_place.filter(item => item.rarity.includes("common") or item.rarity.includes("rare") or item.rarity.includes("epic") or item.rarity.includes("legendary"))>>*/
<div class="cards5" style="gap: 0.25em">
<<for _card range _items_at_place>>
<<capture _card>>
<a data-passage=passage() data-setter="$player_equipment[_card.place] to _card">
<<equip_card _card>>
</a>
<</capture>>
<</for>>
</div>
<</for>><<button "Back" "back">><</button>><br>
<ul>
<li>[[Add a card|add card selection][$back.push(passage())]]</li>
<li>[[Remove a card (sorry about too many confirmations)|remove card selection][$back.push(passage())]]</li>
</ul><p>Click a card to add it to your deck immediately.</p>
<<button "Back" "back">><</button>><br>
<div class="grid4col">
<<for _card range setup.action_cards.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 _btn to _args[0]>>
<<set _disable to false>>
<<set _text to _btn.text>>
<<set _target to _btn.target>>
<<if def _btn.requirement>>
<<set _req to $player_stats[_btn.requirement]>>
<<if (def _btn.threshold) and (ndef _btn.low_threshold)>>
/* only regular threshold */
<<if not (_req >= _btn.threshold)>>
<<set _disable to true>>
<<set _text to _btn.disabled_text ?? _text>>
<</if>>
/* otherwise met, nothing to do */
<<elseif (ndef _btn.threshold) and (def _btn.low_threshold)>>
/* only low threshold */
<<if _req < _btn.low_threshold>>
<<set _target to _btn.low_target ?? _target>>
<<set _text to _btn.low_text ?? _text>>
<<else>>
<<set _disable to true>>
<<set _text to _btn.disabled_text ?? _text>>
<</if>>
<<elseif (def _btn.threshold) and (def _btn.low_threshold)>>
/* low & high threshold. Test high, then low... */
<<if not (_req >= _btn.threshold)>>
/* high not met, try low */
<<if _req < _btn.low_threshold>>
/* low met */
<<set _target to _btn.low_target ?? _target>>
<<set _text to _btn.low_text ?? _text>>
<<elseif def _btn.mid_target>>
/* neither met, but there's a fallback... */
<<set _target to _btn.mid_target>>
<<set _text to _btn.mid_text ?? _text>>
<<else>>
/* neither met, no fallback */
<<set _disable to true>>
<<set _text to _btn.disabled_text ?? _text>>
<</if>>
<</if>>
/* else high is OK, use regular text & target */
<</if>>
/* else both are missing, do nothing */
<<elseif _btn.disabled>>
<<set _text to _btn.disabled_text ?? _text>>
<</if>>
<<if _disable or _btn.disabled is true>>
<button class="btn" disabled>_text</button>
<<else>>
<<capture _btn>>
<button data-setter="_btn.side_effects?.()" @data-passage="_target" class="btn" @style='"background: " + _btn.color'>_text</button>
<</capture>>
<</if>>
<</widget>>
<<widget "event_passage" container>>
/* Args:
* 0: object for event_card widget
* 1: array of "button" objects for player choices, see choice_btn widget
* _contents: passage text */
<<set _wevp_card to _args[0]>>
<<set _wevp_choices to _args[1]>>
<div class="grid2col">
<div><<print _contents>></div>
<div class="flexdown">
<div class="event-container js-tilt"><<event_card _wevp_card>></div>
<<for _choice range _wevp_choices>>
<<choice_btn _choice>>
<</for>>
</div>
</div>
<</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 _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>
<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 */
<<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()}_${_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>>
<<if def _args[1]>>
<span class="enemyhptxt">_args[1]</span>
<</if>>
</div>
<</if>>
<</widget>><<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>>/* '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">><div class="grid2col">
<<set _ecard to {title: "test event", color: "blue", fg_img: "testnpc_f.png", bg_img: "testnpc_b.jpg"}>>
<div class="js-tilt">
<<event_card _ecard>>
</div>
[[back]]
</div><<set _choices to [
{
text: "Back",
target: "back",
color: "blue",
},
{
text: "Wardrobe",
target: "wardrobe",
color: "mediumvioletred",
},
{
text: "Drawer",
target: "drawer",
color: "mediumvioletred",
},
{
text: "women changing room",
target: "women changing room",
color: "mediumvioletred",
},
{
text: "Gym Entrance",
target: "gym entrance",
color: "green",
},
{
text: "Always off, even though req is met",
target: "event test",
color: "green",
requirement: "att",
threshold: -Infinity,
disabled: true,
},
{
text: "?att is >= 5",
disabled_text: "?att is < 5",
target: "event test",
color: "pink",
requirement: "att",
threshold: 5,
},
{
text: "?sub is >= 10, loop",
low_text: "?sub is < 6, go back",
disabled_text: "?sub is 5-9, disable",
target: "event test",
low_target: "back",
color: "red",
requirement: "sub",
threshold: 10,
low_threshold: 6,
},
{
text: "?att is < 5",
disabled_text: "?att is >= 5",
target: "event test",
color: "pink",
requirement: "att",
low_threshold: 5,
},
]>>
<<set _dumb to {
text: '<img style="display: inline-block; vertical-align: middle; width: 90%;" src="img2/actions/image/Show Obedience.png">',
target: "event test",
color: "blue",
}>>
/*<<set _ecard to {title: "this is a really long event", color: "blue", fg_img: "testnpc_f.png", bg_img: "testnpc_b.jpg"}>>*/
/*<<set _ecard to setup.all_clothes.bottom[1]>>*/
<<set _ecard to setup.action_cards[1]>>
<<event_passage _ecard _choices>>
<p>This is a sample event. Who knows what'll happen?</p>
<p>You have these stats: <<print JSON.stringify($player_stats.plain_obj, null, 1)>></p>
<p>Next, here's a "standalone" copy of the first button. This widget isn't really indended for "inline" usage, but it's possible. <<choice_btn _choices[0]>></p>
<p>Also, button elements can have stuff other than text: <<choice_btn _dumb>></p>
<</event_passage>>
/* v6.5 events */<<set $temp.echoices to setup.enemies.regular.randomMany(2)>>
<<set $temp.difficulties to setup.difficulties.randomMany(2)>>
<<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>>
<div class="grid2col">
<<for _idx, _echoice range $temp.echoices>>
<div class="flexdown">
<div class="event-container js-tilt"><<event_card _echoice>></div>
<<choice_btn _btns[_idx]>>
</div>
<</for>>
</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: $exp_stats.masculine lt 200,
disabled_text: "Need 200 ?masculine",
text: "Convince her to undress - 200 ?masculine",
side_effects: () => {
$exp_stats.masculine -= 200;
$back.push("post regular battle precalc");
$back.push("battle end");
},
target: "npc progression",
color: "darkblue",
}
)>>
<<else>>
<<run _choices.push(
{
disabled: $exp_stats.masculine lt 400,
disabled_text: "Need 400 ?masculine",
text: "Ask her to remove panties - 400 ?masculine",
side_effects: () => {
$exp_stats.masculine -= 400;
$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: $exp_stats.feminine lt 200,
disabled_text: "Need 200 ?feminine",
text: "Flirt with Stylist - 200 ?feminine",
side_effects: () => {
$exp_stats.feminine -= 200;
$back.push("stylist battle precalc");
$back.push("battle end");
},
target: "npc progression",
color: "darkviolet",
}
)>>
<<else>>
<<run _choices.push(
{
disabled: $exp_stats.feminine lt 400,
disabled_text: "Need 400 ?feminine",
text: "Seduce Stylist - 400 ?feminine",
side_effects: () => {
$exp_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: $exp_stats.masculine lt 200,
disabled_text: "Need 200 ?masculine",
text: "Train like a real man - 200 ?masculine",
side_effects: () => {
$exp_stats.masculine -= 200;
$back.push("post training precalc");
$back.push("battle end");
},
target: "npc progression",
color: "darkblue",
}
)>>
<<else>>
<<run _choices.push(
{
disabled: $exp_stats.masculine lt 400,
disabled_text: "Need 400 ?masculine",
text: "Train like a superhuman - 400 ?masculine",
side_effects: () => {
$exp_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())>>
<<if $battle_won>>
/* figure out which cards can be upgraded... */
<<set $temp.card_upgrades to $player_deck.sort(setup.card_name_compare).map(card => {
/* if upgradeable... */
if(!card.name.includes("+")) {
const up = setup.action_cards.player_upgrade.find(c => c.is_fem === card.is_fem && c.name.startsWith(card.name));
return up?.combat_reset() ?? null;
}
return null;
})>>
<<else>>
/* "TF" a random masc card to fem */
<<run $player_deck.shuffle()>>
<<set _idx to $player_deck.findIndex(c => !c.is_fem)>>
<<if _idx isnot -1>>
<<set $temp.old to clone($player_deck[_idx])>>
<<run $player_deck[_idx].flip_gender().combat_reset()>>
<<set $temp.new to clone($player_deck[_idx])>>
/* else no masc cards, idk */
<</if>>
<<run $player_deck.sort(setup.card_name_compare)>>
<</if>>
<<goto "post training selection">><<if $battle_won>>
<p>Your training effort succeeded. Pick a card to upgrade or remove:</p>
<div class="grid5col">
<<for _idx, _card range $player_deck>><<capture _idx _card>>
<<link "<<action_card _card>>">>
<<set _up_idx to _idx>>
<<run setup.show_dialog("Upgrade/Remove this card?", "autoanim", "upgrade card confirm")>>
<</link>>
<</capture>><</for>>
</div>
<div class="flexbuttons">
<button data-passage="back" class="btn">Change nothing and move on</button>
</div>
<<else>>
<<event_passage $enemy setup.ok_choices>>
<<if def $temp.old>>
<p class="largertext">Your training effort failed. Not only do you feel more feminine, your thoughts have shifted a bit from the training:</p>
<<card_tf $temp.old $temp.new>>
<<else>>
/* TODO something more...? */
<p class="largertext">Your training effort failed.</p>
<</if>>
<</event_passage>>
<</if>><<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...*/
<<if _new_card !== null>>
<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>
<<else>>
<div style="width: 15em; margin: auto;"><<action_card _old_card>></div>
<p class="largertext">This card is already upgraded, but you can remove it from your deck, if you want.</p>
<</if>>
<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 "Remove!" "back">>
<<run $player_deck.splice(_up_idx, 1)>>
<<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>><<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>>
<<set _target to $enemy.name + " " + $enemy.type + " " + $enemy_progression[$enemy.type][$enemy.id]>>
<<goto _target>>
/* Blue Belle progression */<<set _choices to [{
text: "OK",
target: "Blue Belle regular 1 part 2",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>"Wow! You are a real man!" Belle 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
Bubblegum 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 Belle down. "And I don't think Bubblegum 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: "Blue Belle regular 2 part 2",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/regular male blue belle comic 1.jpg' class="eventimg">
</div><<set _choices to [{
text: "OK",
target: "Blue Belle regular 2 part 3",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>I was getting dressed in the locker room when Belle 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, Belle 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 Blue Belle.</i></p>
<</event_passage>><<set _choices to [{
text: "OK",
target: "Blue Belle regular 3 part 2",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>I were pushing hard again when suddenly Belle ducked under the barbell.</p>
<p>"Agrh!" Belle 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 Belle 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 Belle 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>Belle'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: "Blue Belle 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. Belle 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 Bubblegum 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 Belle 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: "Blue Belle regular 4 part 2",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/regular male blue belle comic 2.jpg' class="eventimg">
</div><<set _choices to [{
text: "OK",
target: "Blue Belle regular 4 part 3",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>Seems like Belle 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 Belle bent over to take something from the floor I couldn't hold it anymore.</p>
<p>"Wow..." Belle 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>Belle 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 Blue Belle.</i></p>
<</event_passage>><<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>This time Belle 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>Belle 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 "blue belle_2_f.png">>
<<set _choices to [{
text: "What happened?",
target: "Blue Belle 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>Belle 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!" Belle 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: "Blue Belle regular 6 part 3",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/regular male blue belle comic 3.jpg' class="eventimg">
</div>/* back to 'normal' */
<<set $enemy.fg_img to "auto">>
<<set _choices to [{
text: "Ok",
target: "Blue Belle regular 6 part 4",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>"What was that for?"</p>
<p>Belle 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, Belle 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 Blue Belle.</i></p>
<</event_passage>>
/* end of Blue Belle progression */
/* Bubblegum progression */<<set _choices to [{
text: "OK",
target: "back",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>I convinced Bubblegum that she would get more clients if she took off her top.</p>
<</event_passage>><<set _choices to [
{
text: "Ok",
target: "Bubblegum regular 2 part 2",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/regular female bubblegum 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 Bubblegum 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 Bubblegum that she would get more clients if she romoved her shorts.</p>
<</event_passage>><<set _choices to [
{
text: "Ok",
target: "Bubblegum regular 4 part 2",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/regular female bubblegum 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 Bubblegum 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 Blue Belle today, so I think I will just continue slowly diyng here." I asked about Belle. "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 Bubblegum that she would get more clients if she romoved her bra.</p>
<</event_passage>><<set _choices to [{
text: "Check the Pillows",
target: "Bubblegum regular 6 part 2",
color: "green",
}]>>
<<event_passage $enemy _choices>>
<p>I convinced Bubblegum 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: "Bubblegum regular 6 part 3",
color: "green",
},
]>>
<div class="flexdown">
<<for _choice range _choices>>
<<choice_btn _choice>>
<</for>>
<img src='img2/npc/regular/regular female bubblegum 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 Bubblegum 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... */
<<run $player_equipment.reset_body_chg()>>
<<set _ecard to {title: "Feminization", color: "magenta", bg_img: "Feminization_b.jpg"}>>
<<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: "To the lobby!",
target: "autosave lobby",
color: "green",
},
]>>
<<set _ecard to {title: "Naked", color: "darkblue", bg_img: "naked_b.jpg"}>>
<<event_passage _ecard _choices>>
<p>I woke up in unfamiliar place. Someone dressed me up in some kinky red lingerie. I didn't remember who I am or what happened to me.</p>
<p>I noticed a screen on the wall telling what to do next:</p>
<p>"Hello! I know that you don't remember a thing. But don't worry, you're one of our best echo hunters!
We were just getting you ready to travel again. Don't worry about your clothing, you'll get some more in the loop! Please head this way..."</p>
<p>Well, my options are either to sit here like an idiot and starve to death or follow their instructions...</p>
<</event_passage>><<set _choices to [
{
text: "Next",
target: "introduction 3",
color: "green",
},
]>>
<<set _ecard to {title: "Drawer", color: "hotpink", bg_img: "drawer_b.jpg"}>>
<<event_passage _ecard _choices>>
<p>"What are you waiting for? Open the drawer and try to find something. Don't you worry, fluf, no one will ever find out that you borrowed something from there."</p>
<</event_passage>><<set _ecard to clone(setup.all_clothes.undies[12])>>
<<run $inv.push(clone(_ecard))>>
<<set _choices to [
{
text: "Next",
target: "introduction 4",
color: "green",
},
]>>
<<event_passage _ecard _choices>>
<p>I managed to find only red panties with the heart on the groin area. It's still better than walking naked.</p>
<p> However, for some weird reason I couldn't wear them. My body just didn't want to do it. Let's check what the screen got to say.</p>
<p>"Yes, you can't wear this cute panties no matter how hard you try. It's because the loop is blocking you from doing that. Just move to the next room, there you can finally wear the panties, as you always wanted."</p>
<p>Loop? What is this person talking about?</p>
<</event_passage>><<set _choices to [
{
text: "Put on the panties, then continue",
target: "introduction 5",
color: "red",
},
]>>
<<set _ecard to {title: "Changing Room", color: "hotpink", bg_img: "women changing room_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?changing_room</p>
<p>"Do you see this icon? If you see such icon in the room that means you can change here.
So you can open your inventory now and wear the panties."</p>
<br>
<p><i>You can open inventory on the left sidebar. To wear an item just click the item you want and then click your current item to swap them.</i></p>
<</event_passage>><<if $player_equipment.undies.id lte 0>>
<<goto "introduction 4">>
<</if>>
<<set _choices to [
{
text: "Next",
target: "introduction 6",
color: "green",
},
]>>
<<set _ecard to {title: "Half Naked", color: "darkblue", bg_img: "half naked_b.jpg"}>>
<<event_passage _ecard _choices>>
<p>"You look adorable in this panties!"</p>
<p>Do they really see me or it's just a setup? I don't see any cameras here...</p>
<p>"Now let's try to make some cash. After all, we saved you, but it costed us a lot. I would like to let you go without paying, fluf. By SIFA company can't save everyone for free, you know."</p>
Oh, great, the debt. I don't event know what happened.
<p> "Your debt is 3000?money in total. But don't you worry, we decided to let you work on it step by step, without pushing yourself too much. 100?money is your first payment. We expect you to pay it after your first loop."</p>
<p>Ok, doesn't sound too much, to be honest.</p>
<p>"Now let's try to earn some cash. Go to the next room."</p>
<</event_passage>><<set _choices to [
{
text: "Relax at the bar",
target: "introduction 7",
color: "green",
},
{
disabled_text: "Not enough ?balance",
text: "Bartender Shift -?balance",
target: "bartender shift calc",
color: "gold",
requirement: "balance",
threshold: 1,
},
]>>
<<set _ecard to {title: "Striptease Bar", color: "blueviolet", bg_img: "striptease bar_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?money ?balance ?stress</p>
<p>Oh no! It's definitely a striptease bar. Don't tell me they gonna force me to dance in this panties for strangers. I'm not a bitch boy or something...</p>
<p>"I could imagine what thoughts you have at the moment, heh. But I keep telling you - don't worry, it's not so bad. You can work here as a bartender, for example. And you fit in just well, heh."</p>
<p>But it doesn't change the fact that I need to work in striptease bar... I think I have no choice anyway...</p>
<p>"But at first, you need to get some balance ?balance points. I think you already mentioned this icon in the room. That means that the room is connected to balance somehow. Try to spend some time at the bar. This time it's free."</p>
<</event_passage>><<set $player_stats.balance += 1>>
<<set _choices to [
{
disabled_text: "Not enough ?money",
text: "Relax at the bar -5?money",
target: "introduction 7",
color: "green",
requirement: "money",
threshold: 5,
},
{
disabled_text: "Not enough ?balance",
text: "Bartender Shift -?balance",
target: "introduction 8",
color: "orange",
requirement: "balance",
threshold: 1,
},
]>>
<<set _ecard to {title: "Striptease Bar", color: "blueviolet", bg_img: "striptease bar_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?money ?balance ?stress</p>
<p>After some time at the bar you felt something changed. Now you can work here.</p>
<p>"Now you can spend your ?balance point to get some cash here."</p>
<</event_passage>><<set $player_stats.money += 10>>
<<set $player_stats.balance -= 1>>
<<set $player_stats.stress += 2>>
<<set _choices to [
{
text: "Look for the next message",
target: "introduction 9",
color: "green",
},
]>>
<<set _ecard to {title: "Bartender Shift", color: "orange", bg_img: "bartender_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?money ?balance</p>
<p>I spent some time at the bar, but this time I was the bartender myself. I can't say it was hard. But doing in half naked is still quite stressful.</p>
<</event_passage>><<set $enemy to clone(setup.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>>[[back]]<br>
[[battle pre calc][$back.push("battle end test"); $enemy to setup.enemies.regular.random()]]
<<set $newactions ??= setup.action_cards.all_player.randomMany(5)>>
/*
<<set _cards to []>>
<<for _c = 0; _c < 5; ++_c>>
<<set _stats to {sub: 0, int: 0, fit: 0, att: 0}>>
<<for _s = 0; _s < _c + 1; ++_s>>
<<set _stats[Object.keys(_stats).random()]++>>
<</for>>
<<run _cards.push({
/* copied the last one from a Mozilla example lol * /
background: ["#6A0000", "#2E3192", "#8F006D", "#176320", "radial-gradient(#e66465, #9198e5)"][_c],
name: "Longer Card Title " + _c,
mana_cost: _stats,
img: "complain_b.jpg",
power: 5 * (_c - 1) + 1,
stat_effects: {obedience: 3 - _c},
description: "Everything is possible, <em>nothing is free.</em>",
rarity_text: ["common", "rare", "epic", "legendary"][(_c + 1) % 4],
})>>
<</for>>
*/
<<set _cards to clone(setup.action_cards.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>
<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>><<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>>/* Mana setup; copy from stats */
/*
<<set $mana to {}>>
<<for _sifa range setup.SIFA>>
<<set $mana[_sifa] to $player_stats[_sifa]>>
<</for>>
*/
<<set $bat_effects to clone($combat_stats)>>
<<for _suit range setup.card_effects>>
<<set $bat_effects[_suit] to $bat_effects[_suit + "_base"]>>
<</for>>
/* Player deck setup */
<<for _card range $player_deck>>
<<run _card.combat_reset()>>
<</for>>
<<set $bat_stock to clone($player_deck).filter(x => x !== null && x !== undefined)>>
<<set $bat_hand to $bat_stock.pluckMany(5)>>
<<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(20 * _enemy_rate * _loop_diff * $game_difficulty * _enemy_diff)>>
/* 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>>
<<statbar "tf">>
</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})`>>
<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 _hand_count lt 5>>
<button class="btn btn-red" data-passage="battle end" data-setter="$battle_won to false">Give up?</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)
.filter(card => card !== null && card !== undefined && card.suit !== "token")
.sort(setup.card_name_compare)>>
<<unset $bat_effects, $bat_stock, $bat_hand, $bat_dump, $bal_cards, $cor_cards, $draw_filter, $mana>>
<<if $battle_won>>
/* 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 _weights to _drops.map(c => {
let w = _rar_weights[c.combat_reset().rarity] ?? 5;
if(c.name.includes("+")) { /* if upgraded... */
w /= 2;
}
return w;
})>>
<<set $temp.new_cards to []>>
<<for _x = 0; _x < 3; _x++>>
<<set _idx to alias_sampler(_weights)()>>
<<set $temp.new_cards.push(_drops.splice(_idx, 1)[0])>>
<<set _weights.splice(_idx, 1)>>
<</for>>
<<if def $current_loop>>
<<set $current_loop.combat_count ??= 0>>
<<set $current_loop.combat_count += 1>>
<</if>>
<<else>>
<<set $player_stats.tf to 10>>
<<if def $current_loop>>
/* subtract 1, min 0 */
<<set $current_loop.combat_count = Math.max(0, ($current_loop.combat_count ?? 0) - 1)>>
<</if>>
<</if>>
<<run $player_equipment.add_tf_points_randomly($player_stats.tf)>>
<<set $temp.tf to $player_stats.tf; $player_stats.tf to 0;>>
<<goto "battle review">>/* TODO show stat changes...? */
<<if $battle_won>>
<p class="largertext">You won the fight against $enemy.name.
<<if $temp.tf is 0>>
You managed to avoid further body transformation.
<<else>>
You were transformed by <<statnum "tf" $temp>> during the fight.
<</if>>
</p>
<p class="largertext">You can add one of these actions to your deck:</p>
<div class="grid3col">
<<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>
<<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 and
got transformed by <<statnum "tf" $temp>> as a result.</p>
<</event_passage>>
<</if>><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>
<<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: "changing room",
side_effects() {
/* to avoid breaking using this for storage/etc. */
$current_loop = {
difficulty: 1,
bonuses: {
colors: {},
styles: {},
},
event_styles: new Set(),
event_colors: new Set(),
}
},
color: "green",
},
/*
{
text: "Recreation Room",
target: "lobby relaxation",
color: "royalblue",
},
*/
{
text: "Reverse Store",
target: "lobby appearance",
color: "darkblue",
},
/*
{
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>>
<div class="grid2col">
<div>
<<if $temp.first_lobby>>
<p>🎵 Let's all go to the lobby... 🎵</p>
<br>
<p><i>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!</i></p>
<p><i>If you got Sigma version you can adjust your character in "Cheat Room", including body, clothes, starting cards, stats, and so on. Good for role play.</i></p>
<<else>>
<p>🎵 Let's all go to the lobby... 🎵</p>
<br>
<br>
<i>
<p>Dive into the loop to play.</p>
<br>
<p>Refresh ?stress and ?arousal in Recreation room.</p>
<br>
<p>Reverse body TF in Reverse Store.</p>
<br>
<p>If you got Sigma version you can adjust your character in "Cheat Room", including body, clothes, starting cards, stats, and so on.</p>
</i>
<</if>>
</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><<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><i>Current difficulty - <b><<print _difficulties[$game_difficulty]>></b></i></p>
<br>
<p><i>You can change game difficulty here. It's one more option in addition to "loop difficulty". For now it affects Echoes hit points, amount of money you lose when giving up to Echo, and debt payments at the end of the loop. And it's still not balanced well, so don't be afraid to switch it if you're feeling too much pain, or not too much.</i></p>
<</event_passage>><<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 $loop_choices to []>>
/* TODO generate these instead. Loop over all the items "properly".
Object.values(SugarCube.setup.all_body).forEach(li => li.forEach(it => it.colors.forEach(c => colors.add(c)))); */
/* removed "nocolor" and "transparent","multicolor","brown","yellow","blonde". */
/* fixed amount of colors styles, gender styles for body/style items moved out of clothing styles */
<<set _colors to ["black","white","blue","pink","red","cyan","green"]>>
<<set _styles to ["lewd","formal","modest","active","comfy","party","cute","study","casual","sexy"]>>
<<set _gender_styles to ["male", "unisex", "female"]>>
/* TODO: number of loops generated is the same as the number of complete difficulties. So at the beginning only 1 loop is generated.
If you complete first difficulty - you will see 2 loops generated. But both of them might be of the same difficulty
maybe there is a better way then using $complete_difficulty to track the number of complete difficulties xD */
/*<<set _max_diff to $complete_difficulty + 1>>*/
<<set _goal to setup.payments[$game_difficulty][0]>>
<<set _paid_frac to (_goal - $debt.payment) / _goal>>
<<set _max_diff to setup.goal_fracs.findLastIndex(f => _paid_frac gte f) + 1>>
/*<<set _random_diff to Math.min(4, $debt.index + 1)>>*/
/*for _num = 0; _num lt (_max_diff * 2); _num++*/
<<for _num = 0; _num lt _max_diff; _num++>>
<<set _loop to {
/* This makes 2 of each difficulty-- 1, 1, 2, 2, etc.
difficulty: ((_num - (_num % 2)) / 2) + 1, */
difficulty: _num + 1,
bonuses: {
colors: {},
styles: {},
},
event_styles: new Set(),
event_colors: new Set(),
}>>
/* added all the colors and gender styles into the loop settings, so only styles that add extra stats take effect for now. Later we return gender and maybe colors */
/* disable bonuses for now...
<<set _bonuses to 3>>
<<set _bonus_colors to 0>>
<<set _bonus_styles to _bonuses - _bonus_colors>>
<<for _i = 0; _i < _bonus_colors; ++_i>>
<<set _color to _colors.random()>>
<<set _loop.event_colors.add(_color)>>
<<set _bonus to setup.SIFA.random()>>
<<set _loop.bonuses.colors[_color] ??= {}>>
<<set _loop.bonuses.colors[_color][_bonus] ??= 0>>
<<set _loop.bonuses.colors[_color][_bonus] += 1>>
<</for>>
<<for _i = 0; _i < _bonus_styles; ++_i>>
<<set _style to _styles.random()>>
<<set _loop.event_styles.add(_style)>>
<<set _bonus to setup.SIFA.random()>>
<<set _loop.bonuses.styles[_style] ??= {}>>
<<set _loop.bonuses.styles[_style][_bonus] ??= 0>>
<<set _loop.bonuses.styles[_style][_bonus] += 1>>
<</for>>
<<set _events to 10>>
<<set _event_styles to 0>>
<<set _event_gender_styles to 3>>
<<set _event_colors to _events - _event_styles - _event_gender_styles>>
<<run _styles.randomMany(_event_styles).forEach(c => _loop.event_styles.add(c))>>
<<run _colors.randomMany(_event_colors).forEach(c => _loop.event_colors.add(c))>>
<<run _gender_styles.randomMany(_event_gender_styles).forEach(c => _loop.event_styles.add(c))>>
*/
<<set $loop_choices.push(_loop)>>
<</for>>
/* The rest of this passage is just for testing.
<<run console.log($loop_choices)>>
<<run console.log(JSON.stringify($loop_choices, null, 2))>>
<<set $current_loop to $loop_choices[0]>>
<<run $player_equipment.calc_all_stats()>>
<<goto "test starting page">>
*/<<include LobbyBanner>>
<<set _next_goal to setup.amount_for_next_frac()>>
<p>/*Each loop has different dress code preferences.*/<<if _next_goal gt 0>>Another difficulty will be unlocked after you pay ?money<<print _next_goal>> toward your debt.<</if>></p>
<p class="largertext">Overall, you still owe ?money<<print $debt.payment>>.</p>
<<if $loop_choices.length is 0>>
<<include "loop gen">>
<</if>>
/*
[[back]]<br>
[[Regen loops?|loop selection][$loop_choices to []]]<br>*/
<<set _diff_str to [null, "Easy", "Medium", "Hard", "Hardest"]>>
<div class="grid2col">
<<for _loop range $loop_choices>><<capture _loop>>
<button class="btn btn-loop" data-passage="changing room" data-setter="$current_loop to _loop">
<h2><<print _diff_str[_loop.difficulty]>></h2>
/*<p>Equipment bonuses:</p>
<<loop_bonuses _loop>>*/
</button>
<</capture>><</for>>
</div><<set _choices to [
{
text: "Start",
target: "start loop",
color: "green",
},
/*
{
text: "Change the Loop",
target: "loop selection",
color: "blue",
},
*/
{
text: "Back to Lobby",
target: "back",
color: "gray",
},
]>>
<<set _ecard to {title: "Changing Room", color: "hotpink", bg_img: "Women Changing Room_b.jpg"}>>
<<event_passage _ecard _choices>>
<p class="framed-icons">?changing_room</p>
<<if not $temp.first_lobby>>
<p>I can change my clothes here.</p>
<</if>>
/*It's better to wear something that fits the dress code, but it isn't necessary.*/
/*<p>I can still change the loop if I want to.</p>*/
/*<br>
<p><i>You can change game difficulty here. It's one more option in addition to "loop difficulty".</i></p>*/
<<include ChangingRoomExtra2>>
<</event_passage>><<set _choices to [
{
text: "Back to Lobby",
target: "back",
color: "gray",
},
]>>
<<set _deck_cost to 300>>
<<set _ecard to {title: "Changing Room", color: "hotpink", bg_img: "Women Changing Room_b.jpg"}>>
<<event_passage _ecard _choices>>
<<if $exp_stats.masculine gt _deck_cost or $exp_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 $exp_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 $exp_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 $exp_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>>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><<if $charview gt 0>>
<div id="avatar"><<include avatar_sidebar>></div>
<<else>>
Continue further to see your character.
<</if>><<set $charview to random(1,3)>>
<a href="https://www.patreon.com/sifagames" target="_blank">
<img @src='"public/banner_right_" + $charview + ".jpg"' style="width: 100%;">
</a>