;;-*-Lisp-*-
(in-package goal)

;; name: palcab-obs.gc
;; name in dgo: palcab-obs
;; dgos: PAC

;; DECOMP BEGINS

(deftype pal-fan-ring (structure)
  ((lightning       lightning-control)
   (radius          float)
   (dist            float)
   (local-z-rotate  float)
   )
  :allow-misaligned
  )


(deftype pal-fan-pole (structure)
  ((rings     pal-fan-ring  6 :inline)
   (z-rotate  float         :offset  96)
   )
  :allow-misaligned
  )


(deftype pal-electric-fan (process-drawable)
  ((root                collide-shape-moving :override)
   (poles               pal-fan-pole          3 :inline)
   (no-collision-timer  time-frame            :offset 536)
   (sound-timer         time-frame)
   (rotate-speed        float)
   (attack-id           uint32)
   (sound-id            sound-id)
   )
  (:state-methods
    idle
    )
  )


(defskelgroup skel-pal-electric-fan pal-electric-fan pal-electric-fan-lod0-jg pal-electric-fan-idle-ja
              ((pal-electric-fan-lod0-mg (meters 20)) (pal-electric-fan-lod1-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 16)
              )

(defstate idle (pal-electric-fan)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('touch)
       (let ((gp-0 (the-as process (as-type proc process-focusable))))
         (when (and gp-0 ((method-of-type touching-shapes-entry prims-touching?)
                          (the-as touching-shapes-entry (-> block param 0))
                          (-> self root)
                          (the-as uint 1)
                          )
                    )
           (let ((s4-1 (vector-z-quaternion! (new 'stack-no-clear 'vector) (-> self root quat))))
             (let ((v1-5 (vector-z-quaternion! (new 'stack-no-clear 'vector) (-> (the-as process-focusable gp-0) root quat))))
               (if (< 0.0 (vector-dot s4-1 v1-5))
                   (vector-float*! s4-1 s4-1 -1.0)
                   )
               )
             (when (send-event
                     gp-0
                     'attack
                     (-> block param 0)
                     (static-attack-info ((id (-> self attack-id))
                                          (vector s4-1)
                                          (shove-back (meters 3))
                                          (shove-up (meters 9))
                                          (control (if (focus-test? (the-as process-focusable gp-0) board)
                                                       1.0
                                                       0.0
                                                       )
                                                   )
                                          )
                                         )
                     )
               (set-time! (-> self no-collision-timer))
               (let ((v1-19 (-> self root root-prim)))
                 (set! (-> v1-19 prim-core collide-as) (collide-spec))
                 (set! (-> v1-19 prim-core collide-with) (collide-spec))
                 )
               0
               )
             )
           )
         )
       )
      )
    )
  :enter (behavior ()
    (set-time! (-> self state-time))
    )
  :trans (behavior ()
    (when (and (nonzero? (-> self no-collision-timer))
               (time-elapsed? (-> self no-collision-timer) (the-as time-frame (-> *TARGET-bank* hit-invulnerable-timeout)))
               )
      (let ((v1-7 (-> self root root-prim)))
        (set! (-> v1-7 prim-core collide-as) (-> self root backup-collide-as))
        (set! (-> v1-7 prim-core collide-with) (-> self root backup-collide-with))
        )
      (set! (-> self no-collision-timer) 0)
      0
      )
    (rider-trans)
    )
  :code sleep-code
  :post (behavior ()
    (local-vars (sv-112 vector) (sv-128 vector) (sv-144 lightning-control))
    (let ((v1-0 (-> self root))
          (f30-0 4369.067)
          (f28-0 (* (-> self rotate-speed) (seconds-per-frame)))
          (gp-0 (new 'stack-no-clear 'vector))
          )
      (set! (-> gp-0 x) 1.0)
      (set! (-> gp-0 y) 1.0)
      (set! (-> gp-0 z) 0.4)
      (set! (-> gp-0 w) 1.0)
      (quaternion-rotate-local-z! (-> v1-0 quat) (-> v1-0 quat) f28-0)
      (dotimes (s5-0 3)
        (let ((s4-0 (-> self poles s5-0)))
          (dotimes (s3-0 6)
            (let ((s2-0 (new 'stack-no-clear 'vector))
                  (s0-0 (-> s4-0 rings s3-0))
                  (s1-0 (quaternion-rotate-local-z!
                          (new 'stack-no-clear 'quaternion)
                          (-> self root quat)
                          (+ (-> s4-0 z-rotate) (/ f28-0 5))
                          )
                        )
                  )
              (set-vector! s2-0 0.0 (-> s0-0 dist) 0.0 1.0)
              (vector-orient-by-quat! s2-0 s2-0 s1-0)
              (vector+! s2-0 s2-0 (-> self root trans))
              (set! sv-112 (new 'stack-no-clear 'vector))
              (set! sv-128 (new 'stack-no-clear 'vector))
              (set! sv-144 (-> s0-0 lightning))
              (set-vector! sv-112 (-> s0-0 radius) 0.0 0.0 0.0)
              (quaternion-rotate-local-z! s1-0 s1-0 (-> s0-0 local-z-rotate))
              (dotimes (s0-1 16)
                (vector-orient-by-quat! sv-128 sv-112 s1-0)
                (vector*! sv-128 sv-128 gp-0)
                (set-point! sv-144 s0-1 (vector+! (new 'stack-no-clear 'vector) s2-0 sv-128))
                (quaternion-rotate-local-y! s1-0 s1-0 f30-0)
                )
              )
            )
          )
        )
      )
    (when (time-elapsed? (-> self state-time) (-> self sound-timer))
      (sound-play "cab-fan-blade")
      (sound-stop (-> self sound-id))
      (sound-play "pal-fan-buzz" :id (-> self sound-id))
      (set! (-> self sound-timer)
            (the-as time-frame (the int (* 300.0 (/ 21845.334 (fabs (-> self rotate-speed))))))
            )
      (set-time! (-> self state-time))
      )
    (update! (-> self sound))
    (rider-post)
    )
  )

;; WARN: Return type mismatch process-drawable vs pal-electric-fan.
(defmethod relocate ((this pal-electric-fan) (offset int))
  (dotimes (v1-0 3)
    (dotimes (a2-0 6)
      (if (nonzero? (-> (the-as pal-electric-fan (&+ this (* 112 v1-0))) poles 0 rings a2-0 lightning))
          (&+! (-> (the-as pal-electric-fan (&+ this (* 112 v1-0))) poles 0 rings a2-0 lightning) offset)
          )
      )
    )
  (the-as pal-electric-fan ((method-of-type process-drawable relocate) this offset))
  )

;; WARN: Return type mismatch object vs none.
(defmethod init-from-entity! ((this pal-electric-fan) (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"
  (let ((s4-0 (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player))))
    (set! (-> s4-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s4-0 reaction) cshape-reaction-default)
    (set! (-> s4-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 10) 0)))
      (set! (-> s4-0 total-prims) (the-as uint 11))
      (set! (-> s3-0 prim-core collide-as) (collide-spec obstacle pusher))
      (set! (-> s3-0 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> s3-0 prim-core action) (collide-action solid rideable))
      (set! (-> s3-0 transform-index) 3)
      (set-vector! (-> s3-0 local-sphere) 0.0 0.0 0.0 65536.0)
      (set! (-> s4-0 root-prim) s3-0)
      )
    (pusher-init s4-0)
    (let ((v1-15 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0))))
      (set! (-> v1-15 prim-core collide-as) (collide-spec obstacle pusher))
      (set! (-> v1-15 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> v1-15 prim-core action) (collide-action solid rideable))
      (set! (-> v1-15 transform-index) 3)
      (set-vector! (-> v1-15 local-sphere) 0.0 0.0 0.0 36864.0)
      )
    (new 'process 'collide-shape-prim-sphere s4-0 (the-as uint 0))
    (new 'process 'collide-shape-prim-sphere s4-0 (the-as uint 0))
    (new 'process 'collide-shape-prim-sphere s4-0 (the-as uint 0))
    (new 'process 'collide-shape-prim-sphere s4-0 (the-as uint 0))
    (new 'process 'collide-shape-prim-sphere s4-0 (the-as uint 0))
    (new 'process 'collide-shape-prim-sphere s4-0 (the-as uint 0))
    (new 'process 'collide-shape-prim-sphere s4-0 (the-as uint 0))
    (new 'process 'collide-shape-prim-sphere s4-0 (the-as uint 0))
    (new 'process 'collide-shape-prim-sphere s4-0 (the-as uint 0))
    (set! (-> s4-0 nav-radius) (* 0.75 (-> s4-0 root-prim local-sphere w)))
    (let ((v1-36 (-> s4-0 root-prim)))
      (set! (-> s4-0 backup-collide-as) (-> v1-36 prim-core collide-as))
      (set! (-> s4-0 backup-collide-with) (-> v1-36 prim-core collide-with))
      )
    (let ((s3-1 (new 'stack-no-clear 'vector))
          (s2-0 (-> (the-as collide-shape-prim-group (-> s4-0 root-prim)) child))
          )
      (dotimes (s1-0 3)
        (vector-rotate-z! s3-1 *y-vector* (* 21845.334 (the float s1-0)))
        (vector-normalize! s3-1 1.0)
        (dotimes (v1-40 3)
          (let* ((a1-21 (-> s2-0 (+ (* 3 s1-0) 1 v1-40)))
                 (a0-26 (-> a1-21 local-sphere))
                 )
            (set! (-> a1-21 prim-id) (the-as uint 1))
            (set! (-> a1-21 prim-core collide-as) (collide-spec obstacle pusher))
            (set! (-> a1-21 prim-core collide-with) (collide-spec jak bot player-list))
            (set! (-> a1-21 transform-index) 3)
            (vector-float*! a0-26 s3-1 (+ 40960.0 (* 8192.0 (the float v1-40))))
            (set! (-> a0-26 w) (+ 4096.0 (* 2048.0 (the float v1-40))))
            )
          )
        )
      )
    (set! (-> this root) s4-0)
    )
  (process-drawable-from-entity! this arg0)
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-pal-electric-fan" (the-as (pointer uint32) #f)))
    (the-as pair 0)
    )
  (logclear! (-> this mask) (process-mask actor-pause))
  (let ((a0-32 (-> this entity)))
    (set! (-> this rotate-speed)
          ((method-of-object a0-32 get-property-value-float)
           a0-32
           'rotspeed
           'interp
           -1000000000.0
           14563.556
           (the-as (pointer res-tag) #f)
           *res-static-buf*
           )
          )
    )
  (let* ((v1-52 *game-info*)
         (a0-34 (+ (-> v1-52 attack-id) 1))
         )
    (set! (-> v1-52 attack-id) a0-34)
    (set! (-> this attack-id) a0-34)
    )
  (set! (-> this no-collision-timer) 0)
  (let ((f1-7 (lerp-scale 55.0 35.0 (fabs (-> this rotate-speed)) 10922.667 18204.445)))
    (set! (-> this sound-timer)
          (the-as time-frame (the int (* 300.0 (/ (* 182.04445 f1-7) (fabs (-> this rotate-speed))))))
          )
    )
  (let ((s5-2
          (new 'static 'lightning-spec
            :name #f
            :flags (lightning-spec-flags lsf2)
            :rand-func #x3
            :start-color (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
            :end-color (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
            :fade-to-color (new 'static 'rgba :r #xbf :b #x8f :a #x5)
            :fade-start-factor 0.2
            :fade-time 120.0
            :texture (new 'static 'texture-id :index #x83 :page #xc)
            :reduction 0.42
            :num-points 16
            :box-size 8192.0
            :merge-factor 0.5
            :merge-count 2
            :radius 3276.8
            :duration -1.0
            :sound #f
            )
          )
        (f30-0 2730.6667)
        (f28-0 216.0)
        )
    (dotimes (s4-2 3)
      (let ((s3-2 (-> this poles s4-2)))
        (if (< 0.0 (-> this rotate-speed))
            (set! (-> s3-2 z-rotate) (* 21954.56 (the float s4-2)))
            (set! (-> s3-2 z-rotate) (* 21736.107 (the float s4-2)))
            )
        (dotimes (s2-1 6)
          (let ((s1-1 (-> s3-2 rings s2-1)))
            (let ((s0-0 (+ s2-1 1)))
              (set! (-> s1-1 lightning) (new 'process 'lightning-control s5-2 this 0.0))
              (set! (-> s1-1 dist) (+ 40960.0 (* f30-0 (the float s0-0))))
              (set! (-> s1-1 radius) (+ 3276.8 (* 4505.6 (/ (the float (* (* s0-0 s0-0) s0-0)) f28-0))))
              )
            (set! (-> s1-1 local-z-rotate) (* 182.04445 (rand-vu-float-range 6.0 10.0)))
            (if (= (logand s2-1 1) 1)
                (set! (-> s1-1 local-z-rotate) (* -1.0 (-> s1-1 local-z-rotate)))
                )
            )
          )
        )
      )
    )
  (set! (-> this sound)
        (new 'process 'ambient-sound (static-sound-spec "fan-blade-motor" :fo-max 70) (-> this root trans))
        )
  (set! (-> this sound-id) (new-sound-id))
  (let ((a0-40 (-> this skel root-channel 0)))
    (set! (-> a0-40 frame-group) (the-as art-joint-anim (-> this draw art-group data 3)))
    (set! (-> a0-40 frame-num) 0.0)
    (joint-control-channel-group! a0-40 (the-as art-joint-anim (-> this draw art-group data 3)) num-func-identity)
    )
  (transform-post)
  (go (method-of-object this idle))
  (none)
  )

(deftype pal-cable-nut (process-drawable)
  ((root               collide-shape-moving :override)
   (sync               sync-linear           :inline)
   (init-quat          quaternion            :inline)
   (sound-played?      symbol                2)
   (hold-percentage    float)
   (wiggle-percentage  float)
   )
  (:state-methods
    idle
    )
  )


(defskelgroup skel-pal-cable-nut pal-cable-nut pal-cable-nut-lod0-jg pal-cable-nut-idle-ja
              ((pal-cable-nut-lod0-mg (meters 20)) (pal-cable-nut-lod1-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 13)
              )

(defstate idle (pal-cable-nut)
  :virtual #t
  :enter (behavior ()
    (set! (-> self sound-played? 0) #f)
    (set! (-> self sound-played? 1) #f)
    )
  :trans rider-trans
  :code (behavior ()
    (until #f
      (let* ((f1-0 (* 6.0 (get-current-phase-no-mod (-> self sync))))
             (f0-4 (the float (the int f1-0)))
             (f30-1 (- f1-0 f0-4))
             (f26-0 (the float (sar (shl (the int (* 10922.667 (+ f0-4 (/ f30-1 (-> self hold-percentage))))) 48) 48)))
             (f28-0 (the float (sar (shl (the int (* 10922.667 f0-4)) 48) 48)))
             )
        (cond
          ((< (-> self hold-percentage) f30-1)
           (when (< (-> self wiggle-percentage) f30-1)
             (when (not (or (-> self sound-played? 0) (< 327680.0 (vector-vector-distance (ear-trans 0) (-> self root trans)))))
               (sound-play "cab-nut-wiggle")
               (set! (-> self sound-played? 0) #t)
               (set! (-> self sound-played? 1) #f)
               )
             (let ((f0-17 (* 182.04445 (sin (the float (sar (shl (the int (* 524288.0 f30-1)) 48) 48))))))
               (* f0-17 (/ (- f30-1 (-> self wiggle-percentage)) (- 1.0 (-> self wiggle-percentage))))
               (quaternion-rotate-local-z!
                 (-> self root quat)
                 (-> self init-quat)
                 (the float (sar (shl (the int (+ 10922.667 f0-17 f28-0)) 48) 48))
                 )
               )
             )
           )
          (else
            (when (not (or (-> self sound-played? 1) (< 327680.0 (vector-vector-distance (ear-trans 0) (-> self root trans)))))
              (sound-play "cab-nut-turn")
              (set! (-> self sound-played? 1) #t)
              (set! (-> self sound-played? 0) #f)
              )
            (quaternion-rotate-local-z! (-> self root quat) (-> self init-quat) f26-0)
            )
          )
        )
      (suspend)
      )
    #f
    )
  :post rider-post
  )

;; WARN: Return type mismatch object vs none.
(defmethod init-from-entity! ((this pal-cable-nut) (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"
  (let ((s4-0 (new 'process 'collide-shape-moving this (collide-list-enum hit-by-player))))
    (set! (-> s4-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s4-0 reaction) cshape-reaction-default)
    (set! (-> s4-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 1) 0)))
      (set! (-> s4-0 total-prims) (the-as uint 2))
      (set! (-> s3-0 prim-core collide-as) (collide-spec obstacle camera-blocker pusher))
      (set! (-> s3-0 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> s3-0 prim-core action) (collide-action solid rideable))
      (set! (-> s3-0 transform-index) 3)
      (set-vector! (-> s3-0 local-sphere) 0.0 0.0 0.0 53248.0)
      (set! (-> s4-0 root-prim) s3-0)
      )
    (pusher-init s4-0)
    (let ((v1-15 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0))))
      (set! (-> v1-15 prim-core collide-as) (collide-spec obstacle pusher))
      (set! (-> v1-15 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> v1-15 prim-core action) (collide-action solid rideable))
      (set! (-> v1-15 transform-index) 3)
      (set-vector! (-> v1-15 local-sphere) 0.0 0.0 0.0 53248.0)
      )
    (set! (-> s4-0 nav-radius) (* 0.75 (-> s4-0 root-prim local-sphere w)))
    (let ((v1-18 (-> s4-0 root-prim)))
      (set! (-> s4-0 backup-collide-as) (-> v1-18 prim-core collide-as))
      (set! (-> s4-0 backup-collide-with) (-> v1-18 prim-core collide-with))
      )
    (set! (-> this root) s4-0)
    )
  (set! (-> this root rider-max-momentum) 8192.0)
  (process-drawable-from-entity! this arg0)
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-pal-cable-nut" (the-as (pointer uint32) #f)))
    (the-as pair 0)
    )
  (logclear! (-> this mask) (process-mask actor-pause))
  (let ((a1-9 (new 'stack-no-clear 'sync-info-params)))
    (let ((v1-27 0))
      (if #t
          (set! v1-27 (logior v1-27 1))
          )
      (set! (-> a1-9 sync-type) 'sync-linear)
      (set! (-> a1-9 sync-flags) (the-as sync-flags v1-27))
      )
    (set! (-> a1-9 entity) (-> this entity))
    (set! (-> a1-9 period) (the-as uint 3600))
    (set! (-> a1-9 percent) 0.0)
    (initialize! (-> this sync) a1-9)
    )
  (set! (-> this hold-percentage) 0.3)
  (set! (-> this wiggle-percentage) 0.8)
  (quaternion-copy! (-> this init-quat) (-> this root quat))
  (let* ((f0-15 (* 6.0 (get-current-phase-no-mod (-> this sync))))
         (f1-4 (the float (the int f0-15)))
         (f0-16 (- f0-15 f1-4))
         (f2-4 (the float (sar (shl (the int (* 10922.667 (+ f1-4 (/ f0-16 (-> this hold-percentage))))) 48) 48)))
         (f1-8 (the float (sar (shl (the int (* 10922.667 f1-4)) 48) 48)))
         )
    (if (< (-> this hold-percentage) f0-16)
        (quaternion-rotate-local-z!
          (-> this root quat)
          (-> this init-quat)
          (the float (sar (shl (the int (+ 10922.667 f1-8)) 48) 48))
          )
        (quaternion-rotate-local-z! (-> this root quat) (-> this init-quat) f2-4)
        )
    )
  (let ((a0-26 (-> this skel root-channel 0)))
    (set! (-> a0-26 frame-group) (the-as art-joint-anim (-> this draw art-group data 3)))
    (set! (-> a0-26 frame-num) 0.0)
    (joint-control-channel-group! a0-26 (the-as art-joint-anim (-> this draw art-group data 3)) num-func-identity)
    )
  (transform-post)
  (go (method-of-object this idle))
  (none)
  )

(deftype pal-rot-gun-shot (guard-shot)
  ()
  )


(defmethod spawn-impact-particles ((this pal-rot-gun-shot))
  "Spawns associated particles with the projectile if applicable"
  (let* ((gp-0 (-> this root trans))
         (a1-0 (-> this tail-pos))
         (s5-1 (vector-! (new 'stack-no-clear 'vector) gp-0 a1-0))
         (f30-0 (vector-length s5-1))
         )
    (let ((s4-1 (vector+float*! (new 'stack-no-clear 'vector) a1-0 s5-1 0.8)))
      (let ((f28-0 (-> *part-id-table* 606 init-specs 4 initial-valuef))
            (s3-0 (-> *part-id-table* 606 init-specs 11 initial-valuef))
            (f26-0 (-> *part-id-table* 606 init-specs 10 initial-valuef))
            )
        (set! (-> *part-id-table* 606 init-specs 4 initial-valuef) f30-0)
        (set! (-> *part-id-table* 606 init-specs 11 initial-valuef) (the-as float #x5))
        (set! (-> *part-id-table* 606 init-specs 10 initial-valuef) 0.0)
        (draw-beam (-> *part-id-table* 606) a1-0 s5-1 #f #t)
        (set! (-> *part-id-table* 606 init-specs 4 initial-valuef) f28-0)
        (set! (-> *part-id-table* 606 init-specs 11 initial-valuef) s3-0)
        (set! (-> *part-id-table* 606 init-specs 10 initial-valuef) f26-0)
        )
      (vector-normalize! s5-1 1.0)
      (launch-particles (-> *part-id-table* 607) s4-1)
      (launch-particles (-> *part-id-table* 608) s4-1)
      )
    (let ((s4-2 (new 'stack-no-clear 'matrix))
          (f22-0 (/ f30-0 (meters 9)))
          (f30-1 (-> *part-id-table* 609 init-specs 3 initial-valuef))
          (f28-1 (-> *part-id-table* 609 init-specs 4 initial-valuef))
          (f26-1 (-> *part-id-table* 609 init-specs 1 initial-valuef))
          (f24-0 (-> *part-id-table* 609 init-specs 1 random-rangef))
          )
      (forward-up->inv-matrix s4-2 s5-1 *up-vector*)
      (set! (-> s4-2 trans quad) (-> gp-0 quad))
      (set! (-> *part-id-table* 609 init-specs 3 initial-valuef) (* f22-0 f30-1))
      (set! (-> *part-id-table* 609 init-specs 4 initial-valuef) (* f22-0 f28-1))
      (set! (-> *part-id-table* 609 init-specs 1 initial-valuef) 1.0)
      (set! (-> *part-id-table* 609 init-specs 1 random-rangef) 1.0)
      (launch-particles (-> *part-id-table* 609) s4-2 :origin-is-matrix #t)
      (set! (-> *part-id-table* 609 init-specs 3 initial-valuef) f30-1)
      (set! (-> *part-id-table* 609 init-specs 4 initial-valuef) f28-1)
      (set! (-> *part-id-table* 609 init-specs 1 initial-valuef) f26-1)
      (set! (-> *part-id-table* 609 init-specs 1 random-rangef) f24-0)
      )
    )
  0
  (none)
  )

(defmethod spawn-shell-particles ((this pal-rot-gun-shot))
  "TODO - confirm"
  (let* ((s3-0 (-> this root))
         (s5-0 (vector-normalize! (vector-! (new 'stack-no-clear 'vector) (-> this tail-pos) (-> s3-0 trans)) 2048.0))
         (gp-0 (new 'stack-no-clear 'vector))
         )
    (set! (-> gp-0 quad) (-> s3-0 trans quad))
    (let ((a2-1 (vector-! (new 'stack-no-clear 'vector) (-> s3-0 trans) (-> this tail-pos)))
          (f30-0 (-> *part-id-table* 606 init-specs 4 initial-valuef))
          (s3-1 (-> *part-id-table* 606 init-specs 11 initial-valuef))
          (f28-0 (-> *part-id-table* 606 init-specs 10 initial-valuef))
          )
      (set! (-> *part-id-table* 606 init-specs 4 initial-valuef) (vector-length a2-1))
      (set! (-> *part-id-table* 606 init-specs 11 initial-valuef) (the-as float #x28))
      (set! (-> *part-id-table* 606 init-specs 10 initial-valuef) -3.2)
      (draw-beam (-> *part-id-table* 606) (-> this tail-pos) a2-1 #f #t)
      (set! (-> *part-id-table* 606 init-specs 4 initial-valuef) f30-0)
      (set! (-> *part-id-table* 606 init-specs 11 initial-valuef) s3-1)
      (set! (-> *part-id-table* 606 init-specs 10 initial-valuef) f28-0)
      )
    (vector+! gp-0 gp-0 s5-0)
    (part-tracker-spawn :to *entity-pool* :group group-guard-shot-hit :mat-joint gp-0)
    )
  0
  (none)
  )

(defmethod play-impact-sound ((this pal-rot-gun-shot) (arg0 projectile-options))
  (let ((v1-0 arg0))
    (cond
      ((zero? v1-0)
       (sound-play "rot-gun-fire" :position (-> this root trans))
       )
      ((= v1-0 (projectile-options lose-altitude))
       (sound-play "pal-rot-gun-sho" :position (-> this root trans))
       )
      )
    )
  0
  (none)
  )

(defstate dissipate (pal-rot-gun-shot)
  :virtual #t
  :enter (behavior ()
    (go-virtual impact)
    )
  )

(defun pal-rot-gun-shot-move ((arg0 pal-rot-gun-shot))
  (projectile-move-fill-line-sphere arg0)
  (let ((s5-0 (-> arg0 root)))
    (let ((s4-0 (new 'stack-no-clear 'vector))
          (f0-0 36864.0)
          )
      (vector-! s4-0 (-> arg0 tail-pos) (-> s5-0 trans))
      (when (< f0-0 (vector-length s4-0))
        (vector-normalize! s4-0 f0-0)
        (vector+! (-> arg0 tail-pos) (-> s5-0 trans) s4-0)
        )
      )
    (if (logtest? (-> s5-0 status) (collide-status touch-surface))
        (go (method-of-object arg0 impact))
        )
    )
  0
  (none)
  )

(defmethod init-proj-collision! ((this pal-rot-gun-shot))
  "Init the [[projectile]]'s [[collide-shape]]"
  (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum hit-by-player))))
    (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s5-0 reaction)
          (the-as (function control-info collide-query vector vector collide-status) cshape-reaction-just-move)
          )
    (set! (-> s5-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (set! (-> s5-0 penetrate-using) (penetrate enemy-yellow-shot))
    (let ((v1-7 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 1))))
      (set! (-> v1-7 prim-core collide-as) (collide-spec projectile))
      (set! (-> v1-7 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> v1-7 prim-core action) (collide-action solid))
      (set-vector! (-> v1-7 local-sphere) 0.0 0.0 0.0 1228.8)
      (set! (-> s5-0 total-prims) (the-as uint 1))
      (set! (-> s5-0 root-prim) v1-7)
      )
    (set! (-> s5-0 nav-radius) (* 0.75 (-> s5-0 root-prim local-sphere w)))
    (let ((v1-10 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-10 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-10 prim-core collide-with))
      )
    (set! (-> s5-0 event-self) 'touched)
    (set! (-> this root) s5-0)
    )
  (set! (-> this root pat-ignore-mask)
        (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noproj #x1 :noendlessfall #x1)
        )
  0
  (none)
  )

(defmethod init-proj-settings! ((this pal-rot-gun-shot))
  "Init relevant settings for the [[projectile]] such as gravity, speed, timeout, etc"
  (set! (-> this tail-pos quad) (-> this root trans quad))
  (set! (-> this attack-mode) 'pal-rot-gun-shot)
  (set! (-> this move) pal-rot-gun-shot-move)
  (set! (-> this max-speed) 630784.0)
  (set! (-> this timeout) (seconds 1.427))
  0
  (none)
  )

(deftype pal-rot-gun (process-drawable)
  ((init-quat        quaternion  :inline)
   (fire-timer       time-frame)
   (gun-index        int32)
   (spin-rate        float)
   (spin-rate-final  float)
   (sound-id         sound-id)
   (shot-sound-id    sound-id)
   (prev-z-rot       float)
   )
  (:state-methods
    idle
    spin
    spin-down
    )
  (:methods
    (pal-rot-gun-method-23 (_type_ matrix) none)
    )
  )


(defskelgroup skel-pal-rot-gun pal-rot-gun pal-rot-gun-lod0-jg pal-rot-gun-idle-ja
              ((pal-rot-gun-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 12)
              )

(defstate idle (pal-rot-gun)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('trigger)
       (go-virtual spin)
       )
      )
    )
  :code sleep-code
  )

(defstate spin (pal-rot-gun)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('untrigger)
       (sound-stop (-> self sound-id))
       (sound-stop (-> self shot-sound-id))
       (go-virtual spin-down)
       )
      )
    )
  :enter (behavior ()
    (set-time! (-> self fire-timer))
    (set! (-> self gun-index) 0)
    0
    )
  :code sleep-code
  :post (behavior ()
    (seek! (-> self spin-rate) (-> self spin-rate-final) (* 3640.889 (seconds-per-frame)))
    (quaternion-rotate-z! (-> self root quat) (-> self root quat) (* (-> self spin-rate) (seconds-per-frame)))
    (let ((f30-0 1.0))
      (when (time-elapsed? (-> self fire-timer) (seconds 0.05))
        (let ((gp-0 (new 'stack-no-clear 'matrix)))
          (let ((s5-0 (-> self node-list data (+ (* (-> self gun-index) 2) 4))))
            (vector<-cspace! (-> gp-0 vector 0) s5-0)
            (vector-normalize-copy! (-> gp-0 vector 1) (-> s5-0 bone transform vector 2) 1.0)
            )
          (vector-rotate-x! (-> gp-0 vector 1) (-> gp-0 vector 1) -455.1111)
          (vector-normalize! (-> gp-0 vector 1) 573440.0)
          (pal-rot-gun-method-23 self gp-0)
          )
        (set! (-> self gun-index) (- 1 (-> self gun-index)))
        (set-time! (-> self fire-timer))
        (set! f30-0 1.2)
        )
      (let* ((f0-10 (the float (sar (shl (the int (quaternion-z-angle (-> self root quat))) 48) 48)))
             (f0-12 (fabs (cos f0-10)))
             )
        (set-palcab-turret-flash! (* f30-0 (* f0-12 f0-12 f0-12)))
        )
      )
    (let ((f30-2 (+ 32768.0 (the float (sar (shl (the int (quaternion-z-angle (-> self root quat))) 48) 48)))))
      (let ((f0-19 (-> self prev-z-rot)))
        (if (or (and (< f0-19 32768.0) (< 32768.0 f30-2)) (< f30-2 f0-19))
            (sound-stop (-> self sound-id))
            )
        )
      (set! (-> self prev-z-rot) f30-2)
      )
    (sound-play "rot-gun" :id (-> self sound-id))
    (let* ((f30-4 (the float (sar (shl (the int (+ 2730.6667 (quaternion-z-angle (-> self root quat)))) 48) 48)))
           (f0-26 (* 0.0000017438616 (vector-vector-distance (-> self root trans) (target-pos 0)) (-> self spin-rate)))
           (f0-30 (- 1.0 (fabs (sin (- f30-4 f0-26)))))
           )
      (sound-play-by-name
        (static-sound-name "rot-gun-shot")
        (-> self shot-sound-id)
        (the int (* 1024.0 f0-30))
        0
        0
        (sound-group sfx)
        (target-pos 0)
        )
      )
    (ja-post)
    )
  )

(defstate spin-down (pal-rot-gun)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('trigger)
       (go-virtual spin)
       )
      )
    )
  :exit (behavior ()
    (sound-stop (-> self sound-id))
    )
  :trans (behavior ()
    (if (>= 0.0 (-> self spin-rate))
        (go-virtual idle)
        )
    )
  :code sleep-code
  :post (behavior ()
    (seek! (-> self spin-rate) 0.0 (* 3640.889 (seconds-per-frame)))
    (quaternion-rotate-z! (-> self root quat) (-> self root quat) (* (-> self spin-rate) (seconds-per-frame)))
    (let ((f30-1 (+ 32768.0 (the float (sar (shl (the int (quaternion-z-angle (-> self root quat))) 48) 48)))))
      (let ((f0-10 (-> self prev-z-rot)))
        (if (or (and (< f0-10 32768.0) (< 32768.0 f30-1)) (< f30-1 f0-10))
            (sound-stop (-> self sound-id))
            )
        )
      (set! (-> self prev-z-rot) f30-1)
      )
    (sound-play-by-name
      (static-sound-name "rot-gun")
      (-> self sound-id)
      (the int (* 1024.0 (* 0.00016479492 (-> self spin-rate))))
      0
      0
      (sound-group sfx)
      #t
      )
    (ja-post)
    )
  )

(defmethod pal-rot-gun-method-23 ((this pal-rot-gun) (arg0 matrix))
  (let ((v1-0 (new 'stack-no-clear 'projectile-init-by-other-params)))
    (let ((a2-0 (-> arg0 vector))
          (a1-1 (-> arg0 vector 1))
          )
      (set! (-> v1-0 ent) (-> this entity))
      (set! (-> v1-0 charge) 1.0)
      (set! (-> v1-0 options) (projectile-options))
      (set! (-> v1-0 pos quad) (-> a2-0 0 quad))
      (set! (-> v1-0 vel quad) (-> a1-1 quad))
      )
    (set! (-> v1-0 notify-handle) (process->handle this))
    (set! (-> v1-0 owner-handle) (the-as handle #f))
    (set! (-> v1-0 ignore-handle) (process->handle this))
    (let* ((a1-9 *game-info*)
           (a2-12 (+ (-> a1-9 attack-id) 1))
           )
      (set! (-> a1-9 attack-id) a2-12)
      (set! (-> v1-0 attack-id) a2-12)
      )
    (set! (-> v1-0 timeout) (seconds 4))
    (ppointer->handle (spawn-projectile pal-rot-gun-shot v1-0 this *default-dead-pool*))
    )
  (none)
  )

(defmethod deactivate ((this pal-rot-gun))
  "Make a process dead, clean it up, remove it from the active pool, and return to dead pool."
  (sound-stop (-> this sound-id))
  (sound-stop (-> this shot-sound-id))
  (call-parent-method this)
  (none)
  )

;; WARN: Return type mismatch object vs none.
(defmethod init-from-entity! ((this pal-rot-gun) (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-pal-rot-gun" (the-as (pointer uint32) #f)))
    (the-as pair 0)
    )
  (logclear! (-> this mask) (process-mask actor-pause))
  (let ((s5-2 (-> this root quat)))
    (quaternion-rotate-local-x! s5-2 s5-2 364.0889)
    (quaternion-rotate-local-z! s5-2 s5-2 16384.0)
    (quaternion-copy! (-> this init-quat) s5-2)
    )
  (set! (-> this spin-rate) 0.0)
  (set! (-> this spin-rate-final) 16384.0)
  (set! (-> this prev-z-rot) 65353.957)
  (set! (-> this sound-id) (new-sound-id))
  (set! (-> this shot-sound-id) (new-sound-id))
  (let ((a0-9 (-> this skel root-channel 0)))
    (set! (-> a0-9 frame-group) (the-as art-joint-anim (-> this draw art-group data 2)))
    (set! (-> a0-9 frame-num) 0.0)
    (joint-control-channel-group! a0-9 (the-as art-joint-anim (-> this draw art-group data 2)) num-func-identity)
    )
  (ja-post)
  (go (method-of-object this idle))
  (none)
  )

(deftype pal-windmill (process-drawable)
  ()
  (:state-methods
    idle
    )
  )


(defskelgroup skel-pal-windmill pal-windmill pal-windmill-lod0-jg pal-windmill-idle-ja
              ((pal-windmill-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 62)
              :longest-edge (meters 21.191)
              )

(defstate idle (pal-windmill)
  :virtual #t
  :code (behavior ()
    (until #f
      (ja-no-eval :group! (ja-group) :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!))
        )
      )
    #f
    )
  :post ja-post
  )

;; WARN: Return type mismatch object vs none.
(defmethod init-from-entity! ((this pal-windmill) (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"
  (logior! (-> this mask) (process-mask ambient))
  (set! (-> this root) (new 'process 'trsqv))
  (process-drawable-from-entity! this arg0)
  (logclear! (-> this mask) (process-mask actor-pause))
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-pal-windmill" (the-as (pointer uint32) #f)))
    (the-as pair 0)
    )
  (go (method-of-object this idle))
  (none)
  )

(deftype pal-flip-step (process-drawable)
  ((task-node  game-task-node-info)
   )
  (:state-methods
    idle
    fall
    fallen
    )
  )


(defskelgroup skel-pal-flip-step pal-flip-step pal-flip-step-lod0-jg pal-flip-step-idle-ja
              ((pal-flip-step-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 6)
              )

(defstate idle (pal-flip-step)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('trigger)
       (go-virtual fall)
       )
      )
    )
  :trans (behavior ()
    (if (and (-> self task-node)
             (logtest? (-> self task-node flags) (game-task-node-flag closed))
             (not (task-node-closed? (game-task-node nest-boss-resolution)))
             )
        (go-virtual fall)
        )
    )
  :code sleep-code
  )

(defstate fall (pal-flip-step)
  :virtual #t
  :code (behavior ()
    (ja-no-eval :group! pal-flip-step-fall-ja :num! (seek!) :frame-num 0.0)
    (until (ja-done? 0)
      (transform-post)
      (suspend)
      (ja :num! (seek!))
      )
    (go-virtual fallen)
    )
  )

(defstate fallen (pal-flip-step)
  :virtual #t
  :code sleep-code
  )

;; WARN: Return type mismatch object vs none.
(defmethod init-from-entity! ((this pal-flip-step) (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"
  (let ((s4-0 (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player))))
    (set! (-> s4-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s4-0 reaction) cshape-reaction-default)
    (set! (-> s4-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (let ((v1-6 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0))))
      (set! (-> v1-6 prim-core collide-as) (collide-spec obstacle))
      (set! (-> v1-6 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> v1-6 prim-core action) (collide-action solid))
      (set! (-> v1-6 transform-index) 3)
      (set-vector! (-> v1-6 local-sphere) 0.0 0.0 0.0 24576.0)
      (set! (-> s4-0 total-prims) (the-as uint 1))
      (set! (-> s4-0 root-prim) v1-6)
      )
    (set! (-> s4-0 nav-radius) (* 0.75 (-> s4-0 root-prim local-sphere w)))
    (let ((v1-9 (-> s4-0 root-prim)))
      (set! (-> s4-0 backup-collide-as) (-> v1-9 prim-core collide-as))
      (set! (-> s4-0 backup-collide-with) (-> v1-9 prim-core collide-with))
      )
    (set! (-> this root) s4-0)
    )
  (process-drawable-from-entity! this arg0)
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-pal-flip-step" (the-as (pointer uint32) #f)))
    (the-as pair 0)
    )
  (set! (-> this task-node) (task-node-by-name (the-as string ((method-of-type res-lump get-property-struct)
                                                               arg0
                                                               'task-name
                                                               'interp
                                                               -1000000000.0
                                                               "palace-cable-resolution"
                                                               (the-as (pointer res-tag) #f)
                                                               *res-static-buf*
                                                               )
                                                       )
                                               )
        )
  (cond
    ((and (-> this task-node)
          (logtest? (-> this task-node flags) (game-task-node-flag closed))
          (not (task-node-closed? (game-task-node nest-boss-resolution)))
          )
     (let ((a0-17 (-> this skel root-channel 0)))
       (set! (-> a0-17 frame-group) (the-as art-joint-anim (-> this draw art-group data 3)))
       (set! (-> a0-17 frame-num)
             (the float (+ (-> (the-as art-joint-anim (-> this draw art-group data 3)) frames num-frames) -1))
             )
       (joint-control-channel-group! a0-17 (the-as art-joint-anim (-> this draw art-group data 3)) num-func-identity)
       )
     (transform-post)
     (go (method-of-object this fallen))
     )
    (else
      (let ((a0-18 (-> this skel root-channel 0)))
        (set! (-> a0-18 frame-group) (the-as art-joint-anim (-> this draw art-group data 2)))
        (set! (-> a0-18 frame-num) 0.0)
        (joint-control-channel-group! a0-18 (the-as art-joint-anim (-> this draw art-group data 2)) num-func-identity)
        )
      (transform-post)
      (go (method-of-object this idle))
      )
    )
  (none)
  )
