From 9d76d6088faacbc3b95f3dd02f8340df2343260b Mon Sep 17 00:00:00 2001 From: LoafyLemon Date: Mon, 22 Apr 2024 18:11:01 +0100 Subject: [PATCH] Engine, Wheel menu, intro, bug fixes * Added IfExpr Action. * Added string evals for If func. * Added reset_action method for RoomObject class. * Added new actions appropriate for room relevant objects. * Fixed a potential issue with reset_variables method within Events class. * Fixed single button radius calculation in wheel menu * Fixed crash if a null list of actions was supplied to create_wheelmenu method. * Converted intro to use wheel menu actions. * Split existing room object labels where it made sense. --- game/scripts/events/Start.rpy | 11 ++ game/scripts/events/queue.rpy | 4 +- game/scripts/gui/_styles_.rpy | 2 +- game/scripts/interface/wheelmenu.rpy | 8 +- game/scripts/rooms/init.rpy | 19 +++ game/scripts/rooms/main_room/init.rpy | 18 +-- .../rooms/main_room/objects/cupboard.rpy | 40 +++--- game/scripts/rooms/main_room/objects/desk.rpy | 32 +++++ game/scripts/rooms/main_room/objects/door.rpy | 127 +++++++++--------- .../rooms/main_room/objects/fireplace.rpy | 32 +++-- .../rooms/main_room/objects/phoenix.rpy | 30 ++--- game/scripts/utility/common_functions.rpy | 4 +- game/scripts/utility/engine.rpy | 17 +++ 13 files changed, 211 insertions(+), 133 deletions(-) diff --git a/game/scripts/events/Start.rpy b/game/scripts/events/Start.rpy index 987c758e..d446b748 100644 --- a/game/scripts/events/Start.rpy +++ b/game/scripts/events/Start.rpy @@ -125,10 +125,15 @@ label genie_intro_E1: # Highlight important objects python: fireplace_OBJ.idle = At("fireplace_idle_shadow", pulse_hover) + fireplace_OBJ.action = {"Examine": (Text("🔍", align=(0.5, 0.5)), Jump("examine_fireplace"), "True")} cupboard_OBJ.idle = At("cupboard_idle", pulse_hover) + cupboard_OBJ.action = {"Examine": (Text("🔍", align=(0.5, 0.5)), Jump("examine_cupboard"), "True")} phoenix_OBJ.idle = At("phoenix_idle", pulse_hover) + phoenix_OBJ.action = {"Examine": (Text("🔍", align=(0.5, 0.5)), Jump("examine_phoenix"), "True")} door_OBJ.idle = At("door_idle", pulse_hover) + door_OBJ.action = {"Examine": (Text("🔍", align=(0.5, 0.5)), Jump("examine_door"), "True")} desk_OBJ.idle = At("ch_gen sit_behind_desk", pulse_hover) + desk_OBJ.action = {"Examine": (Text("🔍", align=(0.5, 0.5)), Jump("examine_desk"), "True")} achievements.unlock("start") states.gen.ev.intro.e1_complete = True @@ -141,6 +146,12 @@ label genie_intro_E2: gen "Did I just spend an entire day examining this room?" ("base", xpos="far_left", ypos="head") call bld("hide") + $ fireplace_OBJ.reset_action() + $ cupboard_OBJ.reset_action() + $ phoenix_OBJ.reset_action() + $ door_OBJ.reset_action() + $ desk_OBJ.reset_action() + $ states.gen.ev.intro.e2_complete = True # Next is Snape intro E1 diff --git a/game/scripts/events/queue.rpy b/game/scripts/events/queue.rpy index cffe1ce3..3c2a6929 100644 --- a/game/scripts/events/queue.rpy +++ b/game/scripts/events/queue.rpy @@ -339,7 +339,9 @@ init -1 python: return # We need to add these after defaults are finished. - renpy.config.label_callbacks.append(execute_event_callbacks) + # Explicitly check callback existence to avoid duplication in case a default var is reset. + if not execute_event_callbacks in renpy.config.label_callbacks: + renpy.config.label_callbacks.append(execute_event_callbacks) def show_events_menu(queues, filter=False, report_progress=True, **kwargs): # This function is a stop gap until we update interfaces. Because it's not tied to any internals, diff --git a/game/scripts/gui/_styles_.rpy b/game/scripts/gui/_styles_.rpy index 85eab8e9..c415b372 100644 --- a/game/scripts/gui/_styles_.rpy +++ b/game/scripts/gui/_styles_.rpy @@ -120,7 +120,7 @@ style imagemap: activate_sound "sounds/qubodup-click2.ogg" style button: - activate_sound "sounds/qubodup-click1.ogg" + activate_sound "sounds/qubodup-click2.ogg" hover_sound "sounds/qubodup-hover1.ogg" insensitive_background "#463b3be6" selected_background "#766a6ae6" diff --git a/game/scripts/interface/wheelmenu.rpy b/game/scripts/interface/wheelmenu.rpy index 0bc26ad9..fa63d0dc 100644 --- a/game/scripts/interface/wheelmenu.rpy +++ b/game/scripts/interface/wheelmenu.rpy @@ -2,6 +2,7 @@ init python in wheelmenu: import math def pos(num_buttons): + num_buttons = max(num_buttons, 2) reference_num_buttons = 32 reference_radius = 0.5 radius = reference_radius * (num_buttons / reference_num_buttons) ** 0.5 @@ -30,6 +31,8 @@ init python in wheelmenu: if condition: return renpy.store.Button(displayable, action=action, style="wheelmenu_button", **kwargs) + elif action is None: + return renpy.store.Button(displayable, action=action, style="wheelmenu_disabled_button", **kwargs) else: return None @@ -46,8 +49,10 @@ init python: buttons.append(wheelmenu.button(displayable, action, condition, tooltip=name)) - positions = wheelmenu.pos(len(buttons)) + if not buttons: + return None + positions = wheelmenu.pos(len(buttons)) return tuple(zip(buttons, positions)) # Nonhashable types cannot be used in a screen, so we use a tuple instead. config.per_frame_screens.append("wheelmenu") @@ -97,6 +102,7 @@ style wheelmenu_button is empty: style wheelmenu_disabled_button is wheelmenu_button: background "#ffffff80" + foreground "#ff00ff" xysize (48, 48) anchor (0.5, 0.5) diff --git a/game/scripts/rooms/init.rpy b/game/scripts/rooms/init.rpy index e7b8eab2..c55d6359 100644 --- a/game/scripts/rooms/init.rpy +++ b/game/scripts/rooms/init.rpy @@ -40,6 +40,11 @@ init -1 python: # Backwards compatibility, to be resolved if possible. self.xpos, self.ypos = self.pos + if isinstance(self.action, dict): + self._default_action = self.action.copy() + else: + self._default_action = self.action + def generate_hash(self): salt = str( [self.id, self.pos, self.idle, self.hover, self.foreground, self.background, self.anchor, self.focus_mask, self.action, self.hovered, self.unhovered, self.tooltip, self.decoration, self.zorder, self.hidden] @@ -105,10 +110,24 @@ init -1 python: raise IndexError(f"Action dict was provided for '{self.id}' but it is empty.") btns = create_wheelmenu(action) + + if not btns: + return None + return Call("wheelmenu", btns=btns, ret=self.room.menu) return action + def reset_action(self): + if isinstance(self._default_action, dict): + self.action = self._default_action.copy() + elif isinstance(self._default_action, set): + self.action = set(self._default_action) + elif isinstance(self._default_action, list): + self.action = self._default_action[:] + else: + self.action = self._default_action + def get_anchor(self): deco = self.decoration diff --git a/game/scripts/rooms/main_room/init.rpy b/game/scripts/rooms/main_room/init.rpy index 73bae1e5..8bb9d305 100644 --- a/game/scripts/rooms/main_room/init.rpy +++ b/game/scripts/rooms/main_room/init.rpy @@ -32,14 +32,14 @@ default door_OBJ = RoomObject( idle="door_idle", focus_mask="door_hover", action={ - "Summon Snape": (Transform("wheelmenu_snape", align=(0.5, 0.5), xysize=(32, 32)), If(states.sna.busy, None, Jump("summon_snape")), "states.sna.unlocked"), - "Summon Tonks": (Transform("wheelmenu_tonks", align=(0.5, 0.5), xysize=(32, 32)), If(states.ton.busy, None, Jump("summon_tonks")), "states.ton.unlocked"), - "Summon Hermione": (Transform("wheelmenu_hermione", align=(0.5, 0.5), xysize=(32, 32)), If(states.her.busy, None, Jump("summon_hermione")), "states.her.unlocked"), - "Summon Cho": (Transform("wheelmenu_cho", align=(0.5, 0.5), xysize=(32, 32)), If(states.cho.busy, None, Jump("summon_cho")), "states.cho.unlocked"), - "Summon Luna": (Transform("wheelmenu_luna", align=(0.5, 0.5), xysize=(32, 32)), If(states.lun.busy, None, Jump("summon_luna")), "states.lun.unlocked"), - "Summon Astoria": (Transform("wheelmenu_astoria", align=(0.5, 0.5), xysize=(32, 32)), If(states.ast.busy, None, Jump("summon_astoria")), "states.ast.unlocked"), - "Summon Susan": (Transform("wheelmenu_susan", align=(0.5, 0.5), xysize=(32, 32)), If(states.sus.busy, None, Jump("summon_susan")), "states.sus.unlocked"), - "Exit": (Text("🚪", align=(0.5, 0.5)), Jump("desk"), "states.map.unlocked"), + "Summon Snape": (Transform("wheelmenu_snape", align=(0.5, 0.5), xysize=(32, 32)), IfExpr("states.sna.busy", None, Jump("summon_snape")), "states.sna.unlocked"), + "Summon Tonks": (Transform("wheelmenu_tonks", align=(0.5, 0.5), xysize=(32, 32)), IfExpr("states.ton.busy", None, Jump("summon_tonks")), "states.ton.unlocked"), + "Summon Hermione": (Transform("wheelmenu_hermione", align=(0.5, 0.5), xysize=(32, 32)), IfExpr("states.her.busy", None, Jump("summon_hermione")), "states.her.unlocked"), + "Summon Cho": (Transform("wheelmenu_cho", align=(0.5, 0.5), xysize=(32, 32)), IfExpr("states.cho.busy", None, Jump("summon_cho")), "states.cho.unlocked"), + "Summon Luna": (Transform("wheelmenu_luna", align=(0.5, 0.5), xysize=(32, 32)), IfExpr("states.lun.busy", None, Jump("summon_luna")), "states.lun.unlocked"), + "Summon Astoria": (Transform("wheelmenu_astoria", align=(0.5, 0.5), xysize=(32, 32)), IfExpr("states.ast.busy", None, Jump("summon_astoria")), "states.ast.unlocked"), + "Summon Susan": (Transform("wheelmenu_susan", align=(0.5, 0.5), xysize=(32, 32)), IfExpr("states.sus.busy", None, Jump("summon_susan")), "states.sus.unlocked"), + "Exit": (Text("🚪", align=(0.5, 0.5)), IfExpr("states.map.unlocked", Jump("desk"), Jump("door")), "True"), }, tooltip="Door" ) @@ -52,7 +52,7 @@ default desk_OBJ = RoomObject( hover="ch_gen sit_behind_desk_hover", focus_mask="ch_gen sit_behind_desk", action={ - "Sleep": (Text("💤", align=(0.5, 0.5)), If(game.daytime, Return("night_start"), Return("day_start")), "True"), + "Sleep": (Text("💤", align=(0.5, 0.5)), IfExpr("game.daytime", Jump("night_start"), Jump("day_start")), "True"), "Jerk Off": (Text("🍆", align=(0.5, 0.5)), Jump("jerk_off"), "True"), "Do Paperwork": (Text("📝", align=(0.5, 0.5)), Jump("paperwork"), "True"), "Open Deck Builder": (Text("🃏", align=(0.5, 0.5)), Jump("deck_builder"), "states.cardgame.unlocked"), diff --git a/game/scripts/rooms/main_room/objects/cupboard.rpy b/game/scripts/rooms/main_room/objects/cupboard.rpy index c7a65c5d..c265d9b0 100644 --- a/game/scripts/rooms/main_room/objects/cupboard.rpy +++ b/game/scripts/rooms/main_room/objects/cupboard.rpy @@ -1,26 +1,5 @@ label cupboard: - if game.day == 1: - if not states.gen.ev.intro.cupboard_examined: - $ states.gen.ev.intro.cupboard_examined = True - $ cupboard_OBJ.idle = "cupboard_idle" - call gen_chibi("stand","behind_desk","base", flip=False) - with d5 - pause.2 - - call bld - gen "*Hmm*..." ("base", xpos="far_left", ypos="head") - gen "A cupboard..." ("base", xpos="far_left", ypos="head") - gen "Maybe I should rummage through this one later..." ("base", xpos="far_left", ypos="head") - call gen_chibi("sit_behind_desk") - else: - gen "Looks like any other cupboard, maybe a bit dustier." ("base", xpos="far_left", ypos="head") - - if states.gen.ev.intro.bird_examined and states.gen.ev.intro.desk_examined and states.gen.ev.intro.cupboard_examined and states.gen.ev.intro.door_examined and states.gen.ev.intro.fireplace_examined: - jump genie_intro_E2 - else: - jump main_room_menu - if states.cupboard_rummaged: if game.daytime: nar "You have already searched the cupboard today." @@ -77,6 +56,25 @@ label cupboard: call gen_chibi("sit_behind_desk") jump main_room_menu +label examine_cupboard: + if not states.gen.ev.intro.cupboard_examined: + $ states.gen.ev.intro.cupboard_examined = True + $ cupboard_OBJ.idle = "cupboard_idle" + $ cupboard_OBJ.action = Jump("examine_cupboard") + call gen_chibi("stand","behind_desk","base", flip=False) + with d5 + pause.2 + + call bld + gen "*Hmm*..." ("base", xpos="far_left", ypos="head") + gen "A cupboard..." ("base", xpos="far_left", ypos="head") + gen "Maybe I should rummage through this one later..." ("base", xpos="far_left", ypos="head") + call gen_chibi("sit_behind_desk") + else: + gen "Looks like any other cupboard, maybe a bit dustier." ("base", xpos="far_left", ypos="head") + + jump main_room_menu + label rum_block(item): if isinstance(item, int): $ game.gold += item diff --git a/game/scripts/rooms/main_room/objects/desk.rpy b/game/scripts/rooms/main_room/objects/desk.rpy index fdcce574..d02a3773 100644 --- a/game/scripts/rooms/main_room/objects/desk.rpy +++ b/game/scripts/rooms/main_room/objects/desk.rpy @@ -265,6 +265,38 @@ screen watch(): else: add "interface/desk/watch/night.webp" xpos watch_x+40 ypos watch_y+6 xanchor 0.5 +label examine_desk: + if not states.gen.ev.intro.desk_examined: + $ states.gen.ev.intro.desk_examined = True + $ desk_OBJ.idle = "ch_gen sit_behind_desk" + $ desk_OBJ.action = Jump("examine_desk") + call bld + gen "A desk of some sort..." ("base", xpos="far_left", ypos="head") + gen "And a letter..." ("base", xpos="far_left", ypos="head") + gen "Mailed to a certain \"Albus Dumbledore\"." ("base", xpos="far_left", ypos="head") + + menu: + gen "Should I open it?" ("base", xpos="far_left", ypos="head") + "-Read the letter-": + call bld + gen "Of course I will!" ("grin", xpos="far_left", ypos="head") + "-Leave it be-": + call bld + gen "Hell no!" ("angry", xpos="far_left", ypos="head") + gen "Of course I will read it!" ("grin", xpos="far_left", ypos="head") + + # First letter from Hermione + $ desk_OBJ.foreground = None + $ letter_hg_1.open() + + gen "*Ehm*........." ("base", xpos="far_left", ypos="head") + gen "What?" ("base", xpos="far_left", ypos="head") + gen "................................." ("base", xpos="far_left", ypos="head") + else: + gen "I've already checked the desk." ("base", xpos="far_left", ypos="head") + + jump main_room_menu + label paperwork: if letter_work_report in mailbox.get_letters(): gen "(I need to get paid first.)" ("base", xpos="far_left", ypos="head") diff --git a/game/scripts/rooms/main_room/objects/door.rpy b/game/scripts/rooms/main_room/objects/door.rpy index 900048ef..9bcc4367 100644 --- a/game/scripts/rooms/main_room/objects/door.rpy +++ b/game/scripts/rooms/main_room/objects/door.rpy @@ -1,66 +1,63 @@ +label examine_door: + if not states.gen.ev.intro.door_examined: + $ states.gen.ev.intro.door_examined = True + $ door_OBJ.idle = "door_idle" + $ door_OBJ.action = Jump("examine_door") + call gen_chibi("stand","door","base") + with d5 + + gen "A sturdy-looking door..." ("base", xpos="far_left", ypos="head") + gen "I wonder what's behind it." ("base", xpos="far_left", ypos="head") + label examining_the_door: + menu: + "-Knock on the door-": + show screen blktone + with d3 + play sound "sounds/knocking.ogg" + "*Knock-knock-knock*" + "..................." + hide screen blktone + with d3 + gen "No reply..." ("base", xpos="far_left", ypos="head") + "-Put your ear on it-": + show screen blktone + with d3 + nar "You put your ear on the door and listen intently..." + gen "I don't hear anything." ("base", xpos="far_left", ypos="head") + hide screen blktone + with d3 + "-Kick the door-": + show screen blktone + with d3 + play sound "sounds/kick.ogg" + pause.2 + with hpunch + "*Thump!*" + play sound "sounds/MaleGasp.ogg" + gen "Blimey! That hurts!" ("angry", xpos="far_left", ypos="head") + ".............................." + hide screen blktone + with d3 + gen "This door could take a thousand kicks and it still wouldn't break..." ("base", xpos="far_left", ypos="head") + "-Smell the door-": + show screen blktone + with d3 + play sound "sounds/sniff.ogg" + gen "...{w} Smells like a door..." ("base", xpos="far_left", ypos="head") + hide screen blktone + with d3 + "-Leave it alone-": + gen "Who knows what kind of dangers could be lurking behind that door?" ("base", xpos="far_left", ypos="head") + gen "I think I'll let it be for now..." ("base", xpos="far_left", ypos="head") + + call gen_chibi("sit_behind_desk") + with d3 + else: + gen "I should leave this door alone for now." ("base", xpos="far_left", ypos="head") + + jump main_room_menu + label door: - if game.day == 1: - if not states.gen.ev.intro.door_examined: - $ states.gen.ev.intro.door_examined = True - $ door_OBJ.idle = "door_idle" - call gen_chibi("stand","door","base") - with d5 - - gen "A sturdy-looking door..." ("base", xpos="far_left", ypos="head") - gen "I wonder what's behind it." ("base", xpos="far_left", ypos="head") - label examining_the_door: - menu: - "-Knock on the door-": - show screen blktone - with d3 - play sound "sounds/knocking.ogg" - "*Knock-knock-knock*" - "..................." - hide screen blktone - with d3 - gen "No reply..." ("base", xpos="far_left", ypos="head") - "-Put your ear on it-": - show screen blktone - with d3 - nar "You put your ear on the door and listen intently..." - gen "I don't hear anything." ("base", xpos="far_left", ypos="head") - hide screen blktone - with d3 - "-Kick the door-": - show screen blktone - with d3 - play sound "sounds/kick.ogg" - pause.2 - with hpunch - "*Thump!*" - play sound "sounds/MaleGasp.ogg" - gen "Blimey! That hurts!" ("angry", xpos="far_left", ypos="head") - ".............................." - hide screen blktone - with d3 - gen "This door could take a thousand kicks and it still wouldn't break..." ("base", xpos="far_left", ypos="head") - "-Smell the door-": - show screen blktone - with d3 - play sound "sounds/sniff.ogg" - gen "...{w} Smells like a door..." ("base", xpos="far_left", ypos="head") - hide screen blktone - with d3 - "-Leave it alone-": - gen "Who knows what kind of dangers could be lurking behind that door?" ("base", xpos="far_left", ypos="head") - gen "I think I'll let it be for now..." ("base", xpos="far_left", ypos="head") - - call gen_chibi("sit_behind_desk") - with d3 - else: - gen "I should leave this door alone for now." ("base", xpos="far_left", ypos="head") - - if states.gen.ev.intro.bird_examined and states.gen.ev.intro.desk_examined and states.gen.ev.intro.cupboard_examined and states.gen.ev.intro.door_examined and states.gen.ev.intro.fireplace_examined: - jump genie_intro_E2 - else: - jump main_room_menu - - call update_character_map_locations - - play sound "sounds/scroll.ogg" - jump summon + gen "I don't know what's waiting for me behind this door." ("base", xpos="far_left", ypos="head") + gen "It might be wiser to stay put for now..." ("base", xpos="far_left", ypos="head") + jump main_room_menu diff --git a/game/scripts/rooms/main_room/objects/fireplace.rpy b/game/scripts/rooms/main_room/objects/fireplace.rpy index ee2a3480..5ceaa61c 100644 --- a/game/scripts/rooms/main_room/objects/fireplace.rpy +++ b/game/scripts/rooms/main_room/objects/fireplace.rpy @@ -1,21 +1,4 @@ label fireplace: - if game.day == 1: - if not states.gen.ev.intro.fireplace_examined: - $ states.gen.ev.intro.fireplace_examined = True - $ fireplace_OBJ.idle = "fireplace_idle_shadow" - call gen_chibi("stand","mid","base") - with d5 - gen "*Hmm*... Looks like an ordinary fireplace..." ("base", xpos="far_left", ypos="head") - call gen_chibi("sit_behind_desk") - with d5 - else: - gen "Looks like a normal fireplace to me." ("base", xpos="far_left", ypos="head") - - if states.gen.ev.intro.bird_examined and states.gen.ev.intro.desk_examined and states.gen.ev.intro.cupboard_examined and states.gen.ev.intro.door_examined and states.gen.ev.intro.fireplace_examined: - jump genie_intro_E2 - else: - jump main_room_menu - if is_puzzle_box_in_fireplace(): call gen_chibi("stand", "fireplace", "fireplace") with d3 @@ -55,6 +38,21 @@ label fireplace: jump main_room_menu +label examine_fireplace: + if not states.gen.ev.intro.fireplace_examined: + $ states.gen.ev.intro.fireplace_examined = True + $ fireplace_OBJ.idle = "fireplace_idle_shadow" + $ fireplace_OBJ.action = Jump("examine_fireplace") + call gen_chibi("stand","mid","base") + with d5 + gen "*Hmm*... Looks like an ordinary fireplace..." ("base", xpos="far_left", ypos="head") + call gen_chibi("sit_behind_desk") + with d5 + else: + gen "Already checked it out." ("base", xpos="far_left", ypos="head") + + jump main_room_menu + init python: def is_puzzle_box_in_fireplace(): return game.day >= 25 and not game.daytime and game.moon and not puzzle_box_ITEM.unlocked and not states.map.seventh_floor.unlocked diff --git a/game/scripts/rooms/main_room/objects/phoenix.rpy b/game/scripts/rooms/main_room/objects/phoenix.rpy index f7145c00..25b0dece 100644 --- a/game/scripts/rooms/main_room/objects/phoenix.rpy +++ b/game/scripts/rooms/main_room/objects/phoenix.rpy @@ -1,20 +1,16 @@ -label phoenix: - - if game.day == 1: - if not states.gen.ev.intro.bird_examined: - $ states.gen.ev.intro.bird_examined = True - $ phoenix_OBJ.idle = "phoenix_idle" - call gen_chibi("stand","mid","base",flip=False) - with d5 - gen "*Hmm*..." ("base", xpos="far_left", ypos="head") - gen "Even this weird-looking bird radiates magic..." ("base", xpos="far_left", ypos="head") - call gen_chibi("sit_behind_desk") - with d5 - else: - gen "It's just a bird. Nothing more to say." ("base", xpos="far_left", ypos="head") - - if states.gen.ev.intro.bird_examined and states.gen.ev.intro.desk_examined and states.gen.ev.intro.cupboard_examined and states.gen.ev.intro.door_examined and states.gen.ev.intro.fireplace_examined: - jump genie_intro_E2 +label examine_phoenix: + if not states.gen.ev.intro.bird_examined: + $ states.gen.ev.intro.bird_examined = True + $ phoenix_OBJ.idle = "phoenix_idle" + $ phoenix_OBJ.action = Jump("examine_phoenix") + call gen_chibi("stand","mid","base",flip=False) + with d5 + gen "*Hmm*..." ("base", xpos="far_left", ypos="head") + gen "Even this weird-looking bird radiates magic..." ("base", xpos="far_left", ypos="head") + call gen_chibi("sit_behind_desk") + with d5 + else: + gen "It's just a bird. Nothing more to say." ("base", xpos="far_left", ypos="head") jump main_room_menu diff --git a/game/scripts/utility/common_functions.rpy b/game/scripts/utility/common_functions.rpy index ff5a0b5e..52d579e1 100644 --- a/game/scripts/utility/common_functions.rpy +++ b/game/scripts/utility/common_functions.rpy @@ -101,7 +101,9 @@ init python early: def reset_variables(*args): """ Resets the given variables to their default values. - Should not be used : instead, define the base value and have a function set the defaulted one to the defined value (or a copy of it). + + As of Ren'py version 8.2.1: + After reevaluating this function and the underlying Ren'py code, this function is deemed safe to use because Ren'Py employs a similar implementation internally, and it is also utilized for user-defined statements. Essentially, it calls execute_default on a node marked as ever_been_changed, followed by running py_eval_bytecode to add it to the global store. The potential side effects to consider is when config.after_default_callbacks is provided, or direct object references are in use. However, this can be easily patched if necessary. """ # Refer to renpy.ast.Default.set_default for implementation details defaults_set = renpy.store._defaults_set diff --git a/game/scripts/utility/engine.rpy b/game/scripts/utility/engine.rpy index 85d24745..3d2bedad 100644 --- a/game/scripts/utility/engine.rpy +++ b/game/scripts/utility/engine.rpy @@ -329,14 +329,31 @@ init -100 python: setattr(self, k, v) # The original does not support nested actions. + # Nor does it support string expressions evaluated at runtime. @renpy.pure def If(expression, true=None, false=None): if isinstance(expression, Action): expression = expression() + elif isinstance(expression, str): + expression = eval(expression) return true if expression else false + @renpy.pure + class IfExpr(Action): + def __init__(self, expr, true=None, false=None): + self.expr = expr + self.true = true + self.false = false + + def __call__(self): + result = If(self.expr, self.true, self.false) + + if isinstance(result, Action): + return result() + return result + # Adds support for nested stores for replay scope def _call_replay(label, scope={}): renpy.display.focus.clear_focus()