default wardrobe_music = False default wardrobe_chitchats = True default wardrobe_autosave = False default wardrobe_suppress_warnings = False default wardrobe_randomise_color = False default wardrobe_global_color = False # Used as custom order for the sorting define wardrobe_subcategories_sorted = { "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, } define wardrobe_categories = ("head", "piercings & tattoos", "upper body", "upper undergarment", "lower body", "lower undergarment", "legwear", "misc") define wardrobe_outfit_schedule = ("day", "night", "cloudy", "rainy", "snowy") default __lock = False default __predicted = None init python: def preload_wardrobe_assets(c): global __lock, __predicted if renpy.version_tuple < (8, 2): renpy.start_predict_screen("wardrobe") else: # use the new renpy.invoke_in_main_thread renpy.invoke_in_main_thread(renpy.start_predict_screen, "wardrobe") # this is not thread-safe, but there's no better way : it's the slow part d = [v[0] for i in c.wardrobe_list for v in i.get_layers(i._hash).values()] if renpy.version_tuple < (8, 2): renpy.start_predict(*d, "interface/wardrobe/*.webp") else: renpy.invoke_in_main_thread(renpy.start_predict, *d, "interface/wardrobe/*.webp") __predicted = d __lock = False def rebuild_wardrobe_icons(items, subcat): if not settings.get("multithreading"): return if subcat == "import": return for i in items.get(subcat, []): i.build_button(subcat) def lock_wardrobe_icon(icon): if not settings.get("multithreading"): return icon lock = bool(DollThread._count) return gray_tint(icon) if lock else icon def randomise_wardrobe_color(cloth): def _func(cloth): if not cloth is None: if wardrobe_randomise_color and cloth.color: col_len = len(cloth.color) col = [] for i in range(col_len): if col_len == 1: col.append(tetriadic_colors[0]) elif col_len == 2: col.append(double_colors[i-1]) elif col_len == 3: col.append(triadic_colors[i-1]) else: try: col.append(tetriadic_colors[i-1]) except: col.append(col[-1].rotate_hue(0.33)) cloth.set_color(col) if wardrobe_global_color: for outfit in char_active.outfits: rebuild = False for i in outfit.group: if not (i.id, i.type) == (cloth.id, cloth.type): continue if len(cloth.color) != len(i.color): print(f"Mismatched color lens:\n{cloth}\n{i}") renpy.notify("Error!") continue i.set_color(cloth.color) i.is_stale() rebuild = True if rebuild: outfit.is_stale() rebuild_wardrobe_icons(category_items, current_subcategory) if settings.get("multithreading"): thread = DollThread(target=_func, args=(cloth,), interval=0.05) thread.start() else: _func(cloth) renpy.restart_interaction() # @functools.cache # Cache resets on wardrobe exit def set_wardrobe_categories(current_category): category_items = OrderedDict( sorted( [ (subcat, [item for item in items if item.unlocked]) for subcat, items in wardrobe_subcategories.get(current_category, {}).items() ], key=lambda x: wardrobe_subcategories_sorted.get(x[0], 0), reverse=True ) ) return category_items style loading_text: color "#ffffff" size 64 style loading_trivia_text: color "#ffffff" size 24 layeredimage loading: always "gui_fade" always Text("Loading", style="loading_text"): align (0.5, 0.35) always "loading_spinner" image loading_spinner: align (0.5, 0.5) Text("{unicode}╞╪═════════╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞═╪════════╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞══╪═══════╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞═══╪══════╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞════╪═════╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞═════╪════╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞══════╪═══╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞═══════╪══╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞════════╪═╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞═════════╪╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞════════╪═╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞═══════╪══╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞══════╪═══╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞═════╪════╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞════╪═════╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞═══╪══════╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞══╪═══════╡{/unicode}", style="loading_text") pause 0.1 Text("{unicode}╞═╪════════╡{/unicode}", style="loading_text") pause 0.1 repeat label wardrobe: $ renpy.call_in_new_context("_wardrobe") return label _wardrobe: $ renpy.config.skipping = None $ _game_menu_screen = None $ _skipping = False $ renpy.suspend_rollback(True) show loading zorder 1000 # Ensure there's no thread in use before assigning a new one. while __lock: $ renpy.pause(0.5, hard=True) $ __lock = True $ renpy.invoke_in_thread(preload_wardrobe_assets, get_character_object(states.active_girl)) # Await thread return # Note: renpy.pause must be called from within the main thread while __lock: $ renpy.pause(0.5, predict=True) hide loading # $ renpy.scene("screens") # show expression screenshot.image call wardrobe_menu show screen main_room show screen ui_top_bar $ _game_menu_screen = "save" # documented $ _skipping = True # documented $ renpy.stop_predict(__predicted) $ __predicted = None $ renpy.suspend_rollback(False) $ renpy.block_rollback() return screen wardrobe(xx, yy): tag wardrobe zorder 24 add "gui_fade" if renpy.mobile: use close_button_background use close_button fixed: use wardrobe_menu(xx, yy) if current_category == "outfits": use wardrobe_outfit_menuitem(20, 50) elif current_subcategory is not None: use wardrobe_menuitem(20, 50) label wardrobe_menu(): $ renpy.dynamic( char_active = get_character_object(states.active_girl), char_outfit = get_character_outfit(states.active_girl, type="last"), ) $ char_outfit.save() $ renpy.dynamic( wardrobe_subcategories = char_active.wardrobe, current_category = "head", ) python: if renpy.android: wardrobe_subcategories.update(outfits=dict.fromkeys(("load", "save", "delete", "schedule"), char_active.outfits)) else: wardrobe_subcategories.update(outfits=dict.fromkeys(("load", "save", "delete", "schedule", "import", "export"), char_active.outfits)) $ renpy.dynamic( category_items = set_wardrobe_categories(current_category), ) $ renpy.dynamic( current_subcategory = next(iter(category_items), ""), ) $ renpy.dynamic( current_item = char_active.get_equipped_wardrobe_item(category_items, current_subcategory), last_track = renpy.music.get_playing(), ) $ rebuild_wardrobe_icons(category_items, current_subcategory) if wardrobe_music: play music "music/Spring_In_My_Step.ogg" fadein 1 if_changed show screen wardrobe(662, 50) label .after_init: $ renpy.hide(get_character_tag(states.active_girl)) $ renpy.config.skipping = None $ _game_menu_screen = None $ _skipping = False $ renpy.suspend_rollback(True) $ renpy.block_rollback() # 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() if wardrobe_global_color: for outfit in char_active.outfits: rebuild = False for i in outfit.group: if not i.id == current_item.id: continue i.set_color(current_item.color) i.is_stale() rebuild = True 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]) elif __choice[0] == "addoutfit": python: _outfit = char_active.create_outfit(temp=True) 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?") if _confirmed: _old_outfit = char_active.outfits[_index] _old_schedule = _old_outfit.schedule.copy() _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 screen wardrobe_menu(xx, yy): tag wardrobe zorder 24 style_prefix "wardrobe" default icon_bg = Frame(gui.format("interface/frames/{}/iconmed.webp"), 6, 6) default icon_frame = Frame(gui.format("interface/frames/{}/iconframe.webp"), 6, 6) default panel = gui.format("interface/frames/{}/wardrobe.webp") window: pos (xx, yy) xysize (344, 507) #background panel use invisible_button() # Main Categories grid 2 4: ypos 108 xoffset -36 xspacing 200 + 72 yspacing 18 for i, category in enumerate(wardrobe_categories): if wardrobe_check_category(category): $ icon = Fixed(icon_bg, Transform("interface/wardrobe/icons/categories/{}/{}.webp".format(states.active_girl, category), zoom=0.45, anchor=(0.5, 0.5), align=(0.5, 0.5)), icon_frame) else: $ icon = Fixed(icon_bg, Transform("interface/wardrobe/icons/categories/{}/{}.webp".format(states.active_girl, category), zoom=0.45, anchor=(0.5, 0.5), align=(0.5, 0.5), matrixcolor=SaturationMatrix(0.0)), icon_frame) $ icon_xoffset = -18 if (i % 2) == 0 else 18 button: focus_mask None xysize (72, 72) background lock_wardrobe_icon(icon) activate_sound "sounds/scroll.ogg" tooltip category sensitive (not bool(DollThread._count)) action Return(["category", category]) if current_category == category: xoffset icon_xoffset # Outfits and Studio hbox: $ icon_yoffset = -18 pos (92, 18) spacing 18 # Outfits Manager button: focus_mask None xysize (72, 72) 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"]) if current_category == "outfits": yoffset icon_yoffset # Studio if not renpy.android: button: focus_mask None xysize (72, 72) background Fixed(icon_bg, Transform("interface/wardrobe/icons/categories/studio.webp", zoom=0.45, anchor=(0.5, 0.5), align=(0.5, 0.5)), icon_frame) tooltip "Photo Studio" action Function(renpy.call_in_new_context, "studio", states.active_girl) add panel # Character image cut to the size of the wardrobe add char_active.image: yoffset -6 corner1 (184, 218) corner2 (924, 1200) zoom 0.45 anchor (0.5, 1.0) 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: focus_mask None xysize (72, 72) align (0.0, 1.0) offset (10, -10) background lock_wardrobe_icon(Transform("interface/wardrobe/icons/random.webp", size=(72,72))) tooltip "Randomise Outfit" sensitive (not DollThread._count) action Return("randomise") use dropdown_menu(name="Options", pos=(12, 56)): textbutton "Music": style gui.theme("dropdown") tooltip "My immortal." selected wardrobe_music action Return("music") textbutton "Chit-chats": style gui.theme("dropdown") tooltip "{color=#35aae2}[states.active_girl]{/color} will make comments regarding your poor fashion tastes." action ToggleVariable("wardrobe_chitchats", True, False) 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"]))] textbutton "Outfits Autosave": style gui.theme("dropdown") tooltip "Outfits will be automatically saved upon exit." action ToggleVariable("wardrobe_autosave", True, False) textbutton "Colour Synchronisation": style gui.theme("dropdown") tooltip "When changing colours of an item, apply it to all outfits with the same item." action ToggleVariable("wardrobe_global_color", True, False) textbutton "Colour Randomisation": style gui.theme("dropdown") tooltip "When randomising outfits, randomise colours as well." action ToggleVariable("wardrobe_randomise_color", True, False) textbutton "Prompts Suppression": style gui.theme("dropdown") tooltip "Disables warnings and prompts asking you to confirm certain actions. (Not recommended)" action ToggleVariable("wardrobe_suppress_warnings", True, False) screen wardrobe_menuitem(xx, yy): tag wardrobe_menuitem zorder 24 style_prefix "wardrobe" default icon_size = (96, 96) default icon_frame = Frame(gui.format("interface/frames/{}/iconframe.webp"), 6, 6) default icon_transparent = Frame("interface/color_picker/checker.webp", tile=True) default panel = gui.format("interface/frames/{}/panel.webp") window: pos (xx, yy) xysize (560, 454) background panel use invisible_button() text "[current_category]" size 22 xalign 0.5 ypos 65 # Colours if current_item and current_item.color: hbox: spacing 2 xanchor 1.0 pos (552, 61) # Colour picker button: xysize (32, 32) tooltip "Dye clothing" action Return(["setcolor", 0]) add "interface/wardrobe/icons/brush.webp": xysize (32, 32) # Subcategory icons hbox: spacing 5 pos (12, 108) for subcategory in category_items.keys(): $ icon = lock_wardrobe_icon("interface/wardrobe/icons/{}.webp".format(subcategory)) button: focus_mask None xysize (72, 72) background Transform(icon, size=(72, 72), fit="contain", alpha=0.65) selected_background Transform(icon, size=(72, 72), fit="contain", ) selected (subcategory == current_subcategory) tooltip subcategory sensitive (not bool(DollThread._count)) action Return(["subcategory", subcategory]) # # Item icons # if not menu_items: # text "Nothing here yet" size 24 align (0.5, 0.6) # else: vpgrid: cols 5 spacing 5 pos (28, 192) xysize (507, 308) mousewheel True scrollbars "vertical" style_prefix gui.theme("wardrobe") for item in category_items.get(current_subcategory, []): add item.button screen wardrobe_outfit_menuitem(xx, yy): tag wardrobe_menuitem zorder 24 style_prefix "wardrobe" default icon_size = (96, 168) default icon_frame = Frame(gui.format("interface/frames/{}/iconframe.webp"), 6, 6) default panel = gui.format("interface/frames/{}/panel.webp") window: pos (xx, yy) xysize (560, 454) background panel use invisible_button() text "[current_category]" size 22 xalign 0.5 ypos 65 # Subcategory icons hbox: spacing 5 pos (8, 108) for subcategory in category_items.keys(): $ icon = lock_wardrobe_icon("interface/wardrobe/icons/{}.webp".format(subcategory)) $ action = Return(["subcategory", subcategory]) 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])]) button: focus_mask None xysize (72, 72) background Transform(icon, alpha=0.65, xsize=72, fit="contain") selected_background Transform(icon, xsize=72, fit="contain") selected (subcategory == current_subcategory) sensitive (not bool(DollThread._count)) tooltip subcategory action action # Outfit icons vpgrid: cols 5 spacing 5 pos (28, 192) xysize (507, 308) # if renpy.android: # mousewheel "horizontal" # scrollbars "horizontal" # else: mousewheel True scrollbars "vertical" style_prefix gui.theme("wardrobe") # Add empty slot if current_subcategory == "save": textbutton "Save": focus_mask None xysize icon_size insensitive_background "#0000001A" idle_background "#00000033" text_align (0.5, 0.5) sensitive (not bool(DollThread._count)) action Return(["addoutfit", None]) if current_subcategory == "import": for item in list_outfit_files(): add item else: for item in reversed(category_items.get(current_subcategory, [])): add item.button screen wardrobe_schedule_menuitem(item): tag dropdown zorder 24 default mpos = renpy.get_mouse_pos() use invisible_button(action=Return(), alternate=Show("wardrobe_schedule_menuitem", item=item)) window: style "empty" pos mpos #use invisible_button(action=NullAction(), alternate=Return()) frame: style "empty" background "#00000080" padding (5, 5, 5, 5) vbox: spacing 0 for i in wardrobe_outfit_schedule: $ boolean = "" if item.schedule[i] else "Not " $ caption = "{}worn during the {}".format(boolean, i) if i in ("day", "night") else "{}worn in {} weather".format(boolean, i) textbutton i: style gui.theme("dropdown") tooltip caption action [ToggleDict(item.schedule, i, True, False), item.clear_button_cache, Function(item.build_button, current_subcategory)] style wardrobe_window is empty style wardrobe_button is empty: foreground None hover_foreground "#ffffff80" activate_sound "sounds/click.ogg" style wardrobe_button_text: color "#fff" insensitive_color "#808080" size 20 outlines [ (2, "#000", 0, 0) ] style wardrobe_item_caption: color "#fff" size 14 outlines [ (1, "#000", 0, 0) ] style dark_wardrobe_window is wardrobe_window style dark_wardrobe_button is wardrobe_button style darK_wardrobe_button_text is wardrobe_button_text style dark_wardrobe_item_caption is wardrobe_item_caption style dark_wardrobe_vscrollbar is dark_vscrollbar style light_wardrobe_window is wardrobe_window style light_wardrobe_button is wardrobe_button style light_wardrobe_button_text is wardrobe_button_text style light_wardrobe_item_caption is wardrobe_item_caption style light_wardrobe_vscrollbar is light_vscrollbar