diff --git a/game/scripts/wardrobe/wardrobe.rpy b/game/scripts/wardrobe/wardrobe.rpy index 32d150c9..b820cbff 100644 --- a/game/scripts/wardrobe/wardrobe.rpy +++ b/game/scripts/wardrobe/wardrobe.rpy @@ -125,6 +125,326 @@ init python: ) return category_items + class __SetColor(Action): + def __init__(self, color): + self.color = color + + def __call__(self): + current_item.set_color(self.color) + 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() + + # renpy.restart_interaction() + + class __AddOutfit(Action): + def __init__(self, outfit): + self.outfit = outfit + + def __call__(self): + outfit_ = char_active.create_outfit(temp=True) + + if outfit_.exists(): + renpy.notify("Save failed: Outfit already exists.") + else: + if self.outfit: + index_ = char_active.outfits.index(self.outfit) + + if wardrobe_suppress_warnings or renpy.confirm("Overwrite this outfit?"): + old_schedule_ = char_active.outfits[index_].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) + + # renpy.restart_interaction() + + class __DelOutfit(Action): + def __init__(self, outfit): + self.outfit = outfit + + def __call__(self): + if wardrobe_suppress_warnings or renpy.confirm("Delete this outfit?"): + self.outfit.delete() + category_items = set_wardrobe_categories(current_category) + renpy.notify("Outfit Deleted.") + + # renpy.restart_interaction() + + class __Export(Action): + def __init__(self, outfit): + self.outfit = outfit + + def __call__(self): + filename = renpy.input("Save as:", datetime.datetime.now().strftime("%d %b %Y-%H%M%S")) + + if not filename.endswith(".png"): + filename += ".png" + + self.outfit.export_data(filename) + achievements.unlock("export") + + # renpy.restart_interaction() + + class __Import(Action): + def __init__(self, param): + self.param = param + + def __call__(self): + outfit_ = char_active.import_outfit(self.param) + + # renpy.restart_interaction() + + class __Randomize(Action): + def __call__(self): + 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}"): + renpy.notify("Advice: If you want to keep an outfit, save it.") + return + + progress = get_character_progression(states.active_girl) + + if wardrobe_randomise_color: + # set once per interaction + tetriadic_colors = [Color(rgb=(renpy.random.random(), renpy.random.random(), renpy.random.random()))] + 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): + 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 progress < get_character_requirement(states.active_girl, "category lower undergarment"): + continue + + if progress >= get_character_requirement(states.active_girl, "unequip panties"): + valid_choices.append(None) + + elif k == "bra": + if progress < get_character_requirement(states.active_girl, "category upper undergarment"): + continue + + if progress >= get_character_requirement(states.active_girl, "unequip bra"): + valid_choices.append(None) + + elif k == "top": + if progress >= get_character_requirement(states.active_girl, "unequip top"): + valid_choices.append(None) + + elif k == "bottom": + if progress >= get_character_requirement(states.active_girl, "unequip bottom"): + valid_choices.append(None) + + elif any(k.startswith(typ) for typ in ("piercing", "tattoo")): + if progress < get_character_requirement(states.active_girl, "category piercings & tattoos"): + continue + + valid_choices.append(None) + + elif k == "hair": + pass + + elif k in char_active.body_layers: + pass + + else: + valid_choices.append(None) + + if valid_choices: + cloth = renpy.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) + + # renpy.restart_interaction() + +label wardrobe_actions: + # TODO: check all variables created in these labels + # also check the ones in the actions above : some of them may need to be global +label .category(category): + if not current_category == category: + if wardrobe_check_category(category): + $ current_category = category + + $ category_items = set_wardrobe_categories(current_category) + $ current_subcategory = next(iter(category_items), "") + + 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", category) + + $ rebuild_wardrobe_icons(category_items, current_subcategory) + + return + +label .subcategory(subcat): + if not current_subcategory == subcat: + $ current_subcategory = subcat + + 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) + + return + +label .equip(item): + ### CLOTHING ### + if isinstance(item, DollCloth): + if item.type == "hair" and char_active.is_equipped_item(item): + play sound "sounds/fail.ogg" + $ renpy.notify("Hair cannot be removed.") + else: + + if char_active.is_equipped_item(item): + # UNEQUIP + if wardrobe_check_unequip(item): + $ wardrobe_react("unequip", item) + $ char_active.unequip(item) + + if current_item: + $ current_item.clear_button_cache() + $ current_item.build_button() + + $ current_item = None + else: + $ wardrobe_react("unequip_fail", item) + else: + # EQUIP + if wardrobe_check_equip(item): + $ wardrobe_react("equip", item) + + # Blacklist handling + if not wardrobe_check_blacklist(item): + $ wardrobe_react("blacklist", item) + + $ item.mark_as_seen() + $ char_active.equip(item) + + if current_item: + $ current_item.clear_button_cache() + $ current_item.build_button() + + $ current_item = item + $ current_item.clear_button_cache() + $ current_item.build_button() + + if wardrobe_fallback_required(item): + # Has to be called regardless of player preference. + call expression get_character_response(states.active_girl, "fallback") pass (item) + else: + $ wardrobe_react("equip_fail", item) + + ### OUTFIT ### + elif isinstance(item, DollOutfit): + $ outfit_ = char_active.create_outfit(temp=True) + + if outfit_ == item: + $ renpy.notify("Load failed: Outfit already equipped.") + else: + if wardrobe_check_equip_outfit(item): + + if not outfit_.exists(): + $ _confirmed = wardrobe_suppress_warnings or renpy.confirm("Discard unsaved changes and load this outfit?") + + if _confirmed: + $ wardrobe_react("equip_outfit", item) + $ char_active.equip(item) + $ current_item = item + else: + $ renpy.notify("Load failed: Cancelled by user.") + else: + $ wardrobe_react("equip_outfit", item) + $ char_active.equip(item) + $ current_item = item + else: + $ wardrobe_react("equip_outfit_fail", item) + + return + +label .touch(tou): + if wardrobe_check_touch(tou): + $ wardrobe_react("touch", tou) + else: + $ wardrobe_react("touch_fail", tou) + + return + +label .schedule(param): + call screen wardrobe_schedule_menuitem(param) + + return + +label .music: + if wardrobe_music: + $ wardrobe_music = False + play music last_track + else: + $ wardrobe_music = True + play music "music/Spring_In_My_Step.ogg" fadein 1. + + return + style loading_text: color "#ffffff" size 64 @@ -238,7 +558,7 @@ screen wardrobe(xx, yy): 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 = get_character_outfit(states.active_girl, type="last"), # outfit when entering, to be restored when leaving ) $ char_outfit.save() @@ -268,17 +588,19 @@ label wardrobe_menu(): 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() + show screen wardrobe(662, 50) + + # when converting to call screen, copy the "else" clause from below (just before jump .after_init) + + label .after_init: + + hide expression get_character_tag(states.active_girl) # ? + # 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