[jak1] Patch "NG+ glitch" (#3690)
Some checks failed
Build / 🖥️ Windows (push) Has been cancelled
Build / 🐧 Linux (push) Has been cancelled
Build / 🍎 MacOS (push) Has been cancelled
Inform Pages Repo / Generate Documentation (push) Has been cancelled
Lint / 📝 Formatting (push) Has been cancelled
Lint / 📝 Required Checks (push) Has been cancelled
Lint / 📝 Optional Checks (push) Has been cancelled

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!
This commit is contained in:
Matt Dallmeyer 2024-10-01 19:17:32 -07:00 committed by GitHub
parent 6b7dd7ae22
commit 03cae68c7d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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.