Files
jak-project/goal_src/jak2/levels/common/enemy/hover/hover-enemy.gc
T
Hat Kid 67d4eda169 decomp: hover-* files, wasp, crimson-guard-hover, flamer, target-turret, drill-turret, jellyfish (#2198)
Manual patches:

- `drill-turret`: The static data for `*turret-13-path*`,
`*turret-14-path*` and `*turret-15-path*` was decompiled by hand and the
integers in the `set-speed-mult` events have been replaced with boxed
integer arrays that contain only that integer in order to make the
compiler happy. To that effect, the event handler in `target-turret` was
changed to access that array instead of just accessing the int.
- `hover-nav-control`: In `hover-nav-control::10`, `arg2` is usually a
`vector`, but there are some places where it is called with `#t` as
`arg2` and, subsequently, crashes the game because it tries to access
the `quad` of `arg2` if `arg2` is truthy. To mitigate this, the
condition `arg2` has been replaced with `(and (!= arg2 #t) arg2)` (in
this case, it would jump to the `else` that just resets the `dest-vel`
and `transv` `quad`s)
- `drill-baron`: The static data for `*drill-ship-turret-speed-event*`
has been decompiled by hand.

TODOs:
- Jellyfish crash the game
- Destroying the metalhead eggs that are on the breakable wall crashes
the game (already happened with the Peacemaker before)
- Figure out why static data of type `turret-path-event` doesn't
decompile

The docs for all the hover-nav and nav-network code could use some love
in the future, I'm not smart enough to figure out what any of that code
actually means, but it seems to work...

Also threw in the fix for the ▲ that was accidentally left commented
out.
2023-02-09 18:22:56 -05:00

1032 lines
37 KiB
Common Lisp

;;-*-Lisp-*-
(in-package goal)
;; name: hover-enemy.gc
;; name in dgo: hover-enemy
;; dgos: FOR, DMI, FRA, STR, NEB, D3A, UNB
;; DECOMP BEGINS
(defmethod general-event-handler hover-enemy ((obj hover-enemy) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
"Handles various events for the enemy
@TODO - unsure if there is a pattern for the events and this should have a more specific name"
(local-vars (v1-41 float))
(rlet ((acc :class vf)
(vf0 :class vf)
(vf1 :class vf)
(vf2 :class vf)
)
(init-vf0-vector)
(case arg2
(('hit 'hit-knocked 'hit-flinch)
(logclear! (-> obj mask) (process-mask actor-pause))
(logclear! (-> obj focus-status) (focus-status dangerous))
(logclear! (-> obj enemy-flags) (enemy-flag enable-on-notice))
(logior! (-> obj enemy-flags) (enemy-flag chase-startup))
(logior! (-> obj focus-status) (focus-status hit))
(if (zero? (-> obj hit-points))
(logior! (-> obj focus-status) (focus-status dead))
)
(logclear! (-> obj enemy-flags) (enemy-flag actor-pause-backup))
(enemy-method-62 obj)
(set! (-> obj enemy-flags) (logior (enemy-flag actor-pause-backup) (-> obj enemy-flags)))
(process-contact-action arg0)
(send-event arg0 'get-attack-count 1)
(cond
((zero? (-> obj hit-points))
(if (rng-hit? obj 0.4)
(go (method-of-object obj flying-death))
(go (method-of-object obj flying-death-explode))
)
)
(else
(go (method-of-object obj knocked))
)
)
#t
)
(('update-formation)
(let ((s5-1 (the-as object (-> arg3 param 0))))
(let* ((f0-0 409.6)
(f0-2 (* f0-0 f0-0))
)
(.lvf vf1 (&-> (vector-! (new 'stack-no-clear 'vector) (the-as vector s5-1) (-> obj offset)) quad))
(.add.w.vf vf2 vf0 vf0 :mask #b1)
(.mul.vf vf1 vf1 vf1)
(.mul.x.vf acc vf2 vf1 :mask #b1)
(.add.mul.y.vf acc vf2 vf1 acc :mask #b1)
(.add.mul.z.vf vf1 vf2 vf1 acc :mask #b1)
(.mov v1-41 vf1)
(if (< f0-2 v1-41)
(hover-nav-control-method-21 (-> obj hover))
)
)
(let ((v0-7 (the-as object (-> obj offset))))
(set! (-> (the-as vector v0-7) quad) (-> (the-as vector s5-1) quad))
v0-7
)
)
)
(('get-hover-nav-sphere)
(if (not (and (-> obj next-state) (let ((v1-49 (-> obj next-state name)))
(or (= v1-49 'dormant) (= v1-49 'dormant-aware))
)
)
)
(-> (the-as collide-shape-prim-group (-> obj root-override2 root-prim))
child
(-> obj hover params nav-collide-prim-index)
prim-core
)
)
)
(else
((method-of-type enemy general-event-handler) obj arg0 arg1 arg2 arg3)
)
)
)
)
(defbehavior hover-enemy-dest-post hover-enemy ()
(local-vars (at-0 int) (at-1 int))
(rlet ((vf0 :class vf)
(vf1 :class vf)
(vf2 :class vf)
)
(init-vf0-vector)
(let ((a1-1 (hover-nav-control-method-16 (-> self hover) (new 'stack-no-clear 'vector)))
(gp-0 (new 'stack-no-clear 'vector))
)
(vector-flatten! gp-0 a1-1 *y-vector*)
(let ((f28-0 (lerp-scale -10922.667 10922.667 (-> gp-0 z) -1.0 1.0))
(f30-0 (lerp-scale 10922.667 -10922.667 (-> gp-0 x) -1.0 1.0))
)
(set! (-> self rotation-vec x)
(deg-seek (-> self rotation-vec x) f28-0 (* 5461.3335 (-> self clock seconds-per-frame)))
)
(set! (-> self rotation-vec z)
(deg-seek (-> self rotation-vec z) f30-0 (* 6371.5557 (-> self clock seconds-per-frame)))
)
)
)
(let ((s4-1 (vector-! (new 'stack-no-clear 'vector) (-> self focus-pos) (-> self root-override2 trans))))
(vector-normalize! s4-1 1.0)
(set! (-> self rotation-vec y)
(deg-seek (-> self rotation-vec y) (vector-y-angle s4-1) (* 14563.556 (-> self clock seconds-per-frame)))
)
)
(hover-enemy-method-146 self)
(hover-nav-control-method-12 (-> self hover))
(enemy-simple-post)
(let ((a0-14
(vector<-cspace! (new 'stack-no-clear 'vector) (-> self node-list data (-> self hover-info main-joint)))
)
(v1-18 (new 'stack-no-clear 'vector))
)
(let ((a1-10 (new 'stack-no-clear 'vector)))
(vector-! v1-18 a0-14 (-> self main-joint-pos))
(let ((a2-7 v1-18))
(.lvf vf1 (&-> v1-18 quad))
(let ((f0-14 (-> self clock frames-per-second)))
(.mov at-0 f0-14)
)
(.mov vf2 at-0)
(.mov.vf vf1 vf0 :mask #b1000)
(.mul.x.vf vf1 vf1 vf2 :mask #b111)
(.svf (&-> a2-7 quad) vf1)
)
(vector-! a1-10 v1-18 (-> self main-joint-vel))
(let ((a2-9 (-> self main-joint-acc)))
(.lvf vf1 (&-> a1-10 quad))
(let ((f0-15 (-> self clock frames-per-second)))
(.mov at-1 f0-15)
)
(.mov vf2 at-1)
(.mov.vf vf1 vf0 :mask #b1000)
(.mul.x.vf vf1 vf1 vf2 :mask #b111)
(.svf (&-> a2-9 quad) vf1)
)
)
(set! (-> self main-joint-pos quad) (-> a0-14 quad))
(set! (-> self main-joint-vel quad) (-> v1-18 quad))
)
0
(hover-enemy-method-142 self)
0
(none)
)
)
(defbehavior hover-enemy-hostile-post hover-enemy ()
(let ((a1-0 (new 'stack-no-clear 'event-message-block)))
(set! (-> a1-0 from) (process->ppointer self))
(set! (-> a1-0 num-params) 0)
(set! (-> a1-0 message) 'get-formation)
(let* ((t9-0 send-event-function)
(v1-2 (-> self formation-entity))
(a0-2 (the-as hover-formation (t9-0
(if v1-2
(-> v1-2 extra process)
)
a1-0
)
)
)
(gp-0 (-> self dest-pos))
)
(cond
(a0-2
(hover-formation-method-15 a0-2 gp-0 (-> self offset))
)
(else
(let* ((s5-0 (handle->process (-> self focus handle)))
(a0-7 (if (type? s5-0 process-focusable)
s5-0
)
)
)
(cond
(a0-7
(let* ((s5-1 (get-trans (the-as process-focusable a0-7) 3))
(a0-9 (vector-! (new 'stack-no-clear 'vector) (-> self root-override2 trans) s5-1))
)
(vector+! gp-0 s5-1 (vector-rotate-y! (new 'stack-no-clear 'vector) (-> self offset) (vector-y-angle a0-9)))
)
)
(else
(set! (-> gp-0 quad) (-> self root-override2 trans quad))
)
)
)
)
)
(hover-nav-control-method-11 (-> self hover) gp-0)
)
)
(hover-enemy-dest-post)
(none)
)
(defmethod hover-enemy-method-142 hover-enemy ((obj hover-enemy))
0
(none)
)
(defmethod hover-enemy-method-153 hover-enemy ((obj hover-enemy))
(let* ((v1-0 (-> obj formation-entity))
(a0-1 (if v1-0
(-> v1-0 extra process)
)
)
)
(if a0-1
(send-event a0-1 'join)
)
)
0
(none)
)
(defmethod hover-enemy-method-154 hover-enemy ((obj hover-enemy))
(let* ((v1-0 (-> obj formation-entity))
(a0-1 (if v1-0
(-> v1-0 extra process)
)
)
)
(if a0-1
(send-event a0-1 'leave)
)
)
0
(none)
)
(defmethod coin-flip? hover-enemy ((obj hover-enemy))
"@returns The result of a 50/50 RNG roll"
#f
)
(defmethod hover-enemy-method-144 hover-enemy ((obj hover-enemy))
(set! (-> obj main-joint-pos quad) (-> obj root-override2 trans quad))
(set! (-> obj main-joint-vel quad) (the-as uint128 0))
(set! (-> obj main-joint-acc quad) (the-as uint128 0))
(set! (-> obj thrust 0) 0.0)
(set! (-> obj thrust 1) 0.0)
0
(none)
)
(defmethod hover-enemy-method-145 hover-enemy ((obj hover-enemy) (arg0 int) (arg1 float) (arg2 int) (arg3 int))
(local-vars (v1-1 int))
0
(if (< 0.0 arg1)
(set! v1-1 arg2)
(set! v1-1 arg3)
)
(let ((a3-5 (-> obj skel root-channel arg0)))
(let ((f0-2 (fabs arg1)))
(set! (-> a3-5 frame-interp 1) f0-2)
(set! (-> a3-5 frame-interp 0) f0-2)
)
(set! (-> a3-5 frame-group) (the-as art-joint-anim (-> obj draw art-group data v1-1)))
(set! (-> a3-5 param 0) 0.0)
(set! (-> a3-5 frame-num) (-> obj skel root-channel 0 frame-num))
(joint-control-channel-group! a3-5 (the-as art-joint-anim (-> obj draw art-group data v1-1)) num-func-chan)
)
(none)
)
;; WARN: Return type mismatch vector vs none.
(defmethod enemy-method-129 hover-enemy ((obj hover-enemy))
(local-vars (s5-0 vector))
(let ((t9-0 (method-of-type enemy enemy-method-129)))
(t9-0 obj)
)
(let ((a0-3 (handle->process (-> obj focus handle))))
(set! s5-0 (when a0-3
(set! s5-0 (-> obj focus-pos))
(set! (-> s5-0 quad) (-> (get-trans (the-as process-focusable a0-3) 3) quad))
s5-0
)
)
)
(none)
)
(defmethod track-target! hover-enemy ((obj hover-enemy))
"Does a lot of various things relating to interacting with the target
- tracks when the enemy was last drawn
- looks at the target and handles attacking
@TODO Not extremely well understood yet"
(hover-enemy-method-148 obj)
(enemy-method-129 obj)
(let ((t9-2 (method-of-type enemy track-target!)))
(t9-2 obj)
)
(hover-nav-control-method-13 (-> obj hover))
(none)
)
(defmethod hover-enemy-method-148 hover-enemy ((obj hover-enemy))
(cond
((and (-> obj draw shadow) (logtest? (-> obj draw status) (draw-control-status on-screen)))
(new 'stack-no-clear 'vector)
(new 'stack-no-clear 'vector)
(let ((s4-0 (new 'stack-no-clear 'collide-query))
(gp-0 (-> obj draw shadow-ctrl settings shadow-dir))
(f30-0 122880.0)
)
(set! (-> s4-0 start-pos quad) (-> obj root-override2 trans quad))
(vector-normalize-copy! (-> s4-0 move-dist) gp-0 f30-0)
(let ((v1-10 s4-0))
(set! (-> v1-10 radius) 2048.0)
(set! (-> v1-10 collide-with) (collide-spec backgnd))
(set! (-> v1-10 ignore-process0) obj)
(set! (-> v1-10 ignore-process1) #f)
(set! (-> v1-10 ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1))
(set! (-> v1-10 action-mask) (collide-action solid))
)
(let ((f0-1 (fill-and-probe-using-line-sphere *collide-cache* s4-0)))
(cond
((>= f0-1 0.0)
(let ((v1-14 (-> obj draw shadow-ctrl)))
(logclear! (-> v1-14 settings flags) (shadow-flags disable-draw))
)
0
(-> s4-0 best-other-tri intersect)
(let ((a1-3 (-> obj root-override2 trans)))
(-> a1-3 y)
(let ((f0-2 (* f0-1 f30-0)))
(shadow-control-method-14
(-> obj draw shadow-ctrl)
a1-3
gp-0
(- (+ 81920.0 f30-0))
(+ -12288.0 f0-2)
(+ 12288.0 f0-2)
)
)
)
)
(else
(let ((v1-25 (-> obj draw shadow-ctrl)))
(logior! (-> v1-25 settings flags) (shadow-flags disable-draw))
)
0
)
)
)
)
)
(else
(let ((v1-28 (-> obj draw shadow-ctrl)))
(logior! (-> v1-28 settings flags) (shadow-flags disable-draw))
)
0
)
)
0
(none)
)
;; WARN: Return type mismatch symbol vs none.
;; WARN: new jak 2 until loop case, check carefully
(defbehavior hover-enemy-fly-code hover-enemy ()
(let ((gp-0 (-> self draw art-group data (-> self enemy-info idle-anim))))
(cond
((-> self restart-fly-anims)
(ja-channel-push! 3 (seconds 0.2))
(ja-no-eval :group! gp-0
:num! (seek! (the float (+ (-> (the-as art-joint-anim gp-0) frames num-frames) -1)) (-> self fly-anim-speed))
:frame-num 0.0
)
(let ((a0-4 (-> self skel root-channel 1)))
(let ((f0-4 0.0))
(set! (-> a0-4 frame-interp 1) f0-4)
(set! (-> a0-4 frame-interp 0) f0-4)
)
(set! (-> a0-4 frame-group) (the-as art-joint-anim gp-0))
(set! (-> a0-4 param 0) (the float (+ (-> (the-as art-joint-anim gp-0) frames num-frames) -1)))
(set! (-> a0-4 param 1) (-> self fly-anim-speed))
(set! (-> a0-4 frame-num) 0.0)
(joint-control-channel-group! a0-4 (the-as art-joint-anim gp-0) num-func-seek!)
)
(let ((a0-5 (-> self skel root-channel 2)))
(let ((f0-9 0.0))
(set! (-> a0-5 frame-interp 1) f0-9)
(set! (-> a0-5 frame-interp 0) f0-9)
)
(set! (-> a0-5 frame-group) (the-as art-joint-anim gp-0))
(set! (-> a0-5 param 0) (the float (+ (-> (the-as art-joint-anim gp-0) frames num-frames) -1)))
(set! (-> a0-5 param 1) (-> self fly-anim-speed))
(set! (-> a0-5 frame-num) 0.0)
(joint-control-channel-group! a0-5 (the-as art-joint-anim gp-0) num-func-seek!)
)
(set! (-> self restart-fly-anims) #f)
)
(else
(ja-no-eval :group! gp-0 :num! (loop! (-> self fly-anim-speed)))
(let ((a0-7 (-> self skel root-channel 1)))
(let ((f0-15 0.0))
(set! (-> a0-7 frame-interp 1) f0-15)
(set! (-> a0-7 frame-interp 0) f0-15)
)
(set! (-> a0-7 frame-group) (the-as art-joint-anim gp-0))
(set! (-> a0-7 param 0) (-> self fly-anim-speed))
(joint-control-channel-group! a0-7 (the-as art-joint-anim gp-0) num-func-loop!)
)
(let ((a0-8 (-> self skel root-channel 2)))
(let ((f0-17 0.0))
(set! (-> a0-8 frame-interp 1) f0-17)
(set! (-> a0-8 frame-interp 0) f0-17)
)
(set! (-> a0-8 frame-group) (the-as art-joint-anim gp-0))
(set! (-> a0-8 param 0) (-> self fly-anim-speed))
(joint-control-channel-group! a0-8 (the-as art-joint-anim gp-0) num-func-loop!)
)
(ja :num! (loop!))
)
)
)
(until #f
(let ((s5-0 (hover-nav-control-method-16 (-> self hover) (new 'stack-no-clear 'vector)))
(gp-1 (-> self hover-info))
)
(seek! (-> self local-dir x) (-> s5-0 x) (* 1.3 (-> self clock seconds-per-frame)))
(seek! (-> self local-dir z) (-> s5-0 z) (* 1.3 (-> self clock seconds-per-frame)))
(hover-enemy-method-145 self 1 (-> self local-dir x) (-> gp-1 fly-left-anim) (-> gp-1 fly-right-anim))
(hover-enemy-method-145 self 2 (-> self local-dir z) (-> gp-1 fly-forward-anim) (-> gp-1 fly-backward-anim))
)
(suspend)
(ja :num! (loop! (-> self fly-anim-speed)))
)
#f
(none)
)
(defstate ambush (hover-enemy)
:virtual #t
:enter (behavior ()
(logior! (-> self enemy-flags) (enemy-flag use-notice-distance))
(hover-enemy-method-140 self #f)
(if (logtest? (-> self path flags) (path-control-flag not-found))
(go process-drawable-art-error "no path")
)
(set! (-> self scale-timer) (the-as uint (-> self clock frame-counter)))
(cond
((not (logtest? (-> self fact-info-override enemy-options) (enemy-option user0)))
(logclear! (-> self enemy-flags) (enemy-flag enable-on-active))
(hover-enemy-method-141 self 0.0)
)
(else
(hover-enemy-method-141 self 1.0)
)
)
(let* ((gp-0 *target*)
(s1-0 (if (type? gp-0 process-focusable)
gp-0
)
)
(gp-1 (new 'stack-no-clear 'vector))
(s2-0 (new 'stack-no-clear 'vector))
(s4-0 (-> self root-override2))
(s5-0 (get-point-at-percent-along-path! (-> self path) (new 'stack-no-clear 'vector) 0.0 'interp))
)
(let ((s0-0 (get-point-at-percent-along-path! (-> self path) (new 'stack-no-clear 'vector) 1.0 'interp))
(s3-1
(-> (the-as collide-shape-prim-group (-> self root-override2 root-prim))
child
(-> (hover-enemy-method-152 self) nav-collide-prim-index)
local-sphere
)
)
)
(if s1-0
(set! (-> self focus-pos quad) (-> (get-trans s1-0 3) quad))
(set! (-> self focus-pos quad) (-> s0-0 quad))
)
(vector-! s2-0 (-> self focus-pos) (-> s4-0 trans))
(vector-normalize! s2-0 1.0)
(set-vector! (-> self rotation-vec) (- (vector-x-angle s2-0)) (vector-y-angle s2-0) 0.0 0.0)
(hover-enemy-method-146 self)
(set! (-> s4-0 trans quad) (-> s5-0 quad))
(if (logtest? (-> self fact-info-override enemy-options) (enemy-option user0))
(vector-!
(-> s4-0 trans)
(-> s4-0 trans)
(vector-orient-by-quat! (new 'stack-no-clear 'vector) s3-1 (-> s4-0 quat))
)
)
)
(displacement-between-points-at-percent-normalized! (-> self path) gp-1 0.0)
(hover-nav-control-method-10
(-> self hover)
s5-0
gp-1
(vector-normalize-copy! (new 'stack-no-clear 'vector) gp-1 (* 0.8 (-> self hover params max-speed)))
)
)
(hover-enemy-method-144 self)
(hover-nav-control-method-18 (-> self hover) (-> self path) -1 -1)
(set! (-> self state-time) (-> self clock frame-counter))
(none)
)
:exit (behavior ()
(local-vars (v1-5 enemy-flag))
(hover-nav-control-method-20 (-> self hover))
(hover-enemy-method-140 self #t)
(let ((v1-4 (-> self enemy-flags)))
(if (logtest? v1-4 (enemy-flag checking-water))
(set! v1-5 (logior v1-4 (enemy-flag enable-on-active)))
(set! v1-5 (logclear v1-4 (enemy-flag enable-on-active)))
)
)
(set! (-> self enemy-flags) v1-5)
(hover-enemy-method-153 self)
(none)
)
:trans (behavior ()
(when (hover-nav-control-method-23 (-> self hover))
(hover-enemy-method-153 self)
(if (not (logtest? (-> self fact-info-override enemy-options) (enemy-option user0)))
(hover-enemy-method-141 self 1.0)
)
(go-virtual hostile)
)
(none)
)
:code hover-enemy-fly-code
:post (behavior ()
(local-vars (v1-19 enemy-flag))
(when (not (logtest? (-> self fact-info-override enemy-options) (enemy-option user0)))
(let ((f0-1 (the float (- (-> self clock frame-counter) (the-as int (-> self scale-timer)))))
(f1-0 1200.0)
)
(when (< f0-1 f1-0)
(let ((f30-0 (fmin 1.0 (/ (+ 30.0 f0-1) f1-0))))
(hover-enemy-method-141 self f30-0)
(when (and (not (logtest? (-> self enemy-flags) (enemy-flag enable-on-active))) (>= f30-0 1.0))
(let ((v1-18 (-> self enemy-flags)))
(if (logtest? v1-18 (enemy-flag checking-water))
(set! v1-19 (logior v1-18 (enemy-flag enable-on-active)))
(set! v1-19 (logclear v1-18 (enemy-flag enable-on-active)))
)
)
(set! (-> self enemy-flags) v1-19)
)
)
)
)
)
(hover-nav-control-method-11 (-> self hover) (the-as vector #f))
(hover-enemy-dest-post)
(none)
)
)
(defstate notice (hover-enemy)
:virtual #t
:enter (behavior ()
(let ((t9-0 (-> (method-of-type enemy notice) enter)))
(if t9-0
(t9-0)
)
)
(let ((gp-0 (new 'stack-no-clear 'vector))
(a0-0 *target*)
(s5-0 (-> self root-override2 trans))
)
(if a0-0
(vector-normalize! (vector-! gp-0 (get-trans a0-0 3) s5-0) 1.0)
(vector-z-quaternion! gp-0 (-> self root-override2 quat))
)
(hover-nav-control-method-10 (-> self hover) s5-0 gp-0 (the-as vector #t))
)
(hover-enemy-method-144 self)
(none)
)
:exit (behavior ()
(let ((t9-0 (-> (method-of-type enemy notice) exit)))
(if t9-0
(t9-0)
)
)
(hover-enemy-method-153 self)
(none)
)
)
(defstate hostile (hover-enemy)
:virtual #t
:code hover-enemy-fly-code
:post hover-enemy-hostile-post
)
(defstate knocked (hover-enemy)
:virtual #t
:enter (behavior ()
(let* ((t9-0 find-parent-method)
(a0-0 hover-enemy)
(t9-1 (-> (the-as state (t9-0 a0-0 30)) enter))
)
(if t9-1
((the-as (function enemy none) t9-1) (the-as enemy a0-0))
)
)
(set! (-> self hit-surface?) #f)
(set! (-> self knocked-start-level) (-> self root-override2 trans y))
(none)
)
:exit (behavior ()
(let ((t9-1 (-> (the-as state (find-parent-method hover-enemy 30)) exit)))
(if t9-1
(t9-1)
)
)
(set! (-> self hit-surface?) #f)
(none)
)
:trans (behavior ()
(let ((gp-0 (-> self root-override2)))
(when (logtest? (-> gp-0 status) (collide-status on-surface))
(when (not (-> self hit-surface?))
(set! (-> self hit-surface?) #t)
(set! (-> self surface-normal quad) (-> gp-0 poly-normal quad))
)
)
(when (and (-> self hit-surface?) (zero? (-> self hit-points)))
(let ((s4-0 (new 'stack-no-clear 'quaternion)))
(let ((s5-0 (new 'stack-no-clear 'vector)))
(vector-z-quaternion! s5-0 (-> gp-0 quat))
(forward-up->quaternion s4-0 s5-0 (-> self surface-normal))
)
(quaternion-slerp! (-> gp-0 quat) (-> gp-0 quat) s4-0 0.25)
)
)
)
(if (and (nonzero? (-> self hit-points))
(zero? (-> self fated-time))
(>= (- (-> self clock frame-counter) (-> self state-time)) (seconds 0.5))
(< (-> self root-override2 trans y) (- (-> self knocked-start-level) (-> self knocked-fall-dist)))
)
(go-virtual knocked-recover)
)
(none)
)
)
(defstate knocked-recover (hover-enemy)
:virtual #t
:event (the-as (function process int symbol event-message-block object :behavior hover-enemy) enemy-event-handler)
:code (behavior ()
(local-vars (v1-38 enemy-flag) (v1-46 enemy-flag))
(ja-channel-push! 1 (seconds 0.5))
(ja-no-eval :group! (-> self draw art-group data (-> self enemy-info knocked-land-anim))
:num! (seek!
(the float
(+ (-> (the-as art-joint-anim (-> self draw art-group data (-> self enemy-info knocked-land-anim)))
frames
num-frames
)
-1
)
)
)
:frame-num 0.0
)
(until (ja-done? 0)
(suspend)
(ja :num! (seek!))
)
(set! (-> self restart-fly-anims) #t)
(if (logtest? (-> self enemy-flags) (enemy-flag check-water))
(logior! (-> self focus-status) (focus-status dangerous))
(logclear! (-> self focus-status) (focus-status dangerous))
)
(let ((v1-37 (-> self enemy-flags)))
(if (logtest? v1-37 (enemy-flag checking-water))
(set! v1-38 (logior v1-37 (enemy-flag enable-on-active)))
(set! v1-38 (logclear v1-37 (enemy-flag enable-on-active)))
)
)
(set! (-> self enemy-flags) v1-38)
(if (logtest? (-> self enemy-flags) (enemy-flag look-at-move-dest))
(set! (-> self mask) (logior (process-mask collectable) (-> self mask)))
(logclear! (-> self mask) (process-mask collectable))
)
(let ((v1-45 (-> self enemy-flags)))
(if (logtest? (enemy-flag no-initial-move-to-ground) v1-45)
(set! v1-46 (logior (enemy-flag check-water-backup) v1-45))
(set! v1-46 (logclear v1-45 (enemy-flag check-water-backup)))
)
)
(set! (-> self enemy-flags) v1-46)
(logclear! (-> self enemy-flags) (enemy-flag actor-pause-backup))
(logclear! (-> self focus-status) (focus-status hit))
(hover-nav-control-method-21 (-> self hover))
(go-hostile self)
(none)
)
:post hover-enemy-hostile-post
)
(defstate flying-death (hover-enemy)
:virtual #t
:event (behavior ((proc process) (arg1 int) (event-type symbol) (event event-message-block))
(case event-type
(('touch 'touched 'attack)
(if (>= (- (-> self clock frame-counter) (-> self state-time)) (seconds 0.5))
(go-virtual flying-death-explode)
)
)
)
)
:enter (behavior ()
(set! (-> self state-time) (-> self clock frame-counter))
(dispose! self)
(stop-looking-at-target! self)
(set! (-> self enemy-flags) (logior (enemy-flag actor-pause-backup) (-> self enemy-flags)))
(logclear! (-> self mask) (process-mask actor-pause))
(logclear! (-> self focus-status) (focus-status dangerous))
(logclear! (-> self enemy-flags) (enemy-flag check-water-backup))
(set! (-> self root-override2 penetrate-using) (penetrate lunge vehicle knocked))
(let ((gp-0 (-> self flying-death-transv)))
(let ((a1-0 (handle->process (-> self incoming attacker-handle))))
(if a1-0
(vector-! gp-0 (-> (the-as process-focusable a1-0) root-override trans) (-> self root-override2 trans))
(vector-! gp-0 (-> self incoming attacker-pos) (-> self root-override2 trans))
)
)
(set! (-> gp-0 y) 0.0)
(vector-normalize! gp-0 1.0)
(vector-rotate90-around-y! gp-0 gp-0)
(if (rng-hit? self 0.5)
(vector-negate! gp-0 gp-0)
)
(let ((f30-0 (get-rand-float-range self 0.0 1.0)))
(vector-float*! gp-0 gp-0 (lerp 98304.0 172032.0 f30-0))
(set! (-> gp-0 y) (lerp 8192.0 98304.0 f30-0))
)
(let ((v1-29 (vector-x-quaternion! (new 'stack-no-clear 'vector) (-> self root-override2 quat))))
(cond
((< 0.0 (vector-dot gp-0 v1-29))
(set! (-> self flying-death-anim) (-> self hover-info fly-left-anim))
(set! (-> self flying-death-engine) (-> self hover-info engine-left))
(set! (-> self flying-death-thrust-rotate) (-> self hover-info thrust-rotate-left))
(set! (-> self flying-death-spin-dest) -524288.0)
)
(else
(set! (-> self flying-death-anim) (-> self hover-info fly-right-anim))
(set! (-> self flying-death-engine) (-> self hover-info engine-right))
(set! (-> self flying-death-thrust-rotate) (-> self hover-info thrust-rotate-right))
(set! (-> self flying-death-spin-dest) 524288.0)
)
)
)
)
(set! (-> self flying-death-spin-axis quad) (-> *y-vector* quad))
(vector-rotate-x!
(-> self flying-death-spin-axis)
(-> self flying-death-spin-axis)
(* 182.04445 (rand-vu-float-range -120.0 120.0))
)
(set-gravity-length (-> self root-override2 dynam) 163840.0)
(set! (-> self hover speed) 0.2)
(set! (-> self flying-death-spin) 0.0)
(enemy-method-103 self)
(set! (-> self state-time) (-> self clock frame-counter))
(none)
)
:trans (behavior ()
(if (or (logtest? (-> self root-override2 status)
(collide-status touch-surface touch-wall touch-ceiling touch-actor impact-surface touch-background)
)
(>= (- (-> self clock frame-counter) (-> self state-time)) (seconds 4))
)
(go-virtual flying-death-explode)
)
(none)
)
:code (behavior ()
(ja-channel-push! 1 (seconds 0.2))
(until #f
(ja-no-eval :group! (-> self draw art-group data (-> self flying-death-anim))
:num! (seek!
(the float
(+ (-> (the-as art-joint-anim (-> self draw art-group data (-> self flying-death-anim))) frames num-frames)
-1
)
)
)
:frame-num 0.0
)
(until (ja-done? 0)
(suspend)
(ja :num! (seek!))
)
)
#f
(none)
)
:post (behavior ()
(seek!
(-> self flying-death-spin)
(-> self flying-death-spin-dest)
(* 196608.0 (-> self clock seconds-per-frame))
)
(let ((gp-0 (-> self root-override2)))
(let ((a2-2
(quaternion-vector-angle!
(new 'stack-no-clear 'quaternion)
(-> self flying-death-spin-axis)
(* (-> self flying-death-spin) (-> self clock seconds-per-frame))
)
)
)
(quaternion*! (-> gp-0 quat) (-> gp-0 quat) a2-2)
)
(vector-v++!
(-> self flying-death-transv)
(compute-acc-due-to-gravity gp-0 (new 'stack-no-clear 'vector) 0.8)
)
(let ((v1-6 (hover-enemy-method-152 self)))
(seek!
(-> self hover speed)
(* 2.0 (-> v1-6 max-speed))
(* 0.8 (-> self clock seconds-per-frame) (-> v1-6 max-acceleration))
)
)
(vector-normalize-copy! (-> gp-0 transv) (-> self flying-death-transv) (-> self hover speed))
(let ((a2-8 (new 'stack-no-clear 'collide-query)))
(set! (-> a2-8 collide-with) (-> gp-0 root-prim prim-core collide-with))
(set! (-> a2-8 ignore-process0) (-> gp-0 process))
(set! (-> a2-8 ignore-process1) #f)
(set! (-> a2-8 ignore-pat) (-> gp-0 pat-ignore-mask))
(set! (-> a2-8 action-mask) (collide-action solid))
(fill-cache-integrate-and-collide gp-0 (-> gp-0 transv) a2-8 (meters 0))
)
)
(enemy-simple-post)
(hover-enemy-method-143 self (-> self flying-death-engine) (-> self flying-death-thrust-rotate))
(none)
)
)
(defstate flying-death-explode (hover-enemy)
:virtual #t
:enter (behavior ()
(dispose! self)
(let ((v1-3 (-> self root-override2 root-prim)))
(set! (-> v1-3 prim-core collide-as) (collide-spec))
(set! (-> v1-3 prim-core collide-with) (collide-spec))
)
0
(logior! (-> self draw status) (draw-control-status no-draw))
(none)
)
:code (behavior ()
(while (-> self child)
(suspend)
)
(cleanup-for-death self)
(none)
)
)
(defmethod go-stare hover-enemy ((obj hover-enemy))
(go-hostile obj)
(none)
)
(defmethod go-stare2 hover-enemy ((obj hover-enemy))
(go-hostile obj)
(none)
)
;; WARN: Return type mismatch quaternion vs none.
(defmethod hover-enemy-method-146 hover-enemy ((obj hover-enemy))
(let ((gp-0 (new 'stack-no-clear 'matrix)))
(matrix-rotate-zxy! gp-0 (-> obj rotation-vec))
(matrix->quaternion (-> obj root-override2 quat) gp-0)
)
(none)
)
;; WARN: Return type mismatch float vs none.
(defmethod hover-enemy-method-147 hover-enemy ((obj hover-enemy))
(let ((s5-0 (-> obj root-override2 quat))
(gp-0 (-> obj rotation-vec))
)
(set! (-> gp-0 z) (quaternion-z-angle s5-0))
(set! (-> gp-0 y) (quaternion-y-angle s5-0))
(set! (-> gp-0 x) (quaternion-x-angle s5-0))
)
(none)
)
(defmethod hover-enemy-method-140 hover-enemy ((obj hover-enemy) (arg0 symbol))
(let ((v1-0 0)
(a0-2 (-> obj root-override2 root-prim))
)
(if arg0
(set! v1-0 1)
)
(set! (-> (the-as collide-shape-prim-group a0-2) child 0 prim-core collide-with) (the-as collide-spec v1-0))
(set! (-> (the-as collide-shape-prim-group a0-2) child 1 prim-core collide-with) (the-as collide-spec v1-0))
(set! (-> (the-as collide-shape-prim-group a0-2) child 2 prim-core collide-with) (the-as collide-spec v1-0))
)
0
(none)
)
;; WARN: Return type mismatch vector vs none.
(defmethod hover-enemy-method-141 hover-enemy ((obj hover-enemy) (arg0 float))
(let ((f0-1 (* (-> obj scale) arg0)))
(set-vector! (-> obj root-override2 scale) (* 1.2 f0-1) (* 0.9 f0-1) f0-1 1.0)
)
(none)
)
(defmethod dispose! hover-enemy ((obj hover-enemy))
"Cleans-up the enemy and any associated resources. Potentially spawns skull gems"
(when (not (logtest? (enemy-flag recover-applied-velocity) (-> obj enemy-flags)))
(process-entity-status! obj (entity-perm-status subtask-complete) #t)
(send-event (ppointer->process (-> obj parent)) 'hover-die)
(hover-enemy-method-154 obj)
((method-of-type enemy dispose!) obj)
)
(none)
)
(defmethod deactivate hover-enemy ((obj hover-enemy))
(hover-nav-control-method-9 (-> obj hover))
((method-of-type enemy deactivate) obj)
(none)
)
;; WARN: Return type mismatch enemy vs hover-enemy.
(defmethod relocate hover-enemy ((obj hover-enemy) (arg0 int))
(if (nonzero? (-> obj hover))
(&+! (-> obj hover) arg0)
)
(the-as hover-enemy ((method-of-type enemy relocate) obj arg0))
)
(defmethod hover-enemy-method-155 hover-enemy ((obj hover-enemy))
(set! (-> obj hover-info) (hover-enemy-method-151 obj))
(set! (-> obj fly-anim-speed) (get-rand-float-range obj 0.8 1.2))
(vector-reset! (-> obj rotation-vec))
(vector-reset! (-> obj dest-pos))
(vector-reset! (-> obj local-dir))
(set! (-> obj scale) 1.0)
(hover-enemy-method-141 obj 1.0)
(set! (-> obj formation-entity) (entity-actor-lookup (-> obj entity) 'alt-actor 0))
(logior! (-> obj skel status) (joint-control-status sync-math))
(let ((t0-0 (hover-enemy-method-152 obj)))
(set! (-> obj hover) (new 'process 'hover-nav-control obj (-> obj root-override2) t0-0))
)
(let ((s5-0 (-> obj offset))
(t9-6 (method-of-type res-lump get-property-struct))
(a0-8 (-> obj entity))
(a1-4 'trans-offset)
(a2-3 'interp)
(a3-1 -1000000000.0)
(t0-1 (new 'stack-no-clear 'vector))
)
(set! (-> t0-1 x) 0.0)
(set! (-> t0-1 y) 20480.0)
(set! (-> t0-1 z) 61440.0)
(set! (-> t0-1 w) 1.0)
(set! (-> s5-0 quad)
(-> (the-as vector (t9-6 a0-8 a1-4 a2-3 a3-1 t0-1 (the-as (pointer res-tag) #f) *res-static-buf*)) quad)
)
)
(set! (-> obj restart-fly-anims) #t)
(set! (-> obj knocked-fall-dist) 8192.0)
0
(none)
)
(deftype wasp (hover-enemy)
((gun-jmod joint-mod :offset-assert 784)
(entity-group actor-group :offset-assert 788)
(smoke-part sparticle-launch-control :offset-assert 792)
(engine-part sparticle-launch-control :offset-assert 796)
(old-gravity float :offset 804)
(knocked-anim int32 :offset-assert 808)
(knocked-recover-anim int32 :offset-assert 812)
(last-fire-time time-frame :offset-assert 816)
(bridge-index int32 :offset-assert 824)
(gun-x-angle float :offset-assert 828)
(gun-x-angle-final float :offset-assert 832)
(path-u float :offset-assert 836)
(path-du float :offset-assert 840)
(path-du-final float :offset-assert 844)
(path-dest float :offset-assert 848)
(plat-pos vector :inline :offset-assert 864)
(sound-id sound-id :offset-assert 880)
(attack-wait-min float :offset-assert 884)
(attack-wait-max float :offset-assert 888)
(attack-miss-dist-min float :offset-assert 892)
(attack-miss-dist-max float :offset-assert 896)
(attack-miss-dist-curr float :offset-assert 900)
)
:heap-base #x310
:method-count-assert 166
:size-assert #x388
:flag-assert #xa603100388
(:methods
(shoot-bridge-wait () _type_ :state 156)
(shoot-bridge-intro () _type_ :state 157)
(shoot-bridge-hold () _type_ :state 158)
(shoot-bridge-hostile () _type_ :state 159)
(shoot-bridge-attack () _type_ :state 160)
(shoot-bridge-outro () _type_ :state 161)
(attack () _type_ :state 162)
(die-now () _type_ :state 163)
(die-explode () _type_ :state 164)
(spawn-wasp-shot (_type_ projectile-init-by-other-params int float float) none 165)
)
)