# # Narration screens # init offset = -1 screen nvl(dialogue, items=None): null define config.check_conflicting_properties = True # Say screen # # The say screen is used to display dialogue to the player. It takes two # parameters, who and what, which are the name of the speaking character and # the text to be displayed, respectively. (The who parameter can be None if no # name is given.) # # This screen must create a text displayable with id "what", as Ren'Py uses # this to manage text display. It can also create displayables with id "who" # and id "window" to apply style properties. # # https://www.renpy.org/doc/html/screen_special.html#say init python: import re def text_inner_thought(string, pattern=re.compile(r"\(([^)]+)\)")): return re.findall(pattern, string) screen say(who, what, side_image=None, icon=None): zorder 31 if _windows_hidden: use invisible_button(action=SetVariable("_windows_hidden", False)) else: if not renpy.get_screen("choice"): use invisible_button(action=Function(ui.saybehavior), keysym="dismiss") # TODO: While this works, there might be a better way to add effects based on contents of the dialogue. if text_inner_thought(what) and not renpy.showing("cg"): add "fade_gradient" if side_image: add side_image yalign 1.0 zoom 0.5 else: add SideImage() window id "window": style gui.theme("say_window") if _windows_hidden: ypos 1000 if _game_menu_screen: use quick_menu if who: window: id "namebox" style gui.theme("namebox") text who: style gui.theme("say_label") text what: id "what" style gui.theme("say_dialogue") if renpy.android: button: style "empty" xysize (235, 100) align (0.0, 1.0) action Rollback() insensitive_child Transform(gui.format("interface/frames/{}/arrow.webp"), xalign=1.0, alpha=0.5) add Transform(gui.format("interface/frames/{}/arrow.webp"), xalign=1.0) button: style "empty" xysize (235, 100) align (1.0, 1.0) action Skip(fast=True, confirm=True) add Transform(gui.format("interface/frames/{}/arrow.webp"), xzoom=-1.0) # Quick menu screen # # The quick menu is displayed in-game to provide easy access to the out-of-game menus. screen quick_menu(): hbox: style_prefix "quick" xalign 1.0 yoffset -30 textbutton _("Q.Save") action QuickSave() textbutton _("Q.Load") action QuickLoad() textbutton _("Skip") action Skip() textbutton _("Auto") action Preference("auto-forward", "toggle") textbutton _("Preferences") action ShowMenu("preferences") style quick_button is default: activate_sound "sounds/click3.ogg" background None xpadding 8 ypadding 8 style quick_button_text is default: size 10 idle_color "#8888" hover_color "#ccc" selected_idle_color "#cc08" selected_hover_color "#cc0" insensitive_color "#4448" # Choice screen # # This screen is used to display the in-game choices presented by the menu # statement. The one parameter, items, is a list of objects, each with caption # and action fields. # # https://www.renpy.org/doc/html/screen_special.html#choice define blacklist_screens = {"say", "letter", "bld1"} define choice_width = int(config.screen_width/2) screen choice(items, menu_yalign=.6): tag menu modal True zorder 30 style_prefix gui.theme("menu") default blacklist_tags = set(get_character_tag(x) for x in states.dolls) # Dont add the fade if character or saybox is present (They have their own triggers for fading) if not any(renpy.get_screen(x) for x in blacklist_screens) and not any(renpy.showing(x, layer="screens") for x in blacklist_tags): add "interface/bld.webp" at fade_hide(0.15) window at fade_show_hide(0.15): style "empty" xalign .5 yalign menu_yalign vbox: spacing 0 default max_progress = max(len(e.kwargs.get("progress", [])) for e in items) for i, entry in enumerate(items, 1): $ style_part = entry.kwargs.get("style", None) button: xsize choice_width ypadding 5 action entry.action sensitive bool(entry.action) if i < 10 and entry.action: keysym ("K_"+str(i), "K_KP"+str(i)) fixed: style "empty" if style_part: style_prefix gui.theme("{}_menu".format(style_part)) fit_first "height" text entry.caption: xsize choice_width-120 # Leave enough margin for number and icon align (0.5, 0.5) if i < 10 and entry.action: text "{size=-2}[i].{/size}" xpos 5 yalign 0.5 $ icon = entry.kwargs.get("icon", None) if icon: add icon xcenter 40 yalign 0.5 $ progress = entry.kwargs.get("progress", None) if progress: hbox: spacing 2 xpos choice_width - 5 xanchor 1. yalign .5 for i in range(max_progress): if i < len(progress): add progress[i] else: null width 21 # Assume icon width style menu_text is default: hover_color "#fff" text_align 0.5 outlines [(1, "#00000080", 1, 0)] style dark_menu_text: color "#9b8d84" insensitive_color "#6c625c" style light_menu_text: color "#f9d592" insensitive_color "#ae9566" style dark_disabled_menu_text: color "#6c625c" style light_disabled_menu_text: color "#ae9566" style menu_button is default: activate_sound "sounds/click3.ogg" style dark_menu_button: background "#5d5151e6" hover_background "#897e75" insensitive_background "#9e8449" style light_menu_button: background "#ac8d5ae6" hover_background "#97681f" insensitive_background "#d1a02eb3" # Input screen # # This screen is used to display renpy.input. The prompt parameter is used to # pass a text prompt in. # # This screen must create an input displayable with id "input" to accept the # various input parameters. # # https://www.renpy.org/doc/html/screen_special.html#input screen input(prompt): zorder 30 style_prefix "say" window: id "window" style gui.theme("say_window") if prompt: window: style gui.theme("namebox") text prompt: style gui.theme("say_label") input id "input": style gui.theme("say_dialogue")