diff --git a/game/scripts/doll/clothes.rpy b/game/scripts/doll/clothes.rpy index 287b08ac..c8708fb3 100644 --- a/game/scripts/doll/clothes.rpy +++ b/game/scripts/doll/clothes.rpy @@ -230,7 +230,7 @@ init python: hbox = [] overlay = [] - action = [Return(["equip", self]), self.build_button] + action = [Call("wardrobe_actions.equip", self, from_current=True), self.build_button] unhovered = None foreground = None hover_foreground = "#ffffff80" @@ -319,7 +319,7 @@ init python: # Method 4 average = (0.3333, 0.3333, 0.3333) - + return Transform(img, maxsize=maxsize, matrixcolor=SepiaMatrix(c, desat=average)*OpacityMatrix(c.alpha)) except TypeError: diff --git a/game/scripts/doll/outfits.rpy b/game/scripts/doll/outfits.rpy index 5b3a1bb4..dc522113 100644 --- a/game/scripts/doll/outfits.rpy +++ b/game/scripts/doll/outfits.rpy @@ -130,25 +130,25 @@ init python: ## One can manipulate the button actions using Button.action if subcat == "delete": - action = Return(["deloutfit", self]) + action = WardrobeDelOutfit(self) elif subcat == "load": - action = Return(["equip", self]) + action = Call("wardrobe_actions.equip", self, from_current=True) elif subcat == "save": - action = Return(["addoutfit", self]) + action = WardrobeAddOutfit(self) # elif subcat == "import": # Imports are taken care of outside the class. - # action = Return(["import", self]) + # action = WardrobeImport(self) elif subcat == "export": - action = Return(["export", self]) + action = WardrobeExport(self) elif subcat == "schedule": if not has_schedule and not is_inadequate: - action = Return(["schedule", self]) - alternate = Return(["schedule", self]) + action = Call("wardrobe_actions.schedule", self, from_current=True) + alternate = Call("wardrobe_actions.schedule", self, from_current=True) foreground = "#00000040" hover_foreground = "#80808040" selected_foreground = "#80808040" elif has_schedule: - action = Return(["schedule", self]) - alternate = Return(["schedule", self]) + action = Call("wardrobe_actions.schedule", self, from_current=True) + alternate = Call("wardrobe_actions.schedule", self, from_current=True) # elif is_inadequate: # foreground = "#b2000040" # hover_foreground = "#CD5C5C40" @@ -286,4 +286,3 @@ init python: if self.has_type(arg): return True return False - diff --git a/game/scripts/wardrobe/functions.rpy b/game/scripts/wardrobe/functions.rpy index dc56eaa4..89867e18 100644 --- a/game/scripts/wardrobe/functions.rpy +++ b/game/scripts/wardrobe/functions.rpy @@ -178,7 +178,7 @@ init -1 python: def build_button(rp): style = "wardrobe_button" child = Fixed(Transform(rp, xsize=96, fit="contain", yalign=1.0, yoffset=-6), Frame(gui.format("interface/frames/{}/iconframe.webp"), 6, 6), xysize=(96, 168)) - action = Return(["import", rp]) + action = WardrobeImport(rp) hover_foreground = "#ffffff80" return Button(child=child, action=action, hover_foreground=hover_foreground, style=style) diff --git a/game/scripts/wardrobe/wardrobe.rpy b/game/scripts/wardrobe/wardrobe.rpy index cb2d67bb..90929130 100644 --- a/game/scripts/wardrobe/wardrobe.rpy +++ b/game/scripts/wardrobe/wardrobe.rpy @@ -151,7 +151,7 @@ init python: # renpy.restart_interaction() - class __AddOutfit(Action): + class WardrobeAddOutfit(Action): def __init__(self, outfit): self.outfit = outfit @@ -188,7 +188,7 @@ init python: # renpy.restart_interaction() - class __DelOutfit(Action): + class WardrobeDelOutfit(Action): def __init__(self, outfit): self.outfit = outfit @@ -202,7 +202,7 @@ init python: # renpy.restart_interaction() - class __Export(Action): + class WardrobeExport(Action): def __init__(self, outfit): self.outfit = outfit @@ -217,7 +217,7 @@ init python: # renpy.restart_interaction() - class __Import(Action): + class WardrobeImport(Action): def __init__(self, param): self.param = param @@ -233,7 +233,7 @@ init python: outfit_ = char_active.create_outfit(temp=True) if not outfit_.exists(): - if (not wardrobe_suppress_warnings) and renpy.confirm("Randomise Outfit?\n{size=-6}Unsaved changes will be lost.{/size}"): + if not (wardrobe_suppress_warnings or renpy.confirm("Randomise Outfit?\n{size=-6}Unsaved changes will be lost.{/size}")): renpy.notify("Advice: If you want to keep an outfit, save it.") return @@ -594,349 +594,47 @@ label wardrobe_menu(): $ renpy.suspend_rollback(True) $ renpy.block_rollback() - show screen wardrobe(662, 50) + label .cancel_close: - # when converting to call screen, copy the "else" clause from below (just before jump .after_init) + call screen wardrobe(662, 50) - label .after_init: + if not wardrobe_autosave: + if not char_active.create_outfit(temp=True).exists(): + $ renpy.notify("Advice: If you want to keep an outfit, save it.") - hide expression get_character_tag(states.active_girl) # ? + if not (wardrobe_suppress_warnings or renpy.confirm("Exit without saving?\n{size=-6}Unsaved changes will be lost.{/size}")): + jump .cancel_close - # Note to self: Do not use a python: block, because - # renpy cannot return to the middle of a python block - # while mixing python and renpy scope - # https://github.com/renpy/renpy/issues/959 - - $ renpy.dynamic(__choice = ui.interact()) - - if __choice[0] == "category": - if not current_category == __choice[1]: - if wardrobe_check_category(__choice[1]): - $ current_category = __choice[1] - - $ category_items = set_wardrobe_categories(current_category) - $ current_subcategory = list(category_items.keys())[0] if category_items else "" - - if current_category == "outfits": - $ char_active.clear_outfit_button_cache() - - $ current_item = char_active.get_equipped_wardrobe_item(category_items, current_subcategory) - - $ char_active.wear("all") - if current_category in ("lower undergarment", "upper undergarment"): - $ char_active.strip("top", "bottom", "robe", "accessory") - elif current_category == "piercings & tattoos": - $ char_active.strip("top", "bottom", "robe", "accessory", "bra", "panties", "stockings", "gloves") - else: - $ wardrobe_react("category_fail", __choice[1]) - - $ rebuild_wardrobe_icons(category_items, current_subcategory) - - elif __choice[0] == "subcategory": - if not current_subcategory == __choice[1]: - $ current_subcategory = __choice[1] - - if current_category == "outfits": - $ char_active.clear_outfit_button_cache() - - $ current_item = char_active.get_equipped_wardrobe_item(category_items, current_subcategory) - - $ rebuild_wardrobe_icons(category_items, current_subcategory) - - elif __choice[0] == "equip": - ### CLOTHING ### - if isinstance(__choice[1], DollCloth): - if __choice[1].type == "hair" and char_active.is_equipped_item(__choice[1]): - play sound "sounds/fail.ogg" - $ renpy.notify("Hair cannot be removed.") - else: - - if char_active.is_equipped_item(__choice[1]): - # UNEQUIP - if wardrobe_check_unequip(__choice[1]): - $ wardrobe_react("unequip", __choice[1]) - $ char_active.unequip(__choice[1]) - - if current_item: - $ current_item.clear_button_cache() - $ current_item.build_button() - - $ current_item = None - else: - $ wardrobe_react("unequip_fail", __choice[1]) - else: - # EQUIP - if wardrobe_check_equip(__choice[1]): - $ wardrobe_react("equip", __choice[1]) - - # Blacklist handling - if not wardrobe_check_blacklist(__choice[1]): - $ wardrobe_react("blacklist", __choice[1]) - - $ __choice[1].mark_as_seen() - $ char_active.equip(__choice[1]) - - if current_item: - $ current_item.clear_button_cache() - $ current_item.build_button() - - $ current_item = __choice[1] - $ current_item.clear_button_cache() - $ current_item.build_button() - - if wardrobe_fallback_required(__choice[1]): - # Has to be called regardless of player preference. - $ renpy.call(get_character_response(states.active_girl, "fallback"), __choice[1]) - else: - $ wardrobe_react("equip_fail", __choice[1]) - - ### OUTFIT ### - elif isinstance(__choice[1], DollOutfit): - $ _outfit = char_active.create_outfit(temp=True) - - if _outfit == __choice[1]: - $ renpy.notify("Load failed: Outfit already equipped.") - else: - if wardrobe_check_equip_outfit(__choice[1]): - - if not _outfit.exists(): - $ _confirmed = wardrobe_suppress_warnings or renpy.call_screen("confirm", "Discard unsaved changes and load this outfit?") - - if _confirmed: - $ wardrobe_react("equip_outfit", __choice[1]) - $ char_active.equip(__choice[1]) - $ current_item = __choice[1] - else: - $ renpy.notify("Load failed: Cancelled by user.") - else: - $ wardrobe_react("equip_outfit", __choice[1]) - $ char_active.equip(__choice[1]) - $ current_item = __choice[1] - else: - $ wardrobe_react("equip_outfit_fail", __choice[1]) - - elif __choice[0] == "setcolor": - python: - current_item.set_color(__choice[1]) - current_item.clear_button_cache() - current_item.build_button() + $ char_active.equip(char_outfit) if wardrobe_global_color: - for outfit in char_active.outfits: - rebuild = False + python hide: + for cloth in char_outfit.group: + for outfit in char_active.outfits: + rebuild = False - for i in outfit.group: - if not i.id == current_item.id: - continue + for i in outfit.group: + if (i.id, i.type) != (cloth.id, cloth.type): + continue - i.set_color(current_item.color) - i.is_stale() - rebuild = True + i.set_color(cloth.color) + i.is_stale() + rebuild = True - if rebuild: - outfit.is_stale() + if rebuild: + outfit.is_stale() - elif __choice[0] == "touch": - if wardrobe_check_touch(__choice[1]): - $ wardrobe_react("touch", __choice[1]) - else: - $ wardrobe_react("touch_fail", __choice[1]) + $ char_active.wear("all") + play audio "sounds/door2.ogg" - elif __choice[0] == "addoutfit": - python: - _outfit = char_active.create_outfit(temp=True) + if wardrobe_music: + play music last_track - if _outfit.exists(): - renpy.notify("Save failed: Outfit already exists.") - else: - if __choice[1]: - _index = char_active.outfits.index(__choice[1]) - _confirmed = wardrobe_suppress_warnings or renpy.call_screen("confirm", "Overwrite this outfit?") + $ DollThread.stop_all() - if _confirmed: - _old_outfit = char_active.outfits[_index] - _old_schedule = _old_outfit.schedule.copy() + $ enable_game_menu() - _outfit = char_active.create_outfit() - _outfit.delete() # Removes it from list only - _outfit.schedule = _old_schedule - - char_active.outfits[_index] = _outfit - _outfit.build_button(current_subcategory) - renpy.notify("Overwritten.") - else: - renpy.notify("Save failed: Cancelled by user.") - - else: - _outfit = char_active.create_outfit() - _outfit.build_button(current_subcategory) - renpy.notify("Outfit Saved.") - - current_item = char_active.get_equipped_wardrobe_item(category_items, current_subcategory) - - category_items = set_wardrobe_categories(current_category) - - elif __choice[0] == "deloutfit": - python: - _confirmed = wardrobe_suppress_warnings or renpy.call_screen("confirm", "Delete this outfit?") - - if _confirmed: - __choice[1].delete() - category_items = set_wardrobe_categories(current_category) - renpy.notify("Outfit Deleted.") - - elif __choice[0] == "export": - python: - filename = renpy.input("Save as:", datetime.datetime.now().strftime("%d %b %Y-%H%M%S")) - - if not filename.endswith(".png"): - filename += ".png" - - __choice[1].export_data(filename) - achievements.unlock("export") - - elif __choice[0] == "import": - $ _outfit = char_active.import_outfit(__choice[1]) - - elif __choice[0] == "schedule": - $ renpy.call_screen("wardrobe_schedule_menuitem", __choice[1]) - - elif __choice == "music": - python: - if wardrobe_music: - wardrobe_music = False - renpy.music.play(last_track) - else: - wardrobe_music = True - renpy.music.play("music/Spring_In_My_Step.ogg", fadein=1) - - elif __choice == "randomise": - python: - _confirmed = False - - _outfit = char_active.create_outfit(temp=True) - - if not _outfit.exists(): - _confirmed = wardrobe_suppress_warnings or renpy.call_screen("confirm", "Randomise Outfit?\n{size=-6}Unsaved changes will be lost.{/size}") - - if not _confirmed: - renpy.notify("Advice: If you want to keep an outfit, save it.") - renpy.jump("wardrobe_menu.after_init") - - progress = get_character_progression(states.active_girl) - - if wardrobe_randomise_color: - # Set once per interaction - tetriadic_colors = [Color("%06x" % random.randint(0, 0xFFFFFF))] - triadic_colors = [tetriadic_colors[0].rotate_hue(0.25)] - double_colors = [tetriadic_colors[0], tetriadic_colors[0].rotate_hue(0.5)] - - for i in range(1, 3): - col = tetriadic_colors[0].rotate_hue((i * 90.0) / 360.0) - tetriadic_colors.append(col) - - col = triadic_colors[i-1].rotate_hue((i * 75.0) / 360.0) - triadic_colors.append(col) - - for k in dict(char_active.states).keys(): - valid_choices = [x for x in char_active.wardrobe_list if (istype(x, (DollCloth, DollClothDynamic, DollMakeup)) and x.type == k and x.unlocked and progress >= x.level)] - - if k == "panties": - if not progress >= get_character_requirement(states.active_girl, "category lower undergarment"): - continue - - if progress >= get_character_requirement(states.active_girl, "unequip panties"): - valid_choices += [None] - elif k == "bra": - if not progress >= get_character_requirement(states.active_girl, "category upper undergarment"): - continue - - if progress >= get_character_requirement(states.active_girl, "unequip bra"): - valid_choices += [None] - elif k == "top": - if progress >= get_character_requirement(states.active_girl, "unequip top"): - valid_choices += [None] - elif k == "bottom": - if progress >= get_character_requirement(states.active_girl, "unequip bottom"): - valid_choices += [None] - elif any(k.startswith(type) for type in ("piercing", "tattoo")): - if not progress >= get_character_requirement(states.active_girl, "category piercings & tattoos"): - continue - - valid_choices += [None] - elif k == "hair": - pass - elif k in char_active.body_layers: - pass - else: - valid_choices += [None] - - if valid_choices: - cloth = random.choice(valid_choices) - - if cloth: - randomise_wardrobe_color(cloth) - char_active.equip(cloth) - else: - char_active.unequip(k) - - if current_item: - current_item.clear_button_cache() - current_item.build_button(current_subcategory) - - current_item = char_active.get_equipped_wardrobe_item(category_items, current_subcategory) - - if current_item: - current_item.clear_button_cache() - current_item.build_button(current_subcategory) - - else: #__choice == "Close": - python: - _confirmed = False - - if wardrobe_autosave: - _outfit = char_active.create_outfit() - else: - _outfit = char_active.create_outfit(temp=True) - - if not _outfit.exists(): - renpy.notify("Advice: If you want to keep an outfit, save it.") - _confirmed = wardrobe_suppress_warnings or renpy.call_screen("confirm", "Exit without saving?\n{size=-6}Unsaved changes will be lost.{/size}") - - if not _confirmed: - renpy.jump("wardrobe_menu.after_init") - - char_active.equip(char_outfit) - - if wardrobe_global_color: - for cloth in char_outfit.group: - for outfit in char_active.outfits: - rebuild = False - - for i in outfit.group: - if not (i.id, i.type) == (cloth.id, cloth.type): - continue - - i.set_color(cloth.color) - i.is_stale() - rebuild = True - - if rebuild: - outfit.is_stale() - - renpy.hide_screen("wardrobe") - char_active.wear("all") - renpy.play('sounds/door2.ogg') - - if wardrobe_music: - renpy.music.play(last_track) - - DollThread.stop_all() - - enable_game_menu() - renpy.return_statement() - - jump .after_init + return screen wardrobe_menu(xx, yy): tag wardrobe @@ -975,7 +673,7 @@ screen wardrobe_menu(xx, yy): activate_sound "sounds/scroll.ogg" tooltip category sensitive (not bool(DollThread._count)) - action Return(["category", category]) + action Call("wardrobe_actions.category", category, from_current=True) if current_category == category: xoffset icon_xoffset @@ -992,7 +690,7 @@ screen wardrobe_menu(xx, yy): background lock_wardrobe_icon(Fixed(icon_bg, Transform("interface/wardrobe/icons/categories/outfits.webp", zoom=0.45, anchor=(0.5, 0.5), align=(0.5, 0.5)), icon_frame)) tooltip "Outfits Manager" sensitive (not bool(DollThread._count)) - action Return(["category", "outfits"]) + action Call("wardrobe_actions.category", "outfit", from_current=True) if current_category == "outfits": yoffset icon_yoffset @@ -1016,9 +714,9 @@ screen wardrobe_menu(xx, yy): align (0.5, 1.0) # Easter Egg (Headpats, boobs, pussy) - button style "empty" xysize (120, 80) xalign 0.525 ypos 60 action Return(["touch", "head"]) - button style "empty" xysize (120, 60) xalign 0.525 ypos 238 action Return(["touch", "breasts"]) - button style "empty" xysize (120, 60) xalign 0.525 ypos 360 action Return(["touch", "vagina"]) + button style "empty" xysize (120, 80) xalign 0.525 ypos 60 action Call("wardrobe_actions.touch", "head", from_current=True) + button style "empty" xysize (120, 60) xalign 0.525 ypos 238 action Call("wardrobe_actions.touch", "breasts", from_current=True) + button style "empty" xysize (120, 60) xalign 0.525 ypos 360 action Call("wardrobe_actions.touch", "vagina", from_current=True) button: focus_mask None @@ -1028,14 +726,14 @@ screen wardrobe_menu(xx, yy): background lock_wardrobe_icon(Transform("interface/wardrobe/icons/random.webp", size=(72,72))) tooltip "Randomise Outfit" sensitive (not DollThread._count) - action Return("randomise") + action __Randomize() use dropdown_menu(name="Options", pos=(12, 56)): textbutton "Music": style gui.theme("dropdown") tooltip "My immortal." selected wardrobe_music - action Return("music") + action Call("wardrobe_actions.music", from_current=True) textbutton "Chit-chats": style gui.theme("dropdown") tooltip "{color=#35aae2}[states.active_girl]{/color} will make comments regarding your poor fashion tastes." @@ -1043,7 +741,7 @@ screen wardrobe_menu(xx, yy): textbutton "Outfits Scheduling": style gui.theme("dropdown") tooltip "{color=#35aae2}[states.active_girl]{/color} will automatically wear outfits\nbased on set schedule, time of day and weather." - action [ToggleVariable(f"states.{states.active_girl[:3]}.wardrobe_scheduling", True, False), If((current_category == "outfits" and current_subcategory == "schedule"), Return(["subcategory", "save"]))] + action [ToggleVariable(f"states.{states.active_girl[:3]}.wardrobe_scheduling", True, False), If((current_category == "outfits" and current_subcategory == "schedule"), Call("wardrobe_actions.subcategory", "save", from_current=True))] textbutton "Outfits Autosave": style gui.theme("dropdown") tooltip "Outfits will be automatically saved upon exit." @@ -1091,7 +789,7 @@ screen wardrobe_menuitem(xx, yy): button: xysize (32, 32) tooltip "Dye clothing" - action Return(["setcolor", 0]) + action __SetColor(0) add "interface/wardrobe/icons/brush.webp": xysize (32, 32) @@ -1111,7 +809,7 @@ screen wardrobe_menuitem(xx, yy): selected (subcategory == current_subcategory) tooltip subcategory sensitive (not bool(DollThread._count)) - action Return(["subcategory", subcategory]) + action Call("wardrobe_actions.subcategory", subcategory, from_current=True) # # Item icons # if not menu_items: @@ -1155,11 +853,11 @@ screen wardrobe_outfit_menuitem(xx, yy): for subcategory in category_items.keys(): $ icon = lock_wardrobe_icon("interface/wardrobe/icons/{}.webp".format(subcategory)) - $ action = Return(["subcategory", subcategory]) + $ action = Call("wardrobe_actions.subcategory", subcategory, from_current=True) if subcategory == "schedule" and not get_character_scheduling(states.active_girl): $ icon = gray_tint(icon) - $ action = Confirm("Outfit scheduling is currently disabled,\nwould you like to turn it on?", [SetVariable(f"states.{states.active_girl[:3]}.wardrobe_scheduling", True), Return(["subcategory", subcategory])]) + $ action = Confirm("Outfit scheduling is currently disabled,\nwould you like to turn it on?", [SetVariable(f"states.{states.active_girl[:3]}.wardrobe_scheduling", True), action]) button: focus_mask None @@ -1195,7 +893,7 @@ screen wardrobe_outfit_menuitem(xx, yy): idle_background "#00000033" text_align (0.5, 0.5) sensitive (not bool(DollThread._count)) - action Return(["addoutfit", None]) + action WardrobeAddOutfit(None) if current_subcategory == "import": for item in list_outfit_files():