From 03cae68c7d7b28530694b825e5da34e5a7d18460 Mon Sep 17 00:00:00 2001 From: Matt Dallmeyer Date: Tue, 1 Oct 2024 19:17:32 -0700 Subject: [PATCH] [jak1] Patch "NG+ glitch" (#3690) Fixes #3644 which I believe is the same underlying issue as "NG+ glitch" To reproduce the issue in #3644 you can: - choose Hub 2 100% in the speedrun fast reset menu - hit the blue sage warp gate switch - go deep enough into any adjacent level (e.g. basin) where `village2` display is turned off - reset speedrun in the fast reset menu - tasks are reset but the switch will be pressed, giving the cutscene early You can also grab orbs/scout flies in `village2`, and they won't be reset properly because of this same bug. It happens because of the way entity perm status is managed across both `level` vs `game-info` objects. - when `village2` is deactivated (still loaded but display hidden), its entity perms are copied to `game-info`'s `perm-list` - this is how we persist `warp-gate-switch-7` being pressed if village2 is ever unloaded - during the speedrun reset `reset-actors` is called: - any active levels (loaded+displayed) have their entity perm statuses reset - because `village2` is not displayed yet, its entity perm statuses are not touched - `game-info` is re-initialized, clearing out its `perm-list` - continue is set to `firecanyon-end` - this unloads `rolling` or whatever to make room for `firecanyon` - `village2` is already loaded, and just gets displayed - at this point the game does copy entity perm status from `game-info` back to the `village2` level - but we reset the game, so it has no data about the warp-gate-switch, leaving it pressed! --- goal_src/jak1/engine/level/level.gc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/goal_src/jak1/engine/level/level.gc b/goal_src/jak1/engine/level/level.gc index c34f6976af3..ad7440d63d7 100644 --- a/goal_src/jak1/engine/level/level.gc +++ b/goal_src/jak1/engine/level/level.gc @@ -623,6 +623,12 @@ ;; copy data from the level to the game-info storage. This will remember permanent level stuff, like ;; what you collected/completed. (copy-perms-from-level! *game-info* this) + ;; og:preserve-this fully clear entity perm status in the level itself (based on reset-actors) + ;; it should be copied back out of game-info on birth to prevent "NG+ glitch" + (let ((lev-ents (-> this entity))) + (dotimes (idx (-> lev-ents length)) + (let ((ent (-> lev-ents data idx entity))) + (update-perm! (-> ent extra perm) 'game (the-as entity-perm-status 1919))))) (send-event *camera* 'level-deactivate (-> this name)) (send-event *target* 'level-deactivate (-> this name)) ;; remove this BSP from the engine. This will stop us from being drawn.