[jak3] Extend speedrun menus for selecting secrets (#4397)

extends the secret selection menu to other categories (act 2, 3, etc)
and adds hero mode categories for act 2 and 3
This commit is contained in:
Matt Dallmeyer
2026-08-30 18:45:25 -07:00
committed by GitHub
parent 427c952558
commit c115da577c
4 changed files with 283 additions and 25 deletions
+2
View File
@@ -87,6 +87,8 @@
;; e.g. for All Open Orbs (Post Game)
(post-game 4)
(post-game-heromode 5)
(act-2-heromode 6)
(act-3-heromode 7)
;; TODO - add ILs and such later
;; there's no point in adding categories that just start from a new-game and have later restrictions
;; because we aren't going to modify the code to make that possible
+270 -23
View File
@@ -143,8 +143,90 @@
lighteco
darkeco))
(defun reset-speedrunner-mode-hm-secrets! ((obj pc-settings-jak3))
(set! (-> obj speedrunner-mode-hm-secrets) (the-as uint64 HERO_MODE_SECRETS))
(defconstant ACT_2_SECRETS
(game-secrets board-fast ;; :avail-after (game-task-node desert-oasis-defense-resolution)
vehicle-fox ;; :avail-after (game-task-node desert-oasis-defense-introduction)
gun-upgrade-red-1 ;; :avail-after (game-task-node arena-fight-2-resolution)
gun-upgrade-red-2 ;; :avail-after (game-task-node arena-fight-3-resolution)
gun-upgrade-yellow-1 ;; :avail-after (game-task-node arena-fight-2-resolution)
gun-upgrade-yellow-2 ;; :avail-after (game-task-node arena-fight-3-resolution)
gun-upgrade-blue-1 ;; :avail-after (game-task-node arena-fight-3-resolution)
gun-upgrade-blue-2 ;; :avail-after (game-task-node mine-boss-resolution)
gun-upgrade-ammo-red ;; :avail-after (game-task-node arena-fight-3-resolution)
gun-upgrade-ammo-yellow ;; :avail-after (game-task-node arena-fight-3-resolution)
gun-upgrade-ammo-blue)) ;; :avail-after (game-task-node mine-boss-resolution)
(defconstant ACT_3_SECRETS
(game-secrets unlimited-turbos ;; :avail-after (game-task-node factory-boss-resolution)
vehicle-hit-points ;; :avail-after (game-task-node nest-hunt-resolution)
board-fast
vehicle-fox
vehicle-mirage ;; :avail-after (game-task-node desert-artifact-race-2-resolution)
vehicle-x-ride ;; :avail-after (game-task-node desert-artifact-race-2-resolution)
darkjak-tracking ;; :avail-after (game-task-node city-destroy-darkeco-resolution)
gun-upgrade-red-1
gun-upgrade-red-2
gun-upgrade-red-3 ;; :avail-after (game-task-node city-gun-course-2-resolution)
gun-upgrade-yellow-1
gun-upgrade-yellow-2
gun-upgrade-yellow-3 ;; :avail-after (game-task-node city-gun-course-1-resolution)
gun-upgrade-blue-1
gun-upgrade-blue-2
gun-upgrade-blue-3 ;; :avail-after (game-task-node city-destroy-grid-resolution)
gun-upgrade-dark-1 ;; :avail-after (game-task-node city-blow-barricade-resolution)
gun-upgrade-ammo-red
gun-upgrade-ammo-yellow
gun-upgrade-ammo-blue
gun-upgrade-ammo-dark)) ;; :avail-after (game-task-node city-blow-barricade-resolution)
(defconstant POST_GAME_SECRETS
(game-secrets endless-ammo ;; :avail-after (game-task-node desert-final-boss-resolution)
invulnerable ;; :avail-after (game-task-node desert-final-boss-resolution)
endless-dark ;; :avail-after (game-task-node desert-final-boss-resolution)
endless-light ;; :avail-after (game-task-node desert-final-boss-resolution)
unlimited-turbos
vehicle-hit-points
board-fast
vehicle-fox
vehicle-mirage
vehicle-x-ride
darkjak-tracking
button-invis ;; :avail-after (game-task-node desert-final-boss-resolution)
gun-upgrade-red-1
gun-upgrade-red-2
gun-upgrade-red-3
gun-upgrade-yellow-1
gun-upgrade-yellow-2
gun-upgrade-yellow-3
gun-upgrade-blue-1
gun-upgrade-blue-2
gun-upgrade-blue-3
gun-upgrade-dark-1
gun-upgrade-dark-2 ;; :avail-after (game-task-node temple-defend-resolution)
gun-upgrade-dark-3 ;; :avail-after (game-task-node city-blow-tower-resolution)
gun-upgrade-ammo-red
gun-upgrade-ammo-yellow
gun-upgrade-ammo-blue
gun-upgrade-ammo-dark))
(defun reset-speedrunner-mode-secrets! ((obj pc-settings-jak3) (cat speedrun-category))
(case cat
(((speedrun-category newgame-heromode) (speedrun-category post-game-heromode) (speedrun-category act-2-heromode) (speedrun-category act-3-heromode))
(set! (-> obj speedrunner-mode-hm-secrets) (the-as uint64 HERO_MODE_SECRETS)))
(((speedrun-category act-2))
(set! (-> obj speedrunner-mode-act2-secrets) (the-as uint64 ACT_2_SECRETS)))
(((speedrun-category act-3))
(set! (-> obj speedrunner-mode-act3-secrets) (the-as uint64 ACT_3_SECRETS)))
(((speedrun-category post-game))
(set! (-> obj speedrunner-mode-postgame-secrets) (the-as uint64 POST_GAME_SECRETS)))
)
(none))
(defun reset-speedrunner-mode-secrets-all! ((obj pc-settings-jak3))
(reset-speedrunner-mode-secrets! obj (speedrun-category newgame-heromode))
(reset-speedrunner-mode-secrets! obj (speedrun-category act-2))
(reset-speedrunner-mode-secrets! obj (speedrun-category act-3))
(reset-speedrunner-mode-secrets! obj (speedrun-category post-game))
(none))
(define-extern reset-arena-trainer-globals (function none))
@@ -187,10 +269,48 @@
(set! (-> *game-info* features) HERO_MODE_FEATURES))))
(((speedrun-category act-2))
(start 'play (get-continue-by-name *game-info* (play-task (game-task sewer-met-hum) 'debug 'play)))
(set-master-mode 'game))
(set-master-mode 'game)
(set! (-> *game-info* secrets) (the-as game-secrets (-> *pc-settings* speedrunner-mode-act2-secrets)))
(set! (-> *game-info* purchase-secrets) (the-as game-secrets (-> *pc-settings* speedrunner-mode-act2-secrets))))
(((speedrun-category act-2-heromode))
(process-spawn-function process
(lambda :behavior process ()
(set! (-> *game-info* mode) 'debug)
(initialize! *game-info* 'game (the game-save #f) (the string #f) (the resetter-spec #f))
(set! (-> *game-info* mode) 'play)
(logior! (-> *game-info* secrets) (game-secrets hero-mode))
(logior! (-> *game-info* purchase-secrets) (game-secrets hero-mode))
(start 'play (get-continue-by-name *game-info* (play-task (game-task sewer-met-hum) 'debug 'play)))
(until (and *target* (!= (-> *target* next-state name) 'target-continue))
(suspend))
(mark-played! (-> *talker-speech* 138)) ;; prevent 600 orbs popup
(send-event *target* 'get-pickup (pickup-type skill) 1000.0)
(send-event *target* 'get-pickup (pickup-type gem) 1000.0)
(set! (-> *game-info* secrets) (the-as game-secrets (-> *pc-settings* speedrunner-mode-hm-secrets)))
(set! (-> *game-info* purchase-secrets) (the-as game-secrets (-> *pc-settings* speedrunner-mode-hm-secrets)))
(set! (-> *game-info* features) HERO_MODE_FEATURES))))
(((speedrun-category act-3))
(start 'play (get-continue-by-name *game-info* (play-task (game-task temple-defend) 'debug 'play)))
(set-master-mode 'game))
(set-master-mode 'game)
(set! (-> *game-info* secrets) (the-as game-secrets (-> *pc-settings* speedrunner-mode-act3-secrets)))
(set! (-> *game-info* purchase-secrets) (the-as game-secrets (-> *pc-settings* speedrunner-mode-act3-secrets))))
(((speedrun-category act-3-heromode))
(process-spawn-function process
(lambda :behavior process ()
(set! (-> *game-info* mode) 'debug)
(initialize! *game-info* 'game (the game-save #f) (the string #f) (the resetter-spec #f))
(set! (-> *game-info* mode) 'play)
(logior! (-> *game-info* secrets) (game-secrets hero-mode))
(logior! (-> *game-info* purchase-secrets) (game-secrets hero-mode))
(start 'play (get-continue-by-name *game-info* (play-task (game-task temple-defend) 'debug 'play)))
(until (and *target* (!= (-> *target* next-state name) 'target-continue))
(suspend))
(mark-played! (-> *talker-speech* 138)) ;; prevent 600 orbs popup
(send-event *target* 'get-pickup (pickup-type skill) 1000.0)
(send-event *target* 'get-pickup (pickup-type gem) 1000.0)
(set! (-> *game-info* secrets) (the-as game-secrets (-> *pc-settings* speedrunner-mode-hm-secrets)))
(set! (-> *game-info* purchase-secrets) (the-as game-secrets (-> *pc-settings* speedrunner-mode-hm-secrets)))
(set! (-> *game-info* features) HERO_MODE_FEATURES))))
(((speedrun-category post-game))
(process-spawn-function process
(lambda :behavior process ()
@@ -199,6 +319,10 @@
(set! (-> *game-info* mode) 'play)
(task-close! "city-win-introduction")
(start 'play (get-continue-by-name *game-info* "wascity-start"))
(until (and *target* (!= (-> *target* next-state name) 'target-continue))
(suspend))
(set! (-> *game-info* secrets) (the-as game-secrets (-> *pc-settings* speedrunner-mode-postgame-secrets)))
(set! (-> *game-info* purchase-secrets) (the-as game-secrets (-> *pc-settings* speedrunner-mode-postgame-secrets)))
)))
(((speedrun-category post-game-heromode))
(process-spawn-function process
@@ -386,6 +510,42 @@
(deactivate self)))
(cam-master-activate-slave #f))
(defmacro speedrun-get-secrets-length (secrets)
(with-gensyms (num-secrets)
`(let ((,num-secrets 0))
(dotimes (i 64)
(when (logtest? ,secrets (shl 1 i)) ;; valid secret
(+! ,num-secrets 1)))
,num-secrets)))
(defmacro speedrun-secrets-confirm (full-secrets index settings-secrets)
(with-gensyms (num-secrets)
`(let ((,num-secrets 0))
(dotimes (i 64)
(when (logtest? ,full-secrets (shl 1 i)) ;; valid secret
(when (= ,num-secrets ,index) ;; index-th valid secret
(logxor! ,settings-secrets (shl 1 i))
(return (pc-settings-save)))
(+! ,num-secrets 1))))))
(defmacro speedrun-secrets-get-label (secrets index str-dest)
(with-gensyms (num-secrets)
`(let ((,num-secrets 0))
(dotimes (i 64)
(when (logtest? ,secrets (shl 1 i)) ;; valid secret
(when (= ,num-secrets ,index) ;; index-th valid secret
(return (copy-string<-string ,str-dest (bitfield->string game-secrets i))))
(+! ,num-secrets 1))))))
(defmacro speedrun-secrets-selected? (full-secrets index settings-secrets)
(with-gensyms (num-secrets)
`(let ((,num-secrets 0))
(dotimes (i 64)
(when (logtest? ,full-secrets (shl 1 i)) ;; valid secret
(when (= ,num-secrets ,index) ;; index-th valid secret
(return (logtest? ,settings-secrets (shl 1 i))))
(+! ,num-secrets 1))))))
(define *speedrun-popup-menu-entries*
(new 'static
'boxed-array
@@ -433,6 +593,15 @@
:is-toggled?
(lambda ()
(= (-> *speedrun-info* category) (speedrun-category act-2))))
(new 'static
'popup-menu-flag
:label "Act 2 Hero Mode"
:on-confirm
(lambda ()
(set-category! *speedrun-info* (speedrun-category act-2-heromode)))
:is-toggled?
(lambda ()
(= (-> *speedrun-info* category) (speedrun-category act-2-heromode))))
(new 'static
'popup-menu-flag
:label "Act 3"
@@ -442,6 +611,15 @@
:is-toggled?
(lambda ()
(= (-> *speedrun-info* category) (speedrun-category act-3))))
(new 'static
'popup-menu-flag
:label "Act 3 Hero Mode"
:on-confirm
(lambda ()
(set-category! *speedrun-info* (speedrun-category act-3-heromode)))
:is-toggled?
(lambda ()
(= (-> *speedrun-info* category) (speedrun-category act-3-heromode))))
(new 'static
'popup-menu-flag
:label "Post-Game"
@@ -470,25 +648,94 @@
(lambda ()
(= (-> *speedrun-info* category) (speedrun-category all-cheats-allowed))))))
(new 'static
'popup-menu-dynamic-submenu
:label "Select Hero Mode secrets"
:get-length
(lambda ()
58)
:get-entry-label
(lambda ((index int) (str-dest string))
(copy-string<-string str-dest (bitfield->string game-secrets index)))
:on-entry-confirm
(lambda ((index int))
(logxor! (-> *pc-settings* speedrunner-mode-hm-secrets) (shl 1 index))
(pc-settings-save))
:entry-selected?
(lambda ((index int))
(logtest? (-> *pc-settings* speedrunner-mode-hm-secrets) (shl 1 index)))
:on-reset
(lambda ()
(reset-speedrunner-mode-hm-secrets! *pc-settings*)
(pc-settings-save)))
'popup-menu-submenu
:label "Select Secrets"
:entries
(new 'static
'boxed-array
:type
popup-menu-entry
(new 'static
'popup-menu-dynamic-submenu
:label "Hero Mode Categories"
:get-length
(lambda ()
58) ;; (gun-upgrade-ammo-dark 57) last one to show
:get-entry-label
(lambda ((index int) (str-dest string))
(copy-string<-string str-dest (bitfield->string game-secrets index)))
:on-entry-confirm
(lambda ((index int))
(logxor! (-> *pc-settings* speedrunner-mode-hm-secrets) (shl 1 index))
(pc-settings-save))
:entry-selected?
(lambda ((index int))
(logtest? (-> *pc-settings* speedrunner-mode-hm-secrets) (shl 1 index)))
:on-reset
(lambda ()
(reset-speedrunner-mode-secrets! *pc-settings* (speedrun-category newgame-heromode))
(pc-settings-save)))
(new 'static
'popup-menu-dynamic-submenu
:label "Act 2"
:get-length
(lambda ()
(speedrun-get-secrets-length ACT_2_SECRETS))
:get-entry-label
(lambda ((index int) (str-dest string))
(speedrun-secrets-get-label ACT_2_SECRETS index str-dest))
:on-entry-confirm
(lambda ((index int))
(speedrun-secrets-confirm ACT_2_SECRETS index (-> *pc-settings* speedrunner-mode-act2-secrets)))
:entry-selected?
(lambda ((index int))
(speedrun-secrets-selected? ACT_2_SECRETS index (-> *pc-settings* speedrunner-mode-act2-secrets)))
:on-reset
(lambda ()
(reset-speedrunner-mode-secrets! *pc-settings* (speedrun-category act-2))
(pc-settings-save))
)
(new 'static
'popup-menu-dynamic-submenu
:label "Act 3"
:get-length
(lambda ()
(speedrun-get-secrets-length ACT_3_SECRETS))
:get-entry-label
(lambda ((index int) (str-dest string))
(speedrun-secrets-get-label ACT_3_SECRETS index str-dest))
:on-entry-confirm
(lambda ((index int))
(speedrun-secrets-confirm ACT_3_SECRETS index (-> *pc-settings* speedrunner-mode-act3-secrets)))
:entry-selected?
(lambda ((index int))
(speedrun-secrets-selected? ACT_3_SECRETS index (-> *pc-settings* speedrunner-mode-act3-secrets)))
:on-reset
(lambda ()
(reset-speedrunner-mode-secrets! *pc-settings* (speedrun-category act-3))
(pc-settings-save))
)
(new 'static
'popup-menu-dynamic-submenu
:label "Post-Game"
:get-length
(lambda ()
(speedrun-get-secrets-length POST_GAME_SECRETS))
:get-entry-label
(lambda ((index int) (str-dest string))
(speedrun-secrets-get-label POST_GAME_SECRETS index str-dest))
:on-entry-confirm
(lambda ((index int))
(speedrun-secrets-confirm POST_GAME_SECRETS index (-> *pc-settings* speedrunner-mode-postgame-secrets)))
:entry-selected?
(lambda ((index int))
(speedrun-secrets-selected? POST_GAME_SECRETS index (-> *pc-settings* speedrunner-mode-postgame-secrets)))
:on-reset
(lambda ()
(reset-speedrunner-mode-secrets! *pc-settings* (speedrun-category post-game))
(pc-settings-save))
)
))
(new 'static
'popup-menu-dynamic-submenu
:label "Custom Category Select"
+5 -2
View File
@@ -112,6 +112,9 @@
(pacman-dpad? symbol)
(speedrunner-mode-custom-bind uint32)
(speedrunner-mode-hm-secrets uint64)
(speedrunner-mode-act2-secrets uint64)
(speedrunner-mode-act3-secrets uint64)
(speedrunner-mode-postgame-secrets uint64)
(memcard-subtitles? symbol)
@@ -201,7 +204,7 @@
(set! (-> obj subtitle-speaker?) 'auto)
0)
(define-extern reset-speedrunner-mode-hm-secrets! (function pc-settings-jak3 none))
(define-extern reset-speedrunner-mode-secrets-all! (function pc-settings-jak3 none))
(defmethod reset-extra ((obj pc-settings-jak3) (call-handlers symbol))
"Set the default goodies settings"
@@ -217,7 +220,7 @@
(dotimes (i 6)
(set! (-> obj flava-unlocked i) #f))
(reset-speedrunner-mode-hm-secrets! obj)
(reset-speedrunner-mode-secrets-all! obj)
;(set! (-> obj stats) *statistics*)
0)
+6
View File
@@ -678,6 +678,9 @@
)
)
(("speedrunner-mode-hm-secrets") (set! (-> obj speedrunner-mode-hm-secrets) (file-stream-read-int file)))
(("speedrunner-mode-act2-secrets") (set! (-> obj speedrunner-mode-act2-secrets) (file-stream-read-int file)))
(("speedrunner-mode-act3-secrets") (set! (-> obj speedrunner-mode-act3-secrets) (file-stream-read-int file)))
(("speedrunner-mode-postgame-secrets") (set! (-> obj speedrunner-mode-postgame-secrets) (file-stream-read-int file)))
;; (("stats")
;; (dosettings (file)
@@ -733,6 +736,9 @@
(format file ")~%")
(format file " (speedrunner-mode-hm-secrets #x~x)~%" (-> obj speedrunner-mode-hm-secrets))
(format file " (speedrunner-mode-act2-secrets #x~x)~%" (-> obj speedrunner-mode-act2-secrets))
(format file " (speedrunner-mode-act3-secrets #x~x)~%" (-> obj speedrunner-mode-act3-secrets))
(format file " (speedrunner-mode-postgame-secrets #x~x)~%" (-> obj speedrunner-mode-postgame-secrets))
;; (format file " (stats~%")
;; (format file " (kill-stats~%")