# Summoner (stable but unofficial and unsupported mod done by pepplez and freddygonzo @ F95zone) # Mod Version 1.0 Current Game Version 0.8c default persistent.pepplez_sum = True # Enable Summoner default persistent.summon_critical_chars = False # Summon critical/unsafe characters default SummonerMod_version = "1.0" default persistent.pep_alpha = 0.5 default persistent.pep_button_size = 24 default persistent.pep_auto_close = True default persistent.pep_TNHUXMod = False default persistent.pep_stand_alone = True default pep_menu_open = False default pep_critical_chars = [] default pep_onhold_chars = [] init 9 python: config.console = True config.developer = False # remove old overlay screen and add a new one (changed the layer to "interface") if "pep_summon_screen" in config.overlay_screens: config.overlay_screens.remove("pep_summon_screen") config.overlay_screens.append("pep_summon_screen") # log message print ("Summoner-Notice: Mod V1.0 by pepplez and freddygonzo @ F95zone loaded.") # strip surnames def pep_forename(name): match = re.match(r'^([A-Z][a-z]+)([A-Z].*)?$', name) return match.group(1) if match else name # options call (if stand alone version) def pep_sum_options(): renpy.call_in_new_context("pep_summoner_options") return # freddygonzo's TNHUXMod installed? https://f95zone.to/threads/262923 def TNHUX_check(): persistent.pep_TNHUXMod = False import glob, os pep_modcheck = glob.glob(os.path.join(config.gamedir, "*TNHUXMod*.rpyc")) if pep_modcheck: persistent.pep_TNHUXMod = True print ("Summoner-Notice: freddygonzo's TNHUXMod detected.") # debug return # run mod check once TNHUX_check() # summon character def pepple_magic(pep_char): global pep_critical_chars, pep_onhold_chars # Char summonable? try: _ = pep_char.location except Exception as err: err_msg = ( f"{{color=#feba00}}Summoner-Error:{{/color}}\n" f"{{color=#fd7c8d}}Can't summon {pep_char} :-({{/color}}") if config.developer: err_msg += f"\nError: {str(err)}" update_messages.append(err_msg) print("Summoner-Error:",pep_char, err, sep=" ") else: pep_critical_found = False for n in pep_critical_chars: z = eval(n) if z is pep_char or pep_char.location == "hold": pep_critical_found = True if pep_char.tag not in pep_onhold_chars: pep_onhold_chars.append(pep_char.tag) sum_msg = "{color=#feba00}Summoner-Warning:{/color}\nIf you're not a modder or developer:\nDo NOT SAVE your game anymore!" update_messages.append(sum_msg) # put char where? if pep_char.location == Player.location: if pep_char.tag in pep_onhold_chars: pep_onhold_chars.remove(pep_char.tag) pep_critical_found = True if not pep_critical_found: pep_char.location = pep_char.home summoner_send_location = "bg_"+str(pep_char.tag) elif pep_critical_found: pep_char.location = "hold" sum_notice = ( f"{{color=#feba00}}Summoner-Notice:{{/color}}\n" f"{{color=#fd7c8d}}Critical Char {pep_char.tag}{{/color}}" f"\nHas put {{color=#feba00}}on 'hold'{{/color}}") print ("Summoner-Notice: Critical Char", pep_char.tag, "has put on 'hold'") if config.developer: update_messages.append(sum_notice) summoner_send_location = "hold" else: summoner_send_location = str(Player.location) if not pep_critical_found: pep_char.location = Player.location elif persistent.summon_critical_chars and pep_critical_found: pep_char.location = Player.location sum_notice = ( f"{{color=#feba00}}Summoner-Notice:{{/color}}\n" f"{{color=#fd7c8d}}Critical Char {pep_char.tag}{{/color}}" f"\nSummoned to: {{color=#feba00}}{Player.location}{{/color}}") print ("Summoner-Notice: Critical Char", pep_char.tag, "summoned to:", Player.location) if config.developer: update_messages.append(sum_notice) send_Characters(pep_char, summoner_send_location, behavior = False) return screen pep_summon_screen(): # set critical chars list here (for future game updates) timer .1 repeat False action SetVariable("pep_critical_chars", ["AmahlFarouk","OroroMunroe"]), if persistent.pep_auto_close: # close Summoner menu if location changed default pep_player_location = None if pep_player_location != Player.location: instant action SetVariable("pep_menu_open" , False) $ pep_player_location = Player.location layer "interface" if persistent.pepplez_sum and sandbox and not ( black_screen[0] or belt_collapsed or ongoing_Event or ongoing_Scene or renpy.get_screen("phone_screen") or renpy.get_screen("interactions_screen") or renpy.get_screen("sex_screen") or renpy.get_screen("master_screen") is None or renpy.get_screen("_console") ): vbox: spacing 1 if Party: anchor (1.0, 0.0) pos (0.727, 0.012) else: anchor (1.0, 0.0) pos (0.759, 0.012) if pep_menu_open: hbox: spacing 1 align (1.0, 1.0) for z in sorted(ch1_Companions): $ y = eval(z) if z in sorted(pep_critical_chars) or y.location == "hold" or z in pep_onhold_chars: $ z_text ="{color=#fd7c8d}"+pep_forename(str(z))+"{/color}" else: $ z_text = pep_forename(z) if z in sorted(pep_critical_chars) or y.location =="hold" and not persistent.summon_critical_chars: continue use base_button( Function (pepple_magic, pep_char = y), button_alpha = persistent.pep_alpha, padding = (8, 4, 8, 6), text = z_text, text_size = persistent.pep_button_size) use base_button( ToggleVariable("pep_menu_open"), button_alpha = persistent.pep_alpha, padding = (15, 2, 15, 8), text = "x", text_size = persistent.pep_button_size) hbox: align (1.0, 1.0) for z in sorted(all_Sprites): if z not in sorted(ch1_Companions): $ y = eval(z) if z in sorted(pep_critical_chars) or z in pep_onhold_chars: $ z_text ="{color=#fd7c8d}"+pep_forename(str(z))+"{/color}" else: $ z_text = pep_forename(z) if z in sorted(pep_critical_chars) and not persistent.summon_critical_chars: continue use base_button( Function (pepple_magic, pep_char = y), button_alpha = persistent.pep_alpha, padding = (8, 4, 8, 6), button_shadow = True, text = z_text, text_size = persistent.pep_button_size) # Options enabled? if not persistent.pep_TNHUXMod or persistent.pep_stand_alone: hbox: align (1.0, 1.0) use base_button( Function (pep_sum_options), button_alpha = persistent.pep_alpha, padding = (15, 2, 15, 8), text = "[...]", text_size = persistent.pep_button_size,) else: use base_button( ToggleVariable("pep_menu_open"), button_alpha = persistent.pep_alpha, padding = (8, 4, 8, 6), button_shadow = True, text = "Summon", text_size = persistent.pep_button_size) # Summoner Options (if stand alone version) screen summoner_options(): tag menu layer "screens" modal True style_prefix "game_menu" use menu_background(spinning = True) default tab = "summoner" default tab_label = "MOD OPTIONS" if persistent.animated_interface: timer 1.0 action ToggleVariable("interface_blinking") repeat True modal 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 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) hbox: align(0.09, 0.4) 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 UNRESTRICTED SUMMONING" anchor (0.0, 0.5) pos (0.035, 0.235) text "WARNING: enables summoning red-marked characters that can cause crashes! (NOT RECOMMENDED)" 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.summon_critical_chars"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.summon_critical_chars, button_shadow = True) # Auto close Summoner Menu hbox: align(0.68, 0.4) 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 MENU AUTO CLOSE" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enables Auto-Close Summoner menu by location change." 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.pep_auto_close"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.pep_auto_close, button_shadow = True) # Enable stand-alone menu even with TNHUXMod loaded if persistent.pep_TNHUXMod: hbox: align(0.68, 0.6) 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 STAND ALONE MENU" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enables this options menu even if the TNHUXMod is loaded." 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.pep_stand_alone"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.pep_stand_alone, button_shadow = True) else: hbox: align(0.68, 0.6) 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 "TNHUXMod not found" anchor (0.0, 0.5) pos (0.035, 0.235) text "You may want to get it from {a=https://f95zone.to/threads/262923}F95zone{/a}." anchor (0.0, 0.0) pos (0.035, 0.45) xsize 0.68: font "agency_fb.ttf" size 24 text_align 0.0 # Developer mode hbox: align(0.68, 0.8) 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 DEVELOPER MODE" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enables Ren'Py Developer-Menu. Keys: Shift+D" 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("config.developer"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = config.developer, button_shadow = True) # button background alpha slider hbox: align(0.09, 0.6) 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 $ pep_a = round(persistent.pep_alpha, 1) text "BUTTON BACKGROUND ALPHA: [pep_a]/1.0" anchor (0.0, 0.5) pos (0.035, 0.235) bar value FieldValue(persistent,"pep_alpha", 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)): 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) # button text size slider hbox: align(0.09, 0.8) 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 "BUTTON TEXT SIZE: [persistent.pep_button_size]/50" anchor (0.0, 0.5) pos (0.035, 0.235) bar value FieldValue(persistent,"pep_button_size", offset=20, range =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) use options_section( [SetScreenVariable("tab", "summoner"), SetScreenVariable("tab_label", "MOD OPTIONS")], pos = (0.208, 0.204), xysize = (int(372 * game_resolution), int(124 * game_resolution)), text = "Summoner", selected = tab == "summoner") 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") # TNHUXoptions screen summoner_TNHUXoptions(): 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 SUMMONER" anchor (0.0, 0.5) pos (0.035, 0.235) text "Show the Summoner's interface" 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.pepplez_sum"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.pepplez_sum, 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 UNRESTRICTED SUMMONING" anchor (0.0, 0.5) pos (0.035, 0.235) text "WARNING: enables summoning red-marked characters that can cause crashes! (NOT RECOMMENDED)" 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.summon_critical_chars"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.summon_critical_chars, button_shadow = True) # Auto close Summoner Menu hbox: align(0.0, 0.6) 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 MENU AUTO CLOSE" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enables Auto-Close Summoner menu by location change." 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.pep_auto_close"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.pep_auto_close, button_shadow = True) # Enable stand-alone menu hbox: align(0.0, 0.6) 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 STAND ALONE MENU" anchor (0.0, 0.5) pos (0.035, 0.235) text "Enables the Summoner options menu button.." 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.pep_stand_alone"), anchor = (1.0, 1.0), pos = (0.95, 0.86), selected = persistent.pep_stand_alone, button_shadow = True) # button background alpha slider hbox: xalign 1.0 yoffset - 345 # move box 345 pixel up cause it was shown elswehere, wtf? 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 $ pep_a = round(persistent.pep_alpha, 1) text "BUTTON BACKGROUND ALPHA: [pep_a]/1.0" anchor (0.0, 0.5) pos (0.035, 0.235) bar value FieldValue(persistent,"pep_alpha", 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)): 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) # button text size slider hbox: xalign 1.0 yoffset - 345 # move box pixel up (yeah, here we go again, lmao) 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 "BUTTON TEXT SIZE: [persistent.pep_button_size]/50" anchor (0.0, 0.5) pos (0.035, 0.235) bar value FieldValue(persistent,"pep_button_size", offset=20, range =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) # label for stand alone version label pep_summoner_options: call screen summoner_options return