mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 21:27:52 -04:00
8d28bb3480
Closes #1872 --------- Co-authored-by: ManDude <7569514+ManDude@users.noreply.github.com>
517 lines
17 KiB
Common Lisp
517 lines
17 KiB
Common Lisp
;;-*-Lisp-*-
|
|
(in-package goal)
|
|
|
|
;; name: mech.gc
|
|
;; name in dgo: mech
|
|
;; dgos: DRILLMTN, UNB, RUI
|
|
|
|
(declare-type mech process-drawable)
|
|
(define-extern mech-init (function entity-actor matrix3 handle float none :behavior mech))
|
|
|
|
;; DECOMP BEGINS
|
|
|
|
(if (not (nmember "mechp" *kernel-packages*))
|
|
(set! *kernel-packages* (cons "mechp" *kernel-packages*))
|
|
)
|
|
|
|
(deftype mech (process-drawable)
|
|
((root-override collide-shape-moving :offset 128)
|
|
(extra-trans vector :inline :offset-assert 208)
|
|
(condition int32 :offset-assert 224)
|
|
(shadow-backup basic :offset-assert 228)
|
|
(rider uint64 :offset-assert 232)
|
|
(shield-value float :offset-assert 240)
|
|
(nav-sphere-handle uint64 :offset-assert 248)
|
|
(probe-time time-frame :offset-assert 256)
|
|
)
|
|
:heap-base #x90
|
|
:method-count-assert 25
|
|
:size-assert #x108
|
|
:flag-assert #x1900900108
|
|
(:methods
|
|
(wait-for-start () _type_ :state 20)
|
|
(idle () _type_ :state 21)
|
|
(pickup ((state mech)) _type_ :state 22)
|
|
(wait-for-return () _type_ :state 23)
|
|
(mech-method-24 (_type_) none 24)
|
|
)
|
|
)
|
|
|
|
|
|
(defmethod mech-method-24 mech ((obj mech))
|
|
(if (nonzero? (-> obj part))
|
|
(spawn (-> obj part) (-> obj root-override trans))
|
|
)
|
|
(update! (-> obj sound))
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defstate wait-for-start (mech)
|
|
:virtual #t
|
|
:event (behavior ((proc process) (arg1 int) (event-type symbol) (event event-message-block))
|
|
(the-as
|
|
object
|
|
(case event-type
|
|
(('attack 'bonk)
|
|
(send-event proc 'target-mech-get-off 90)
|
|
(let ((a1-3 (new 'stack-no-clear 'event-message-block)))
|
|
(set! (-> a1-3 from) (process->ppointer self))
|
|
(set! (-> a1-3 num-params) 2)
|
|
(set! (-> a1-3 message) 'shove)
|
|
(set! (-> a1-3 param 0) (the-as uint #f))
|
|
(let ((v1-9 (new 'static 'attack-info :mask (attack-info-mask shove-back shove-up id))))
|
|
(let* ((a0-8 *game-info*)
|
|
(a2-2 (+ (-> a0-8 attack-id) 1))
|
|
)
|
|
(set! (-> a0-8 attack-id) a2-2)
|
|
(set! (-> v1-9 id) a2-2)
|
|
)
|
|
(set! (-> v1-9 shove-back) 12288.0)
|
|
(set! (-> v1-9 shove-up) 4096.0)
|
|
(set! (-> a1-3 param 1) (the-as uint v1-9))
|
|
)
|
|
(send-event-function proc a1-3)
|
|
)
|
|
(the-as structure #f)
|
|
)
|
|
(('touch)
|
|
(send-event proc 'target-mech-get-off 90)
|
|
(send-shoves
|
|
(-> self root-override)
|
|
proc
|
|
(the-as touching-shapes-entry (-> event param 0))
|
|
0.7
|
|
6144.0
|
|
16384.0
|
|
)
|
|
(the-as structure #f)
|
|
)
|
|
(('trans)
|
|
(vector+! (the-as vector (-> event param 0)) (-> self root-override trans) (-> self extra-trans))
|
|
)
|
|
(('shadow)
|
|
(cond
|
|
((-> event param 0)
|
|
(let ((v0-2 (the-as structure (-> self shadow-backup))))
|
|
(set! (-> self draw shadow) (the-as shadow-geo v0-2))
|
|
v0-2
|
|
)
|
|
)
|
|
(else
|
|
(set! (-> self draw shadow) #f)
|
|
(the-as structure #f)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
:exit (behavior ()
|
|
(set! (-> self root-override root-prim prim-core action) (collide-action))
|
|
(set! (-> self root-override penetrated-by) (the-as penetrate -1))
|
|
(none)
|
|
)
|
|
:code (behavior ()
|
|
(go-virtual idle)
|
|
(none)
|
|
)
|
|
)
|
|
|
|
(defstate idle (mech)
|
|
:virtual #t
|
|
:event (-> (method-of-type mech wait-for-start) event)
|
|
:enter (behavior ()
|
|
(set! (-> self nav-sphere-handle) (the-as uint #f))
|
|
(let ((s5-0 (find-nearest-nav-mesh (-> self root-override trans) 8192.0)))
|
|
(when s5-0
|
|
(let ((gp-0 (new 'stack-no-clear 'vector)))
|
|
(vector-z-quaternion! gp-0 (-> self root-override quat))
|
|
(vector-normalize! gp-0 5120.0)
|
|
(vector+! gp-0 gp-0 (-> self root-override trans))
|
|
(set! (-> self nav-sphere-handle)
|
|
(the-as uint (ppointer->handle (process-spawn simple-nav-sphere #x46266666 gp-0 s5-0 -1 :to self)))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
(none)
|
|
)
|
|
:exit (behavior ()
|
|
(send-event (handle->process (-> self nav-sphere-handle)) 'die-fast)
|
|
((-> (method-of-type mech wait-for-start) exit))
|
|
(none)
|
|
)
|
|
:code (behavior ()
|
|
(change-parent self *entity-pool*)
|
|
(ja-channel-set! 1)
|
|
(ja :group! mech-mech-idle-ja)
|
|
(set! (-> self root-override root-prim prim-core action) (collide-action solid can-ride no-standon))
|
|
(set! (-> self root-override penetrated-by) (penetrate))
|
|
0.0
|
|
(let ((f30-0 20480.0))
|
|
(until #f
|
|
(when (and (logtest? (-> self draw status) (draw-control-status on-screen))
|
|
(>= (- (current-time) (-> self probe-time)) (seconds 1))
|
|
)
|
|
(move-to-ground
|
|
(-> self root-override)
|
|
8192.0
|
|
40960.0
|
|
#t
|
|
(collide-spec backgnd obstacle hit-by-player-list hit-by-others-list pusher)
|
|
)
|
|
(set! (-> self probe-time) (current-time))
|
|
)
|
|
(when (and (and *target*
|
|
(and (>= f30-0 (vector-vector-distance (-> self root-override trans) (-> *target* control trans)))
|
|
(not (logtest? (focus-status teleporting) (-> *target* focus-status)))
|
|
)
|
|
)
|
|
(not (focus-test? *target* in-head pole board mech dark))
|
|
(can-display-query? self (the-as string #f) -99.0)
|
|
(-> *setting-control* user-current pilot)
|
|
)
|
|
(let ((gp-0
|
|
(new 'stack 'font-context *font-default-matrix* 32 320 0.0 (font-color default) (font-flags shadow kerning))
|
|
)
|
|
)
|
|
(let ((v1-31 gp-0))
|
|
(set! (-> v1-31 width) (the float 340))
|
|
)
|
|
(let ((v1-32 gp-0))
|
|
(set! (-> v1-32 height) (the float 80))
|
|
)
|
|
(let ((v1-33 gp-0))
|
|
(set! (-> v1-33 scale) 0.9)
|
|
)
|
|
(set! (-> gp-0 flags) (font-flags shadow kerning large))
|
|
(print-game-text
|
|
(lookup-text! *common-text* (text-id press-triangle-to-use) #f)
|
|
gp-0
|
|
#f
|
|
44
|
|
(bucket-id progress)
|
|
)
|
|
)
|
|
(if (and (cpad-pressed? 0 triangle) (send-event *target* 'change-mode 'mech self (-> self shield-value)))
|
|
(go-virtual pickup (method-of-object self wait-for-return))
|
|
)
|
|
)
|
|
(target-look-at-me! :trans (vector+! (new 'stack-no-clear 'vector) (the-as vector (-> self root-override root-prim prim-core)) (new 'static 'vector :y 2048.0 :w 1.0)))
|
|
(mech-method-24 self)
|
|
(suspend)
|
|
)
|
|
)
|
|
#f
|
|
(none)
|
|
)
|
|
:post (the-as (function none :behavior mech) ja-post)
|
|
)
|
|
|
|
(defstate pickup (mech)
|
|
:virtual #t
|
|
:event (behavior ((proc process) (arg1 int) (event-type symbol) (event event-message-block))
|
|
(case event-type
|
|
(('draw)
|
|
(ja-channel-set! 1)
|
|
(ja :group! mech-mech-idle-ja)
|
|
(set! (-> self root-override root-prim prim-core action) (collide-action solid can-ride no-standon))
|
|
(set! (-> self root-override penetrated-by) (penetrate))
|
|
(transform-post)
|
|
)
|
|
(('trans)
|
|
(vector+! (the-as vector (-> event param 0)) (-> self root-override trans) (-> self extra-trans))
|
|
)
|
|
(('touch 'attack 'bonk)
|
|
#f
|
|
)
|
|
(('shadow)
|
|
(cond
|
|
((-> event param 0)
|
|
(let ((v0-1 (the-as object (-> self shadow-backup))))
|
|
(set! (-> self draw shadow) (the-as shadow-geo v0-1))
|
|
v0-1
|
|
)
|
|
)
|
|
(else
|
|
(set! (-> self draw shadow) #f)
|
|
#f
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
:enter (behavior ((arg0 (state mech)))
|
|
(let ((t9-0 (-> arg0 enter)))
|
|
(if t9-0
|
|
(t9-0)
|
|
)
|
|
)
|
|
(none)
|
|
)
|
|
:code (behavior ((arg0 (state mech)))
|
|
(ja-channel-set! 0)
|
|
(ja-post)
|
|
(while (zero? (ja-group-size))
|
|
(if (or (not *target*)
|
|
(or (< 24576.0 (vector-vector-distance (-> self root-override trans) (-> *target* control trans)))
|
|
(focus-test? *target* teleporting)
|
|
)
|
|
)
|
|
(go arg0)
|
|
)
|
|
(mech-method-24 self)
|
|
(suspend)
|
|
)
|
|
(while (and *target* (focus-test? *target* mech))
|
|
(mech-method-24 self)
|
|
(suspend)
|
|
)
|
|
(let ((s5-0 (current-time)))
|
|
(until (>= (- (current-time) s5-0) (seconds 1))
|
|
(mech-method-24 self)
|
|
(suspend)
|
|
)
|
|
)
|
|
(go arg0)
|
|
(none)
|
|
)
|
|
)
|
|
|
|
(defstate wait-for-return (mech)
|
|
:virtual #t
|
|
:event (behavior ((proc process) (arg1 int) (event-type symbol) (event event-message-block))
|
|
(the-as
|
|
object
|
|
(case event-type
|
|
(('trans)
|
|
(vector+! (the-as vector (-> event param 0)) (-> self root-override trans) (-> self extra-trans))
|
|
)
|
|
(('shadow)
|
|
(cond
|
|
((-> event param 0)
|
|
(let ((v0-1 (the-as structure (-> self shadow-backup))))
|
|
(set! (-> self draw shadow) (the-as shadow-geo v0-1))
|
|
v0-1
|
|
)
|
|
)
|
|
(else
|
|
(set! (-> self draw shadow) #f)
|
|
(the-as structure #f)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
:code (behavior ()
|
|
(ja-channel-set! 0)
|
|
(ja-post)
|
|
(cleanup-for-death self)
|
|
(none)
|
|
)
|
|
)
|
|
|
|
;; WARN: Return type mismatch object vs none.
|
|
(defbehavior mech-init mech ((arg0 entity-actor) (arg1 matrix3) (arg2 handle) (arg3 float))
|
|
(let ((s2-0 (new 'process 'collide-shape-moving self (collide-list-enum usually-hit-by-player))))
|
|
(set! (-> s2-0 dynam) (copy *standard-dynamics* 'process))
|
|
(set! (-> s2-0 reaction) cshape-reaction-default)
|
|
(set! (-> s2-0 no-reaction)
|
|
(the-as (function collide-shape-moving collide-query vector vector object) nothing)
|
|
)
|
|
(let ((v1-6 (new 'process 'collide-shape-prim-sphere s2-0 (the-as uint 0))))
|
|
(set! (-> v1-6 prim-core collide-as) (collide-spec obstacle obstacle-for-jak))
|
|
(set! (-> v1-6 prim-core collide-with) (collide-spec jak player-list))
|
|
(set! (-> v1-6 prim-core action) (collide-action solid can-ride no-standon))
|
|
(set! (-> v1-6 transform-index) 0)
|
|
(set-vector! (-> v1-6 local-sphere) 0.0 6553.6 5324.8 6553.6)
|
|
(set! (-> s2-0 total-prims) (the-as uint 1))
|
|
(set! (-> s2-0 root-prim) v1-6)
|
|
)
|
|
(set! (-> s2-0 nav-radius) (* 0.75 (-> s2-0 root-prim local-sphere w)))
|
|
(let ((v1-9 (-> s2-0 root-prim)))
|
|
(set! (-> s2-0 backup-collide-as) (-> v1-9 prim-core collide-as))
|
|
(set! (-> s2-0 backup-collide-with) (-> v1-9 prim-core collide-with))
|
|
)
|
|
(set! (-> self root-override) s2-0)
|
|
)
|
|
(set! (-> self rider) (the-as uint arg2))
|
|
(when arg0
|
|
(process-entity-set! self arg0)
|
|
(process-drawable-from-entity! self arg0)
|
|
(set-yaw-angle-clear-roll-pitch! (-> self root-override) (res-lump-float arg0 'rotoffset))
|
|
)
|
|
(when arg1
|
|
(set! (-> self root-override trans quad) (-> arg1 vector 0 quad))
|
|
(quaternion-copy! (-> self root-override quat) (the-as quaternion (-> arg1 vector 1)))
|
|
)
|
|
(initialize-skeleton
|
|
self
|
|
(the-as skeleton-group (art-group-get-by-name *level* "skel-mech" (the-as (pointer uint32) #f)))
|
|
(the-as pair 0)
|
|
)
|
|
(set! (-> self shadow-backup) (-> self draw shadow))
|
|
(set! (-> self draw shadow-ctrl) *mech-shadow-control*)
|
|
(let ((v1-27 (-> self node-list data)))
|
|
(set! (-> v1-27 0 param0) (the-as (function cspace transformq none) cspace<-transformq+trans!))
|
|
(set! (-> v1-27 0 param1) (the-as basic (-> self root-override trans)))
|
|
(set! (-> v1-27 0 param2) (the-as basic (-> self extra-trans)))
|
|
)
|
|
(set! (-> self condition) (res-lump-value arg0 'index int :time -1000000000.0))
|
|
(set! (-> self fact)
|
|
(new 'process 'fact-info self (pickup-type eco-pill-random) (-> *FACT-bank* default-eco-pill-green-inc))
|
|
)
|
|
(set! (-> self shield-value) arg3)
|
|
(set! (-> self nav-sphere-handle) (the-as uint #f))
|
|
(if (-> self entity)
|
|
(move-to-ground
|
|
(-> self root-override)
|
|
8192.0
|
|
40960.0
|
|
#t
|
|
(collide-spec backgnd obstacle hit-by-player-list hit-by-others-list pusher)
|
|
)
|
|
)
|
|
(set! (-> self sound)
|
|
(new 'process 'ambient-sound (static-sound-spec "zoom-teleport" :fo-max 30) (-> self root-override trans))
|
|
)
|
|
(set! (-> self draw light-index) (the-as uint 30))
|
|
(if (handle->process arg2)
|
|
(go-virtual idle)
|
|
(go-virtual wait-for-start)
|
|
)
|
|
(none)
|
|
)
|
|
|
|
(defmethod init-from-entity! mech ((obj mech) (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"
|
|
(mech-init arg0 (the-as matrix3 #f) (the-as handle #f) 100.0)
|
|
(none)
|
|
)
|
|
|
|
(deftype mech-target (process-drawable)
|
|
()
|
|
:heap-base #x50
|
|
:method-count-assert 22
|
|
:size-assert #xc8
|
|
:flag-assert #x16005000c8
|
|
(:methods
|
|
(idle () _type_ :state 20)
|
|
(active () _type_ :state 21)
|
|
)
|
|
)
|
|
|
|
|
|
(defskelgroup skel-mech-target mech mech-target-lod0-jg mech-target-idle-ja
|
|
((mech-target-lod0-mg (meters 999999)))
|
|
:bounds (static-spherem 0 0 0 4)
|
|
)
|
|
|
|
(defstate idle (mech-target)
|
|
:virtual #t
|
|
:event (behavior ((proc process) (arg1 int) (event-type symbol) (event event-message-block))
|
|
(case event-type
|
|
(('look-at-point)
|
|
(set! (-> self state-time) (current-time))
|
|
(go-virtual active)
|
|
)
|
|
)
|
|
)
|
|
:trans (behavior ()
|
|
(if (and (and *target* (and (>= 98304.0 (vector-vector-distance (-> self root trans) (-> *target* control trans)))
|
|
(not (logtest? (focus-status teleporting) (-> *target* focus-status)))
|
|
)
|
|
)
|
|
(focus-test? *target* mech)
|
|
)
|
|
(go-virtual active)
|
|
)
|
|
(none)
|
|
)
|
|
:code (behavior ()
|
|
(while (< 0.0 (-> self root scale x))
|
|
(seek! (-> self root scale x) 0.0 (* 8.0 (-> self clock seconds-per-frame)))
|
|
(set! (-> self root scale y) (-> self root scale x))
|
|
(ja-post)
|
|
(suspend)
|
|
)
|
|
(logior! (-> self draw status) (draw-control-status no-draw))
|
|
(ja-post)
|
|
(sleep-code)
|
|
(none)
|
|
)
|
|
)
|
|
|
|
(defstate active (mech-target)
|
|
:virtual #t
|
|
:event (-> (method-of-type mech-target idle) event)
|
|
:enter (behavior ()
|
|
(set! (-> self state-time) (current-time))
|
|
(none)
|
|
)
|
|
:trans (behavior ()
|
|
(if (and (or (or (not *target*) (or (< 106496.0 (vector-vector-distance (-> self root trans) (-> *target* control trans)))
|
|
(focus-test? *target* teleporting)
|
|
)
|
|
)
|
|
(not (logtest? (focus-status mech) (-> *target* focus-status)))
|
|
)
|
|
(>= (- (current-time) (-> self state-time)) (seconds 10))
|
|
)
|
|
(go-virtual idle)
|
|
)
|
|
(none)
|
|
)
|
|
:code (behavior ()
|
|
(sound-play "mech-target")
|
|
(let ((f30-0 0.0))
|
|
(logclear! (-> self draw status) (draw-control-status no-draw))
|
|
(while (< (-> self root scale x) 1.0)
|
|
(seek! (-> self root scale x) 1.0 (* 8.0 (-> self clock seconds-per-frame)))
|
|
(set! (-> self root scale y) (-> self root scale x))
|
|
(set! f30-0 (seek f30-0 1.0 (* 2.0 (-> self clock seconds-per-frame))))
|
|
(ja :num! (loop! f30-0))
|
|
(ja-post)
|
|
(suspend)
|
|
)
|
|
(until #f
|
|
(set! f30-0 (seek f30-0 1.0 (* 0.25 (-> self clock seconds-per-frame))))
|
|
(ja :num! (loop! f30-0))
|
|
(ja-post)
|
|
(suspend)
|
|
)
|
|
)
|
|
#f
|
|
(none)
|
|
)
|
|
)
|
|
|
|
;; WARN: Return type mismatch object vs none.
|
|
(defbehavior mech-target-init mech ((arg0 vector) (arg1 quaternion) (arg2 entity-actor))
|
|
(process-entity-set! self arg2)
|
|
(set! (-> self root-override) (the-as collide-shape-moving (new 'process 'trsqv)))
|
|
(set! (-> self root-override trans quad) (-> arg0 quad))
|
|
(quaternion-copy! (-> self root-override quat) arg1)
|
|
(set! (-> self root-override scale x) 0.0)
|
|
(set! (-> self root-override scale y) 0.0)
|
|
(initialize-skeleton
|
|
self
|
|
(the-as skeleton-group (art-group-get-by-name *level* "skel-mech-target" (the-as (pointer uint32) #f)))
|
|
(the-as pair 0)
|
|
)
|
|
(go-virtual wait-for-start)
|
|
(none)
|
|
)
|
|
|
|
;; WARN: Return type mismatch (pointer process) vs (pointer mech-target).
|
|
(defun mech-target-spawn ((arg0 vector) (arg1 process) (arg2 quaternion) (arg3 entity-actor))
|
|
(process-spawn mech-target :init mech-target-init arg0 arg2 arg3 :to arg1)
|
|
)
|