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

;; name: fort-robotank.gc
;; name in dgo: fort-robotank
;; dgos: FORDUMPC, FDA

(declare-type fort-robotank process-drawable)


(defenum robotank-flags
  :bitfield #t
  :type uint16
  (roflags-0)
  (roflags-1)
  (roflags-2)
  (roflags-3)
  (roflags-4)
  (roflags-5)
  (roflags-6)
  (roflags-7)
  (roflags-8)
  (roflags-9)
  (roflags-10)
  (roflags-11)
  (roflags-12)
  (roflags-13)
  (roflags-14)
  (roflags-15)
  )

;; DECOMP BEGINS

(defpartgroup group-robotank-barrel-sparks
  :id 562
  :bounds (static-bspherem 0 0 0 8)
  :parts ((sp-item 2474 :fade-after (meters 120) :falloff-to (meters 120) :flags (bit7)))
  )

(defpart 2474
  :init-specs ((:texture (motion-blur-part effects))
    (:num 1.0 6.0)
    (:x (meters -4) (meters 8))
    (:scale-x (meters 1))
    (:rot-x 4)
    (:scale-y (meters 0.05) (meters 0.05))
    (:r 32.0 96.0)
    (:g :copy r)
    (:b 255.0)
    (:a 64.0 64.0)
    (:omega (degrees 0.03375))
    (:vel-y (meters 0.016666668) (meters 0.033333335))
    (:fade-r -0.85333335)
    (:fade-g -0.85333335)
    (:accel-y (meters -0.0026666666) (meters -0.001))
    (:friction 0.875)
    (:timer (seconds 0.085) (seconds 0.33))
    (:flags (sp-cpuinfo-flag-0 sp-cpuinfo-flag-2 sp-cpuinfo-flag-3))
    (:func 'sparticle-motion-blur)
    (:next-time (seconds 0.017) (seconds 0.98))
    (:next-launcher 2475)
    (:conerot-x (degrees -45) (degrees 90))
    (:conerot-y (degrees -45) (degrees 90))
    (:conerot-z (degrees -45) (degrees 90))
    (:rotate-y (degrees 0))
    (:conerot-radius (meters 0) (meters 0.2))
    )
  )

(defpart 2475
  :init-specs ((:fade-r 0.0) (:fade-g 0.0) (:fade-b 0.0) (:fade-a -0.85333335 -1.7066667))
  )

(deftype fort-robotank-segment-event (structure)
  ((source      handle)
   (event-type  symbol)
   (actor       string)
   (pos-norm    float)
   (param-obj   object)
   (param-func  (function fort-robotank none)  :overlay-at param-obj)
   (param-sym   symbol                         :overlay-at param-obj)
   )
  )


(deftype fort-robotank-segment (structure)
  ((flags               uint16)
   (max-speed           float)
   (next-segment        int32)
   (next-segment-start  float)
   (event-count         int32)
   (event-tbl           (inline-array fort-robotank-segment-event))
   )
  )


(deftype fort-robotank-path-info (structure)
  ((path           path-control)
   (dir            vector  :inline)
   (u              float)
   (du             float)
   (du-final       float)
   (prev-u         float)
   (max-speed      float)
   (dist           float)
   (dir-y-angle    float)
   (start-y-angle  float)
   )
  )


(deftype fort-robotank-path-info-array (inline-array-class)
  ((data  fort-robotank-path-info  :inline :dynamic)
   )
  )


(set! (-> fort-robotank-path-info-array heap-base) (the-as uint 64))

(deftype fort-robotank-wheel-info (structure)
  ((jmod    joint-mod-spinner)
   (radius  float)
   )
  )


(deftype fort-robotank-tread-info (structure)
  ((wheel          fort-robotank-wheel-info  7 :inline)
   (texture        texture-anim)
   (locator-joint  int32)
   (pos            vector                    :inline)
   )
  )


(deftype fort-robotank (process-drawable)
  ((root                collide-shape-moving     :override)
   (barrel-part         sparticle-launch-control)
   (roller-jmod         joint-mod)
   (vibe-jmod           joint-mod)
   (tread               fort-robotank-tread-info  2 :inline)
   (path-info           fort-robotank-path-info-array)
   (segment-table       (inline-array fort-robotank-segment))
   (flags               robotank-flags)
   (pov-cam-offset      vector                    2 :inline)
   (turret              handle)
   (no-collision-timer  time-frame)
   (buzz-timer          time-frame)
   (player-u            float)
   (player-prev-u       float)
   (roller-spin-rate    float)
   (engine-vibe-rate    float)
   (engine-vibe-amp     float)
   (attack-id           uint32)
   (path-index          int32)
   (path-count          int32)
   (continue-index      int32)
   (idle-sound          ambient-sound)
   (barrel-sound        ambient-sound)
   )
  (:state-methods
    idle
    turning
    moving
    pause
    die
    )
  (:methods
    (fort-robotank-method-25 (_type_) event-message-block)
    (fort-robotank-method-26 (_type_ int float float) symbol)
    (fort-robotank-method-27 (_type_) none)
    )
  )


(define *fort-robotank-1-segment-table*
  (new 'static 'inline-array fort-robotank-segment 4
    (new 'static 'fort-robotank-segment
      :flags #x17
      :max-speed 6.0
      :next-segment 1
      :event-count 5
      :event-tbl (new 'static 'inline-array fort-robotank-segment-event 5
        (new 'static 'fort-robotank-segment-event :event-type 'external-cam-on :actor "camera-229")
        (new 'static 'fort-robotank-segment-event :event-type 'external-cam-off :actor #f :pos-norm 0.3)
        (new 'static 'fort-robotank-segment-event :event-type 'pov-cam-on :actor #f :pos-norm 0.3)
        (new 'static 'fort-robotank-segment-event
          :event-type 'send-event
          :actor "fort-fence-a-1"
          :pos-norm 0.1
          :param-obj 'start-loading
          )
        (new 'static 'fort-robotank-segment-event
          :event-type 'send-event
          :actor "fort-elec-gate-10"
          :pos-norm 0.9375
          :param-obj 'trigger
          )
        )
      )
    (new 'static 'fort-robotank-segment
      :flags #x7
      :max-speed 9.0
      :next-segment 2
      :event-count 4
      :event-tbl (new 'static 'inline-array fort-robotank-segment-event 5
        (new 'static 'fort-robotank-segment-event
          :event-type 'code
          :pos-norm 0.01
          :param-obj (lambda () (set-setting! 'target-height 'abs (meters -1) 0) (none))
          )
        (new 'static 'fort-robotank-segment-event
          :event-type 'send-event
          :actor "fort-fence-a-1"
          :pos-norm 0.0104
          :param-obj 'break
          )
        (new 'static 'fort-robotank-segment-event
          :event-type 'send-event
          :actor "fort-fence-b-1"
          :pos-norm 0.66667
          :param-obj 'start-loading
          )
        (new 'static 'fort-robotank-segment-event
          :source (new 'static 'handle :process #x1 :u64 #x1)
          :event-type 'pov-cam-off
          :pos-norm 0.83
          )
        (new 'static 'fort-robotank-segment-event
          :event-type 'code
          :pos-norm 0.83
          :param-obj (lambda ((arg0 fort-robotank)) (send-event (handle->process (-> arg0 turret)) 'set-spread #x44e38e39) (none))
          )
        )
      )
    (new 'static 'fort-robotank-segment
      :flags #x20
      :max-speed 10.0
      :next-segment 3
      :event-count 4
      :event-tbl (new 'static 'inline-array fort-robotank-segment-event 4
        (new 'static 'fort-robotank-segment-event
          :event-type 'code
          :param-obj (lambda ((arg0 fort-robotank)) (send-event (handle->process (-> arg0 turret)) 'set-spread #x43b60b61) (none))
          )
        (new 'static 'fort-robotank-segment-event :event-type 'external-cam-on :actor "camera-176")
        (new 'static 'fort-robotank-segment-event :event-type 'external-cam-off :pos-norm 0.38)
        (new 'static 'fort-robotank-segment-event
          :event-type 'send-event
          :actor "fort-fence-b-1"
          :pos-norm 0.0793
          :param-obj 'break
          )
        )
      )
    (new 'static 'fort-robotank-segment :flags #x20 :max-speed 8.0 :next-segment 3)
    )
  )

(define *fort-robotank-2-segment-table*
  (new 'static 'inline-array fort-robotank-segment 1
    (new 'static 'fort-robotank-segment :flags #x8 :max-speed 6.0 :next-segment-start 7.586)
    )
  )

(defskelgroup skel-fort-robotank fort-robotank fort-robotank-lod0-jg fort-robotank-idle-ja
              ((fort-robotank-lod0-mg (meters 20)) (fort-robotank-lod1-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 9)
              :origin-joint-index 3
              )

(defmethod fort-robotank-method-25 ((this fort-robotank))
  (with-pp
    (let ((v1-0 (-> this root)))
      (when (< (-> *event-queue* length) (-> *event-queue* allocated-length))
        (let ((v0-0 (-> *event-queue* data (-> *event-queue* length))))
          (+! (-> *event-queue* length) 1)
          (set! (-> v0-0 form-handle) (process->handle pp))
          (set! (-> v0-0 to-handle) (process->handle (handle->process (-> this turret))))
          (set! (-> v0-0 num-params) 4)
          (set! (-> v0-0 message) 'update)
          (set! (-> v0-0 param 0) (the-as uint (-> v1-0 trans)))
          (set! (-> v0-0 param 1) (the-as uint (-> v1-0 quat)))
          (set! (-> v0-0 param 2) (the-as uint (-> this node-list data 3)))
          (set! (-> v0-0 param 3) (the-as uint (-> this vibe-jmod twist)))
          v0-0
          )
        )
      )
    )
  )

(defbehavior fort-robotank-post fort-robotank ()
  (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
    )
  (fort-robotank-method-25 self)
  (seek! (-> self roller-jmod twist y) (-> self roller-spin-rate) (* 16384.0 (seconds-per-frame)))
  (let ((gp-0 (vector<-cspace! (new 'stack-no-clear 'vector) (joint-node fort-robotank-lod0-jg rollerrot)))
        (s4-0 (get-field-spec-by-id (-> *part-id-table* 2474) (sp-field-id spt-num)))
        (s5-0 (new 'stack-no-clear 'matrix))
        )
    (set! (-> s4-0 random-rangef) (lerp-scale 1.0 6.0 (-> self roller-jmod twist y) 8192.0 65536.0))
    (+! (-> gp-0 y) -6144.0)
    (quaternion->matrix s5-0 (-> self root quat))
    (set! (-> s5-0 trans quad) (-> gp-0 quad))
    (spawn-with-matrix (-> self barrel-part) s5-0)
    )
  (dotimes (gp-1 2)
    (let* ((s5-1 (-> self tread gp-1))
           (s4-1 (vector<-cspace! (new 'stack-no-clear 'vector) (-> self node-list data (-> s5-1 locator-joint))))
           )
      (let ((s3-1 (vector-! (new 'stack-no-clear 'vector) s4-1 (-> s5-1 pos))))
        (let ((s2-0 (vector-x-quaternion! (new 'stack-no-clear 'vector) (-> self root quat))))
          (if (= gp-1 1)
              (vector-float*! s2-0 s2-0 -1.0)
              )
          (let ((s1-0 (get-field-spec-by-id (-> *part-id-table* 2471) (sp-field-id spt-num)))
                (f30-0 (vector-length s3-1))
                (f28-0 (* 12288.0 (seconds-per-frame)))
                )
            (set! (-> s1-0 initial-valuef) (lerp-scale 0.0 0.5 f30-0 0.0 f28-0))
            (set! (-> s1-0 random-rangef) (lerp-scale 0.0 1.0 f30-0 0.0 f28-0))
            )
          (let ((a1-14 (forward-up-nopitch->inv-matrix (new 'stack-no-clear 'matrix) s2-0 *up-vector*)))
            (set! (-> a1-14 trans quad) (-> s4-1 quad))
            (+! (-> a1-14 trans y) -2498.56)
            (spawn-with-matrix (-> self part) a1-14)
            )
          )
        (vector-inv-orient-by-quat! s3-1 s3-1 (-> self root quat))
        (let ((f30-1 (fabs (-> s3-1 z))))
          (dotimes (s3-2 7)
            (let ((s2-1 (-> s5-1 wheel s3-2)))
              (set! (-> s2-1 jmod spin-rate) (* (atan f30-1 (-> s2-1 radius)) (-> self clock frames-per-second)))
              )
            )
          (set! (-> s5-1 texture frame-delta) (* 0.00028388444 (-> self clock frames-per-second) f30-1))
          )
        )
      (set! (-> s5-1 pos quad) (-> s4-1 quad))
      )
    )
  (let ((v1-65 (-> self path-info data (-> self path-index))))
    (cond
      ((and (logtest? (-> self flags) (robotank-flags roflags-2)) (!= (-> v1-65 u) (-> v1-65 prev-u)))
       (seek! (-> self engine-vibe-rate) 3.0 (seconds-per-frame))
       (seek! (-> self engine-vibe-amp) 1.0 (seconds-per-frame))
       )
      (else
        (seek! (-> self engine-vibe-rate) 1.0 (seconds-per-frame))
        (seek! (-> self engine-vibe-amp) 0.4 (seconds-per-frame))
        )
      )
    )
  (let* ((f0-35 30.0)
         (f1-7 65536.0)
         (f2-1 (the float (current-time)))
         (f0-36 (/ (* f1-7 (- f2-1 (* (the float (the int (/ f2-1 f0-35))) f0-35))) f0-35))
         (f28-1 (sin f0-36))
         (f30-2 (* 300.0 (/ 1.0 (-> self engine-vibe-rate))))
         (f0-39 (the float (current-time)))
         (f24-0 (/ (- f0-39 (* (the float (the int (/ f0-39 f30-2))) f30-2)) f30-2))
         (f28-2 (* f28-1 (sin (* 65536.0 f24-0))))
         )
    (let* ((f0-44 (sin 7281.778))
           (f1-16 (- 1.0 f0-44))
           (f26-0 0.0)
           )
      (when (and (or (< f0-44 f24-0) (< f24-0 f1-16)) (time-elapsed? (-> self buzz-timer) (the int (/ f30-2 2))))
        (let* ((gp-2 *target*)
               (a0-43 (if (type? gp-2 process-focusable)
                          gp-2
                          )
                      )
               )
          (if a0-43
              (set! f26-0
                    (lerp-scale 1.0 0.0 (vector-vector-distance (-> self root trans) (get-trans a0-43 0)) 81920.0 327680.0)
                    )
              )
          )
        (cpad-set-buzz!
          (-> *cpad-list* cpads 0)
          1
          (the int (* 255.0 (* 0.49 f26-0)))
          (the-as time-frame (max 45 (the int (/ f30-2 4))))
          )
        (set-time! (-> self buzz-timer))
        )
      )
    (quaternion-axis-angle!
      (the-as quaternion (-> self vibe-jmod twist))
      0.0
      0.0
      1.0
      (* 182.04445 (* (-> self engine-vibe-amp) f28-2))
      )
    )
  (dotimes (gp-4 (-> self path-count))
    (debug-draw (-> self path-info data gp-4 path))
    )
  (when (logtest? (-> self flags) (robotank-flags roflags-7))
    (let ((gp-5 (quaternion-inverse! (new 'stack-no-clear 'quaternion) (-> self root quat)))
          (a1-28 (new 'stack-no-clear 'event-message-block))
          )
      (set! (-> a1-28 from) (process->ppointer self))
      (set! (-> a1-28 num-params) 0)
      (set! (-> a1-28 message) 'get-rotate-quat)
      (let ((s5-3 (send-event-function (handle->process (-> self turret)) a1-28))
            (s4-3 (new 'stack-no-clear 'quaternion))
            (s2-3 (-> (the-as fort-robotank-turret (handle->process (-> self turret))) root trans))
            (s1-1 (-> self root trans))
            (s3-4 (new 'stack-no-clear 'vector))
            )
        (let ((a1-30 (new 'stack-no-clear 'event-message-block)))
          (set! (-> a1-30 from) (process->ppointer self))
          (set! (-> a1-30 num-params) 0)
          (set! (-> a1-30 message) 'get-gun-elevation-cam)
          (let ((f30-3 (the-as float (send-event-function (handle->process (-> self turret)) a1-30))))
            (vector-! s3-4 s2-3 s1-1)
            (vector-orient-by-quat! s3-4 s3-4 gp-5)
            (quaternion*! s4-3 (the-as quaternion s5-3) gp-5)
            (quaternion-normalize! s4-3)
            (quaternion-rotate-local-x! s4-3 s4-3 f30-3)
            )
          )
        (vector-orient-by-quat! (the-as vector (-> self pov-cam-offset)) (-> self pov-cam-offset 1) s4-3)
        (vector+! (the-as vector (-> self pov-cam-offset)) (the-as vector (-> self pov-cam-offset)) s3-4)
        )
      )
    )
  (update-trans! (-> self sound) (-> self root trans))
  (update! (-> self sound))
  (update-trans! (-> self idle-sound) (-> self root trans))
  (update! (-> self idle-sound))
  (update-trans! (-> self barrel-sound) (-> self root trans))
  (update! (-> self barrel-sound))
  (pusher-post)
  (none)
  )

(defbehavior fort-robotank-handler fort-robotank ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  (case arg2
    (('trigger)
     (when (and *target* (< (-> self continue-index) (the-as int (-> arg3 param 0))))
       (if (< (-> self continue-index) 0)
           (add-process *gui-control* self (gui-channel alert) (gui-action play) "cityv107" -99.0 0)
           )
       (when (< (-> *event-queue* length) (-> *event-queue* allocated-length))
         (let ((v1-14 (-> *event-queue* data (-> *event-queue* length))))
           (+! (-> *event-queue* length) 1)
           (set! (-> v1-14 form-handle) (process->handle self))
           (set! (-> v1-14 to-handle) (process->handle (handle->process (-> self turret))))
           (set! (-> v1-14 num-params) 0)
           (set! (-> v1-14 message) 'trigger)
           )
         )
       (logior! (-> self flags) (robotank-flags roflags-5))
       (let ((ret (the-as object (-> arg3 param 0))))
         (set! (-> self continue-index) (the-as int ret))
         ret
         )
       )
     )
    (('trans)
     (-> self root trans)
     )
    (('die)
     (go-virtual die)
     )
    (('fire-suppress-on)
     (send-event (handle->process (-> self turret)) 'fire-suppress #t)
     )
    (('fire-suppress-off)
     (send-event (handle->process (-> self turret)) 'fire-suppress #f)
     )
    (('touch 'attack)
     (when ((method-of-type touching-shapes-entry prims-touching?)
            (the-as touching-shapes-entry (-> arg3 param 0))
            (-> self root)
            (the-as uint 1)
            )
       (let ((s5-0 (if (type? arg0 process-focusable)
                       (the-as process-focusable arg0)
                       )
                   )
             )
         (when s5-0
           (let ((a0-48 (vector-z-quaternion! (new 'stack-no-clear 'vector) (-> self root quat))))
             (when (send-event
                     s5-0
                     'attack-or-shove
                     (-> arg3 param 0)
                     (static-attack-info ((id (-> self attack-id))
                                          (vector a0-48)
                                          (shove-back (if (and (-> self next-state) (= (-> self next-state name) 'idle))
                                                          16384.0
                                                          49152.0
                                                          )
                                                      )
                                          (shove-up (meters 6))
                                          (control (if (focus-test? s5-0 board)
                                                       1.0
                                                       0.0
                                                       )
                                                   )
                                          )
                                         )
                     )
               (set-time! (-> self no-collision-timer))
               (let ((v1-45 (-> self root root-prim)))
                 (set! (-> v1-45 prim-core collide-as) (collide-spec))
                 (set! (-> v1-45 prim-core collide-with) (collide-spec))
                 )
               0
               )
             )
           )
         )
       )
     )
    (('stop-music)
     (remove-setting! 'music)
     (remove-setting! 'music-volume)
     (remove-setting! 'sound-mode)
     )
    )
  )

(defmethod fort-robotank-method-26 ((this fort-robotank) (arg0 int) (arg1 float) (arg2 float))
  (local-vars
    (sv-96 fort-robotank-segment-event)
    (sv-112 (function process-tree event-message-block object))
    (sv-128 event-message-block)
    )
  (with-pp
    (let* ((s4-0 (* 0.00001 (the float (the int (+ 0.5 (* 100000.0 arg1))))))
           (s3-0 (* 0.00001 (the float (the int (+ 0.5 (* 100000.0 arg2))))))
           (s2-0 (-> this segment-table (-> this path-index)))
           (s1-0 (-> s2-0 event-tbl))
           )
      (dotimes (s0-0 (-> s2-0 event-count))
        (set! sv-96 (-> s1-0 s0-0))
        (let ((f0-4 (-> sv-96 pos-norm)))
          (when (and (= (-> sv-96 source) arg0) (>= s4-0 f0-4) (< s3-0 f0-4))
            (case (-> sv-96 event-type)
              (('send-event)
               (set! sv-128 (new 'stack-no-clear 'event-message-block))
               (set! (-> sv-128 from) (process->ppointer pp))
               (set! (-> sv-128 num-params) 0)
               (set! (-> sv-128 message) (the-as symbol (-> sv-96 param-obj)))
               (set! sv-112 send-event-function)
               (let ((a0-11 (process-by-ename (-> sv-96 actor))))
                 (sv-112 a0-11 sv-128)
                 )
               )
              (('code)
               (let ((t9-2 (-> sv-96 param-obj)))
                 (if t9-2
                     ((the-as (function fort-robotank none) t9-2) this)
                     )
                 )
               )
              (('pov-cam-on)
               (set-setting! 'mode-name 'cam-pov-track 0.0 0)
               (set-setting! 'allow-look-around #f 0.0 0)
               (set-setting! 'target-height 'abs (meters -3) 0)
               (let ((v1-27 (process->ppointer this)))
                 (set-setting! 'pov-handle v1-27 3.0 (-> v1-27 0 pid))
                 )
               (set-setting! 'pov-offset 'asdf (-> this pov-cam-offset) 0)
               (send-event (handle->process (-> this turret)) 'pov-cam-on)
               (logior! (-> this flags) (robotank-flags roflags-7))
               (let ((v1-41 (-> (the-as collide-shape-prim-group (-> this root root-prim)) child 2)))
                 (set! (-> v1-41 prim-core collide-as) (collide-spec enemy pusher))
                 (set! (-> v1-41 prim-core collide-with) (collide-spec jak bot player-list))
                 )
               )
              (('pov-cam-off)
               (remove-setting! 'pov-handle)
               (remove-setting! 'mode-name)
               (remove-setting! 'allow-look-around)
               (remove-setting! 'target-height)
               (remove-setting! 'pov-offset)
               (send-event (handle->process (-> this turret)) 'pov-cam-off)
               (logclear! (-> this flags) (robotank-flags roflags-7))
               (let ((v1-57 (-> (the-as collide-shape-prim-group (-> this root root-prim)) child 2)))
                 (set! (-> v1-57 prim-core collide-as) (collide-spec))
                 (set! (-> v1-57 prim-core collide-with) (collide-spec))
                 )
               0
               )
              (('external-cam-on)
               (hide-hud-quick #f)
               (set-setting! 'entity-name (-> sv-96 actor) 0.0 0)
               (set-setting! 'process-mask 'set 0.0 (process-mask movie enemy))
               (remove-setting! 'target-height)
               (process-grab? *target* #f)
               (send-event (handle->process (-> this turret)) 'fire-suppress #t)
               )
              (('external-cam-off)
               (remove-setting! 'entity-name)
               (remove-setting! 'process-mask)
               (remove-setting! 'target-height)
               (process-release? *target*)
               (send-event (handle->process (-> this turret)) 'fire-suppress #f)
               )
              )
            )
          )
        )
      )
    #f
    )
  )

;; WARN: Return type mismatch object vs none.
(defmethod fort-robotank-method-27 ((this fort-robotank))
  (let ((s5-0 (-> this segment-table (-> this path-index) flags)))
    (send-event (handle->process (-> this turret)) 'use-los (if (logtest? s5-0 16)
                                                                #t
                                                                #f
                                                                )
                )
    (send-event (handle->process (-> this turret)) 'limit-reticle-elev (if (logtest? s5-0 32)
                                                                           #t
                                                                           #f
                                                                           )
                )
    )
  (none)
  )

(defstate idle (fort-robotank)
  :virtual #t
  :event fort-robotank-handler
  :enter (behavior ()
    (fort-robotank-method-25 self)
    (set! (-> self roller-spin-rate) 2730.6667)
    )
  :trans (behavior ()
    (when (and (name= (-> self name) "fort-robotank-6") (task-node-closed? (game-task-node fortress-dump-deal)))
      (when (< (-> *event-queue* length) (-> *event-queue* allocated-length))
        (let ((v1-8 (-> *event-queue* data (-> *event-queue* length))))
          (+! (-> *event-queue* length) 1)
          (set! (-> v1-8 form-handle) (process->handle self))
          (set! (-> v1-8 to-handle) (process->handle (handle->process (-> self turret))))
          (set! (-> v1-8 num-params) 0)
          (set! (-> v1-8 message) 'trigger)
          )
        )
      (logior! (-> self flags) (robotank-flags roflags-5))
      )
    (when (logtest? (-> self flags) (robotank-flags roflags-5))
      (logclear! (-> self flags) (robotank-flags roflags-5))
      (set-setting! 'music 'danger11 0.0 0)
      (set-setting! 'music-volume 'rel 0.9 0)
      (go-virtual moving)
      )
    )
  :code sleep-code
  :post fort-robotank-post
  )

(defstate turning (fort-robotank)
  :virtual #t
  :event fort-robotank-handler
  :enter (behavior ()
    (set! (-> self path-info data (-> self path-index) start-y-angle) (quaternion-y-angle (-> self root quat)))
    (set! (-> self roller-spin-rate) 32768.0)
    )
  :trans (behavior ()
    (let* ((gp-0 (-> self path-info data (-> self path-index)))
           (s5-0 (-> self root))
           (f30-0 (quaternion-y-angle (-> s5-0 quat)))
           (f28-0 (fabs (deg-diff f30-0 (-> gp-0 start-y-angle))))
           (f30-1 (fabs (deg-diff f30-0 (vector-y-angle (-> gp-0 dir)))))
           )
      (let* ((f0-3 (fmin f28-0 f30-1))
             (f0-6 (fmax 728.1778 (fmin 10012.444 (* 4.0 f0-3))))
             )
        (seek-toward-heading-vec! s5-0 (-> gp-0 dir) f0-6 (seconds 0.02))
        )
      (if (< f30-1 36.40889)
          (go-virtual pause)
          )
      )
    )
  :code sleep-code
  :post (behavior ()
    (fort-robotank-post)
    )
  )

(defstate moving (fort-robotank)
  :virtual #t
  :event fort-robotank-handler
  :enter (behavior ()
    (set! (-> self roller-spin-rate) 65536.0)
    (let ((v1-4 (-> self path-info data (-> self path-index))))
      (set! (-> v1-4 u) 0.0)
      (set! (-> v1-4 prev-u) -1.0)
      (set! (-> v1-4 du) 0.0)
      (set! (-> v1-4 du-final) 0.01)
      )
    (fort-robotank-method-27 self)
    )
  :exit (behavior ()
    (logclear! (-> self flags) (robotank-flags roflags-2))
    )
  :trans (behavior ()
    (if (not *target*)
        (go-virtual die)
        )
    (let* ((gp-0 *target*)
           (a0-1 (if (type? gp-0 process-focusable)
                     gp-0
                     )
                 )
           )
      (when a0-1
        (if (< (-> (get-trans a0-1 0) y) (+ -18432.0 (-> self root trans y)))
            (go-virtual die)
            )
        )
      )
    (let* ((v1-14 (-> self path-index))
           (s5-0 (-> self path-info data v1-14))
           (gp-1 (-> self segment-table v1-14))
           )
      (fort-robotank-method-26 self 0 (-> s5-0 u) (-> s5-0 prev-u))
      (let ((s4-0 *target*))
        (if (if (type? s4-0 process-focusable)
                s4-0
                )
            (fort-robotank-method-26 self 1 (-> self player-u) (-> self player-prev-u))
            )
        )
      (when (= (-> s5-0 u) 1.0)
        (cond
          ((logtest? (-> gp-1 flags) 1)
           (set! (-> self path-index) (-> gp-1 next-segment))
           (go-virtual turning)
           )
          (else
            (set! (-> self path-index) (-> gp-1 next-segment))
            (let ((gp-2 (-> self path-info data (-> self path-index))))
              (set! (-> gp-2 u)
                    (/ (-> self segment-table (-> self path-index) next-segment-start) (get-num-segments (-> gp-2 path)))
                    )
              (set! (-> gp-2 prev-u) (+ -0.1 (-> gp-2 u)))
              (set! (-> gp-2 du) 0.01)
              (set! (-> gp-2 du-final) 0.01)
              )
            0
            (fort-robotank-method-27 self)
            )
          )
        )
      )
    )
  :code (behavior ()
    (logclear! (-> self flags) (robotank-flags roflags-2))
    (suspend-for (seconds 0.1)
      )
    (logior! (-> self flags) (robotank-flags roflags-2))
    (sleep-code)
    )
  :post (behavior ()
    (when (logtest? (-> self flags) (robotank-flags roflags-2))
      (let* ((gp-0 *target*)
             (s3-0 (if (type? gp-0 process-focusable)
                       gp-0
                       )
                   )
             (s5-0 (if s3-0
                       (get-trans s3-0 0)
                       (the-as vector #f)
                       )
                   )
             (gp-1 (-> self path-info data (-> self path-index)))
             )
        (-> self segment-table (-> self path-index))
        (let ((s4-0 (-> gp-1 path))
              (s2-0 (new 'stack-no-clear 'vector))
              )
          (let ((f30-0 (-> gp-1 u))
                (s0-0 (new 'stack-no-clear 'vector))
                (s1-0 (-> self root))
                )
            (get-point-at-percent-along-path! s4-0 (-> s1-0 trans) f30-0 'interp)
            (+! (-> s1-0 trans y) 1024.0)
            (displacement-between-points-at-percent-normalized! s4-0 s0-0 f30-0)
            (displacement-between-points-at-percent-scaled! s4-0 s2-0 f30-0 (-> gp-1 du-final))
            (seek-toward-heading-vec! s1-0 s0-0 16384.0 (seconds 0.02))
            )
          (set! (-> gp-1 prev-u) (-> gp-1 u))
          (set! (-> self player-prev-u) (-> self player-u))
          (if s3-0
              (set! (-> self player-u) (get-path-percentage-at-furthest-point s4-0 s5-0))
              )
          (let ((f30-1 (* (-> gp-1 du) (/ (-> gp-1 max-speed) (vector-length s2-0))))
                (f28-0 1.0)
                )
            (if (logtest? (-> self segment-table (-> self path-index) flags) 1)
                (set! f28-0
                      (fmin 1.0 (* 0.000048828126
                                   (+ 2048.0 (vector-vector-distance
                                               (-> self root trans)
                                               (get-point-at-percent-along-path! s4-0 (new 'stack-no-clear 'vector) 1.0 'interp)
                                               )
                                      )
                                   )
                            )
                      )
                )
            (when s3-0
              (let* ((s2-2 (-> self segment-table (-> self path-index) flags))
                     (f26-1 (-> self player-u))
                     (s3-1 (method-of-type path-control get-point-in-path!))
                     (s3-2 (s3-1 s4-0 (new 'stack-no-clear 'vector) (* f26-1 (get-num-segments s4-0)) 'interp))
                     (f20-0 (vector-vector-distance s3-2 s5-0))
                     (f24-1 (total-distance s4-0))
                     (f22-0 (+ -20480.0 f24-1))
                     )
                (when (logtest? s2-2 2)
                  (if (< (* f26-1 f24-1) (fmin (+ 61440.0 (* (-> gp-1 u) f24-1)) f22-0))
                      (set! f28-0 (if (and (< f20-0 8192.0) (< (-> gp-1 u) f26-1))
                                      1.0
                                      (fmin f28-0 (lerp-scale
                                                    0.0
                                                    1.0
                                                    (if (< f26-1 (-> gp-1 u))
                                                        0.0
                                                        (vector-vector-distance (-> self root trans) s3-2)
                                                        )
                                                    6144.0
                                                    61440.0
                                                    )
                                            )
                                      )
                            )
                      )
                  )
                (when (logtest? s2-2 4)
                  (if (< (fmin (+ 102400.0 (* (-> gp-1 u) f24-1)) f22-0) (* f26-1 f24-1))
                      (set! f28-0
                            (fmax f28-0 (lerp-scale 1.0 2.0 (vector-vector-distance (-> self root trans) s3-2) 102400.0 143360.0))
                            )
                      )
                  )
                )
              )
            (set! (-> gp-1 u) (fmax 0.0 (fmin 1.0 (+ (-> gp-1 u) (* f28-0 f30-1 (seconds-per-frame))))))
            (seek! (-> gp-1 du) (-> gp-1 du-final) (* 0.5 (seconds-per-frame) (-> gp-1 du-final)))
            (update-vol! (-> self sound) (lerp-scale 0.0 1.0 (* f28-0 f30-1) 0.0 0.03))
            (update-vol! (-> self barrel-sound) (lerp-scale 0.0 1.0 (* f28-0 f30-1) 0.0 0.01))
            )
          )
        )
      )
    (fort-robotank-post)
    )
  )

(defstate pause (fort-robotank)
  :virtual #t
  :event fort-robotank-handler
  :enter (behavior ()
    (set! (-> self roller-spin-rate) 16384.0)
    )
  :trans (behavior ()
    (when (logtest? (-> self flags) (robotank-flags roflags-5))
      (logclear! (-> self flags) (robotank-flags roflags-5))
      (go-virtual moving)
      )
    )
  :code sleep-code
  :post fort-robotank-post
  )

(defstate die (fort-robotank)
  :virtual #t
  :code (behavior ()
    (remove-setting! 'pov-handle)
    (remove-setting! 'pov-offset)
    (remove-setting! 'mode-name)
    (remove-setting! 'allow-look-around)
    (remove-setting! 'entity-name)
    (remove-setting! 'process-mask)
    (remove-setting! 'target-height)
    (send-event (handle->process (-> self turret)) 'die)
    (suspend-for (seconds 2)
      )
    (while (-> self child)
      (suspend)
      )
    )
  :post pusher-post
  )

(defmethod deactivate ((this fort-robotank))
  "Make a process dead, clean it up, remove it from the active pool, and return to dead pool."
  (stop! (-> this idle-sound))
  (stop! (-> this barrel-sound))
  ((method-of-type process-drawable deactivate) this)
  (none)
  )

(defmethod relocate ((this fort-robotank) (offset int))
  (if (nonzero? (-> this barrel-part))
      (&+! (-> this barrel-part) offset)
      )
  (if (nonzero? (-> this roller-jmod))
      (&+! (-> this roller-jmod) offset)
      )
  (if (nonzero? (-> this vibe-jmod))
      (&+! (-> this vibe-jmod) offset)
      )
  (if (nonzero? (-> this idle-sound))
      (&+! (-> this idle-sound) offset)
      )
  (if (nonzero? (-> this barrel-sound))
      (&+! (-> this barrel-sound) offset)
      )
  (let ((v1-20 (-> this path-info)))
    (when (nonzero? v1-20)
      (dotimes (a0-2 (-> this path-count))
        (if (nonzero? (-> v1-20 data a0-2 path))
            (&+! (-> v1-20 data a0-2 path) offset)
            )
        )
      (&+! (-> this path-info) offset)
      )
    )
  (dotimes (v1-24 2)
    (dotimes (a0-4 7)
      (if (nonzero? (the-as
                      joint-mod
                      (-> (the-as (pointer uint32) (&+ (&+ (the-as (pointer uint32) this) (* 144 v1-24)) (* a0-4 16))) 55)
                      )
                    )
          (set! (-> (&+ (&+ (the-as (pointer uint32) this) (* 144 v1-24)) (* a0-4 16)) 55)
                (the-as
                  uint
                  (&+
                    (the-as
                      joint-mod
                      (-> (the-as (pointer uint32) (&+ (&+ (the-as (pointer uint32) this) (* 144 v1-24)) (* a0-4 16))) 55)
                      )
                    offset
                    )
                  )
                )
          )
      )
    )
  (call-parent-method this offset)
  )

;; WARN: Return type mismatch object vs none.
(defmethod init-from-entity! ((this fort-robotank) (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 3) 0)))
      (set! (-> s4-0 total-prims) (the-as uint 4))
      (set! (-> s3-0 prim-core collide-as) (collide-spec enemy 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))
      (set-vector! (-> s3-0 local-sphere) 0.0 0.0 0.0 47104.0)
      (set! (-> s4-0 root-prim) s3-0)
      )
    (pusher-init s4-0)
    (let ((v1-14 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 1))))
      (set! (-> v1-14 prim-core collide-as) (collide-spec enemy camera-blocker pusher))
      (set! (-> v1-14 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> v1-14 prim-core action) (collide-action solid))
      (set! (-> v1-14 transform-index) 5)
      (set-vector! (-> v1-14 local-sphere) 0.0 0.0 0.0 24576.0)
      )
    (let ((v1-16 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 1) (the-as uint 0))))
      (set! (-> v1-16 prim-core collide-as) (collide-spec enemy camera-blocker pusher))
      (set! (-> v1-16 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> v1-16 prim-core action) (collide-action solid))
      (set! (-> v1-16 transform-index) 3)
      (set-vector! (-> v1-16 local-sphere) 0.0 0.0 -8192.0 28672.0)
      )
    (let ((v1-18 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 3) (the-as uint 0))))
      (set! (-> v1-18 prim-core action) (collide-action solid))
      (set! (-> v1-18 transform-index) 3)
      (set-vector! (-> v1-18 local-sphere) 0.0 0.0 -8192.0 36864.0)
      )
    (set! (-> s4-0 nav-radius) (* 0.75 (-> s4-0 root-prim local-sphere w)))
    (let ((v1-21 (-> s4-0 root-prim)))
      (set! (-> s4-0 backup-collide-as) (-> v1-21 prim-core collide-as))
      (set! (-> s4-0 backup-collide-with) (-> v1-21 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-fort-robotank" (the-as (pointer uint32) #f)))
    (the-as pair 0)
    )
  (logclear! (-> this mask) (process-mask actor-pause))
  (process-entity-status! this (entity-perm-status no-kill) #t)
  (set! (-> this fact)
        (new 'process 'fact-info this (pickup-type eco-pill-random) (-> *FACT-bank* default-eco-pill-green-inc))
        )
  (set! (-> this flags) (robotank-flags))
  (set! (-> this no-collision-timer) 0)
  (set! (-> this engine-vibe-rate) 1.0)
  (set! (-> this buzz-timer) 0)
  (let* ((v1-31 *game-info*)
         (a0-30 (+ (-> v1-31 attack-id) 1))
         )
    (set! (-> v1-31 attack-id) a0-30)
    (set! (-> this attack-id) a0-30)
    )
  (cond
    ((name= (-> this name) "fort-robotank-2")
     (set! (-> this segment-table) *fort-robotank-1-segment-table*)
     (set! (-> this path-count) 4)
     )
    ((name= (-> this name) "fort-robotank-6")
     (set! (-> this segment-table) *fort-robotank-2-segment-table*)
     (set! (-> this path-count) 1)
     )
    (else
      (go process-drawable-art-error "unknown actor-node name")
      )
    )
  (set! (-> this path-info) (new 'process 'fort-robotank-path-info-array (-> this path-count)))
  (dotimes (s5-2 (-> this path-count))
    (let ((s4-2 (-> this path-info data s5-2)))
      (if (logtest? (-> this segment-table s5-2 flags) 8)
          (set! (-> s4-2 path) (new 'process 'curve-control this 'path -1000000000.0))
          (set! (-> s4-2 path) (new 'process 'curve-control this 'path (the float s5-2)))
          )
      (logior! (-> s4-2 path flags) (path-control-flag display draw-line draw-point draw-text))
      (set! (-> s4-2 u) 0.0)
      (set! (-> s4-2 du) (-> s4-2 u))
      (set! (-> s4-2 max-speed) (* 4096.0 (-> this segment-table s5-2 max-speed)))
      (set! (-> s4-2 dist) (total-distance (-> s4-2 path)))
      (set! (-> s4-2 start-y-angle) 0.0)
      (displacement-between-two-points-normalized! (-> s4-2 path) (-> s4-2 dir) 0.0)
      )
    )
  (set! (-> this path-index) 0)
  (set! (-> this continue-index) -1)
  (let ((s5-3 (new 'stack-no-clear 'vector)))
    (let ((s4-3 (-> this path-info data 0 path)))
      (get-point-in-path! s4-3 (-> this root trans) 0.0 'interp)
      (+! (-> this root trans y) 1024.0)
      (displacement-between-points-at-percent-normalized! s4-3 s5-3 0.0)
      )
    (set-heading-vec! (-> this root) s5-3)
    )
  (let ((a0-46 (-> this skel root-channel 0)))
    (set! (-> a0-46 frame-group) (the-as art-joint-anim (-> this draw art-group data 3)))
    (set! (-> a0-46 frame-num) 0.0)
    (joint-control-channel-group! a0-46 (the-as art-joint-anim (-> this draw art-group data 3)) num-func-identity)
    )
  (transform-post)
  (let ((s5-4 (new 'stack-no-clear 'vector)))
    (set-vector! s5-4 0.0 12541.952 -6778.88 1.0)
    (set! (-> this turret)
          (ppointer->handle
            (process-spawn fort-robotank-turret (-> this root trans) (-> this root quat) s5-4 #x42000000 :to this)
            )
          )
    )
  (set! (-> this roller-jmod) (the-as joint-mod (new 'process 'joint-mod-spinner this 5 *x-vector* 0.0)))
  (set! (-> this roller-spin-rate) 0.0)
  (set! (-> this vibe-jmod) (the-as joint-mod (new 'process 'joint-mod-blend-local this 4 #t)))
  (set! (-> this vibe-jmod scale y) 0.5)
  (quaternion-axis-angle! (the-as quaternion (-> this vibe-jmod twist)) 0.0 0.0 1.0 0.0)
  (let ((s5-5 (-> this tread)))
    (set! (-> s5-5 0 wheel 0 jmod) (new 'process 'joint-mod-spinner this 6 *x-vector* 0.0))
    (set! (-> s5-5 0 wheel 0 radius) 2048.0)
    )
  (let ((s5-6 (-> this tread 0 wheel 1)))
    (set! (-> s5-6 jmod) (new 'process 'joint-mod-spinner this 7 *x-vector* 0.0))
    (set! (-> s5-6 radius) 2048.0)
    )
  (let ((s5-7 (-> this tread 0 wheel 2)))
    (set! (-> s5-7 jmod) (new 'process 'joint-mod-spinner this 8 *x-vector* 0.0))
    (set! (-> s5-7 radius) 2048.0)
    )
  (let ((s5-8 (-> this tread 0 wheel 3)))
    (set! (-> s5-8 jmod) (new 'process 'joint-mod-spinner this 9 *x-vector* 0.0))
    (set! (-> s5-8 radius) 2048.0)
    )
  (let ((s5-9 (-> this tread 0 wheel 4)))
    (set! (-> s5-9 jmod) (new 'process 'joint-mod-spinner this 10 *x-vector* 0.0))
    (set! (-> s5-9 radius) 2048.0)
    )
  (let ((s5-10 (-> this tread 0 wheel 5)))
    (set! (-> s5-10 jmod) (new 'process 'joint-mod-spinner this 11 *x-vector* 0.0))
    (set! (-> s5-10 radius) 2048.0)
    )
  (let ((s5-11 (-> this tread 0 wheel 6)))
    (set! (-> s5-11 jmod) (new 'process 'joint-mod-spinner this 12 *x-vector* 0.0))
    (set! (-> s5-11 radius) 2048.0)
    )
  (let ((s5-12 (-> this tread 1)))
    (set! (-> s5-12 wheel 0 jmod) (new 'process 'joint-mod-spinner this 13 *x-vector* 0.0))
    (set! (-> s5-12 wheel 0 radius) 2048.0)
    )
  (let ((s5-13 (-> this tread 1 wheel 1)))
    (set! (-> s5-13 jmod) (new 'process 'joint-mod-spinner this 14 *x-vector* 0.0))
    (set! (-> s5-13 radius) 2048.0)
    )
  (let ((s5-14 (-> this tread 1 wheel 2)))
    (set! (-> s5-14 jmod) (new 'process 'joint-mod-spinner this 15 *x-vector* 0.0))
    (set! (-> s5-14 radius) 2048.0)
    )
  (let ((s5-15 (-> this tread 1 wheel 3)))
    (set! (-> s5-15 jmod) (new 'process 'joint-mod-spinner this 16 *x-vector* 0.0))
    (set! (-> s5-15 radius) 2048.0)
    )
  (let ((s5-16 (-> this tread 1 wheel 4)))
    (set! (-> s5-16 jmod) (new 'process 'joint-mod-spinner this 17 *x-vector* 0.0))
    (set! (-> s5-16 radius) 2048.0)
    )
  (let ((s5-17 (-> this tread 1 wheel 5)))
    (set! (-> s5-17 jmod) (new 'process 'joint-mod-spinner this 18 *x-vector* 0.0))
    (set! (-> s5-17 radius) 2048.0)
    )
  (let ((s5-18 (-> this tread 1 wheel 6)))
    (set! (-> s5-18 jmod) (new 'process 'joint-mod-spinner this 19 *x-vector* 0.0))
    (set! (-> s5-18 radius) 2048.0)
    )
  (set! (-> this tread 0 texture) (-> *fortress-pris-texture-anim-array* array-data 0))
  (set! (-> this tread 0 texture frame-delta) 0.0)
  (let ((v1-128 9))
    (set! (-> this tread 0 locator-joint) v1-128)
    (vector<-cspace! (-> this tread 0 pos) (-> this node-list data v1-128))
    )
  (set! (-> this tread 1 texture) (-> *fortress-pris-texture-anim-array* array-data 1))
  (set! (-> this tread 1 texture frame-delta) 0.0)
  (let ((v1-135 16))
    (set! (-> this tread 1 locator-joint) v1-135)
    (vector<-cspace! (-> this tread 1 pos) (-> this node-list data v1-135))
    )
  (set-vector! (-> this pov-cam-offset 0) 0.0 13516.8 -13516.8 1.0)
  (set-vector! (-> this pov-cam-offset 1) 0.0 13516.8 -13516.8 1.0)
  (set! (-> this part) (create-launch-control (-> *part-group-id-table* 561) this))
  (set! (-> this barrel-part) (create-launch-control (-> *part-group-id-table* 562) this))
  (set! (-> this sound)
        (new 'process 'ambient-sound (static-sound-spec "robotank-tread" :fo-max 70) (-> this root trans))
        )
  (set! (-> this idle-sound)
        (new 'process 'ambient-sound (static-sound-spec "robotank-idle" :fo-max 50) (-> this root trans))
        )
  (set! (-> this barrel-sound)
        (new 'process 'ambient-sound (static-sound-spec "robotank-barrel" :fo-max 50) (-> this root trans))
        )
  (update-vol! (-> this sound) 0.0)
  (update-vol! (-> this idle-sound) 1.0)
  (update-vol! (-> this barrel-sound) 0.25)
  (go (method-of-object this idle))
  (none)
  )
