From 59788d5f167d6726e2c5c436db82f140e68f673f Mon Sep 17 00:00:00 2001 From: LoafyLemon Date: Tue, 15 Oct 2024 17:22:38 +0100 Subject: [PATCH] Wardrobe * Handle equip/unequip methods * Handle dialogues inside interfaces * Fix style assignment * Move wardrobe checks inside wardrobe python scope --- game/scripts/doll/clothes.rpy | 4 +- game/scripts/gui/say.rpy | 11 ++- game/scripts/utility/common_functions.rpy | 4 + game/scripts/wardrobe/reactions.rpy | 38 ++++---- game/scripts/wardrobe/wardrobe.rpy | 106 +++++++++++++++++++--- 5 files changed, 128 insertions(+), 35 deletions(-) diff --git a/game/scripts/doll/clothes.rpy b/game/scripts/doll/clothes.rpy index 92d9b399..70143969 100644 --- a/game/scripts/doll/clothes.rpy +++ b/game/scripts/doll/clothes.rpy @@ -234,7 +234,7 @@ init python: hbox = [] overlay = [] - action = [Return(["equip", self]), self.build_button] + action = [Function(wardrobe.equip, self), self.build_button] unhovered = None if is_inadequate: @@ -268,7 +268,7 @@ init python: child = Fixed(child, *overlay, fit_first=True) if is_inadequate: - style = wardrobe_item_button_inadequate + style = "wardrobe_item_button_inadequate" return Button(child=child, focus_mask=None, xysize=(96, 96), action=action, tooltip=("\n".join(warnings)), unhovered=unhovered, style=style, selected=is_equipped) diff --git a/game/scripts/gui/say.rpy b/game/scripts/gui/say.rpy index c557b32b..ec98b9fe 100644 --- a/game/scripts/gui/say.rpy +++ b/game/scripts/gui/say.rpy @@ -28,6 +28,10 @@ screen say(who, what, side_doll=None, side_image=None, icon=None): layer "interface" zorder 0 + if not is_game_menu(): + # Allows dialogues to function inside interface elements + use invisible_button(Return(), keysym="dismiss") + if states.settings.interface_hidden: use hider @@ -106,16 +110,17 @@ screen quickbox(): xalign 1.0 if states.settings.quickbox_expanded: textbutton "󰈉" action ToggleVariable("states.settings.interface_hidden", True, False) tooltip _("Hide Interface") keysym "hide_windows" # Hide Interface (\F0209) - textbutton "󰇚" action QuickSave() tooltip _("Quick Save") # File Save (\F01DA) - textbutton "󰕒" action QuickLoad() tooltip _("Quick Load") # File Load (\F0552) + textbutton "󰇚" action QuickSave() tooltip _("Quick Save") sensitive is_game_menu() # File Save (\F01DA) + textbutton "󰕒" action QuickLoad() tooltip _("Quick Load") sensitive is_game_menu() # File Load (\F0552) textbutton "󰁪" action Preference("auto-forward", "toggle") tooltip _("Auto-Forward Dialogue") # Autoplay (\F18F2) - textbutton "󰒓" action ShowMenu("navigation") tooltip _("Game Options") # Settings (\F0493) + textbutton "󰒓" action ShowMenu("navigation") tooltip _("Game Options") sensitive is_game_menu() # Settings (\F0493) textbutton "󰮫" action ToggleVariable("states.settings.quickbox_expanded", True, False) tooltip _("Toggle Quick Action Box") # Menu (\F0BAB) style quickbox_button style quickbox_button_text: font gui.glyph_font color "#bbbbbb" + insensitive_color "#505050" hover_color "#ffffff" selected_color "#EA8E61" selected_hover_color "#ffffff" diff --git a/game/scripts/utility/common_functions.rpy b/game/scripts/utility/common_functions.rpy index a8f77bf7..47f5b592 100644 --- a/game/scripts/utility/common_functions.rpy +++ b/game/scripts/utility/common_functions.rpy @@ -129,6 +129,10 @@ init python early: global _game_menu_screen _game_menu_screen = "navigation" + def is_game_menu(): + global _game_menu_screen + return _game_menu_screen is not None + def make_revertable(obj): if isinstance(obj, _list): return [make_revertable(x) for x in obj] diff --git a/game/scripts/wardrobe/reactions.rpy b/game/scripts/wardrobe/reactions.rpy index 0c7efa2a..bc8dad51 100644 --- a/game/scripts/wardrobe/reactions.rpy +++ b/game/scripts/wardrobe/reactions.rpy @@ -1,43 +1,43 @@ -init python: +init python in wardrobe: def wardrobe_check_category(category): - req = get_character_requirement(states.active_girl, f"category {category}") - flag = get_character_progression(states.active_girl) + req = renpy.store.get_character_requirement(renpy.store.states.active_girl, f"category {category}") + flag = renpy.store.get_character_progression(renpy.store.states.active_girl) return (flag >= req) def wardrobe_check_touch(what): - req = get_character_requirement(states.active_girl, f"touch {what}") - flag = get_character_progression(states.active_girl) + req = renpy.store.get_character_requirement(renpy.store.states.active_girl, f"touch {what}") + flag = renpy.store.get_character_progression(renpy.store.states.active_girl) return (flag >= req) def wardrobe_check_equip(item): req = item.level - flag = get_character_progression(states.active_girl) + flag = renpy.store.get_character_progression(renpy.store.states.active_girl) return (flag >= req) def wardrobe_check_unequip(item): - req = get_character_requirement(states.active_girl, f"unequip {item.type}") - flag = get_character_progression(states.active_girl) + req = renpy.store.get_character_requirement(renpy.store.states.active_girl, f"unequip {item.type}") + flag = renpy.store.get_character_progression(renpy.store.states.active_girl) return (flag >= req) def wardrobe_check_equip_outfit(item): req = max((i.level for i in item.group)) - flag = get_character_progression(states.active_girl) + flag = renpy.store.get_character_progression(renpy.store.states.active_girl) has_bra = any(i.type == "bra" for i in item.group) has_panties = any(i.type == "panties" for i in item.group) if not has_bra: - req = max(req, get_character_requirement(states.active_girl, "unequip bra")) + req = max(req, renpy.store.get_character_requirement(renpy.store.states.active_girl, "unequip bra")) if not has_panties: - req = max(req, get_character_requirement(states.active_girl, "unequip panties")) + req = max(req, renpy.store.get_character_requirement(renpy.store.states.active_girl, "unequip panties")) if any(i.type.startswith(("piercing", "tattoo")) for i in item.group): - req = max(req, get_character_requirement(states.active_girl, "category piercings & tattoos")) + req = max(req, renpy.store.get_character_requirement(renpy.store.states.active_girl, "category piercings & tattoos")) return (flag >= req) @@ -45,29 +45,29 @@ init python: if not item.blacklist: return True - req = max((get_character_requirement(states.active_girl, f"unequip {i}") for i in item.blacklist)) - flag = get_character_progression(states.active_girl) + req = max((renpy.store.get_character_requirement(renpy.store.states.active_girl, f"unequip {i}") for i in item.blacklist)) + flag = renpy.store.get_character_progression(renpy.store.states.active_girl) return (flag >= req) def wardrobe_fallback_required(item): fallbacks = {"top", "bottom", "bra", "panties"} - char = get_character_object(states.active_girl) - req = [get_character_requirement(states.active_girl, f"unequip {i}") for i in fallbacks if not char.is_equipped(i) and not i in char.blacklist] + char = renpy.store.get_character_object(renpy.store.states.active_girl) + req = [renpy.store.get_character_requirement(renpy.store.states.active_girl, f"unequip {i}") for i in fallbacks if not char.is_equipped(i) and not i in char.blacklist] if not req: return False req = max(req) - flag = get_character_progression(states.active_girl) + flag = renpy.store.get_character_progression(renpy.store.states.active_girl) return not (flag >= req) def wardrobe_react(what, arg): global _skipping - if wardrobe_chitchats: + if chitchats: _skipping = True renpy.suspend_rollback(False) renpy.block_rollback() - renpy.call_in_new_context(get_character_response(states.active_girl, what), arg) + renpy.call_in_new_context(renpy.store.get_character_response(renpy.store.states.active_girl, what), arg) return diff --git a/game/scripts/wardrobe/wardrobe.rpy b/game/scripts/wardrobe/wardrobe.rpy index 651867a0..d0dc620f 100644 --- a/game/scripts/wardrobe/wardrobe.rpy +++ b/game/scripts/wardrobe/wardrobe.rpy @@ -40,6 +40,72 @@ init python in wardrobe: return renpy.store.Image(fp, oversample=4) return renpy.store.Image("gui/creamy_pumpkin_pie/icons/noicon.png", oversample=4) + def equip(item): + scope = renpy.get_screen("wardrobe").scope + character = scope["character"] + + if item.type == "hair" and character.is_equipped_item(item): + renpy.play("sounds/fail.ogg") + renpy.notify("Hair cannot be removed.") + else: + + if character.is_equipped_item(item): + if wardrobe_check_unequip(item): + wardrobe_react("unequip", item) + character.unequip(item) + else: + wardrobe_react("unequip_fail", item) + else: + if wardrobe_check_equip(item): + wardrobe_react("equip", item) + + if not wardrobe_check_blacklist(item): + wardrobe_react("blacklist", item) + + item.mark_as_seen() + character.equip(item) + + if wardrobe_fallback_required(item): + # Has to be called regardless of player preference. + renpy.call(get_character_response(states.active_girl, "fallback"), item) + else: + 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() + label wardrobe(inter_pause=True): $ disable_game_menu() if inter_pause: @@ -50,7 +116,6 @@ label wardrobe(inter_pause=True): jump main_room_menu screen wardrobe(): - modal True layer "interface" zorder 0 style_prefix "wardrobe" @@ -85,7 +150,7 @@ screen wardrobe(): button: add wardrobe.get_icon(category) xysize (64, 64) - tooltip "[category]" + tooltip category action [SetScreenVariable("selected_category", category), SetScreenVariable("selected_subcategory", None)] null height 5 @@ -93,12 +158,15 @@ screen wardrobe(): null height 5 if selected_category: - hbox: - for subcategory in character.wardrobe[selected_category]: - button: - add wardrobe.get_icon(subcategory) xysize (64, 64) - tooltip "[subcategory]" - action SetScreenVariable("selected_subcategory", subcategory) + viewport: + ysize 32 + edgescroll (60, 50) + mousewheel "horizontal" + hbox: + for subcategory in character.wardrobe[selected_category]: + button: + label subcategory + action SetScreenVariable("selected_subcategory", subcategory) null height 5 add "frame_spacer" xsize 500 xalign 0.5 @@ -115,7 +183,11 @@ screen wardrobe(): for item in character.wardrobe[selected_category][selected_subcategory]: add item.button add character.image align (1.0, 1.0) zoom 0.6 - textbutton "Return" action [SetScreenVariable("navigation_last_frame_atl", navigation_last_frame_hide), SetScreenVariable("navigation_atl", navigation_hide), SetScreenVariable("navigation_exit", True)] keysym "game_menu" align (1.0, 0) + + vbox: + align (0.5, 1.0) + textbutton "Return" action wardrobe.exit keysym "game_menu" + textbutton "Strip" action wardrobe.strip style wardrobe_item_button is empty: background Transform("wheelmenu_button", xysize=(96,96)) @@ -126,8 +198,8 @@ style wardrobe_item_button is empty: # anchor (0.5, 0.5) style wardrobe_item_button_inadequate is empty: - background Transform("wheelmenu_button", xysize=(64,64)) - hover_background At(Transform("wheelmenu_button_opaque", xysize=(64,64), matrixcolor=TintMatrix("#ff0000")), wheelmenu_hover_anim) + background Transform("wheelmenu_button", xysize=(96,96)) + hover_background At(Transform("wheelmenu_button_opaque", xysize=(96,96), matrixcolor=TintMatrix("#ff0000")), wheelmenu_hover_anim) hover_sound "sounds/qubodup-hover1.ogg" activate_sound "sounds/qubodup-click2.ogg" # anchor (0.5, 0.5) @@ -137,3 +209,15 @@ style wardrobe_frame is empty: 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 5 +style wardrobe_label_text is wardrobe_button_text +style wardrobe_viewport: + fit_first True + xsize 500