WTS/game/scripts/wardrobe/wardrobe.rpy

375 lines
16 KiB
Plaintext
Raw Normal View History

2024-10-13 08:38:11 +00:00
# Defines
define wardrobe.outfit_schedule = ("day", "night", "cloudy", "rainy", "snowy")
define wardrobe.subcategories = {
2022-05-16 23:48:22 +00:00
"hair": 5, "shirts": 5, "skirts": 5, "pantyhose": 5, "slot1": 5, "panties": 5, "save": 5,
"earrings": 4, "sweaters": 4, "trousers": 4, "stockings": 4, "bikini panties": 4, "load": 4,
"neckwear": 3, "dresses": 3, "shorts": 3, "socks": 3, "schedule": 3,
"one-piece suits": 2, "import": 2,
"robes": 1, "export": 1,
"gloves": 0, "pubes": 0, "delete": 0,
"other": -1,
}
2024-10-13 08:38:11 +00:00
# Settings
default wardrobe.music = True
2024-10-13 08:38:11 +00:00
default wardrobe.chitchats = True
default wardrobe.autosave = False
default wardrobe.suppress_warnings = False
default wardrobe.randomize_color = False
default wardrobe.global_color = False
default wardrobe.allow_opacity = False
2024-10-13 08:38:11 +00:00
# Functions
init python in wardrobe:
from collections import OrderedDict
_last_track = None
2024-10-13 08:38:11 +00:00
def get_subcategories(d):
return OrderedDict(
sorted(
[
(subcat, [item for item in items if item.unlocked])
2024-10-13 08:38:11 +00:00
for subcat, items in subcategories.get(d, {}).items()
],
2024-10-13 08:38:11 +00:00
key=lambda x: subcategories.get(x[0], 0),
reverse=True
)
)
2024-10-13 08:38:11 +00:00
def get_icon(category):
fp = f"gui/creamy_pumpkin_pie/icons/{category}.png"
if renpy.loadable(fp):
return renpy.store.Image(fp, oversample=4)
return renpy.store.Image("gui/creamy_pumpkin_pie/icons/noicon.png", oversample=4)
def change_section(section):
scope = renpy.get_screen("wardrobe").scope
if scope["selected_section"] == section:
return
scope["selected_section"] = section
scope["selected_category"] = None
scope["selected_subcategory"] = None
def change_category(category):
scope = renpy.get_screen("wardrobe").scope
if scope["selected_category"] == category:
return
scope["selected_category"] = category
scope["selected_subcategory"] = None
def change_subcategory(subcategory):
scope = renpy.get_screen("wardrobe").scope
if scope["selected_subcategory"] == subcategory:
return
scope["selected_subcategory"] = subcategory
def change_item(item):
scope = renpy.get_screen("wardrobe").scope
scope["selected_layer"] = 0
scope["layers"] = item.color
scope["selected_item"] = item
renpy.store.colorpicker.set_layer(item, 0)
renpy.restart_interaction()
def toggle_setting(setting):
if setting == "music":
if renpy.store.wardrobe.music == False:
renpy.store.wardrobe.music = True
renpy.music.play("music/Spring_In_My_Step.ogg")
else:
renpy.store.wardrobe.music = False
renpy.music.play(_last_track, fadein=1)
else:
# StoreModule is a bit of a hack, but it's the only way to do this.
renpy.store.wardrobe.__dict__[setting] = not renpy.store.wardrobe.__dict__[setting]
renpy.restart_interaction()
def equip(item):
scope = renpy.get_screen("wardrobe").scope
character = scope["character"]
# Check if the item is hair and already equipped
if item.type == "hair" and character.is_equipped_item(item):
# If so, play a sound and display a notification to indicate that hair cannot be removed
renpy.play("sounds/fail.ogg")
renpy.notify("Hair cannot be removed.")
else:
# Check if the item is already equipped
if character.is_equipped_item(item):
# If so, check if it's possible to unequip the item
if wardrobe_check_unequip(item):
# If so, play a reaction and then remove the item from the character's equipment
wardrobe_react("unequip", item)
character.unequip(item)
else:
# Otherwise, play a failed unequip reaction
wardrobe_react("unequip_fail", item)
else:
# If the item is not already equipped, check if it's possible to equip the item
if wardrobe_check_equip(item):
# If so, play a reaction and then add the item to the character's equipment
wardrobe_react("equip", item)
# Check if the item is on the blacklist
if not wardrobe_check_blacklist(item):
# If so, play a blacklist reaction
wardrobe_react("blacklist", item)
# Mark the item as seen and equip it to the character
item.mark_as_seen()
character.equip(item)
# Check if a fallback response is required for the item
if wardrobe_fallback_required(item):
# If so, call the fallback response function
renpy.call(get_character_response(states.active_girl, "fallback"), item)
else:
# Otherwise, play a failed equip reaction
wardrobe_react("equip_fail", item)
renpy.restart_interaction()
def strip():
scope = renpy.get_screen("wardrobe").scope
state = scope.get("__character_strip", 0)
character = scope["character"]
if state == 0: # Strip to underwear
character.strip("clothes")
character.wear("bra", "panties")
scope["__character_strip"] = 1
elif state == 1: # Strip naked
character.strip("bra", "panties")
scope["__character_strip"] = 2
elif state == 2: # Wear everything
character.wear("all")
scope["__character_strip"] = 0
renpy.restart_interaction()
def exit():
scope = renpy.get_screen("wardrobe").scope
character = scope["character"]
# Handle exit animation
scope["navigation_last_frame_atl"] = renpy.store.navigation_last_frame_hide
scope["navigation_atl"] = renpy.store.navigation_hide
scope["navigation_exit"] = True
# Save the outfit
outfit = renpy.store.get_character_outfit(renpy.store.states.active_girl, typ="last")
outfit.save()
# Reset states
character.wear("all")
renpy.restart_interaction()
# Context
2024-10-13 08:38:11 +00:00
label wardrobe(inter_pause=True):
$ disable_game_menu()
$ wardrobe._last_track = renpy.music.get_playing()
if wardrobe.music:
play music "music/Spring_In_My_Step.ogg"
2024-10-13 08:38:11 +00:00
if inter_pause:
# Ensures all irrelevant screens are hidden before capturing the surface tree
with Pause(0.2)
call screen wardrobe
$ enable_game_menu()
jump main_room_menu
# Interface
2024-10-13 08:38:11 +00:00
screen wardrobe():
layer "interface"
zorder 0
2022-05-16 23:48:22 +00:00
style_prefix "wardrobe"
2024-10-13 08:38:11 +00:00
default navigation_atl = navigation_show
default last_frame = (screenshot.capture() or screenshot.image)
default navigation_last_frame_atl = navigation_last_frame_show
default navigation_exit = False
2022-05-16 23:48:22 +00:00
2024-10-13 08:38:11 +00:00
default character = get_character_object(states.active_girl)
default selected_section = None
2024-10-13 08:38:11 +00:00
default selected_category = None
default selected_subcategory = None
default selected_item = None
default selected_layer = 0
2022-05-16 23:48:22 +00:00
2024-10-13 08:38:11 +00:00
add last_frame at navigation_last_frame_atl
2022-05-16 23:48:22 +00:00
2024-10-13 08:38:11 +00:00
add "gui_fade_both" at gui_fade
2022-05-16 23:48:22 +00:00
2024-10-13 08:38:11 +00:00
if navigation_exit:
timer 0.4 action Return()
2022-05-16 23:48:22 +00:00
2024-10-13 08:38:11 +00:00
frame:
at navigation_atl
2022-05-16 23:48:22 +00:00
2024-10-13 08:38:11 +00:00
vbox:
# Sections
2022-05-16 23:48:22 +00:00
hbox:
spacing 0
2024-10-13 08:38:11 +00:00
button:
add wardrobe.get_icon("outfits") xysize (64, 64)
tooltip "Outfits"
action Function(wardrobe.change_section, "outfits") selected (selected_section == "outfits")
button:
add wardrobe.get_icon("color_picker") xysize (64, 64)
tooltip "Colour Picker"
action Function(wardrobe.change_section, "color_picker") selected (selected_section == "color_picker")
button:
add wardrobe.get_icon("outfits") xysize (64, 64)
tooltip "Settings"
action Function(wardrobe.change_section, "settings") selected (selected_section == "settings")
null height 3
2024-10-13 08:38:11 +00:00
add "frame_spacer" xsize 500 xalign 0.5
null height 3
if selected_section == "outfits":
# Categories
hbox:
spacing 0
for category in character.wardrobe:
if category == "hidden":
continue
button:
add wardrobe.get_icon(category) xysize (64, 64)
tooltip category
action Function(wardrobe.change_category, category) selected (selected_category == category)
null height 3
2024-10-13 08:38:11 +00:00
add "frame_spacer" xsize 500 xalign 0.5
null height 3
# Subcategories
if selected_category:
viewport:
ysize 28
edgescroll (60, 50)
mousewheel "horizontal"
hbox:
for subcategory in character.wardrobe[selected_category]:
button:
label subcategory
action Function(wardrobe.change_subcategory, subcategory) selected (selected_subcategory == subcategory)
add "frame_spacer" xsize 500 xalign 0.5
null height 5
# Items
if selected_subcategory:
vpgrid:
cols 5
ysize 399
xspacing 5
yspacing 5
mousewheel True
scrollbars "vertical"
for item in character.wardrobe[selected_category][selected_subcategory]:
add item.button
elif selected_section == "color_picker":
# Included in a single screen because local screen scopes don't work as they should with functions.
hbox:
# Item list
vpgrid:
cols 1
ysize 520
yspacing 4
scrollbars "vertical"
mousewheel True
for state in character.states.values():
$ item = state[0]
if item and item.color:
button:
add AlphaMask(Transform(item.icon, xysize=(48, 48)), Transform("wheelmenu_button_opaque", xysize=(48, 48)))
action Function(wardrobe.change_item, item) selected (selected_item == item)
if selected_item:
$ is_blacklisted = selected_item.type.startswith(tuple(selected_item.blacklist_unequip))
$ is_allowed = selected_item.type.startswith(("makeup", "tattoo"))
vbox:
label _("Layers") xalign 0.0
hbox:
spacing 4
for n, col in enumerate(selected_item.color):
button:
xysize (32, 32)
background col
selected_foreground "#ffffff80"
action Function(colorpicker.set_layer, selected_item, n)
selected (n == selected_layer)
# alternate Return(["replace", col])
text str(n+1)
hbox:
add colorpicker.cp.cpsv xysize (255, 255)
add colorpicker.cp.cph xysize (30, 255)
if not is_blacklisted and (is_allowed or wardrobe.allow_opacity):
add colorpicker.cp.cpa xysize (255, 30)
elif selected_section == "settings":
textbutton _("Special Music") action Function(wardrobe.toggle_setting, "music") selected wardrobe.music style "wardrobe_checkbox_button"
textbutton _("Chitchats") action Function(wardrobe.toggle_setting, "chitchats") selected wardrobe.chitchats style "wardrobe_checkbox_button"
textbutton _("Autosave") action Function(wardrobe.toggle_setting, "autosave") selected wardrobe.autosave style "wardrobe_checkbox_button"
textbutton _("Suppress Warnings") action Function(wardrobe.toggle_setting, "suppress_warnings") selected wardrobe.suppress_warnings style "wardrobe_checkbox_button"
textbutton _("Randomize Colours") action Function(wardrobe.toggle_setting, "randomize_color") selected wardrobe.randomize_color style "wardrobe_checkbox_button"
textbutton _("Global Colours") action Function(wardrobe.toggle_setting, "global_color") selected wardrobe.global_color style "wardrobe_checkbox_button"
textbutton _("Allow Opacity Slider") action Function(wardrobe.toggle_setting, "allow_opacity") selected wardrobe.allow_opacity style "wardrobe_checkbox_button"
2024-10-13 08:38:11 +00:00
add character.image align (1.0, 1.0) zoom 0.6
vbox:
align (0.5, 1.0)
textbutton "Return" action wardrobe.exit keysym "game_menu"
textbutton "Strip" action wardrobe.strip
2024-10-13 08:38:11 +00:00
style wardrobe_item_button is empty:
background Transform("wheelmenu_button", xysize=(96,96))
hover_background At(Transform("wheelmenu_button_opaque", xysize=(96,96)), wheelmenu_hover_anim)
selected_foreground Transform("interface/topbar/icon_check.webp", align=(1.0, 1.0), size=(24, 24))
hover_sound "sounds/qubodup-hover1.ogg"
2024-10-13 08:38:11 +00:00
activate_sound "sounds/qubodup-click2.ogg"
# anchor (0.5, 0.5)
2022-05-16 23:48:22 +00:00
2024-10-13 08:38:11 +00:00
style wardrobe_item_button_inadequate is empty:
background Transform("wheelmenu_button", xysize=(96,96))
hover_background At(Transform("wheelmenu_button_opaque", xysize=(96,96), matrixcolor=TintMatrix("#ff0000")), wheelmenu_hover_anim)
2024-10-13 08:38:11 +00:00
hover_sound "sounds/qubodup-hover1.ogg"
activate_sound "sounds/qubodup-click2.ogg"
# anchor (0.5, 0.5)
style wardrobe_frame is empty:
xsize 540
yfill True
padding (10, 10)
background Frame(Image("gui/creamy_pumpkin_pie/side_frame.png", oversample=4), 0, 100, 9, 75, tile=False)
style wardrobe_button is frame_button:
xpadding 0
style wardrobe_button_text is frame_button_text:
size 18
style wardrobe_label:
xpadding 5
ypadding 2
style wardrobe_label_text is wardrobe_button_text
style wardrobe_viewport:
fit_first True
xsize 500
style wardrobe_checkbox_button:
padding (6, 4)
hover_background Frame(Image("gui/creamy_pumpkin_pie/book/book_select.png", oversample=4), 20, 0, 20, 0, tile=False)
foreground Transform(Image("gui/creamy_pumpkin_pie/book/book_button_check_empty.png", oversample=4), xpos=6, yalign=0.5)
selected_foreground Transform(Image("gui/creamy_pumpkin_pie/book/book_button_check_checked.png", oversample=4), xpos=6, yalign=0.5)
insensitive_foreground Transform(Image("gui/creamy_pumpkin_pie/book/book_button_check_empty.png", oversample=4), alpha=0.5, xpos=6, yalign=0.5)
style wardrobe_checkbox_button_text is wardrobe_button_text:
first_indent 24