Files
jak-project/goal_src/jak2/levels/forest/wren.gc
T
Tyler Wilding 6f093f98ff gsrc: Add convenience macros for masking VF operations (#3824)
Migrates all code, there should be no change in the compilation output
(linter should check this)

At first i was considering making these builtins, which short of a bunch
of code generation, would require some sort of dynamic definition in
`Atoms.cpp`. This isn't hard but, i figured it would be better to keep
it simple and just generate the OG macros.

Fixes https://github.com/open-goal/jak-project/issues/233
2025-01-11 12:16:05 -05:00

484 lines
15 KiB
Common Lisp

;;-*-Lisp-*-
(in-package goal)
;; name: wren.gc
;; name in dgo: wren
;; dgos: FOR
(defenum wren-flags
:bitfield #t
:type uint16
(wrflags-0)
(wrflags-1)
(wrflags-2)
(wrflags-3)
(wrflags-4)
(wrflags-5)
(wrflags-6)
(wrflags-7)
)
;; DECOMP BEGINS
(deftype wren (process-drawable)
((move-dest vector :inline)
(fly-curve curve-control 2)
(fly-index uint32)
(fly-speed float)
(fly-y-rate float)
(fly-interp float)
(path-u float)
(path-du float)
(path-du-mod float)
(bob-level float)
(bob-level-seek float)
(bank-angle float)
(peck-timer uint64)
(flags wren-flags)
)
(:state-methods
hunt
peck
fly
land
on-branch
die
)
(:methods
(spooked? (_type_) symbol)
(debug-draw-path (_type_) symbol)
)
)
(defskelgroup skel-wren wren wren-lod0-jg wren-idle-ja
((wren-lod0-mg (meters 999999)))
:bounds (static-spherem 0 0 0 4)
)
(defmethod debug-draw-path ((this wren))
"Draws the associated [[curve-control]]s associated with this wren"
(dotimes (s5-0 2)
(if (-> this fly-curve s5-0)
(debug-draw (-> this fly-curve s5-0))
)
)
#f
)
(defbehavior fly-post wren ()
(rlet ((acc :class vf)
(vf0 :class vf)
(vf1 :class vf)
(vf2 :class vf)
(vf3 :class vf)
)
(init-vf0-vector)
(seek! (-> self bob-level) (-> self bob-level-seek) (* 12288.0 (seconds-per-frame)))
(let ((gp-0 (-> self fly-curve (-> self fly-index))))
(get-point-at-percent-along-path! gp-0 (-> self root trans) (-> self path-u) 'interp)
(seek! (-> self path-u) 1.0 (* (-> self path-du) (-> self path-du-mod) (seconds-per-frame)))
(seek! (-> self path-du) 0.2 (* 0.1 (seconds-per-frame)))
(let* ((f30-0 (-> self path-u))
(f0-16 (fmin 1.0 (+ 0.125 f30-0)))
(s4-0 (displacement-between-points-at-percent-normalized! gp-0 (new 'stack-no-clear 'vector) f0-16))
(s3-0 (displacement-between-points-at-percent-normalized! gp-0 (new 'stack-no-clear 'vector) f30-0))
(gp-1 (-> self root quat))
)
(forward-up->quaternion gp-1 s4-0 *up-vector*)
(set! (-> self fly-y-rate) (tan (vector-x-angle s4-0)))
(let ((s5-1 (new 'stack-no-clear 'vector)))
(let ((v1-16 s3-0)
(a0-9 s4-0)
)
(.lvf vf1 (&-> v1-16 quad))
(.lvf vf2 (&-> a0-9 quad))
)
(.add.x.vf.y vf1 vf0 vf0)
(.add.x.vf.y vf2 vf0 vf0)
(.outer.product.a.vf acc vf1 vf2)
(.outer.product.b.vf vf3 vf2 vf1 acc)
(.svf (&-> s5-1 quad) vf3)
(let* ((f0-19 (acos (vector-dot s3-0 s4-0)))
(f1-8 (if (< 0.0 (vector-dot s5-1 *up-vector*))
(- f0-19)
f0-19
)
)
)
(if (and (-> self next-state) (= (-> self next-state name) 'fly))
(seek! (-> self bank-angle) f1-8 (* f0-19 (seconds-per-frame)))
(seek! (-> self bank-angle) 0.0 (* 8192.0 (seconds-per-frame)))
)
)
)
(quaternion-rotate-local-z! gp-1 gp-1 (-> self bank-angle))
)
)
0
(debug-draw-path self)
(+! (-> self root trans y) (-> self bob-level))
(ja-post)
(none)
)
)
;; WARN: Return type mismatch object vs symbol.
(defmethod spooked? ((this wren))
"@returns a [[symbol]] indicating if Jak is considered close enough to the wren to spook it.
If so, it transitions from [[wren::peck]] to [[wren::hunt]]"
(let* ((gp-0 *target*)
(a0-2 (if (type? gp-0 process-focusable)
gp-0
)
)
)
(the-as symbol (and a0-2 (< (vector-vector-xz-distance (-> this root trans) (get-trans a0-2 0)) 102400.0)))
)
)
(defstate hunt (wren)
:virtual #t
:trans (behavior ()
(when (< (vector-vector-xz-distance (-> self root trans) (-> self move-dest)) 2048.0)
(cond
((logtest? (-> self flags) (wren-flags wrflags-2))
(logclear! (-> self flags) (wren-flags wrflags-2))
(set! (-> self fly-index) (the-as uint 0))
(go-virtual fly)
)
(else
(go-virtual peck)
)
)
)
)
:code (behavior ()
(until #f
(ja-no-eval :group! wren-hop-ja :num! (seek!) :frame-num 0.0)
(until (ja-done? 0)
(suspend)
(ja :num! (seek!))
)
)
#f
)
:post (behavior ()
(local-vars (at-0 int))
(rlet ((vf0 :class vf)
(vf1 :class vf)
(vf2 :class vf)
)
(init-vf0-vector)
(let ((gp-1 (vector-! (new 'stack-no-clear 'vector) (-> self move-dest) (-> self root trans))))
(vector-normalize! gp-1 12288.0)
(let ((v1-1 (new 'stack-no-clear 'vector)))
(.lvf vf1 (&-> gp-1 quad))
(let ((f0-0 (seconds-per-frame)))
(.mov at-0 f0-0)
)
(.mov vf2 at-0)
(.mov.vf.w vf1 vf0)
(.mul.x.vf.xyz vf1 vf1 vf2)
(.svf (&-> v1-1 quad) vf1)
(vector+! (-> self root trans) (-> self root trans) v1-1)
)
)
(ja-post)
)
)
)
(defstate peck (wren)
:virtual #t
:enter (behavior ()
(set-time! (-> self state-time))
(set! (-> self peck-timer) (the-as uint (the int (* 300.0 (rand-vu-float-range 1.4 4.3)))))
(logclear! (-> self flags) (wren-flags wrflags-1 wrflags-2))
)
:trans (behavior ()
(when (time-elapsed? (-> self state-time) (the-as time-frame (-> self peck-timer)))
(let ((gp-1 (vector-! (new 'stack-no-clear 'vector) (-> self move-dest) (-> self root trans))))
(if (< (fabs (deg-diff (quaternion-y-angle (-> self root quat)) (vector-y-angle gp-1))) 728.1778)
(go-virtual hunt)
)
)
)
(when (logtest? (-> self flags) (wren-flags wrflags-1))
(logclear! (-> self flags) (wren-flags wrflags-1))
(when (spooked? self)
(get-point-in-path! (-> self fly-curve 0) (-> self move-dest) 0.0 'interp)
(set-yaw-angle-clear-roll-pitch!
(-> self root)
(vector-y-angle (vector-! (new 'stack-no-clear 'vector) (-> self move-dest) (-> self root trans)))
)
(logior! (-> self flags) (wren-flags wrflags-2))
(go-virtual hunt)
)
)
)
:code (behavior ()
(local-vars (v1-34 symbol))
(until #f
(logclear! (-> self flags) (wren-flags wrflags-0))
(let ((f0-0 (rand-vu-float-range 0.0 (get-num-segments (-> self path)))))
(get-point-in-path! (-> self path) (-> self move-dest) f0-0 'interp)
)
(logior! (-> self flags) (wren-flags wrflags-1))
(ja-no-eval :group! wren-peck-ja :num! (seek!) :frame-num 0.0)
(until (ja-done? 0)
(suspend)
(ja :num! (seek!))
)
#t
(let ((v1-33 (the-as symbol (logand (-> self flags) (wren-flags wrflags-1)))))
(set! v1-33 v1-33)
(cmove-#f-zero v1-34 v1-33 v1-33)
)
(let ((gp-1 (current-time))
(s5-1 (the int (* 300.0 (rand-vu-float-range 0.1 0.6))))
(f30-1 1.0)
)
(ja-no-eval :group! wren-idle-ja :num! (loop! f30-1) :frame-num 0.0)
(until (time-elapsed? gp-1 s5-1)
(suspend)
(ja :num! (loop! f30-1))
)
)
(logior! (-> self flags) (wren-flags wrflags-0))
(let ((gp-2 (current-time))
(s5-2 (the int (* 300.0 (rand-vu-float-range 0.2 1.5))))
(f30-3 1.0)
)
(ja-no-eval :group! wren-idle-ja :num! (loop! f30-3) :frame-num 0.0)
(until (time-elapsed? gp-2 s5-2)
(suspend)
(ja :num! (loop! f30-3))
)
)
)
#f
)
:post (behavior ()
(if (logtest? (-> self flags) (wren-flags wrflags-0))
(seek-to-point-toward-point! (-> self root) (-> self move-dest) 262144.0 (seconds 0.02))
)
(ja-post)
)
)
(defstate fly (wren)
:virtual #t
:enter (behavior ()
(set! (-> self path-u) 0.0)
(set! (-> self path-du) 0.0)
(set! (-> self path-du-mod) 1.0)
(set! (-> self fly-speed) 0.0)
(set! (-> self fly-interp) 0.0)
(set! (-> self bob-level) 0.0)
(set! (-> self bob-level-seek) 0.0)
)
:trans (behavior ()
(when (< 0.99 (-> self path-u))
(if (-> self fly-curve (logand (+ (-> self fly-index) 1) 1))
(go-virtual land)
(go-virtual die)
)
)
)
:code (behavior ()
(let ((gp-0 (current-time))
(s5-0 240)
(f30-0 2.0)
)
(ja-no-eval :group! wren-takeoff-ja :num! (loop! f30-0) :frame-num 0.0)
(until (time-elapsed? gp-0 s5-0)
(suspend)
(ja :num! (loop! f30-0))
)
)
(ja-channel-push! 2 (seconds 0.3))
(ja-no-eval :group! wren-glide-ja :num! (seek!) :frame-num 0.0)
(let ((a0-4 (-> self skel root-channel 1)))
(let ((f0-5 0.0))
(set! (-> a0-4 frame-interp 1) f0-5)
(set! (-> a0-4 frame-interp 0) f0-5)
)
(set! (-> a0-4 frame-group) (the-as art-joint-anim wren-fly-ja))
(set! (-> a0-4 param 0) (the float (+ (-> (the-as art-joint-anim wren-fly-ja) frames num-frames) -1)))
(set! (-> a0-4 param 1) 1.0)
(set! (-> a0-4 frame-num) 0.0)
(joint-control-channel-group! a0-4 (the-as art-joint-anim wren-fly-ja) num-func-seek!)
)
(until #f
(let ((f0-11 (fmax -0.2 (fmin 0.5 (-> self fly-y-rate)))))
(seek! (-> self fly-interp) (lerp-scale 0.0 1.0 f0-11 -0.2 0.5) (seconds-per-frame))
)
(let ((f30-1 (-> self fly-interp)))
(seek! (-> self path-du-mod) (+ 0.9 (/ f30-1 5)) (* 0.5 (seconds-per-frame)))
(set! (-> self bob-level-seek) (+ -12288.0 (* 24576.0 f30-1)))
(let ((v1-59 (-> self skel root-channel 0)))
(let ((f0-23 (- 1.0 f30-1)))
(set! (-> v1-59 frame-interp 1) f0-23)
(set! (-> v1-59 frame-interp 0) f0-23)
)
(set! (-> v1-59 frame-group) (the-as art-joint-anim wren-glide-ja))
)
(ja :chan 1 :group! wren-fly-ja :frame-interp0 f30-1 :frame-interp1 f30-1)
(let ((f30-2 (lerp 0.6 2.4 f30-1)))
(ja :num! (loop! f30-2))
(ja :chan 1 :num! (loop! f30-2))
)
)
(suspend)
)
#f
)
:post fly-post
)
(defstate land (wren)
:virtual #t
:code (behavior ()
(set! (-> self bob-level-seek) 0.0)
(ja-channel-push! 1 (seconds 0.3))
(while (!= (-> self path-u) 1.0)
(ja-no-eval :group! wren-land-ja :num! (seek!) :frame-num 0.0)
(until (ja-done? 0)
(suspend)
(ja :num! (seek!))
)
)
(go-virtual on-branch)
)
:post (behavior ()
(seek! (-> self path-du-mod) 0.0 (* 0.5 (seconds-per-frame)))
(fly-post)
)
)
(defstate on-branch (wren)
:virtual #t
:enter (behavior ()
(let ((v1-6 (displacement-between-points-at-percent-normalized!
(-> self fly-curve (logand (+ (-> self fly-index) 1) 1))
(new 'stack-no-clear 'vector)
0.1
)
)
)
(vector+! (-> self move-dest) (-> self root trans) v1-6)
)
)
:trans (behavior ()
(let ((gp-1 (vector-! (new 'stack-no-clear 'vector) (-> self move-dest) (-> self root trans))))
(when (< (fabs (deg-diff (quaternion-y-angle (-> self root quat)) (vector-y-angle gp-1))) 728.1778)
(when (time-elapsed? (-> self state-time) (the-as time-frame (-> self peck-timer)))
(set! (-> self fly-index) (logand (+ (-> self fly-index) 1) 1))
(go-virtual fly)
)
)
)
)
:code (behavior ()
(logclear! (-> self flags) (wren-flags wrflags-0))
(ja-channel-push! 1 (seconds 0.2))
(let ((gp-0 (current-time))
(s5-0 (the int (* 300.0 (rand-vu-float-range 4.2 16.8))))
(f30-1 1.0)
)
(ja-no-eval :group! wren-idle-ja :num! (loop! f30-1) :frame-num 0.0)
(until (time-elapsed? gp-0 s5-0)
(suspend)
(ja :num! (loop! f30-1))
)
)
(logior! (-> self flags) (wren-flags wrflags-0))
(let ((gp-1 (current-time))
(s5-1 600)
(f30-2 1.0)
)
(ja-no-eval :group! wren-idle-ja :num! (loop! f30-2) :frame-num 0.0)
(until (time-elapsed? gp-1 s5-1)
(suspend)
(ja :num! (loop! f30-2))
)
)
)
:post (behavior ()
(if (logtest? (-> self flags) (wren-flags wrflags-0))
(seek-to-point-toward-point! (-> self root) (-> self move-dest) 262144.0 (seconds 0.02))
)
(debug-draw-path self)
(ja-post)
)
)
(defstate die (wren)
:virtual #t
:code (behavior ()
(cleanup-for-death self)
(suspend)
0
)
)
(defmethod relocate ((this wren) (offset int))
(dotimes (v1-0 2)
(when (-> this fly-curve v1-0)
(if (nonzero? (-> this fly-curve v1-0))
(&+! (-> this fly-curve v1-0) offset)
)
)
)
(call-parent-method this offset)
)
;; WARN: Return type mismatch object vs none.
(defmethod init-from-entity! ((this wren) (arg0 entity-actor))
"Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that.
This commonly includes things such as:
- stack size
- collision information
- loading the skeleton group / bones
- sounds"
(set! (-> this root) (new 'process 'trsqv))
(process-drawable-from-entity! this arg0)
(initialize-skeleton
this
(the-as skeleton-group (art-group-get-by-name *level* "skel-wren" (the-as (pointer uint32) #f)))
(the-as pair 0)
)
(logclear! (-> this mask) (process-mask actor-pause))
(let ((f0-0 (rand-vu-float-range 1.5 3.5)))
(set-vector! (-> this root scale) f0-0 f0-0 f0-0 1.0)
)
(set! (-> this fly-index) (the-as uint 0))
(set! (-> this path-u) 0.0)
(set! (-> this flags) (wren-flags))
(set! (-> this bob-level) 0.0)
(set! (-> this bank-angle) 0.0)
(set! (-> this path) (new 'process 'path-control this 'idle 0.0 arg0 #f))
(logior! (-> this path flags) (path-control-flag display draw-line draw-point draw-text))
(cond
((logtest? (-> this path flags) (path-control-flag not-found))
(dotimes (s5-1 2)
(set! (-> this fly-curve s5-1) (new 'process 'curve-control this 'path (the float s5-1)))
(logior! (-> this fly-curve s5-1 flags) (path-control-flag display draw-line draw-point draw-text))
)
(setup-masks (-> this draw) 0 -1)
(setup-masks (-> this draw) 8 0)
(go (method-of-object this fly))
)
(else
(set! (-> this fly-curve 0) (new 'process 'curve-control this 'takeoff -1000000000.0))
(logior! (-> this fly-curve 0 flags) (path-control-flag display draw-line draw-point draw-text))
(set! (-> this fly-curve 1) #f)
(setup-masks (-> this draw) 0 -1)
(setup-masks (-> this draw) 2 0)
(go (method-of-object this peck))
)
)
(none)
)