Files
jak-project/goal_src/jak2/levels/common/enemy/hover/hover-enemy-battle.gc
T
water111 637990314b wip: better stack var support (#4222)
Closes #736

---------

Co-authored-by: Hat Kid <6624576+Hat-Kid@users.noreply.github.com>
2026-04-19 00:14:44 +02:00

300 lines
8.4 KiB
Common Lisp

;;-*-Lisp-*-
(in-package goal)
;; name: hover-enemy-battle.gc
;; name in dgo: hover-enemy-battle
;; dgos: FOR, DMI, FRA, STR, NEB, D3A, UNB
(declare-type base-turret process-focusable)
(declare-type turret base-turret)
;; DECOMP BEGINS
(deftype hover-enemy-battle-command (structure)
((command symbol)
(wave uint16)
(time time-frame)
(alive-count int32)
)
)
(deftype hover-enemy-manager (process)
((command-table (array hover-enemy-battle-command))
(path path-control)
(formation hover-formation-control)
(actor-group (pointer actor-group))
(actor-group-count int32)
(total-to-spawn int32)
(num-spawned int32)
(alive-count int32)
(formation-timer time-frame)
)
(:state-methods
idle
spawning
die
)
(:methods
(hover-enemy-manager-init! (_type_ (array hover-enemy-battle-command)) none)
(spawn-enemy (_type_ uint) none)
)
)
(defbehavior hover-enemy-manager-handler hover-enemy-manager ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
(local-vars (v0-0 object))
(case arg2
(('join 'leave 'set-type 'get-formation 'set-los)
(when (-> self formation)
(let ((v1-2 (-> self formation))
(a1-8 arg0)
)
(case arg2
(('join)
(hover-formation-control-method-17 v1-2 a1-8)
)
(('leave)
(hover-formation-control-method-18 v1-2 a1-8)
)
(('set-type)
(let ((a1-11 1))
(case (-> arg3 param 0)
(('line)
(set! a1-11 0)
)
(('circle)
(set! a1-11 2)
)
(('semicircle)
(set! a1-11 3)
)
)
(try-update-formation-type v1-2 (the-as formation-type a1-11))
)
)
(('get-formation)
v1-2
)
(('set-los)
(cond
((-> arg3 param 0)
(set! v0-0 (logior (-> v1-2 flags) 2))
(set! (-> v1-2 flags) (the-as uint v0-0))
)
(else
(set! v0-0 (logand -3 (-> v1-2 flags)))
(set! (-> v1-2 flags) (the-as uint v0-0))
)
)
v0-0
)
)
)
)
)
(('num-alive?)
(-> self alive-count)
)
(('num-spawned?)
(-> self num-spawned)
)
(('total-to-spawn?)
(-> self total-to-spawn)
)
(('hover-die)
(set! v0-0 (max 0 (+ (-> self alive-count) -1)))
(set! (-> self alive-count) (the-as int v0-0))
v0-0
)
(('path)
(if (not (logtest? (-> self path flags) (path-control-flag not-found)))
(-> self path)
)
)
)
)
(defbehavior hover-enemy-manager-post hover-enemy-manager ()
(when (-> self formation)
(let ((gp-0 (-> self formation)))
(let ((a0-0 gp-0))
((the-as (function hover-formation-control none) (method-of-object a0-0 hover-formation-control-method-14))
a0-0
)
)
(when (and (logtest? (-> gp-0 flags) 2) (time-elapsed? (-> self formation-timer) (seconds 0.2)))
(hover-formation-control-method-11 gp-0)
(set-time! (-> self formation-timer))
)
)
)
(if (not (logtest? (-> self path flags) (path-control-flag not-found)))
(debug-draw (-> self path))
)
(none)
)
(defstate idle (hover-enemy-manager)
:virtual #t
:event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
(case message
(('trigger)
(go-virtual spawning)
)
(else
(hover-enemy-manager-handler proc argc message block)
)
)
)
:code sleep-code
:post hover-enemy-manager-post
)
(defstate spawning (hover-enemy-manager)
:virtual #t
:event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
(case message
(('spawning?)
#t
)
(else
(hover-enemy-manager-handler proc argc message block)
)
)
)
:enter (behavior ()
(let ((a0-0 (-> self formation)))
(if a0-0
(set-anchor-proc a0-0 (process->handle *target*))
)
)
)
:code (behavior ()
(let ((gp-0 (-> self command-table)))
(dotimes (s5-0 (-> gp-0 length))
(case (-> gp-0 s5-0 command)
(('spawn)
(spawn-enemy self (-> gp-0 s5-0 wave))
)
(('wait)
)
)
(suspend-for (-> gp-0 s5-0 time)
)
(while (< (-> gp-0 s5-0 alive-count) (-> self alive-count))
(suspend)
)
)
)
(suspend-for (seconds 2)
)
(go-virtual die)
)
:post hover-enemy-manager-post
)
(defstate die (hover-enemy-manager)
:virtual #t
:event hover-enemy-manager-handler
:code (behavior ()
(while (-> self child)
(suspend)
)
(process-entity-status! self (entity-perm-status dead) #t)
)
)
(defmethod spawn-enemy ((this hover-enemy-manager) (arg0 uint))
(when (< arg0 (the-as uint (-> this actor-group-count)))
(dotimes (s4-0 (-> this actor-group arg0 length))
(let* ((s1-0 (-> this actor-group arg0 data s4-0 actor))
(s2-0 (-> (the-as entity-actor s1-0) etype))
(s3-0 (new 'stack-no-clear 'transformq))
)
(set! (-> s3-0 trans quad) (-> s1-0 extra trans quad))
(quaternion-copy! (-> s3-0 quat) (-> (the-as entity-actor s1-0) quat))
(set! (-> s3-0 scale x) (the-as float s1-0))
(set! (-> s3-0 scale y) (the-as float #f))
(set! (-> s3-0 scale z) (the-as float #t))
(let ((s1-1 (get-process *default-dead-pool* s2-0 #x4000)))
(when (when s1-1
(let ((t9-2 (method-of-type process activate)))
(t9-2 s1-1 this (symbol->string (-> s2-0 symbol)) (the-as pointer #x70004000))
)
(run-now-in-process s1-1 enemy-init-by-other this s3-0)
(-> s1-1 ppointer)
)
(+! (-> this alive-count) 1)
(+! (-> this num-spawned) 1)
)
)
)
)
)
0
(none)
)
(defmethod relocate ((this hover-enemy-manager) (offset int))
(when (-> this formation)
(if (nonzero? (-> this formation))
(&+! (-> this formation) offset)
)
)
(if (nonzero? (-> this path))
(&+! (-> this path) offset)
)
(call-parent-method this offset)
)
(defmethod hover-enemy-manager-init! ((this hover-enemy-manager) (arg0 (array hover-enemy-battle-command)))
"Initialize this [[hover-enemy-manager]]."
(set! (-> this command-table) arg0)
(set! (-> this path) (new 'process 'path-control this 'path 0.0 (-> this entity) #f))
(logior! (-> this path flags) (path-control-flag display draw-line draw-point draw-text))
(let* ((sv-16 (new 'static 'res-tag))
(v1-5 (res-lump-data (-> this entity) 'actor-groups pointer :tag-ptr (& sv-16)))
)
(cond
((and v1-5 (nonzero? (-> sv-16 elt-count)))
(set! (-> this actor-group) (the-as (pointer actor-group) v1-5))
(set! (-> this actor-group-count) (the-as int (-> sv-16 elt-count)))
)
(else
(set! (-> this actor-group) (the-as (pointer actor-group) #f))
(set! (-> this actor-group-count) 0)
0
)
)
)
(set! (-> this total-to-spawn) 0)
(set! (-> this num-spawned) 0)
(when (-> this command-table)
(let ((v1-13 (-> this command-table)))
(dotimes (a0-6 (-> v1-13 length))
(if (= (-> v1-13 a0-6 command) 'spawn)
(+! (-> this total-to-spawn) (-> this actor-group (-> v1-13 a0-6 wave) length))
)
)
)
)
(set! (-> this formation) #f)
(set-time! (-> this formation-timer))
(set! (-> this alive-count) 0)
0
(none)
)
;; WARN: Return type mismatch object vs none.
(defbehavior hover-enemy-manager-init-by-other hover-enemy-manager ((arg0 entity-actor) (arg1 (array hover-enemy-battle-command)))
(set! (-> self entity) arg0)
(hover-enemy-manager-init! self arg1)
(go-virtual idle)
(none)
)
(defun hover-manager-spawn ((arg0 turret) (arg1 entity-actor) (arg2 (array hover-enemy-battle-command)))
(ppointer->process (process-spawn hover-enemy-manager arg1 arg2 :to arg0))
)