init python: renpy.config.console = True renpy.config.developer = True renpy.config.quit_action = Quit(confirm=False) renpy.config.keymap['toggle_afm'].append("K_a") renpy.config.keymap['toggle_skip'].remove('K_TAB') # http://www.pygame.org/docs/ref/key.html # Mod Detection import glob, os # Detect Summoner Mod # https://f95zone.to/threads/266878/ mod_summoner = glob.glob(os.path.join(config.gamedir, "*summoner*.rpyc")) def build_mod_text(): if config.version == "0.8c": text = "{color=#FFA920}with TNHUXMod " + TNHUXMod_version else: text = "{color=#D92912}with incompatible TNHUXMod " + TNHUXMod_version if mod_summoner: text += "{color=#FFB100} + Summoner " + SummonerMod_version text += "{/color}" return text ## This code ensures that the quick_menu screen is displayed in-game, whenever ## the player has not explicitly hidden the interface. config.overlay_screens.append("quick_menu") def _toggle_quick_menu(): setattr(store, 'suppress_overlay', False) if not hasattr(store,"quick_menu"): setattr(store, 'quick_menu', False) setattr(store, 'quick_menu', not quick_menu) return config.keymap[ 'toggle_quick_menu' ] = [ 'w' ] config.underlay.append(renpy.Keymap(toggle_quick_menu = Function(_toggle_quick_menu))) # splashscreen skip init python: import os os.environ["RENPY_SKIP_SPLASHSCREEN"] = "1" # mod variables define TNHUXMod_version = "v0.8c.18" default persistent.Fahrenheit = False default persistent.spinning_logo = False default persistent.fps_portraits = False default persistent.xp_numbers = False default persistent.qm_transparency = 0.5 default persistent.qm_buttons = set() if renpy.android else {"save"} default persistent.text_cps = 0 default persistent.afm_time = 10 default persistent.screen_shake = False default persistent.mod_filters = False init 10: # disable screen shakes if persistent.screen_shake: define subtle_screenshake = None define small_screenshake = None define big_screenshake = None define orgasm_shake = None define rumble = None # definitions.rpy: Midday to Afternoon define time_options = ("Morning", "Afternoon", "Evening", "Night", "Late Night") # base.rpy: code below adds the hotkey-toggle to the quick_menu, adds the "Auto" forward button, and slightly adjusts the button colors define quick_menu = True screen quick_menu(): style_prefix "quick" if quick_menu and not (black_screen[0] or renpy.get_screen("Player_menu") or renpy.get_screen("shop_screen") or renpy.get_screen("Wardrobe_screen") or renpy.get_screen("customization_screen") or renpy.get_screen("summoner_options")): vbox: if renpy.get_screen("Wardrobe_screen"): align (0.0, 1.0) elif renpy.get_screen("sex_screen"): align (0.86, 1.0) # (0.5, 1.0) else: align (1.0, 1.0) if persistent.large_text_mode: spacing -8 # new spacing setting else: spacing -8 # new spacing setting at Transform(alpha = persistent.qm_transparency) # new transparency setting if config.rollback_enabled and "back" not in persistent.qm_buttons: textbutton "[localize('menu_back')]": action Rollback() if persistent.large_text_mode: text_size 32 # 42 else: text_size 32 if "skip" not in persistent.qm_buttons: textbutton _("Skip"): action Skip() if persistent.large_text_mode: text_size 32 # 42 else: text_size 32 if "pref" not in persistent.qm_buttons: textbutton _("Pref"): action ShowMenu("options") if persistent.large_text_mode: text_size 32 # 42 else: text_size 32 if "save" not in persistent.qm_buttons: textbutton _("Save"): action ShowMenu("save") if persistent.large_text_mode: text_size 32 # 42 else: text_size 32 if "q.save" not in persistent.qm_buttons: textbutton _("Q.Save"): action QuickSave() if persistent.large_text_mode: text_size 32 # 42 else: text_size 32 if "q.load" not in persistent.qm_buttons: textbutton _("Q.Load"): action QuickLoad() if persistent.large_text_mode: text_size 32 # 42 else: text_size 32 if "auto" not in persistent.qm_buttons: textbutton _("Auto"): action Preference("auto-forward", "toggle") if persistent.large_text_mode: text_size 32 # 42 else: text_size 32 style quick_button_text: font "agency_fb.ttf" outlines [(1,"#0000007F")] insensitive_color "#99999966" idle_color "#999999" hover_color "#FFFFFF" selected_idle_color "#CCCCCC" selected_hover_color "#FFFFFF" # base.rpy: removes the quit-confirmation, rearrangement of the menu buttons screen navigation(): use base_button( Return(), pos = (0.820, 0.299), xysize = (int(645*game_resolution), int(194*game_resolution)), padding = (15, 15, 15, 15), button_shadow = True, text = "RETURN") use base_button( ShowMenu("save"), pos = (0.820, 0.3905), xysize = (int(645*game_resolution), int(194*game_resolution)), padding = (15, 15, 15, 15), button_shadow = True, text = "SAVE") use base_button( ShowMenu("load"), pos = (0.820, 0.482), xysize = (int(645*game_resolution), int(194*game_resolution)), padding = (15, 15, 15, 15), button_shadow = True, text = "LOAD") use base_button( ShowMenu("options"), pos = (0.820, 0.5735), xysize = (int(645*game_resolution), int(194*game_resolution)), padding = (15, 15, 15, 15), button_shadow = True, text = "OPTIONS") use base_button( ShowMenu("supporters_screen"), pos = (0.820, 0.665), xysize = (int(645*game_resolution), int(194*game_resolution)), padding = (15, 15, 15, 15), button_shadow = True, text = "CREDITS") use base_button( MainMenu(), pos = (0.820, 0.7565), xysize = (int(645*game_resolution), int(194*game_resolution)), padding = (15, 15, 15, 15), button_shadow = True, text = "MAIN MENU") use base_button( Quit(confirm = False), pos = (0.820, 0.848), xysize = (int(645*game_resolution), int(194*game_resolution)), padding = (15, 15, 15, 15), button_shadow = True, text = "QUIT") # base.rpy: expands the slot buttons, white slot text, more slot info screen file_picker(): default columns = 3 default rows = 6 use menu_background(spinning = True) vbox anchor (0.0, 0.0) pos (0.005, 0.01): # spacing 2 hbox: # spacing 2 use base_button( FilePagePrevious(), padding = (30, 10, 30, 10), text = "<", text_size = 26) for page in ("auto", "quick"): use base_button( FilePage(page), padding = (30, 10, 30, 10), selected = FileCurrentPage() == page, text = page.upper(), text_size = 26) for i in range(1, 21): use base_button( FilePage(i), padding = (30, 10, 30, 10), selected = FileCurrentPage() == f"{i}", text = f"{i}", text_size = 26) use base_button( FilePageNext(), padding = (30, 10, 30, 10), text = ">", text_size = 26) null height 8 grid columns rows pos (0.005, 0.01) xsize 0.8: style_prefix "file_picker" transpose True xfill True spacing 5 for i in range(1, columns*rows + 1): $ file_name = FileSlotName(i, columns * rows) $ file_time = FileTime(i, format=_("{#file_time}%a, %b %d %Y, %H:%M"), empty = _("EMPTY")) # https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior $ save_name = FileSaveName(i) button ysize 0.155: xfill True hbox align (0.0, 0.5): spacing 15 add FileScreenshot(i) yalign 0.5 text "[file_name].\n[save_name!ti]\n[file_time!t]": font "agency_fb.ttf" size 23 color "#fff" text_align 0.0 if save_name: if renpy.android: use base_button( FileDelete(i), anchor = (1.0, 0.0), pos = (1.02, 0.0), xysize = (int(192*0.4), int(194*0.4)), padding = (15, 15, 15, 15), button_shadow = True, image = "images/interfaces/[interface_resolution]/interactions/close.webp", image_zoom = 0.4, image_shadow = True, animated = False) else: use base_button( FileDelete(i), anchor = (1.0, 0.0), pos = (1.02, 0.0), xysize = (int(192*0.25), int(194*0.25)), padding = (15, 15, 15, 15), button_shadow = True, image = "images/interfaces/[interface_resolution]/interactions/close.webp", image_zoom = 0.25, image_shadow = True, animated = False) key "save_delete" action FileDelete(i) action FileAction(i) # main_menu.rpy: removes the quit-confirmation screen main_menu(): tag menu add Solid("#363535") xysize (1.0, 1.0) use menu_background(characters = True, spinning = True) add "images/interfaces/[interface_resolution]/main_menu/small_elements.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/main_menu/big_elements.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/main_menu/game_version.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/main_menu/logo.webp" zoom high_resolution_interface_adjustment add "menu_comic" text "GAME VERSION" anchor (0.0, 0.5) pos (0.025, 0.96): size 25 text "[config.version]" anchor (1.0, 0.5) pos (0.157, 0.96): size 25 text "[build_mod_text()]" anchor (0.0, 0.5) pos (0.172, 0.96): size 25 use base_button( OpenURL("https://patreon.com/ronchon"), pos = (0.712, 0.868), xysize = (int(192 * game_resolution), int(194 * game_resolution)), button_shadow = True, image = "images/interfaces/[interface_resolution]/main_menu/patreon.webp", image_zoom = high_resolution_interface_adjustment, image_shadow = True) use base_button( OpenURL("https://soundcloud.com/grey_scale"), pos = (0.768, 0.868), xysize = (int(192 * game_resolution), int(194 * game_resolution)), button_shadow = True, image = "images/interfaces/[interface_resolution]/main_menu/soundcloud.webp", image_zoom = high_resolution_interface_adjustment, image_shadow = True) use base_button( OpenURL("https://discord.gg/kFjf49QVns"), pos = (0.824, 0.868), xysize = (int(192 * game_resolution), int(194 * game_resolution)), button_shadow = True, image = "images/interfaces/[interface_resolution]/main_menu/discord.webp", image_zoom = high_resolution_interface_adjustment, image_shadow = True) use base_button( Quit(confirm = False), pos = (0.88, 0.868), xysize = (int(192 * game_resolution), int(194 * game_resolution)), button_shadow = True, image = "images/interfaces/[interface_resolution]/interactions/close.webp", image_zoom = high_resolution_interface_adjustment, image_shadow = True) use base_button( Start(), pos = (0.164, 0.47), xysize = (int(839 * game_resolution), int(194 * game_resolution)), button_shadow = True, text = "NEW GAME", text_size = 45) use base_button( Continue(), pos = (0.164, 0.573), xysize = (int(627 * game_resolution), int(194 * game_resolution)), button_shadow = True, text = "CONTINUE", text_size = 45) use base_button( ShowMenu("load"), pos = (0.332, 0.573), xysize = (int(192 * game_resolution), int(194 * game_resolution)), button_shadow = True, image = "images/interfaces/[interface_resolution]/main_menu/load.webp", image_zoom = high_resolution_interface_adjustment, image_shadow = True) use base_button( ShowMenu("options"), pos = (0.164, 0.676), xysize = (int(839 * game_resolution), int(194 * game_resolution)), button_shadow = True, text = "OPTIONS", text_size = 45) # base.rpy: removes the spinning X-logo screen menu_background(characters = False, spinning = False): layer "master" add Solid("#363535") xysize (1.0, 1.0) if characters: add "characters_background" zoom interface_adjustment if not persistent.spinning_logo: add "images/interfaces/[interface_resolution]/main_menu/spin.webp" align (0.5, 0.5) zoom interface_adjustment: if persistent.animated_interface and spinning: at spin add "images/interfaces/[interface_resolution]/main_menu/overlay.webp" zoom interface_adjustment # hotkeys.rpy: game hotkeys. Changes here should also be made to: screen options() screen hotkeys1_screen(): if persistent.volume_muted: key "-" action [ SetVariable("persistent.volume_muted", False), SetMute(["sfx", "music"], False)] # - else: key "-" action [ SetVariable("persistent.volume_muted", True), SetMute(["sfx", "music"], True)] # - key "K_RETURN" action DisableAllInputValues() screen hotkeys2_screen(): key "p" action ToggleScreen("phone_screen") # p key "t" action ToggleScreen("remote_vibrator_screen") # t if Player.location != Player.home: key "r" action Call("travel", Player.home, from_current = True) # r if Player.location != "bg_classroom": key "c" action Call("travel", "bg_classroom", from_current = True) # c if Player.location != "bg_Danger": key "g" action Call("travel", "bg_Danger", from_current = True) # g if Player.schedule or Player.date_planned: key "q" action Show("say", who = None, what = "I've got plans today.", hide_after = 3.0) # q elif black_screen[0] or not sandbox or ongoing_Event or ongoing_Scene or renpy.get_screen("Player_menu") or renpy.get_screen("shop_screen") or renpy.get_screen("Wardrobe_screen") or renpy.get_screen("customization_screen") or renpy.get_screen("phone_screen") or renpy.get_screen("sex_screen"): key "q" action Show("say", who = None, what = "I shouldn't skip now.", hide_after = 3.0) # q else: key "q" action Call("go_to_sleep", automatic = True, from_current = True) # q if quick_location_1: key "1" action Function(quick_location_1.exec) # 1 if quick_location_2: key "2" action Function(quick_location_2.exec) # 2 if quick_location_3: key "3" action Function(quick_location_3.exec) # 3 # new "Xavier's Study" hotkey if Player.location != "bg_office": key "x" action Call("travel", "bg_office", from_current = True) # x # new "Mall" hotkey if Player.location != "bg_mall": key "l" action Call("travel", "bg_mall", from_current = True) # l # new "Kitchen" hotkey if Player.location != "bg_kitchen": key "k" action Call("travel", "bg_kitchen", from_current = True) # k # new "Pool" hotkey if Player.location != "bg_pool": key "o" action Call("travel", "bg_pool", from_current = True) # o screen hotkeys3_screen(): key "mousedown_3" action [ Hide("phone_screen"), Hide("Wardrobe_screen"), ToggleScreen("Player_menu", page = "map")] screen hotkeys4_screen(): key "i" action ToggleScreen("Player_menu", page = "inventory") key "j" action ToggleScreen("Player_menu", page = "journal") key "m" action ToggleScreen("Player_menu", page = "map") # belt.rpy: thousands separator, daily income display, and Celcius-Fahrenheit toggle for player belt, remote button only shown if remote vibrator inserted in any character screen belt_screen(): add "images/interfaces/[interface_resolution]/belt/background.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/belt/stamina.webp" zoom high_resolution_interface_adjustment imagebutton: idle At(f"images/interfaces/{interface_resolution}/belt/hide_idle.webp", interface_zoom) hover At(f"images/interfaces/{interface_resolution}/belt/hide.webp", interface_zoom) action ToggleVariable("belt_collapsed") tooltip "Hide Belt" text "[week[weekday][0:2]]" anchor (0.5, 0.5) pos (0.964, 0.04): font "magneto_bold.ttf" size 40 text "[time_options[time_index]]" anchor (0.5, 0.5) pos (0.964, 0.075): size 30 hbox anchor (1.0, 0.5) pos (0.822, 0.0345) ysize int(99 * game_resolution): spacing 6 box_reverse True if Player.History.check("attended_class", tracker = "weekly") >= 3: imagebutton: idle At(f"images/interfaces/{interface_resolution}/belt/attendance.webp", high_resolution_interface_zoom) hover At(f"images/interfaces/{interface_resolution}/belt/attendance.webp", high_resolution_interface_zoom) action NullAction() tooltip "Attendance Bonus" if Player.sweat >= Player.sweaty_threshold or Player.chlorine >= Player.chlorinated_threshold: imagebutton: idle At(f"images/interfaces/{interface_resolution}/belt/sweaty.webp", high_resolution_interface_zoom) hover At(f"images/interfaces/{interface_resolution}/belt/sweaty.webp", high_resolution_interface_zoom) action NullAction() tooltip "Sweaty" else: imagebutton: idle At(f"images/interfaces/{interface_resolution}/belt/neutral.webp", high_resolution_interface_zoom) hover At(f"images/interfaces/{interface_resolution}/belt/neutral.webp", high_resolution_interface_zoom) action NullAction() tooltip "Neutral" if Party: imagebutton: idle At(f"images/interfaces/{interface_resolution}/belt/followed.webp", high_resolution_interface_zoom) hover At(f"images/interfaces/{interface_resolution}/belt/followed.webp", high_resolution_interface_zoom) action NullAction() tooltip "Being Followed" hbox anchor (0.5, 0.5) pos (0.8925, 0.035) ysize 0.241: for s in range(Player.max_stamina): if s >= clock: imagebutton: idle At(f"images/interfaces/{interface_resolution}/belt/stamina_empty.webp", interface_zoom) hover At(f"images/interfaces/{interface_resolution}/belt/stamina_empty.webp", interface_zoom) action NullAction() tooltip "Stamina (Empty)" else: imagebutton: idle At(f"images/interfaces/{interface_resolution}/belt/stamina_full.webp", interface_zoom) hover At(f"images/interfaces/{interface_resolution}/belt/stamina_full.webp", interface_zoom) action NullAction() tooltip "Stamina" for s in range(Player.max_stamina, 4): imagebutton: idle At(f"images/interfaces/{interface_resolution}/belt/stamina_lock.webp", high_resolution_interface_zoom) hover At(f"images/interfaces/{interface_resolution}/belt/stamina_lock.webp", high_resolution_interface_zoom) action NullAction() tooltip "Stamina (Locked)" # thousands separator, daily income display text "$['{:,}'.format(Player.cash)]+[Player.income]/day" anchor (1.0, 0.5) pos (0.862, 0.0815): size 25 # Celcius-Fahrenheit toggle key "d" action ToggleVariable("persistent.Fahrenheit") if persistent.Fahrenheit: text u"['{:.1f}'.format(temperature[time_index]*9/5+32)] \u00b0F" anchor (0.5, 0.5) pos (0.903, 0.0815): size 25 else: text u"[temperature[time_index]] \u00b0C" anchor (0.5, 0.5) pos (0.903, 0.0815): size 25 if not belt_collapsed: $ buttons_locked = (not idling or renpy.get_screen("say") or ongoing_Scene or phone_texting) $ button_condition = (not current_phone_Chat or not current_phone_Chat.mandatory_text_options) $ buttons = ["inventory", "journal", "map"] if Player.Inventory.get_active("phone"): $ buttons.append("phone") # check if remote vibrator inserted in any character if Player.Inventory.get_active("remote_vibrator_controller") and get_remote_vibrator_Characters() != (): $ buttons.append("remote") for t, kind in enumerate(buttons): if kind == "inventory": $ hotkey = "I" elif kind == "journal": $ hotkey = "J" elif kind == "map": $ hotkey = "M" elif kind == "phone": $ hotkey = "P" elif kind == "remote": $ hotkey = "T" if buttons_locked: $ actions = None $ tooltip = None elif button_condition: if kind == "map": $ actions = Show("Player_menu", page = kind) elif kind == "phone": if not renpy.get_screen("phone_screen"): $ actions = Show("phone_screen") else: $ actions = [ Hide("phone_screen"), Function(move_location, Player.location), ] elif kind == "remote": $ actions = ToggleScreen("remote_vibrator_screen") else: $ actions = [ Show("Player_menu", page = kind), SetVariable(f"{kind}_alert", False)] $ tooltip = f"Open {titlize(kind)}" if buttons_locked or button_condition: use belt_button( actions, pos = (0.9323, 0.103 + t * 0.131), xysize = (int(237 * game_resolution), int(281 * game_resolution)), text = f"Hotkey: {hotkey}", image = f"images/interfaces/{interface_resolution}/belt/{kind}.webp", image_zoom = high_resolution_interface_adjustment, image_shadow = True, tooltip = tooltip, ) if sandbox: for q, quick_location in enumerate([quick_location_1, quick_location_2, quick_location_3]): if quick_location: if buttons_locked: $ actions = NullAction() $ tooltip = None elif button_condition: $ actions = Function(quick_location.exec) $ tooltip = f"Move to QuickLoc{q + 1}" if buttons_locked or button_condition: use quick_button( actions, pos = (0.907, 0.369 + q * 0.042), xysize = (int(87 * game_resolution), int(87 * game_resolution)), text = f"{q + 1}", tooltip = tooltip, ) if button_condition: if inventory_alert: add "images/interfaces/[interface_resolution]/belt/inventory_alert.webp" anchor (0.5, 0.5) pos (0.935, 0.108) zoom high_resolution_interface_adjustment if journal_alert: add "images/interfaces/[interface_resolution]/belt/red_alert.webp" anchor (0.5, 0.5) pos (0.935, 0.239) zoom high_resolution_interface_adjustment if EventScheduler.marked_locations: add "images/interfaces/[interface_resolution]/belt/red_alert.webp" anchor (0.5, 0.5) pos (0.935, 0.37) zoom high_resolution_interface_adjustment if Player.Inventory.get_active("phone"): if unread_messages or institute_broadcast: add "images/interfaces/[interface_resolution]/belt/phone_alert.webp" anchor (0.5, 0.5) pos (0.935, 0.502) zoom high_resolution_interface_adjustment if persistent.tooltips_enabled: use tooltips() # remote_vibrator.rpy: screen only shown when at least one remote vibrator inserted in any character screen remote_vibrator_screen(): default index = 0 layer "interface" # check if remote vibrator inserted in any character if black_screen[0] or get_remote_vibrator_Characters() == (): pass elif any(renpy.get_screen(screen) for screen in remote_vibrator_disabled_screens): pass elif ongoing_Event: pass else: $ Characters = get_remote_vibrator_Characters() if index > len(Characters) - 1: $ index = 0 $ button_condition = (idling and (not current_phone_Chat or not current_phone_Chat.mandatory_text_options) and not ongoing_Scene and not ongoing_Event) add "images/interfaces/[interface_resolution]/belt/remote_background.webp" zoom high_resolution_interface_adjustment if button_condition: if Characters and Characters[index].remote_vibrator: bar value VariableValue(f"{Characters[index].tag}.remote_vibrator", 1.0) anchor (0.5, 0.5) pos (0.846, 0.800) xysize (int(275 * game_resolution), int(48 * game_resolution)): left_bar At(f"images/interfaces/{interface_resolution}/belt/remote_intensity.webp", interface_zoom) right_bar At(f"images/interfaces/{interface_resolution}/belt/remote_intensity.webp", interface_zoom) thumb Frame("images/interfaces/full/belt/remote_selector.webp") thumb_offset int(17 * game_resolution) else: bar value 0.0 range 1.0 anchor (0.5, 0.5) pos (0.846, 0.800) xysize (int(275 * game_resolution), int(48 * game_resolution)): left_bar At(f"images/interfaces/{interface_resolution}/belt/remote_intensity.webp", interface_zoom) right_bar At(f"images/interfaces/{interface_resolution}/belt/remote_intensity.webp", interface_zoom) thumb Frame("images/interfaces/full/belt/remote_selector.webp") thumb_offset int(17 * game_resolution) else: if Characters and Characters[index].remote_vibrator: bar value Characters[index].remote_vibrator range 1.0 anchor (0.5, 0.5) pos (0.846, 0.800) xysize (int(275 * game_resolution), int(48 * game_resolution)): left_bar At(f"images/interfaces/{interface_resolution}/belt/remote_intensity.webp", interface_zoom) right_bar At(f"images/interfaces/{interface_resolution}/belt/remote_intensity.webp", interface_zoom) thumb Frame("images/interfaces/full/belt/remote_selector.webp") thumb_offset int(17 * game_resolution) else: bar value 0.0 range 1.0 anchor (0.5, 0.5) pos (0.846, 0.800) xysize (int(275 * game_resolution), int(48 * game_resolution)): left_bar At(f"images/interfaces/{interface_resolution}/belt/remote_intensity.webp", interface_zoom) right_bar At(f"images/interfaces/{interface_resolution}/belt/remote_intensity.webp", interface_zoom) thumb Frame("images/interfaces/full/belt/remote_selector.webp") thumb_offset int(17 * game_resolution) if Characters: if button_condition: if Characters[index].remote_vibrator == 0.0: $ actions = [SetField(Characters[index], "remote_vibrator", 0.1)] if renpy.random.random() < 0.2: $ actions.append(Call("remote_vibrator_narration_interaction", Characters[index], "on", from_current = True)) else: $ actions = [SetField(Characters[index], "remote_vibrator", 0.0)] if renpy.random.random() < 0.2: $ actions.append(Call("remote_vibrator_narration_interaction", Characters[index], "off", from_current = True)) else: $ actions = NullAction() else: $ actions = None imagebutton: idle At(f"images/interfaces/{interface_resolution}/belt/remote_off.webp", interface_zoom) hover At(f"images/interfaces/{interface_resolution}/belt/remote_on.webp", interface_zoom) selected_idle At(f"images/interfaces/{interface_resolution}/belt/remote_on.webp", interface_zoom) selected Characters and Characters[index].remote_vibrator action actions imagebutton: idle At(f"images/interfaces/{interface_resolution}/belt/remote_left_idle.webp", interface_zoom) hover At(f"images/interfaces/{interface_resolution}/belt/remote_left.webp", interface_zoom) if Characters: if button_condition: action SetScreenVariable("index", (index - 1) % len(Characters)) else: action NullAction() else: action None if Characters: text "[Characters[index].name]" anchor (0.5, 0.5) pos (0.846, 0.699): size 25 imagebutton: idle At(f"images/interfaces/{interface_resolution}/belt/remote_right_idle.webp", interface_zoom) hover At(f"images/interfaces/{interface_resolution}/belt/remote_right.webp", interface_zoom) if Characters: if button_condition: action SetScreenVariable("index", (index + 1) % len(Characters)) else: action NullAction() else: action None if renpy.get_screen("say") or phone_texting: button xysize (1.0, 1.0): background None hover_sound None activate_sound None action Return() # shop.rpy: thousands separator for shops screen shop_screen(shop_type, discount = 1.0, unrestricted = False): default page = 0 default Item = None default cart = [] default bought_something = False layer "interface" on "show" action Function(hide_Characters_for_interface, Present) on "hide" action Function(show_Characters_for_interface, Present) if black_screen[0]: pass elif renpy.get_screen("options"): pass else: if persistent.animated_interface: timer 1.0 action ToggleVariable("interface_blinking") repeat True modal True $ inventory = list(get_shop_inventory(shop_type, unrestricted = unrestricted).values()) if Player.check_trait("charming_personality"): $ discount *= 0.9 use menu_background(spinning = True) add "images/interfaces/[interface_resolution]/shop/background.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/shop/cash.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/shop/panels.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/shop/tab.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/shop/total.webp" zoom interface_adjustment if shop_type == "clothing": add "images/interfaces/[interface_resolution]/shop/mutant_couture.webp" zoom high_resolution_interface_adjustment elif shop_type == "gift": add "images/interfaces/[interface_resolution]/shop/bear_with_me.webp" zoom high_resolution_interface_adjustment elif shop_type == "lingerie": add "images/interfaces/[interface_resolution]/shop/xtreme_intimates.webp" zoom high_resolution_interface_adjustment elif shop_type == "sex": add "images/interfaces/[interface_resolution]/shop/moaning_of_life.webp" zoom high_resolution_interface_adjustment if len(inventory) > 7: $ actions = SetScreenVariable("page", (page - 1) % math.ceil(len(inventory) / 7)) else: $ actions = None use shop_tab_button( actions, anchor = (0.0, 0.0), pos = (0.058, 0.637), xysize = (int(194 * game_resolution), int(105 * game_resolution)), image = f"images/interfaces/{interface_resolution}/shop/left.webp", image_zoom = high_resolution_interface_adjustment, ) if len(inventory) > 7: $ actions = SetScreenVariable("page", (page + 1) % math.ceil(len(inventory) / 7)) else: $ actions = None use shop_tab_button( actions, anchor = (0.0, 0.0), pos = (0.268, 0.637), xysize = (int(194 * game_resolution), int(105 * game_resolution)), image = f"images/interfaces/{interface_resolution}/shop/right.webp", image_zoom = high_resolution_interface_adjustment, ) if page < 9: $ page_number = f"0{page + 1}" else: $ page_number = f"{page + 1}" if math.ceil(len(inventory) / 7) == 0: $ max_page_number = "" elif math.ceil(len(inventory) / 7) < 9: $ max_page_number = f"/0{math.ceil(len(inventory) / 7)}" else: $ max_page_number = f"/{math.ceil(len(inventory) / 7)}" if interface_blinking: text "TAB{alpha=0.0}_{/alpha}[page_number][max_page_number]" anchor (0.5, 0.5) pos (0.186, 0.661): size 35 else: text "TAB_[page_number][max_page_number]" anchor (0.5, 0.5) pos (0.186, 0.661): size 35 vbox anchor (0.5, 0.0) pos (0.546, 0.315) xysize (0.41, 0.6): spacing -5 for i in range(7 * page, 7 * page + 7): if i > len(inventory) - 1: continue $ I = inventory[i] $ quantity = 0 $ removable_Item = None for I_temp in cart: if I.Owner == I_temp.Owner and I.string == I_temp.string: $ quantity += 1 $ removable_Item = I_temp fixed xysize (1.0, int(177 * game_resolution)): button anchor (0.0, 0.5) pos (0.0, 0.5) xysize (int(884 * game_resolution), int(135 * game_resolution)): idle_background At(f"images/interfaces/{interface_resolution}/shop/item_idle.webp", interface_zoom) hover_background At(f"images/interfaces/{interface_resolution}/shop/item.webp", interface_zoom) selected_idle_background At(f"images/interfaces/{interface_resolution}/shop/item.webp", interface_zoom) selected Item and Item.Owner == I.Owner and Item.string == I.string action SetScreenVariable("Item", I) text f"{titlize(I.name, only_first = False)}" anchor (0.0, 0.5) pos (0.02, 0.5): font "agency_fb.ttf" size 30 add "images/interfaces/[interface_resolution]/shop/price.webp" anchor (0.5, 0.5) pos (0.6735, 0.5) zoom interface_adjustment if discount != 1.0: $ discounted_price = int(discount * I.price) text "${s}[I.price]{/s} [discounted_price]" anchor (0.5, 0.5) pos (0.6735, 0.5): size 30 else: text "$[I.price]" anchor (0.5, 0.5) pos (0.6735, 0.5): size 30 $ actions = None if I.Owner not in {None, Player}: if not check_cart(cart, f"{I.Owner}_{I.string}"): $ actions = AddToSet(cart, I) elif isinstance(I.unlocked, python_set): if not check_cart(cart, I.string, unlocked = I.unlocked): $ actions = AddToSet(cart, I) else: $ actions = AddToSet(cart, I) use shop_amount_button( actions, anchor = (0.5, 0.5), pos = (0.8068, 0.5), xysize = (int(107 * game_resolution), int(135 * game_resolution)), image = f"images/interfaces/{interface_resolution}/shop/plus.webp", image_zoom = high_resolution_interface_adjustment, ) add "images/interfaces/[interface_resolution]/shop/quantity.webp" anchor (0.5, 0.5) pos (0.88, 0.5) zoom interface_adjustment text "[quantity]" anchor (0.5, 0.5) pos (0.88, 0.5): size 30 if removable_Item: $ actions = RemoveFromSet(cart, removable_Item) else: $ actions = None use shop_amount_button( actions, anchor = (1.0, 0.5), pos = (0.9855, 0.5), xysize = (int(107 * game_resolution), int(135 * game_resolution)), image = f"images/interfaces/{interface_resolution}/shop/minus.webp", image_zoom = high_resolution_interface_adjustment, ) text "CASH{alpha=0.0}_{/alpha}" anchor (0.0, 0.5) pos (0.065, 0.586): size 36 # thousands separator text "$['{:,}'.format(Player.cash)]" anchor (1.0, 0.5) pos (0.318, 0.586): size 36 $ total_cost = 0 for I in cart: $ total_cost += I.price $ total_cost = int(total_cost * discount) text "TOTAL{alpha=0.0}_{/alpha}" anchor (0.0, 0.5) pos (0.505, 0.91): size 36 text "$[total_cost]" anchor (1.0, 0.5) pos (0.745, 0.91): size 36 imagebutton: idle At(f"images/interfaces/{interface_resolution}/shop/buy_idle.webp", interface_zoom) hover At(f"images/interfaces/{interface_resolution}/shop/buy.webp", interface_zoom) if cart and Player.cash >= total_cost: action [ SetScreenVariable("bought_something", True), Function(buy_cart, cart = cart, discount = discount), SetScreenVariable("cart", []), SetVariable("inventory_alert", True), ] else: action None tooltip "Buy Cart" text "BUY" anchor (0.5, 0.5) pos (0.367, 0.91): size 36 imagebutton: idle At(f"images/interfaces/{interface_resolution}/shop/clear_idle.webp", interface_zoom) hover At(f"images/interfaces/{interface_resolution}/shop/clear.webp", interface_zoom) action SetScreenVariable("cart", []) tooltip "Clear Cart" text "CLEAR" anchor (0.5, 0.5) pos (0.445, 0.91): size 36 imagebutton: idle At(f"images/interfaces/{interface_resolution}/shop/quit_idle.webp", interface_zoom) hover At(f"images/interfaces/{interface_resolution}/shop/quit.webp", interface_zoom) action Return(bought_something) tooltip "Exit" text "DONE" anchor (0.0, 0.5) pos (0.065, 0.738): size 36 text "ITEM DESCRIPTION{alpha=0.0}_{/alpha}" anchor (0.0, 0.5) pos (0.776, 0.336): size 36 text "TRACKER{alpha=0.0}_{/alpha}" anchor (0.0, 0.5) pos (0.776, 0.683): size 36 text "OWNED{alpha=0.0}_{/alpha}" anchor (0.0, 0.5) pos (0.776, 0.91): size 36 if Item: if isinstance(Item, ItemClass): text "[Item.description]" anchor (0.5, 0.5) pos (0.851, 0.507) xysize (0.159, 0.235): size 30 if shop_type in {"clothing", "lingerie"}: add "images/interfaces/full/icons/[Item.Owner.tag].webp" anchor (0.5, 0.5) pos (0.851, 0.797) zoom 0.5 else: vpgrid anchor (0.5, 0.5) pos (0.8555, 0.805) xysize (0.16, 0.12): cols 5 spacing 10 draggable True mousewheel True if Item.filter_type == "key_gifts": for C in Item.unlocked: fixed xysize (int(0.2 * 252), int(0.2 * 252)): add "images/interfaces/full/icons/[C].webp" zoom 0.2 if getattr(store, C).Inventory.get(Item.string): add "images/interfaces/[interface_resolution]/interactions/gift.webp" align (1.0, 1.0) zoom 0.2 else: for C in get_Item_Characters(Item): fixed xysize (int(0.2 * 252), int(0.2 * 252)): if check_approval(C, threshold = C.gift_thresholds.get(Item.string, (0, 0))): if shop_type == "gift" and Item.string not in C.gift_bonuses: add "images/interfaces/full/icons/[C.tag].webp" zoom 0.2 matrixcolor matrix_colors["black_and_white"] else: add "images/interfaces/full/icons/[C.tag].webp" zoom 0.2 else: add "images/interfaces/full/icons/[C.tag].webp" zoom 0.2 matrixcolor matrix_colors["black_and_white"] if C.Inventory.get(Item.string): add "images/interfaces/[interface_resolution]/interactions/gift.webp" align (1.0, 1.0) zoom 0.2 text "[Player.Inventory.get_number(Item.string)]" anchor (1.0, 0.5) pos (0.926, 0.91): size 36 if black_screen[0] or renpy.get_screen("say"): button xysize (1.0, 1.0): background None hover_sound None activate_sound None if not renpy.get_screen("choice"): action Return() else: action NullAction() use quick_menu() if persistent.tooltips_enabled: use tooltips() # Player_menu.rpy: thousands separator for inventory screen inventory_screen(giving_gift): default inventory_page = 0 default inventory_filter = "gift" default inventory_Item = None $ Item_list = [] for Item_string in Player.Inventory.Items: for I in Player.Inventory.Items[Item_string]: if inventory_filter == "gift" and isinstance(I, ClothingClass): $ Item_list.append(Item_string) elif isinstance(I, ItemClass): if Item_string in Item_list: continue if inventory_filter not in I.filter_type: continue if I.Owner == Player and inventory_filter == "key": $ Item_list.append(Item_string) elif I.Owner != Player and inventory_filter == "gift": $ Item_list.append(Item_string) add "images/interfaces/[interface_resolution]/Player_menu/inventory_background.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/Player_menu/inventory_cash.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/Player_menu/inventory_description.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/Player_menu/inventory_name.webp" zoom interface_adjustment if math.floor(len(Item_list) / 15) > 0: add "images/interfaces/[interface_resolution]/Player_menu/inventory_pages.webp" zoom interface_adjustment use inventory_page( SetLocalVariable("inventory_page", (inventory_page - 1) % math.ceil(len(Item_list) / 15)), pos = (0.056, 0.205), xysize = (int(372 * game_resolution), int(124 * game_resolution)), image = "images/interfaces/[interface_resolution]/Player_menu/inventory_left.webp", image_zoom = high_resolution_interface_adjustment, image_shadow = True) if inventory_page < 9: if interface_blinking: text "TAB{alpha=0.0}_{/alpha}0[inventory_page + 1]" anchor (0.5, 0.5) pos (0.199, 0.234): size 35 else: text "TAB_0[inventory_page + 1]" anchor (0.5, 0.5) pos (0.199, 0.234): size 35 else: if interface_blinking: text "TAB{alpha=0.0}_{/alpha}[inventory_page + 1]" anchor (0.5, 0.5) pos (0.199, 0.234): size 35 else: text "TAB_[inventory_page + 1]" anchor (0.5, 0.5) pos (0.199, 0.234): size 35 use inventory_page( SetLocalVariable("inventory_page", (inventory_page + 1) % math.ceil(len(Item_list) / 15)), pos = (0.250, 0.205), xysize = (int(372 * game_resolution), int(124 * game_resolution)), image = "images/interfaces/[interface_resolution]/Player_menu/inventory_right.webp", image_zoom = high_resolution_interface_adjustment, image_shadow = True) grid 5 3 anchor (0.0, 0.0) pos (0.065, 0.319) xysize (0.6, 0.7): xspacing 9 yspacing 7 for i in range(15 * inventory_page, min(15 * (inventory_page + 1), len(Item_list))): if inventory_filter == "key": $ Owner = Player elif giving_gift: $ Owner = None else: $ Owner = False $ I = Player.Inventory.get(Item_list[i], filter = inventory_filter, Owner = Owner) if not I and giving_gift: $ I = Player.Inventory.get(Item_list[i], filter = inventory_filter, Owner = focused_Character) $ actions = [SetLocalVariable("inventory_Item", I)] if giving_gift: if isinstance(I, ClothingClass): if I.Owner == focused_Character: $ actions.append(Show("confirm_gift_screen", Character = focused_Character, Item = I)) elif isinstance(I, ItemClass): if I.shop_type == "sex" and "piercing" not in I.string and not get_interactions(focused_Character.interactions, {"gift", "sexy_gift", I.tag}, optionals = {"first", "repeat"}): $ actions.append(Show("cannot_gift_screen", Character = focused_Character, Item = I)) elif I.shop_type != "sex" and not get_interactions(focused_Character.interactions, {"gift", I.tag}, optionals = {"first", "repeat"}): $ actions.append(Show("cannot_gift_screen", Character = focused_Character, Item = I)) elif ("piercing" in I.string or "plug" in I.string or "vibrator" in I.string) and focused_Character.Inventory.get(I.string): $ actions.append(Show("cannot_gift_screen", Character = focused_Character, Item = I)) elif isinstance(I.unlocked, python_set): if focused_Character.tag in I.unlocked: $ actions.append(Show("confirm_gift_screen", Character = focused_Character, Item = I)) elif I.Owner and I.Owner != Character: pass elif I.Owner != Player: $ actions.append(Show("confirm_gift_screen", Character = focused_Character, Item = I)) button xysize (int(426 * game_resolution), int(426 * game_resolution)): if I and inventory_Item == I: background At(f"images/interfaces/{interface_resolution}/Player_menu/inventory_selector.webp", interface_zoom) else: background None hover_sound None if isinstance(I, ClothingClass): if I.shop_type == "clothing": add "images/interfaces/[interface_resolution]/items/mutant_couture.webp" anchor (0.5, 0.5) pos (0.5, 0.4) zoom 0.2 * interface_adjustment elif I.shop_type == "lingerie": add "images/interfaces/[interface_resolution]/items/xtreme_intimates.webp" anchor (0.5, 0.5) pos (0.5, 0.4) zoom 0.2 * interface_adjustment add "images/interfaces/full/icons/[I.Owner.tag].webp" anchor (0.5, 0.5) pos (0.91, 0.857) zoom 0.18 elif isinstance(I, ItemClass): if "piercing" in I.string: add "images/interfaces/[interface_resolution]/items/piercings.webp" anchor (0.5, 0.5) pos (0.5, 0.4) zoom 0.2 * interface_adjustment else: add "images/interfaces/[interface_resolution]/items/[I.image].webp" anchor (0.5, 0.5) pos (0.5, 0.4) zoom 0.2 * interface_adjustment if Player.Inventory.get_number(I.string, filter = inventory_filter, Owner = Owner) > 1: text "x[Player.Inventory.get_number(I.string, filter = inventory_filter, Owner = Owner)]" anchor (0.5, 1.0) pos (0.5, 0.95): size 32 if I and giving_gift and focused_Character.Inventory.get(I.string): add "images/interfaces/[interface_resolution]/interactions/gift.webp" anchor (1.0, 0.5) pos (0.99, 0.86) zoom 0.25 action actions add "images/interfaces/[interface_resolution]/Player_menu/inventory_filters.webp" zoom interface_adjustment for f, filter in enumerate(["gift", "key"]): use inventory_filter( [SetLocalVariable("inventory_Item", None), SetLocalVariable("inventory_filter", filter), SetLocalVariable("inventory_page", 0)], filter_type = filter, pos = (0.451 + f * 0.097, 0.205), xysize = (int(372 * game_resolution), int(124 * game_resolution)), selected = inventory_filter == filter) text "ITEM NAME{alpha=0.0}_{/alpha}" anchor (0.0, 0.5) pos (0.673, 0.234): size 35 if inventory_Item: if isinstance(inventory_Item, ClothingClass): text "[inventory_Item.name!u]" anchor (1.0, 0.5) pos (0.925, 0.234): if len(inventory_Item.name) > 20: size 25 elif len(inventory_Item.name) > 15: size 30 else: size 35 elif isinstance(inventory_Item, ItemClass): text "[inventory_Item.name!u]" anchor (1.0, 0.5) pos (0.925, 0.234): if len(inventory_Item.name) > 20: size 25 elif len(inventory_Item.name) > 15: size 30 else: size 35 text "[inventory_Item.description]" anchor (0.5, 0.0) pos (0.8, 0.35) xysize (0.25, 0.44): size 40 if inventory_Item.filter_type == "key_gifts" and inventory_Item.Owner == Player: vbox anchor (0.5, 0.5) pos (0.8, 0.77): spacing 5 text "ACTIVE?": size 40 use options_onoff( ToggleField(inventory_Item, "active"), selected = inventory_Item.active, ) text "CASH{alpha=0.0}_{/alpha}" anchor (0.0, 0.5) pos (0.673, 0.905): size 45 # thousands separator text "$['{:,}'.format(Player.cash)]" anchor (1.0, 0.5) pos (0.9265, 0.905): size 45 # phone.rpy: Celcius-Fahrenheit toggle for player phone screen home_screen(): style_prefix "phone" if time_index in {1, 2, 3}: add "images/interfaces/[interface_resolution]/phone/clock_[time_index].webp" zoom high_resolution_interface_adjustment elif time_index < 1: add "images/interfaces/[interface_resolution]/phone/clock_1.webp" zoom high_resolution_interface_adjustment elif time_index > 3: add "images/interfaces/[interface_resolution]/phone/clock_3.webp" zoom high_resolution_interface_adjustment if weather: add "images/interfaces/[interface_resolution]/phone/weather_[weather].webp" zoom high_resolution_interface_adjustment else: add "images/interfaces/[interface_resolution]/phone/weather.webp" zoom high_resolution_interface_adjustment text "[week[weekday]], [time_options[time_index]]" anchor (0.0, 0.5) pos (0.15, 0.132): size 30 color "#ffffff" # Celcius-Fahrenheit toggle key "d" action ToggleVariable("persistent.Fahrenheit") if persistent.Fahrenheit: text u"['{:.1f}'.format(temperature[time_index]*9/5+32)] \u00b0F" anchor (0.0, 0.5) pos (0.22, 0.169): size 30 color "#ffffff" else: text u"[temperature[time_index]] \u00b0C" anchor (0.0, 0.5) pos (0.22, 0.169): size 30 color "#ffffff" button: background At(f"images/interfaces/{interface_resolution}/phone/search_bar_background.webp", interface_zoom) idle_foreground At(f"images/interfaces/{interface_resolution}/phone/search_bar_idle.webp", high_resolution_interface_zoom) hover_foreground At(f"images/interfaces/{interface_resolution}/phone/search_bar.webp", high_resolution_interface_zoom) selected_idle_foreground At(f"images/interfaces/{interface_resolution}/phone/search_bar.webp", high_resolution_interface_zoom) selected input_cheats action [ SetVariable("current_input", ""), ToggleVariable("input_cheats")] focus_mask True add "images/interfaces/[interface_resolution]/phone/search_bar_microphone.webp" zoom high_resolution_interface_adjustment add "images/interfaces/[interface_resolution]/phone/search_bar_icon.webp" zoom high_resolution_interface_adjustment if input_cheats: input value VariableInputValue("current_input", default = True) anchor (0.0, 0.5) pos (0.224, 0.235): font "agency_fb.ttf" if len(current_input) < 25: size 30 elif len(current_input) < 35: size 26 elif len(current_input) < 40: size 24 elif len(current_input) < 45: size 20 else: size 18 color "#ffffff" length 50 key "K_RETURN" action [ Function(enter_cheat_code, current_input), SetVariable("input_cheats", False)] if humhum_available and not humhum_hidden: $ humhumthread_to_display = HumHumPool.HumHumThreads[list(HumHumPool.HumHumThreads.keys())[humhum_index]] add "images/interfaces/[interface_resolution]/phone/home_humhum_box.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/phone/home_humhum_newest.webp" zoom high_resolution_interface_adjustment imagebutton: idle At(f"images/interfaces/{interface_resolution}/phone/home_humhum_left_idle.webp", high_resolution_interface_zoom) hover At(f"images/interfaces/{interface_resolution}/phone/home_humhum_left.webp", high_resolution_interface_zoom) action [ SetVariable("humhum_index", (humhum_index - 1) % len(list(HumHumPool.HumHumThreads.keys()))), SetVariable("humhum_yadjustment.value", 0), SetVariable("humhum_reply_yadjustment.value", 0)] imagebutton: idle At(f"images/interfaces/{interface_resolution}/phone/home_humhum_right_idle.webp", high_resolution_interface_zoom) hover At(f"images/interfaces/{interface_resolution}/phone/home_humhum_right.webp", high_resolution_interface_zoom) action [ SetVariable("humhum_index", (humhum_index + 1) % len(list(HumHumPool.HumHumThreads.keys()))), SetVariable("humhum_yadjustment.value", 0), SetVariable("humhum_reply_yadjustment.value", 0)] if len(humhumthread_to_display.HumHums) > 1: imagebutton: idle At(f"images/interfaces/{interface_resolution}/phone/home_humhum_comments_idle.webp", interface_zoom) hover At(f"images/interfaces/{interface_resolution}/phone/home_humhum_comments.webp", interface_zoom) action ToggleVariable("humhum_expanded") else: add "images/interfaces/[interface_resolution]/phone/home_humhum_comments_idle.webp" zoom interface_adjustment text "COMMENTS" anchor (0.5, 0.5) pos (0.5, 0.458): font "agency_fb_bold.ttf" size 24 color "#4e4e4e" if humhumthread_to_display.HumHums[0].Owner != Player: add "images/interfaces/full/icons/[humhumthread_to_display.HumHums[0].Owner.tag].webp" anchor (0.5, 0.5) pos (0.18, 0.350) zoom 0.18 else: add "images/interfaces/full/icons/Player_[Player.background_color].webp" anchor (0.5, 0.5) pos (0.18, 0.350) zoom 0.18 fixed anchor (0.0, 0.0) pos (0.238, 0.325) xysize (0.6, 0.102): viewport id "home_humhum_viewport" yadjustment humhum_yadjustment anchor (0.0, 0.0) pos (0.02, 0.01) xysize (0.96, 0.98): draggable True mousewheel True text "[humhumthread_to_display.HumHums[0].body!i]" align (0.0, 0.0): size 28 textalign 0.0 vbar value YScrollValue("home_humhum_viewport") anchor (0.5, 0.5) pos (0.855, 0.377) xysize (int(27 * game_resolution), int(227 * game_resolution)): base_bar Frame("images/interfaces/full/phone/home_humhum_scrollbar.webp") thumb "images/interfaces/full/phone/home_humhum_scrollbar_thumb.webp" thumb_offset int(66 * game_resolution / 2 / 3) unscrollable "hide" if humhum_expanded and len(humhumthread_to_display.HumHums) > 1: add "images/interfaces/[interface_resolution]/phone/home_humhum_reply_box.webp" zoom interface_adjustment fixed anchor (0.5, 0.0) pos (0.5, 0.487) xysize (0.73, 0.172): viewport id "home_humhum_reply_viewport" yadjustment humhum_reply_yadjustment anchor (0.0, 0.0) pos (0.02, 0.01) xysize (0.96, 0.98): draggable True mousewheel True vbox xsize 1.0: null height 4 for h in range(1, len(humhumthread_to_display.HumHums)): hbox xalign 0.0 xsize 0.98: vbox align (0.0, 0.5) xsize int(252 * 0.18): if humhumthread_to_display.HumHums[h].Owner != Player: add "images/interfaces/full/icons/[humhumthread_to_display.HumHums[h].Owner.tag].webp" yalign 0.0 zoom 0.18 else: add "images/interfaces/full/icons/Player_[Player.background_color].webp" yalign 0.0 zoom 0.18 # text "[humhumthread_to_display.HumHums[h].Owner.call_sign]": # size 24 null width 8 frame align (0.0, 0.5) xsize int(770 * game_resolution): background Frame("images/interfaces/full/phone/home_humhum_comments_frame.webp") text "[humhumthread_to_display.HumHums[h].body!i]" align (0.0, 0.0): size 28 textalign 0.0 null height 4 vbar value YScrollValue("home_humhum_reply_viewport") anchor (0.5, 0.0) pos (0.855, 0.490) xysize (int(27 * game_resolution), int(348 * game_resolution)): base_bar Frame("images/interfaces/full/phone/home_humhum_reply_scrollbar.webp") thumb "images/interfaces/full/phone/home_humhum_scrollbar_thumb.webp" thumb_offset int(66 * game_resolution / 2 / 3) unscrollable "hide" # if len(humhumthread_to_display.HumHums) > 1: # imagebutton: # idle At(f"images/interfaces/{interface_resolution}/phone/home_humhum_reply_idle.webp", interface_zoom) # hover At(f"images/interfaces/{interface_resolution}/phone/home_humhum_reply.webp", interface_zoom) # action ToggleVariable("humhum_expanded") # else: add "images/interfaces/[interface_resolution]/phone/home_humhum_reply_idle.webp" zoom interface_adjustment text "Share your hums. . ." anchor (0.0, 0.5) pos (0.149, 0.682): size 22 color "#4e4e4e" text "REPLY" anchor (0.5, 0.5) pos (0.802, 0.682): font "agency_fb_bold.ttf" size 24 color "#4e4e4e" imagebutton anchor (0.5, 0.5) pos (0.75, 0.8): idle At("images/interfaces/full/icons/blah_idle.webp", phone_icon) hover At("images/interfaces/full/icons/blah.webp", phone_icon) action [ SetScreenVariable("loading", True), SetVariable("current_phone_screen", "blah_choice")] # Player_menu.rpy: adds friendship points to portraits screen relationships_screen(): default relationships_filter = None default relationships_Entry = None default relationships_quirk_start = 0 add "images/interfaces/[interface_resolution]/Player_menu/relationships_label.webp" zoom interface_adjustment if interface_blinking: text "RELATIONSHIPS{alpha=0.0}_{/alpha}" anchor (0.0, 0.5) pos (0.064, 0.234): size 35 else: text "RELATIONSHIPS_" anchor (0.0, 0.5) pos (0.064, 0.234): size 35 add "images/interfaces/[interface_resolution]/Player_menu/relationships_side.webp" zoom interface_adjustment text "FILTER" anchor (0.0, 0.5) pos (0.064, 0.331): size 35 for f, filter in enumerate(["friend", "companion"]): if relationships_filter == filter: $ actions = SetLocalVariable("relationships_filter", None) else: $ actions = [ SetLocalVariable("relationships_Entry", None), SetLocalVariable("relationships_filter", filter), ] if filter == "friend": $ size = 30 elif filter == "companion": $ size = 24 use relationships_filter( actions, filter_type = filter, pos = (0.207 + f * 0.058, 0.317), xysize = (int(210 * game_resolution), int(60 * game_resolution)), text_size = size, selected = relationships_filter == filter) vpgrid id "relationships_viewport" anchor (0.5, 0.0) pos (0.18, 0.392) xysize (int(911 * game_resolution), int(1114 * game_resolution)): cols 1 draggable True mousewheel True for C in GameState.all_Characters: if C in GameState.all_Companions: if relationships_filter not in {"companion", None}: continue if C not in GameState.active_Companions(): continue $ kind = "companion" elif C.check_trait("friend"): if relationships_filter not in {"friend", None}: continue ## eventually remove continue $ kind = "friend" else: continue button xysize (int(911 * game_resolution), int(191 * game_resolution)): idle_background At(f"images/interfaces/{interface_resolution}/Player_menu/relationships_{kind}_idle.webp", high_resolution_interface_zoom) hover_background At(f"images/interfaces/{interface_resolution}/Player_menu/relationships_{kind}.webp", high_resolution_interface_zoom) selected_idle_background At(f"images/interfaces/{interface_resolution}/Player_menu/relationships_{kind}.webp", high_resolution_interface_zoom) selected relationships_Entry == C if C.full_name == "???": text "[C.name]" anchor (0.0, 0.5) pos (0.1, 0.5): font "agency_fb.ttf" size 36 color "#000000" else: text "[C.full_name]" anchor (0.0, 0.5) pos (0.1, 0.5): font "agency_fb.ttf" size 36 color "#000000" action SetLocalVariable("relationships_Entry", C) vbar value YScrollValue("relationships_viewport") anchor (0.5, 0.0) pos (0.315, 0.392) xysize (int(40 * game_resolution), int(1114 * game_resolution)): base_bar Frame("images/interfaces/full/Player_menu/scrollbar.webp") thumb "images/interfaces/full/Player_menu/scrollbar_thumb.webp" thumb_offset int(276 * game_resolution / 2 / 10) unscrollable "hide" if relationships_Entry: add "images/interfaces/[interface_resolution]/Player_menu/relationships_box.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/Player_menu/relationships_bottom.webp" zoom interface_adjustment add "images/interfaces/full/photos/[relationships_Entry.tag].webp" anchor (0.5, 0.5) pos (0.4215, 0.3785) zoom 0.5 add "images/interfaces/[interface_resolution]/Player_menu/relationships_love.webp" zoom interface_adjustment text "[relationships_Entry.love]" anchor (0.5, 0.5) pos (0.435, 0.4655): font "agency_fb.ttf" size 30 color "#000000" add "images/interfaces/[interface_resolution]/Player_menu/relationships_trust.webp" zoom interface_adjustment text "[relationships_Entry.trust]" anchor (0.5, 0.5) pos (0.435, 0.5065): font "agency_fb.ttf" size 30 color "#000000" text "PUBLIC NAME" anchor (0.0, 0.5) pos (0.495, 0.242): font "agency_fb.ttf" size 28 text "[relationships_Entry.public_name]" anchor (1.0, 0.5) pos (0.713, 0.242): font "agency_fb.ttf" size 28 text "RELATIONSHIP STATUS" anchor (0.0, 0.5) pos (0.495, 0.297): font "agency_fb.ttf" size 28 if relationships_Entry not in Partners: text "Single" anchor (1.0, 0.5) pos (0.713, 0.297): font "agency_fb.ttf" size 28 elif relationships_Entry.check_trait("polyamorous"): text "Polyamorous" anchor (1.0, 0.5) pos (0.713, 0.297): font "agency_fb.ttf" size 28 else: text "In a relationship" anchor (1.0, 0.5) pos (0.713, 0.297): font "agency_fb.ttf" size 28 text "[relationships_Entry.pronouns['possessive_adjective']!u] PETNAMES" anchor (0.0, 0.5) pos (0.495, 0.353): font "agency_fb.ttf" size 28 viewport anchor (1.0, 0.5) pos (0.72, 0.353) xysize (0.13, 0.03): draggable True mousewheel True text "[', '.join(sorted(relationships_Entry.petnames))]": font "agency_fb.ttf" size 24 text "MY PETNAMES" anchor (0.0, 0.5) pos (0.495, 0.411): font "agency_fb.ttf" size 28 viewport anchor (1.0, 0.5) pos (0.72, 0.411) xysize (0.13, 0.03): draggable True mousewheel True text "[', '.join(sorted(relationships_Entry.Player_petnames))]": font "agency_fb.ttf" size 24 text "MOOD" anchor (0.5, 0.5) pos (0.829, 0.234): font "agency_fb.ttf" size 28 hbox anchor (0.0, 0.5) pos (0.736, 0.286) ysize int(107 * game_resolution): if relationships_Entry.is_in_normal_mood(): use relationships_status( "happy", text_color = "#00ff06") if relationships_Entry.get_status() == "mad": use relationships_status( "mad", text_color = "#f00d48") if relationships_Entry.status["horny"] or relationships_Entry.status["nympho"]: use relationships_status( "horny", text_color = "#dd64e8") for status, color in (("sad1", "#0dd3f0"), ("heartbroken", "#ffd304")): if relationships_Entry.status.get(status, False): use relationships_status( status, text_color = color) text "FRIENDSHIPS" anchor (0.5, 0.55) pos (0.829, 0.3455): font "agency_fb.ttf" size 22 text "Best Friends" anchor (0.5, 0.55) pos (0.771, 0.387): font "agency_fb.ttf" size 20 text "Good Friends" anchor (0.5, 0.55) pos (0.834, 0.387): font "agency_fb.ttf" size 20 text "Friends" anchor (0.5, 0.55) pos (0.896, 0.387): font "agency_fb.ttf" size 20 text "Acquaintances" anchor (0.5, 0.55) pos (0.771, 0.416): font "agency_fb.ttf" size 18 text "Rivals" anchor (0.5, 0.55) pos (0.834, 0.416): font "agency_fb.ttf" size 20 text "Enemies" anchor (0.5, 0.55) pos (0.896, 0.416): font "agency_fb.ttf" size 20 vpgrid id "relationships_friendship_viewport" anchor (0.0, 0.5) pos (0.505, 0.4935) xysize (0.385, int(195 * game_resolution)): cols len(relationships_Entry.friendship) draggable True mousewheel True spacing 20 for C in relationships_Entry.friendship: if C != relationships_Entry.tag and getattr(store, C) in GameState.active_Companions(): $ friendship = relationships_Entry.get_friendship(getattr(store, C)) fixed xysize (int(135 * game_resolution), int(195 * game_resolution)): add "images/interfaces/full/photos/[C].webp" align (0.5, 0.5) zoom 0.13 add "images/interfaces/[interface_resolution]/Player_menu/relationships_[friendship].webp" align (0.5, 0.5) zoom interface_adjustment # friendship points in portraits if not persistent.fps_portraits: text "[relationships_Entry.friendship[C]]" align (0.51, 0.98) size 16 outlines [(1,"#000")]: if friendship == 3: color "#01FF60" elif friendship == 2: color "#01FED2" elif friendship == 1: color "#00A1FB" elif friendship == -1: color "#F55209" elif friendship == -2: color "#F60D4A" for q, (quirk, description) in enumerate(relationships_Entry.database["quirks"][relationships_quirk_start:relationships_quirk_start + 2]): text "[titlize(quirk, only_first = False)]" anchor (0.0, 0.5) pos (0.37 + 0.288 * q, 0.5815): font "agency_fb.ttf" size 30 frame anchor (0.5, 0.0) pos (0.503 + 0.288 * q, 0.614) xsize 0.275: text "[description]" xalign 0.0: font "agency_fb.ttf" size 28 textalign 0.0 if len(relationships_Entry.database["quirks"]) > 2: use relationships_tab( SetLocalVariable("relationships_quirk_start", (relationships_quirk_start - 1) % len(relationships_Entry.database["quirks"])), "<<<<", anchor = (0.5, 0.5), pos = (0.503, 0.795), ) use relationships_tab( SetLocalVariable("relationships_quirk_start", (relationships_quirk_start + 1) % len(relationships_Entry.database["quirks"])), ">>>>", anchor = (0.5, 0.5), pos = (0.503 + 0.288, 0.795), ) # updates.rpy: shorter notification timer screen updates_screen(): default update_message = None style_prefix "updates" if update_message: timer 2.8 action SetLocalVariable("update_message", None) # timer 3.3 frame: if renpy.get_screen("sex_screen"): anchor (0.0, 0.0) pos (0.07, 0.0125) # (0.0, 1.0) pos (0.02, 0.98) else: anchor (0.0, 0.0) pos (0.02, 0.0125) # (0.0, 0.0) pos (0.02, 0.02) text "[update_message]" at transform: # better always adjust the sum of these timer values to the "timer" one above fade_in(0.4) # 0.4 pause 2.0 # 2.5 fade_out(0.4) # 0.4 elif update_messages: instant action [ SetLocalVariable("update_message", update_messages[0]), RemoveFromSet(update_messages, update_messages[0])] # game_menu.rpy: hotkeys added to the Options menu screen options(): default tab = "graphics" default tab_label = "GRAPHIC OPTIONS" default image_filters = [None, "comic", "tv"] default image_caches = [512, 1024, 2048, 4096] default default_body_hairs = ["default", "hairy", "shaven"] layer "screens" tag menu modal True style_prefix "game_menu" if persistent.animated_interface: timer 1.0 action ToggleVariable("interface_blinking") repeat True modal True use menu_background(spinning = True) add "images/interfaces/[interface_resolution]/options/frame.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/options/buttons.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/options/label.webp" zoom interface_adjustment use options_section( [SetScreenVariable("tab", "graphics"), SetScreenVariable("tab_label", "GRAPHICS OPTIONS")], pos = (0.208, 0.204), xysize = (int(372 * game_resolution), int(124 * game_resolution)), text = "GRAPHICS", selected = tab == "graphics") use options_section( [SetScreenVariable("tab", "audio"), SetScreenVariable("tab_label", "AUDIO OPTIONS")], pos = (0.305, 0.204), xysize = (int(372 * game_resolution), int(124 * game_resolution)), text = "AUDIO", selected = tab == "audio") use options_section( [SetScreenVariable("tab", "hotkeys"), SetScreenVariable("tab_label", "HOTKEYS")], pos = (0.402, 0.204), xysize = (int(372 * game_resolution), int(124 * game_resolution)), text = "HOTKEYS", selected = tab == "hotkeys") use options_section( [SetScreenVariable("tab", "gameplay"), SetScreenVariable("tab_label", "GAMEPLAY OPTIONS")], pos = (0.499, 0.204), xysize = (int(372 * game_resolution), int(124 * game_resolution)), text = "GAMEPLAY", selected = tab == "gameplay") # new mod options tab use base_button( [SetScreenVariable("tab", "mod"), SetScreenVariable("tab_label", "MOD OPTIONS")], pos = (0.610, 0.198), xysize = (int(395*game_resolution), int(153*game_resolution)), text = "TNHUXMod", selected = tab == "mod", text_size = 29) # new summoner mod options tab if mod_summoner: use base_button( [SetScreenVariable("tab", "summoner"), SetScreenVariable("tab_label", "MOD OPTIONS")], pos = (0.713, 0.198), xysize = (int(395*game_resolution), int(153*game_resolution)), text = "Summoner", selected = tab == "summoner", text_size = 29) if interface_blinking: text "[tab_label]{alpha=0.0}_{/alpha}" anchor (0.0, 0.5) pos (0.065, 0.232) else: text "[tab_label]_" anchor (0.0, 0.5) pos (0.065, 0.232) viewport id "options_viewport" anchor (0.5, 0.0) pos (0.4235, 0.31) xysize (0.72, 0.62): draggable True mousewheel True vbox align (0.5, 0.0): spacing 0 if tab == "graphics": hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "WINDOWED MODE" anchor (0.0, 0.5) pos (0.035, 0.235) text "Toggle between windowed and fullscreen modes" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 if preferences.fullscreen: use options_onoff( Preference("display", "window"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = not preferences.fullscreen, button_shadow = True, ) else: use options_onoff( Preference("display", "fullscreen"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = not preferences.fullscreen, button_shadow = True, ) fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "FLASHING EFFECTS" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enable flashing lights and effects during gameplay" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.flashing_lights"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.flashing_lights, button_shadow = True, ) hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "CINEMATIC BARS" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enable cinematic bars during events" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.cinematic_bars"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.cinematic_bars, button_shadow = True, ) fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "LOW RESOLUTION (REQUIRES RESTART)" anchor (0.0, 0.5) pos (0.035, 0.235) text "Use downscaled images - may reduce crashing on devices with low available memory" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.low_res"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.low_res, button_shadow = True, ) hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "IMAGE FILTER" anchor (0.0, 0.5) pos (0.035, 0.235) text "Toggle between filter overlays" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.45: font "agency_fb.ttf" size 24 textalign 0.0 use customization_button( SetVariable("persistent.image_filter", image_filters[(image_filters.index(persistent.image_filter) - 1) % len(image_filters)]), anchor = (0.0, 1.0), pos = (0.5, 0.9), xysize = (int(197 * game_resolution), int(181 * game_resolution)), image = "images/interfaces/[interface_resolution]/customization/left.webp", image_zoom = high_resolution_interface_adjustment, image_shadow = True, ) if persistent.image_filter: text "[persistent.image_filter!u]" anchor (0.5, 1.0) pos (0.73, 0.74) else: text "OFF" anchor (0.5, 1.0) pos (0.73, 0.74) use customization_button( SetVariable("persistent.image_filter", image_filters[(image_filters.index(persistent.image_filter) + 1) % len(image_filters)]), anchor = (1.0, 1.0), pos = (0.96, 0.9), xysize = (int(197 * game_resolution), int(181 * game_resolution)), image = "images/interfaces/[interface_resolution]/customization/right.webp", image_zoom = high_resolution_interface_adjustment, image_shadow = True, ) fixed xysize (int(684 * 2.0 * game_resolution), int(175 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "LIVE2D LITE" anchor (0.0, 0.5) pos (0.035, 0.235) text "Disable Live2D features that may negatively impact game performance, including physics and breathing animations" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.live2d_lite"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.live2d_lite, button_shadow = True, ) hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "PATREON SILHOUETTES" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enable background silhouettes belonging to Patreon supporters" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.silhouettes_enabled"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.silhouettes_enabled, button_shadow = True, ) fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "SHOW BACKGROUND" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enable characters to be displayed in the background" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.show_background"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.show_background, button_shadow = True, ) hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "HOVER EFFECT" anchor (0.0, 0.5) pos (0.035, 0.235) text "Highlight interactable characters upon mouse over" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.hover_highlights"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.hover_highlights, button_shadow = True, ) fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "MAP ICONS" anchor (0.0, 0.5) pos (0.035, 0.235) text "Display character icons on the map" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.map_icons"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.map_icons, button_shadow = True, ) hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "TOGGLE UI" anchor (0.0, 0.5) pos (0.035, 0.235) text "Toggle visibility of UI" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 if belt_hidden or sex_screen_hidden: use options_onoff( [SetVariable("belt_hidden", False), SetVariable("sex_screen_hidden", False)], anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = (not belt_hidden and not sex_screen_hidden), button_shadow = True, ) else: use options_onoff( [SetVariable("belt_hidden", True), SetVariable("sex_screen_hidden", True)], anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = (not belt_hidden and not sex_screen_hidden), button_shadow = True, ) fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "ANIMATED INTERFACE" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enable animations in interfaces\nDisable interface filters under TNHUXMod" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.animated_interface"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.animated_interface, button_shadow = True, ) hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "LARGE TEXT MODE" anchor (0.0, 0.5) pos (0.035, 0.235) text "Increase text size in dialogue and choice menus" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.large_text_mode"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.large_text_mode, button_shadow = True, ) fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "BLOOD/GORE ENABLED" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enable blood and (very light) gore" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.gore_enabled"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.gore_enabled, button_shadow = True, ) hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "IMAGE CACHE SIZE (REQUIRES RESTART)" anchor (0.0, 0.5) pos (0.035, 0.235) use customization_button( SetVariable("persistent.image_cache", image_caches[(image_caches.index(persistent.image_cache) - 1) % len(image_caches)]), anchor = (0.0, 1.0), pos = (0.25, 0.9), xysize = (int(197 * game_resolution), int(181 * game_resolution)), image = "images/interfaces/[interface_resolution]/customization/left.webp", image_zoom = high_resolution_interface_adjustment, image_shadow = True, ) text "[persistent.image_cache] MB" anchor (0.5, 1.0) pos (0.5, 0.74) use customization_button( SetVariable("persistent.image_cache", image_caches[(image_caches.index(persistent.image_cache) + 1) % len(image_caches)]), anchor = (1.0, 1.0), pos = (0.75, 0.9), xysize = (int(197 * game_resolution), int(181 * game_resolution)), image = "images/interfaces/[interface_resolution]/customization/right.webp", image_zoom = high_resolution_interface_adjustment, image_shadow = True, ) fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "PRELOAD ASSETS (REQUIRES RESTART)" anchor (0.0, 0.5) pos (0.035, 0.235) hbox anchor (0.5, 1.0) pos (0.5, 0.86): spacing 10 for asset in ("characters", "backgrounds", "interfaces"): use base_button( ToggleSetMembership(persistent.preloads, asset), xysize = (int(350 * game_resolution), int(150 * game_resolution)), selected = asset in persistent.preloads, text = asset.upper(), text_size = 28, animated = False, ) hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "WAIT FOR IMAGE PREDICTION" anchor (0.0, 0.5) pos (0.035, 0.235) text "Pause at loading screen until image prediction is complete\nTurn this off to vastely speed-up loading times!" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.wait_for_prediction"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.wait_for_prediction, button_shadow = True, ) fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "IMAGE CACHE USAGE" anchor (0.0, 0.5) pos (0.035, 0.235) bar value renpy.display.im.cache.get_current_size(2)/renpy.display.im.cache.cache_limit range 1.0 anchor (0.5, 0.0) pos (0.492, 0.58) xysize (int(600 * 2.0 * game_resolution), int(20 * 2.0 * game_resolution)): left_bar Frame(At("images/interfaces/full/options/scrollbar.webp", tint("#bb1616"))) right_bar Frame("images/interfaces/full/options/scrollbar.webp") thumb None elif tab == "audio": hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "EFFECTS VOLUME" anchor (0.0, 0.5) pos (0.035, 0.235) bar value Preference("sound volume") anchor (0.5, 0.0) pos (0.492, 0.58) xysize (int(600 * 2.0 * game_resolution), int(20 * 2.0 * game_resolution)): base_bar Frame("images/interfaces/full/options/scrollbar.webp") thumb "images/interfaces/full/options/scrollbar_thumb.webp" thumb_offset int(7 * 2.0 * game_resolution) fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "MUTE" anchor (0.0, 0.5) pos (0.035, 0.235) text "Disable all in-game sound" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 if persistent.volume_muted: use options_onoff( [SetVariable("persistent.volume_muted", False), SetMute(["sfx", "music"], False)], anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.volume_muted, button_shadow = True, ) else: use options_onoff( [SetVariable("persistent.volume_muted", True), SetMute(["sfx", "music"], True)], anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.volume_muted, button_shadow = True, ) hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "MUSIC VOLUME" anchor (0.0, 0.5) pos (0.035, 0.235) bar value Preference("music volume") anchor (0.5, 0.0) pos (0.492, 0.58) xysize (int(600 * 2.0 * game_resolution), int(20 * 2.0 * game_resolution)): base_bar Frame("images/interfaces/full/options/scrollbar.webp") thumb "images/interfaces/full/options/scrollbar_thumb.webp" thumb_offset int(7 * 2.0 * game_resolution) null width int(684 * 2.0 * game_resolution) elif tab == "hotkeys": grid 4 6 pos (0.01, 0.02): # grid 4 4 xspacing 17 # 85 yspacing 39 # 110 hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "1": size 36 color "#000000" text "QUIKLOC 1" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "2": size 36 color "#000000" text "QUIKLOC 2" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "3": size 36 color "#000000" text "QUIKLOC 3" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "-": size 36 color "#000000" text "TOGGLE MUTE" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "Q": size 36 color "#000000" text "SKIP DAY" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "W": size 36 color "#000000" text "TOGGLE QUICK MENU" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "R": size 36 color "#000000" text "PLAYER ROOM" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "T": size 36 color "#000000" text "REMOTE VIBRATOR" align (0.0, 0.5) # if not Player.Inventory.get("remote_vibrator_controller"): # at Transform(alpha = 0.0) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "I": size 36 color "#000000" text "INVENTORY" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "O": size 36 color "#000000" text "POOL" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "P": size 36 color "#000000" text "PHONE" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "A": size 36 color "#000000" text "TOGGLE AUTO-FORWARD" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "S": size 36 color "#000000" text "SCREENSHOT" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "D": size 36 color "#000000" text "TOGGLE TEMPERATURE" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "F": size 36 color "#000000" text "TOGGLE FULLSCREEN" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "G": size 36 color "#000000" text "DANGER ROOM" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "H": size 36 color "#000000" text "TOGGLE UI" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "J": size 36 color "#000000" text "JOURNAL" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "K": size 36 color "#000000" text "KITCHEN" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "L": size 36 color "#000000" text "MALL" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "X": size 36 color "#000000" text "XAVIER'S STUDY" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "C": size 36 color "#000000" text "CLASSROOM" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "V": size 36 color "#000000" text "TOGGLE SELF-VOICING" align (0.0, 0.5) hbox xalign 0.0: fixed xysize (int(158*game_resolution), int(150*game_resolution)): add "images/interfaces/[interface_resolution]/options/key.webp" zoom interface_adjustment text "M": size 36 color "#000000" text "MAP" align (0.0, 0.5) elif tab == "gameplay": hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "SKIP UNSEEN TEXT" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enable skipping through dialogue and narrations that have not been seen" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("preferences.skip_unseen"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = preferences.skip_unseen, button_shadow = True, ) if config.rollback_enabled: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "SCROLLING ROLLBACK" anchor (0.0, 0.5) pos (0.035, 0.235) text "Rollback by scrolling the mousewheel" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 if persistent.scrolling_rollback: use options_onoff( [Function(config.keymap["rollback"].remove, "mousedown_4"), Function(config.keymap["rollforward"].remove, "mousedown_5"), SetVariable("persistent.scrolling_rollback", False), Function(renpy.clear_keymap_cache)], anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.scrolling_rollback, button_shadow = True, ) else: use options_onoff( [Function(config.keymap["rollback"].append, "mousedown_4"), Function(config.keymap["rollforward"].append, "mousedown_5"), SetVariable("persistent.scrolling_rollback", True), Function(renpy.clear_keymap_cache)], anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.scrolling_rollback, button_shadow = True, ) hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "TOOLTIPS" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enable tooltips, revealed by hovering over an element" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.tooltips_enabled"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.tooltips_enabled, button_shadow = True, ) fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "JOURNAL HINTS" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enable objective hints in the journal, revealed by hovering over an objective" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.journal_hints"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.journal_hints, button_shadow = True, ) hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "WARDROBE DIALOGUE" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enable dialogue and character reactions in the wardrobe menu" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.Wardrobe_dialogue"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.Wardrobe_dialogue, button_shadow = True, ) fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "WARDROBE MOVEMENT" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enable dynamic movement of the wardrobe menu camera" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.Wardrobe_movement"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.Wardrobe_movement, button_shadow = True, ) hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "PLAYER BODY VISIBLE" anchor (0.0, 0.5) pos (0.035, 0.235) text "Show Player's body during sex" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 if Player.check_trait("body_visible"): use options_onoff( Function(Player.remove_trait, "body_visible"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = Player.check_trait("body_visible"), button_shadow = True, ) else: use options_onoff( Function(Player.give_trait, "body_visible"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = Player.check_trait("body_visible"), button_shadow = True, ) fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "PLAYER HEAD VISIBLE" anchor (0.0, 0.5) pos (0.035, 0.235) text "Show Player's head during sex" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 if Player.check_trait("head_visible"): use options_onoff( Function(Player.remove_trait, "head_visible"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = Player.check_trait("head_visible"), button_shadow = True, ) else: use options_onoff( Function(Player.give_trait, "head_visible"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = Player.check_trait("head_visible"), button_shadow = True, ) hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "CHARACTER INITIATED ACTIONS" anchor (0.0, 0.5) pos (0.035, 0.235) text "Allow characters to initiate actions during sex" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.Character_initiated_Actions"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.Character_initiated_Actions, button_shadow = True, ) fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "FOOT CONTENT" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enable foot-themed content during sex" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.disable_foot_content"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = not persistent.disable_foot_content, button_shadow = True, ) hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "ALTERNATE RMB MODE" anchor (0.0, 0.5) pos (0.035, 0.235) text "Toggle between right mouse button opening the save menu and the Player menu" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 if persistent.alternate_rmb: use options_onoff( [Function(config.keymap["game_menu"].append, "mousedown_3"), SetVariable("persistent.alternate_rmb", False), Function(renpy.clear_keymap_cache)], anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.alternate_rmb, button_shadow = True, ) else: use options_onoff( [Function(config.keymap["game_menu"].remove, "mousedown_3"), SetVariable("persistent.alternate_rmb", True), Function(renpy.clear_keymap_cache)], anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.alternate_rmb, button_shadow = True, ) fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "DEFAULT BODY HAIR" anchor (0.0, 0.5) pos (0.035, 0.235) text "Set default body hair for all characters (requires reload or new day)" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.45: font "agency_fb.ttf" size 24 textalign 0.0 use customization_button( SetVariable("persistent.default_body_hair", default_body_hairs[(default_body_hairs.index(persistent.default_body_hair) - 1) % len(default_body_hairs)]), anchor = (0.0, 1.0), pos = (0.5, 0.9), xysize = (int(197 * game_resolution), int(181 * game_resolution)), image = "images/interfaces/[interface_resolution]/customization/left.webp", image_zoom = high_resolution_interface_adjustment, image_shadow = True, ) text "[persistent.default_body_hair!u]" anchor (0.5, 1.0) pos (0.73, 0.74) use customization_button( SetVariable("persistent.default_body_hair", default_body_hairs[(default_body_hairs.index(persistent.default_body_hair) + 1) % len(default_body_hairs)]), anchor = (1.0, 1.0), pos = (0.96, 0.9), xysize = (int(197 * game_resolution), int(181 * game_resolution)), image = "images/interfaces/[interface_resolution]/customization/right.webp", image_zoom = high_resolution_interface_adjustment, image_shadow = True, ) hbox: fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "ENABLE WET HAIR" anchor (0.0, 0.5) pos (0.035, 0.235) text "Allow character's hair to be automatically set to its wet variant when they are wet" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.enable_wet_hair"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.enable_wet_hair, button_shadow = True, ) fixed xysize (int(684 * 2.0 * game_resolution), int(172 * 2.0 * game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "CAP STATS BY SEASON" anchor (0.0, 0.5) pos (0.035, 0.235) text "Impose seasonal caps on Love and Trust in the first chapter a character is introduced" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 textalign 0.0 use options_onoff( ToggleVariable("persistent.stat_caps"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.stat_caps, button_shadow = True, ) # new mod options tab if tab == "mod": hbox: fixed xysize (int(684*2.0*game_resolution), int(172*2.0*game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "TEXT SPEED: [persistent.text_cps]" anchor (0.0, 0.5) pos (0.035, 0.235) bar value VariableValue("persistent.text_cps", 150) anchor (0.5, 0.0) pos (0.492, 0.58) xysize (int(600*2.0*game_resolution), int(20*2.0*game_resolution)): base_bar Frame("images/interfaces/full/options/scrollbar.webp") thumb "images/interfaces/full/options/scrollbar_thumb.webp" thumb_offset int(7*2.0*game_resolution) $ preferences.text_cps = persistent.text_cps fixed xysize (int(684*2.0*game_resolution), int(172*2.0*game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "AUTO-FORWARD TIME: [persistent.afm_time]" anchor (0.0, 0.5) pos (0.035, 0.235) bar value VariableValue("persistent.afm_time", 30) anchor (0.5, 0.0) pos (0.492, 0.58) xysize (int(600*2.0*game_resolution), int(20*2.0*game_resolution)): base_bar Frame("images/interfaces/full/options/scrollbar.webp") thumb "images/interfaces/full/options/scrollbar_thumb.webp" thumb_offset int(7*2.0*game_resolution) $ preferences.afm_time = persistent.afm_time hbox: fixed xysize (int(684*2.0*game_resolution), int(172*2.0*game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "QUICK MENU TRANSPARENCY: [round(persistent.qm_transparency,1)]" anchor (0.0, 0.5) pos (0.035, 0.235) bar value VariableValue("persistent.qm_transparency", 1.0) anchor (0.5, 0.0) pos (0.492, 0.58) xysize (int(600*2.0*game_resolution), int(20*2.0*game_resolution)): base_bar Frame("images/interfaces/full/options/scrollbar.webp") thumb "images/interfaces/full/options/scrollbar_thumb.webp" thumb_offset int(7*2.0*game_resolution) fixed xysize (int(684*2.0*game_resolution), int(172*2.0*game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "DISABLE QUICK MENU BUTTONS" anchor (0.0, 0.5) pos (0.035, 0.235) hbox anchor (0.5, 1.0) pos (0.5, 0.86): spacing 10 for asset in ("back", "skip", "pref", "save", "q.save", "q.load", "auto"): use base_button( ToggleSetMembership(persistent.qm_buttons, asset), xysize = (int(160*game_resolution), int(150*game_resolution)), selected = asset in persistent.qm_buttons, text = asset.upper(), text_size = 24, animated = False) hbox: fixed xysize (int(684*2.0*game_resolution), int(172*2.0*game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "ENABLE XP NUMBERS DISPLAY" anchor (0.0, 0.5) pos (0.035, 0.235) text "Show XP numbers instead of a bar on the Skills screen" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 text_align 0.0 use options_onoff( ToggleVariable("persistent.xp_numbers"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.xp_numbers, button_shadow = True) fixed xysize (int(684*2.0*game_resolution), int(172*2.0*game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "ENABLE BEARDS IN PLAYER PORTRAIT" anchor (0.0, 0.5) pos (0.035, 0.235) text "Select beards in the player customization menu\n(option will be removed if officially supported)" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 text_align 0.0 if Player.check_trait("beards_unlocked"): use options_onoff( Function(Player.remove_trait, "beards_unlocked"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = Player.check_trait("beards_unlocked"), button_shadow = True) else: use options_onoff( Function(Player.give_trait, "beards_unlocked"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = Player.check_trait("beards_unlocked"), button_shadow = True) hbox: fixed xysize (int(684*2.0*game_resolution), int(172*2.0*game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "DISABLE SPINNING X-MEN LOGO" anchor (0.0, 0.5) pos (0.035, 0.235) text "Hide the spinning X-Men logo in the main and option menu" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 text_align 0.0 use options_onoff( ToggleVariable("persistent.spinning_logo"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.spinning_logo, button_shadow = True) fixed xysize (int(684*2.0*game_resolution), int(172*2.0*game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "DISABLE FRIENDSHIP POINTS DISPLAY" anchor (0.0, 0.5) pos (0.035, 0.235) text "Hide the friendship points display on the Friendships screen" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 text_align 0.0 use options_onoff( ToggleVariable("persistent.fps_portraits"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.fps_portraits, button_shadow = True) hbox: fixed xysize (int(684*2.0*game_resolution), int(172*2.0*game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "DISABLE SCREEN SHAKE (REQUIRES RESTART)" anchor (0.0, 0.5) pos (0.035, 0.235) text "Disable screen shake effects" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 text_align 0.0 use options_onoff( ToggleVariable("persistent.screen_shake"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.screen_shake, button_shadow = True) fixed xysize (int(684*2.0*game_resolution), int(172*2.0*game_resolution)): add "images/interfaces/[interface_resolution]/options/box.webp" zoom interface_adjustment text "DISABLE INTERFACE FILTERS" anchor (0.0, 0.5) pos (0.035, 0.235) text "Disable interface filters. Disable Animated Interface under Graphics for only the pulse effect" anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 text_align 0.0 use options_onoff( ToggleVariable("persistent.mod_filters"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.mod_filters, button_shadow = True) # new summoner mod options tab if tab == "summoner": use summoner_TNHUXoptions() vbar value YScrollValue("options_viewport") anchor (0.5, 0.5) pos (0.79, 0.62) xysize (int(20 * 2.0 * game_resolution), 0.6): base_bar Frame("images/interfaces/full/options/scrollbar_vertical.webp") thumb "images/interfaces/full/options/scrollbar_vertical_thumb.webp" thumb_offset int(7 * 2.0 * game_resolution) unscrollable "hide" use navigation # Player_menu.rpy: adds XP numbers display screen skills_screen(): default skills_leaderboard_type = "combat" default skills_ability_type = "daily" default skills_ability = None $ leaderboard_Characters = get_leaderboard(skills_leaderboard_type) add "images/interfaces/[interface_resolution]/Player_menu/skills_leaderboard_background.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/Player_menu/skills_leaderboard_buttons.webp" zoom interface_adjustment for l, leaderboard_type in enumerate(["combat", "cognitive"]): use skills_leaderboard( SetLocalVariable("skills_leaderboard_type", leaderboard_type), pos = (0.056 + l * 0.098, 0.205), xysize = (int(374 * game_resolution), int(123 * game_resolution)), text = leaderboard_type.upper(), selected = skills_leaderboard_type == leaderboard_type) text "Place" anchor (0.5, 0.5) pos (0.072, 0.306): size 26 text "Name" anchor (0.5, 0.5) pos (0.114, 0.306): size 26 text "Points" anchor (0.5, 0.5) pos (0.226, 0.306): size 26 vbox anchor (0.0, 0.0) pos (0.0585, 0.328) xysize (int(729 * game_resolution), 0.557): spacing 2 for c, C in enumerate(leaderboard_Characters): fixed xysize (int(729 * game_resolution), int(79 * game_resolution)): if C == Player: add "images/interfaces/[interface_resolution]/Player_menu/skills_leaderboard_Player.webp" zoom interface_adjustment text "[C.first_name]" anchor (0.0, 0.5) pos (0.22, 0.5): size 28 color "#000000" elif C in GameState.all_Sprites: add "images/interfaces/[interface_resolution]/Player_menu/skills_leaderboard_character.webp" zoom interface_adjustment text "[C.public_name]" anchor (0.0, 0.5) pos (0.22, 0.5): size 28 color "#000000" else: add "images/interfaces/[interface_resolution]/Player_menu/skills_leaderboard_generic.webp" zoom interface_adjustment text "[C.public_name]" anchor (0.0, 0.5) pos (0.22, 0.5): size 28 color "#000000" if c == 0: text "1st" anchor (0.5, 0.5) pos (0.091, 0.602): font "raydis.otf" size 22 color "#000000" elif c == 1: text "2nd" anchor (0.5, 0.5) pos (0.091, 0.602): font "raydis.otf" size 22 color "#000000" elif c == 2: text "3rd" anchor (0.5, 0.5) pos (0.091, 0.602): font "raydis.otf" size 22 color "#000000" $ score = int(C.leaderboard_score[skills_leaderboard_type]) text "[score]" anchor (0.5, 0.5) pos (0.895, 0.5): size 28 color "#000000" text "Leaderboard Resetting In. . ." anchor (0.0, 0.5) pos (0.06, 0.916): size 26 text "[14 - day % 14] Days" anchor (0.5, 0.5) pos (0.227, 0.916): size 26 add "images/interfaces/[interface_resolution]/Player_menu/skills_leaderboard_lines.webp" zoom interface_adjustment add "images/interfaces/[interface_resolution]/Player_menu/skills_abilities_top.webp" zoom interface_adjustment for a, ability_type in enumerate(["daily", "mutant"]): if ability_type == "daily": $ text = "PERKS" elif ability_type == "mutant": $ text = "MUTANT ABILITIES" use skills_abilities( SetLocalVariable("skills_ability_type", ability_type), pos = (0.267 + a * 0.192, 0.205), xysize = (int(737 * game_resolution), int(122 * game_resolution)), text = text, selected = skills_ability_type == ability_type) add "images/interfaces/[interface_resolution]/Player_menu/skills_background_[skills_ability_type].webp" zoom interface_adjustment for ability in all_abilities: if all_abilities[ability]["type"] != skills_ability_type: continue use skills_node( SetLocalVariable("skills_ability", ability), ability, anchor = (0.5, 0.5), pos = all_abilities[ability]["menu_position"], xysize = (int(209 * game_resolution), int(193 * game_resolution)), selected = skills_ability == ability, image_zoom = 0.5 * high_resolution_interface_adjustment, image_shadow = True) add "images/interfaces/[interface_resolution]/Player_menu/skills_status.webp" zoom interface_adjustment use Player_portrait( anchor = (0.5, 0.5), pos = (0.733, 0.382), zoom = game_resolution) for scholarship in Player.scholarships: add "images/interfaces/[interface_resolution]/Player_menu/skills_[scholarship].webp" zoom high_resolution_interface_adjustment if "athletic" in Player.scholarships: text "ATHLETICS" anchor (0.5, 0.5) pos (0.755, 0.584): font "agency_fb.ttf" size 30 elif "academic" in Player.scholarships: text "ACADEMICS" anchor (0.5, 0.5) pos (0.755, 0.584): font "agency_fb.ttf" size 30 elif "artistic" in Player.scholarships: text "ARTS" anchor (0.5, 0.5) pos (0.755, 0.584): font "agency_fb.ttf" size 30 text "LVL" anchor (0.0, 0.5) pos (0.819, 0.239): font "agency_fb.ttf" size 30 text "[Player.level]" anchor (1.0, 0.5) pos (0.87, 0.239): font "agency_fb.ttf" size 30 text "[Player.skill_points]" anchor (0.5, 0.5) pos (0.9, 0.239): font "agency_fb.ttf" size 30 add "images/interfaces/[interface_resolution]/Player_menu/skills.webp" anchor (0.5, 0.5) pos (0.9145, 0.239) zoom 0.3 * interface_adjustment # xp_numbers text "XP" anchor (0.0, 0.545) pos (0.819, 0.285): font "agency_fb.ttf" size 30 if Player.XP >= Player.XP_goal: add "images/interfaces/[interface_resolution]/Player_menu/skills_xp_bar.webp" anchor (1.0, 0.5) pos (0.921, 0.285) zoom interface_adjustment elif Player.level == 1: if not persistent.xp_numbers: bar value Player.XP range Player.XP_goal anchor (1.0, 0.5) pos (0.921, 0.285) xysize (int(277 * game_resolution), int(24 * game_resolution)): left_bar At(f"images/interfaces/{interface_resolution}/Player_menu/skills_xp_bar.webp", interface_zoom) right_bar At(f"images/interfaces/{interface_resolution}/Player_menu/skills_xp_empty_bar.webp", interface_zoom) thumb None thumb_offset 0 else: text "['{:,}'.format(Player.XP)]/['{:,}'.format(Player.XP_goal)]" anchor (1.0, 0.545) pos (0.921, 0.285) size 30 font "agency_fb.ttf" else: if not persistent.xp_numbers: bar value (Player.XP - Player.XP_goal / 1.75) range (Player.XP_goal - Player.XP_goal / 1.75) anchor (1.0, 0.5) pos (0.921, 0.285) xysize (int(277 * game_resolution), int(24 * game_resolution)): left_bar At(f"images/interfaces/{interface_resolution}/Player_menu/skills_xp_bar.webp", interface_zoom) right_bar At(f"images/interfaces/{interface_resolution}/Player_menu/skills_xp_empty_bar.webp", interface_zoom) thumb None thumb_offset 0 else: text "['{:,}'.format(Player.XP)]/['{:,}'.format(Player.XP_goal)]" anchor (1.0, 0.545) pos (0.921, 0.285) size 30 font "agency_fb.ttf" if Player.level == max_level[chapter]: add "images/interfaces/[interface_resolution]/Player_menu/skills_max.webp" anchor (0.5, 0.5) pos (0.886, 0.285) zoom high_resolution_interface_adjustment text "MUTANT RANK" anchor (0.0, 0.5) pos (0.819, 0.332): font "agency_fb.ttf" size 25 text "[Player.mutant_rank!u]" anchor (1.0, 0.5) pos (0.921, 0.332): font "agency_fb.ttf" size 25 text "REPUTATION" anchor (0.5, 0.5) pos (0.871, 0.3875): size 28 text "Grade Point Average" anchor (0.0, 0.5) pos (0.8085, 0.427): font "agency_fb.ttf" size 18 if Player.reputation["academic"] == "n/a": pass elif Player.reputation["academic"] >= 3.999: add "images/interfaces/[interface_resolution]/Player_menu/skills_academic_bar.webp" zoom interface_adjustment anchor (0.0, 0.5) pos (0.8085, 0.462) add "images/interfaces/[interface_resolution]/Player_menu/skills_max.webp" anchor (0.5, 0.5) pos (0.849, 0.462) zoom high_resolution_interface_adjustment else: bar value (Player.reputation["academic"] - math.floor(Player.reputation["academic"])) range 1.0 anchor (0.0, 0.5) pos (0.8085, 0.462) xysize (int(308 * game_resolution), int(26 * game_resolution)): left_bar At(f"images/interfaces/{interface_resolution}/Player_menu/skills_academic_bar.webp", interface_zoom) right_bar At(f"images/interfaces/{interface_resolution}/Player_menu/skills_empty_bar.webp", interface_zoom) thumb None thumb_offset 0 if Player.reputation["academic"] == "n/a": text "N/A" anchor (0.5, 0.5) pos (0.914, 0.463): font "raydis.otf" size 28 color "#27bfff" elif Player.reputation["academic"] >= 3.999: text "4.0" anchor (0.5, 0.5) pos (0.914, 0.463): font "raydis.otf" size 28 color "#27bfff" elif Player.reputation["academic"] >= 3.99: text "3.99" anchor (0.5, 0.5) pos (0.914, 0.463): font "raydis.otf" size 28 color "#27bfff" else: text "[round(Player.reputation['academic'], 2)]" anchor (0.5, 0.5) pos (0.914, 0.463): font "raydis.otf" size 28 color "#27bfff" text "Danger Room Level" anchor (0.0, 0.5) pos (0.8085, 0.497): font "agency_fb.ttf" size 18 if Player.reputation["combat"] >= 10.0: add "images/interfaces/[interface_resolution]/Player_menu/skills_combat_bar.webp" zoom interface_adjustment anchor (0.0, 0.5) pos (0.8085, 0.532) add "images/interfaces/[interface_resolution]/Player_menu/skills_max.webp" anchor (0.5, 0.5) pos (0.849, 0.532) zoom high_resolution_interface_adjustment else: bar value (Player.reputation["combat"] - math.floor(Player.reputation["combat"])) range 1.0 anchor (0.0, 0.5) pos (0.8085, 0.532) xysize (int(308 * game_resolution), int(26 * game_resolution)): left_bar At(f"images/interfaces/{interface_resolution}/Player_menu/skills_combat_bar.webp", interface_zoom) right_bar At(f"images/interfaces/{interface_resolution}/Player_menu/skills_empty_bar.webp", interface_zoom) thumb None thumb_offset 0 text "[math.floor(Player.reputation['combat'])]" anchor (0.5, 0.5) pos (0.914, 0.534): font "raydis.otf" size 28 color "#ed3c3e" text "Popularity Poll" anchor (0.0, 0.5) pos (0.8085, 0.568): font "agency_fb.ttf" size 18 $ number_of_Characters = len(get_leaderboard("social")) if Player.reputation["social"] >= 1.0: add "images/interfaces/[interface_resolution]/Player_menu/skills_social_bar.webp" zoom interface_adjustment anchor (0.0, 0.5) pos (0.8085, 0.602) add "images/interfaces/[interface_resolution]/Player_menu/skills_max.webp" anchor (0.5, 0.5) pos (0.849, 0.602) zoom high_resolution_interface_adjustment else: bar value Player.reputation["social"] range 1/number_of_Characters anchor (0.0, 0.5) pos (0.8085, 0.602) xysize (int(308 * game_resolution), int(26 * game_resolution)): left_bar At(f"images/interfaces/{interface_resolution}/Player_menu/skills_social_bar.webp", interface_zoom) right_bar At(f"images/interfaces/{interface_resolution}/Player_menu/skills_empty_bar.webp", interface_zoom) thumb None thumb_offset 0 text "[math.ceil((1.0 - Player.reputation['social']) * number_of_Characters) + 1]" anchor (0.5, 0.5) pos (0.914, 0.604): font "raydis.otf" size 28 color "#6aea5c" if skills_ability: add "images/interfaces/[interface_resolution]/Player_menu/skills_box.webp" zoom interface_adjustment text "[all_abilities[skills_ability]['name']!u]" anchor (0.0, 0.5) pos (0.679, 0.679): if len(all_abilities[skills_ability]["name"]) > 18: size 22 elif len(all_abilities[skills_ability]["name"]) > 12: size 24 elif len(all_abilities[skills_ability]["name"]) > 8: size 26 else: size 30 frame anchor (0.5, 0.5) pos (0.801, 0.799) xysize (0.245, 0.202): text "[all_abilities[skills_ability]['description']]" xalign 0.5: font "agency_fb.ttf" size 30 textalign 0.5 if not Player.check_trait(skills_ability) and all_abilities[skills_ability]["cost"] and Player.skill_points >= all_abilities[skills_ability]["cost"]: imagebutton anchor (0.5, 0.5) pos (0.825, 0.679): idle At(f"images/interfaces/{interface_resolution}/Player_menu/skills_purchase.webp", interface_zoom) hover At(f"images/interfaces/{interface_resolution}/Player_menu/skills_purchased.webp", interface_zoom) action [ Function(Player.give_trait, skills_ability), Function(Player.History.update, f"bought_skill_{skills_ability_type}"), ] if skills_ability_type == "daily": text "UNLOCK" anchor (0.5, 0.5) pos (0.825, 0.679): font "agency_fb.ttf" size 25 elif skills_ability_type == "mutant": text "AWAKEN" anchor (0.5, 0.5) pos (0.825, 0.679): font "agency_fb.ttf" size 25 elif not Player.check_trait(skills_ability): add "images/interfaces/[interface_resolution]/Player_menu/skills_purchase.webp" anchor (0.5, 0.5) pos (0.825, 0.679) zoom interface_adjustment if skills_ability_type == "daily": text "UNLOCK" anchor (0.5, 0.5) pos (0.825, 0.679): font "agency_fb.ttf" size 25 elif skills_ability_type == "mutant": text "AWAKEN" anchor (0.5, 0.5) pos (0.825, 0.679): font "agency_fb.ttf" size 25 else: add "images/interfaces/[interface_resolution]/Player_menu/skills_purchased.webp" anchor (0.5, 0.5) pos (0.825, 0.679) zoom interface_adjustment text "ACTIVE" anchor (0.5, 0.5) pos (0.825, 0.679): font "agency_fb.ttf" size 25 text "COST" anchor (0.0, 0.5) pos (0.8725, 0.679): font "agency_fb.ttf" size 24 text "[all_abilities[skills_ability]['cost']]" anchor (1.0, 0.5) pos (0.9065, 0.679): font "agency_fb.ttf" size 24 add "images/interfaces/[interface_resolution]/Player_menu/skills.webp" anchor (0.5, 0.5) pos (0.9145, 0.679) zoom 0.25 * interface_adjustment # overlays.rpy: toggle to disable filters screen filter(): layer "filters" $ red_power = Player.get_trait("red_power", default = 0.0) $ enhanced_power = Player.get_trait("enhanced_power", default = 0.0) if not red_power else 0.0 $ power_value = red_power or Player.power $ power_tint = "#912828" if red_power else None if power_value: $ veins_image = "veins_enhanced" if enhanced_power else "veins" $ veins_value = enhanced_power if enhanced_power else power_value fixed xysize (1.0, 1.0): if Player.desire and not persistent.mod_filters: add "images/interfaces/[interface_resolution]/sex/climax_fringe.webp" zoom interface_adjustment: if persistent.animated_interface: at pulse(Player.desire) else: alpha Player.desire if power_value and not persistent.mod_filters: add "images/interfaces/[interface_resolution]/Player_power/power.webp" zoom interface_adjustment: if power_tint: if persistent.animated_interface: at tint(power_tint), pulse(power_value) else: at tint(power_tint) alpha power_value else: if persistent.animated_interface: at pulse(power_value) else: alpha power_value add "images/interfaces/[interface_resolution]/Player_power/[veins_image].webp" zoom interface_adjustment: if power_tint: if persistent.animated_interface: at tint(power_tint), pulse(veins_value) else: at tint(power_tint) alpha veins_value else: if persistent.animated_interface: at pulse(veins_value) else: alpha veins_value at filters_fade_in if persistent.image_filter: add "images/interfaces/[interface_resolution]/filters/[persistent.image_filter].webp" zoom background_adjustment alpha 0.4 # database.rpy: new Quests, Friendships, and Relationships tutorial topics define database_entries_tutorial[_("Quests")] = { 0: { "string": _("Each companion has main quests available that are required to be accomplished to continue to the next season.\n\nBesides the obligatory main objectives, there are also optional ones that offer additional opportunities to learn more about the characters.\nFor additional information about optional objectives, you can hover the cursor above each one to learn more how to achieve them.\n\nIf you earn enough Love and Trust with each character, you can further develop the relationships to them which are listed as side quests.\n\nNote that you may still complete all optional objectives and side quests after you have already completed the main ones before proceeding to the next season.\nUnfinished side quests can be carried over to the next seasons; optional objectives of main quests not."), } } define database_entries_tutorial[_("Friendships")] = { 0: { "string": _("Many activities can be shared with more than one character forming a stronger bond between them.\n\nAsk characters to follow you or text them by phone to come to your location to let them participate in attending class, studying, training, relaxing at the pool, and many other activities together.\n\nFormer acquaintances become good or even best friends the more often they share any activity with you and others together.\n\nNot every character can become Best Friends to everyone else. Such deep connection is reserved only for two companions as a pair.\nSome characters might not even understand the meaning of friendships due to difficulties in their former life, so it is highly encouraged to help those overcoming their social problems."), } } define database_entries_tutorial[_("Relationships")] = { 0: { "string": _("After dating a companion and increasing enough Love and Trust, you are ready to move forward to form a stronger partnership.\nYou can either wait for your companion to make the first step or ask her yourself if she wants to become your girlfriend.\n\nIf you don't feel committed to only a single partner, you could also try to woo several ones, but be aware you need to build a lot more Trust for such polyamorous relationship before they accept it.\nAfter accepting to let you have multiple partners, you also need to ask each girlfriend first who else you want to date. They will only accept others who are at least Friend to them.\n\nThe final step in a relationship is if your companion confesses her love to you.\nThis is also the time you may have sexual intercourse with her."), } } init 10 python: # inventory\camera.rpy: DLSR "camera" name change original_camera = all_Items.get("camera", {}).copy() all_Items["camera"] = {**original_camera, "name": _("DLSR camera")} # mechanics\taking_class.rpy: removes XP-notifications of NPCs def take_class_after(Characters: CharacterClass | Iterable[CharacterClass] | None = None) -> None: if not Characters: Characters = [] elif isinstance(Characters, CharacterClass): Characters = [Characters] store.clock = 0 distribute_friendship(Characters, value = 1) for C in Characters: if C.behavior == "taking_class": C.History.update("attended_class") C.History.update("attended_class_with_Player") elif C.behavior == "teaching": C.History.update("taught_class") C.History.update("taught_class_with_Player") gained_XP = int(20 * C.stat_modifier["XP"]) C.XP += gained_XP if time_index in C.schedule and C.schedule[time_index][1] == C.behavior: del C.schedule[time_index] # update_messages.append(localize("activity_update", Character_color = C.color, name = C.name, XP_color = "#feba00", XP = gained_XP, activity_color = "#feba00", activity = localize("activity_take_class").capitalize())) reset_behavior(C) update_approval(C, "trust", small_stat) reset_behavior(Player) Player.History.update("attended_class") if Player.check_trait("notetaking"): gained_XP = int(1.2 * 20 * Player.stat_modifier["XP"] * Player.max_stamina) else: gained_XP = int(20 * Player.stat_modifier["XP"] * Player.max_stamina) Player.XP += gained_XP update_messages.append(localize("activity_update", Character_color = "#feba00", name = Player.first_name, XP_color = "#feba00", XP = gained_XP, activity_color = "#feba00", activity = localize("activity_take_class").capitalize())) if clock or time_index == 3: fade_in_from_black(0.4) return # core\mechanics\activities\studying.rpy: removes XP-notifications of NPCs def study_after(Characters: CharacterClass | Iterable[CharacterClass] | None = None) -> None: if not Characters: Characters = [] elif isinstance(Characters, CharacterClass): Characters = [Characters] distribute_friendship(Characters, value = 1) for C in Characters: C.History.update("studied") C.History.update("studied_with_Player") gained_XP = int(10 * C.stat_modifier["XP"]) C.XP += gained_XP if time_index in C.schedule and C.schedule[time_index][1] == C.behavior: del C.schedule[time_index] # update_messages.append(localize("activity_update", Character_color = C.color, name = C.name, XP_color = "#feba00", XP = gained_XP, activity_color = "#feba00", activity = localize("activity_study").capitalize())) reset_behavior(C) update_approval(C, "trust", small_stat) reset_behavior(Player) Player.History.update("studied") gained_XP = int(10 * Player.stat_modifier["XP"]) Player.XP += gained_XP update_messages.append(localize("activity_update", Character_color = "#feba00", name = Player.first_name, XP_color = "#feba00", XP = gained_XP, activity_color = "#feba00", activity = localize("activity_study").capitalize())) return # core\mechanics\activities\training.rpy: removes XP-notifications of NPCs def train_after(Characters: CharacterClass | Iterable[CharacterClass] | None = None) -> None: if not Characters: Characters = [] elif isinstance(Characters, CharacterClass): Characters = [Characters] distribute_friendship(Characters, value = 1) for C in Characters: C.History.update("trained") C.History.update("trained_with_Player") C.sweat += 0.5 gained_XP = int(10 * C.stat_modifier["XP"]) C.XP += gained_XP if time_index in C.schedule and C.schedule[time_index][1] == C.behavior: del C.schedule[time_index] schedule_shower(C) # update_messages.append(localize("activity_update", Character_color = C.color, name = C.name, XP_color = "#feba00", XP = gained_XP, activity_color = "#feba00", activity = localize("activity_train").capitalize())) reset_behavior(C) update_approval(C, "trust", small_stat) reset_behavior(Player) Player.History.update("trained") Player.sweat += 1 gained_XP = int(10 * Player.stat_modifier["XP"]) Player.XP += gained_XP update_messages.append(localize("activity_update", Character_color = "#feba00", name = Player.first_name, XP_color = "#feba00", XP = gained_XP, activity_color = "#feba00", activity = localize("activity_train").capitalize())) return # progression.rpy: removes level-notifications of NPCs def level_up() -> None: for C in GameState.all_Companions | {Player}: while C.level < max_level[chapter - 1] and C.XP >= C.XP_goal: C.level += 1 # update_messages.append(localize("updates_level_up", Character_color = C.color, name = C.name, level_color = "#feba00", level = C.level)) if C.level >= max_level[chapter - 1]: C.XP = C.XP_goal return # text replacements def replace_text(t): t = t.replace("Bathe ", "Shower ") t = t.replace("Paizuri", "Titjob") t = t.replace("Dlsr", "DLSR") t = t.replace("Mma", "MMA") t = t.replace("veiner", "wiener") t = t.replace("Remain celibate", "Remain a virgin") t = t.replace("$1000", "$1,000") t = t.replace("$5000", "$5,000") t = t.replace("$10k", "$10,000") t = t.replace("$50k", "$50,000") t = t.replace("3 or", "three or") return t config.replace_text = replace_text