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

;; name: grunt-mech.gc
;; name in dgo: grunt-mech
;; dgos: DRILLMTN, UNB, RUI

;; DECOMP BEGINS

(deftype grunt-mech-hold (structure)
  ((reserve-mask  uint8)
   (lower-hold    int8)
   (grunt-handle  handle)
   (timeout       uint64)
   (local-pos     vector  :inline)
   (local-rot     vector  :inline)
   (local-mat     matrix  :inline)
   (world-mat     matrix  :inline)
   )
  )


(deftype grunt-mech-info (basic)
  ((reserved-mask     uint8)
   (last-update-time  time-frame)
   (holds             grunt-mech-hold  6 :inline)
   )
  (:methods
    (grunt-mech-info-method-9 (_type_ int process symbol) symbol)
    (grunt-mech-info-method-10 (_type_) none)
    )
  )


(define *grunt-mech-info*
  (new 'static 'grunt-mech-info :holds (new 'static 'inline-array grunt-mech-hold 6
                                         (new 'static 'grunt-mech-hold
                                           :reserve-mask #x11
                                           :lower-hold 4
                                           :local-pos (new 'static 'vector :x 163.84 :y 4874.24 :z 3522.56 :w 1.0)
                                           :local-rot (new 'static 'vector :y 32768.0 :w 1.0)
                                           )
                                         (new 'static 'grunt-mech-hold
                                           :reserve-mask #x22
                                           :lower-hold 5
                                           :local-pos (new 'static 'vector :x 958.464 :y 4874.24 :z -2678.784 :w 1.0)
                                           :local-rot (new 'static 'vector :w 1.0)
                                           )
                                         (new 'static 'grunt-mech-hold
                                           :reserve-mask #x4
                                           :lower-hold -1
                                           :local-pos (new 'static 'vector :x 3223.552 :y 4874.24 :z 217.088 :w 1.0)
                                           :local-rot (new 'static 'vector :y 49152.0 :w 1.0)
                                           )
                                         (new 'static 'grunt-mech-hold
                                           :reserve-mask #x8
                                           :lower-hold -1
                                           :local-pos (new 'static 'vector :x -3170.304 :y 4874.24 :z 520.192 :w 1.0)
                                           :local-rot (new 'static 'vector :y 16384.0 :w 1.0)
                                           )
                                         (new 'static 'grunt-mech-hold
                                           :reserve-mask #x11
                                           :lower-hold -1
                                           :local-pos (new 'static 'vector :x 516.096 :y 1929.216 :z 2449.408 :w 1.0)
                                           :local-rot (new 'static 'vector :x -9975.308 :y 34955.266 :z -205.34613 :w 1.0)
                                           )
                                         (new 'static 'grunt-mech-hold
                                           :reserve-mask #x22
                                           :lower-hold -1
                                           :local-pos (new 'static 'vector :x 413.696 :y 1929.216 :z -1785.856 :w 1.0)
                                           :local-rot (new 'static 'vector :x -10709.129 :y 1107.0122 :z 54.795376 :w 1.0)
                                           )
                                         )
                                )
  )

(let ((gp-0 *grunt-mech-info*))
  (set! (-> gp-0 last-update-time) 0)
  (set! (-> gp-0 reserved-mask) (the-as uint 0))
  (countdown (s5-0 6)
    (let ((s4-0 (-> gp-0 holds s5-0)))
      (set! (-> s4-0 grunt-handle) (the-as handle #f))
      (set! (-> s4-0 timeout) (the-as uint 0))
      (matrix-rotate-xyz! (-> s4-0 local-mat) (-> s4-0 local-rot))
      (set! (-> s4-0 local-mat trans quad) (-> s4-0 local-pos quad))
      )
    )
  )

(defmethod grunt-mech-info-method-10 ((this grunt-mech-info))
  (let ((s5-0 (current-time)))
    (when (!= (-> this last-update-time) s5-0)
      (when (< s5-0 (-> this last-update-time))
        (countdown (v1-4 6)
          (let ((a0-4 (-> this holds v1-4)))
            (set! (-> a0-4 grunt-handle) (the-as handle #f))
            (set! (-> a0-4 timeout) (the-as uint 0))
            )
          0
          )
        (set! (-> this reserved-mask) (the-as uint 0))
        0
        )
      (set! (-> this last-update-time) s5-0)
      (let ((v1-8 *target*))
        (cond
          ((and v1-8 (focus-test? v1-8 mech))
           (let ((s4-0 (-> v1-8 manipy 0 node-list data 3)))
             (dotimes (s3-0 6)
               (let ((s2-0 (-> this holds s3-0)))
                 (matrix*! (-> s2-0 world-mat) (-> s2-0 local-mat) (-> s4-0 bone transform))
                 (vector-float*! (-> s2-0 world-mat trans) (-> s2-0 world-mat trans) (/ 1.0 (-> s2-0 world-mat trans w)))
                 (when (and (!= (-> s2-0 grunt-handle) #f) (>= s5-0 (the-as time-frame (-> s2-0 timeout))))
                   (set! (-> s2-0 grunt-handle) (the-as handle #f))
                   (logclear! (-> this reserved-mask) (-> s2-0 reserve-mask))
                   )
                 )
               )
             )
           )
          (else
            (countdown (v1-25 6)
              (let ((a0-16 (-> this holds v1-25)))
                (set! (-> a0-16 grunt-handle) (the-as handle #f))
                (set! (-> a0-16 timeout) (the-as uint 0))
                )
              0
              )
            (set! (-> this reserved-mask) (the-as uint 0))
            0
            )
          )
        )
      )
    )
  (none)
  )

(defmethod grunt-mech-info-method-9 ((this grunt-mech-info) (arg0 int) (arg1 process) (arg2 symbol))
  (grunt-mech-info-method-10 this)
  (let ((v1-2 *target*))
    (when (and v1-2 (focus-test? v1-2 mech) (not (logtest? (-> v1-2 focus-status) (focus-status dead ignore))))
      (let ((v1-8 (-> this holds arg0)))
        (when (and (!= (-> v1-8 grunt-handle) #f) (= (handle->process (-> v1-8 grunt-handle)) arg1))
          (set! (-> v1-8 timeout) (the-as uint (+ (current-time) (seconds 0.5))))
          (return #t)
          )
        (when (not (logtest? (-> this reserved-mask) (-> v1-8 reserve-mask)))
          (when (not arg2)
            (logior! (-> this reserved-mask) (-> v1-8 reserve-mask))
            (set! (-> v1-8 grunt-handle) (process->handle arg1))
            (set! (-> v1-8 timeout) (the-as uint (+ (current-time) (seconds 0.5))))
            )
          #t
          )
        )
      )
    )
  )

(deftype grunt-mech (grunt)
  ((hold-id        int8)
   (dismount-dest  vector  :inline)
   )
  (:state-methods
    mech-lunge
    mech-hold
    mech-dismount
    mech-post-circling
    mech-pre-circling
    )
  (:methods
    (grunt-mech-method-191 (_type_) none)
    (grunt-mech-method-192 (_type_) symbol)
    (grunt-mech-method-193 (_type_) int)
    (grunt-mech-method-194 (_type_) none)
    (grunt-mech-method-195 (_type_ vector vector vector) symbol)
    )
  )


(defmethod common-post ((this grunt-mech))
  "Does a lot of various things relating to interacting with the target
- tracks when the enemy was last drawn
- looks at the target and handles attacking
@TODO Not extremely well understood yet"
  ((method-of-type grunt common-post) this)
  0
  (none)
  )

;; ERROR: Unsupported inline assembly instruction kind - [mula.s f0, f3]
;; ERROR: Unsupported inline assembly instruction kind - [madda.s f1, f4]
;; ERROR: Unsupported inline assembly instruction kind - [madd.s f0, f2, f5]
(defmethod grunt-mech-method-193 ((this grunt-mech))
  (local-vars (f0-3 float) (sv-592 vector))
  (let ((s4-0 *grunt-mech-info*))
    (grunt-mech-info-method-10 s4-0)
    (let ((gp-0 -1))
      (let ((f30-0 0.0)
            (s3-0 (-> this root trans))
            )
        (countdown (s2-0 4)
          (let ((s1-0 (-> s4-0 holds s2-0)))
            (when (grunt-mech-info-method-9 s4-0 s2-0 this #t)
              (let ((s0-0 (new 'stack-no-clear 'vector)))
                (set! sv-592 (new 'stack-no-clear 'vector))
                (set! (-> s0-0 quad) (-> s1-0 world-mat vector 2 quad))
                (set! (-> s0-0 y) 0.0)
                (vector-normalize! s0-0 1.0)
                (vector-! sv-592 (-> s1-0 world-mat trans) (-> this root trans))
                (set! (-> sv-592 y) 0.0)
                (vector-normalize! sv-592 1.0)
                (let ((f0-2 (-> sv-592 x))
                      (f1-0 (-> sv-592 y))
                      (f2-0 (-> sv-592 z))
                      (f3-0 (-> s0-0 x))
                      (f4-0 (-> s0-0 y))
                      (f5-0 (-> s0-0 z))
                      )
                  ;; og:preserve-this inlined vector-dot
                  ;; (.mula.s f0-2 f3-0)
                  ;; (.madda.s f1-0 f4-0)
                  ;; (.madd.s f0-3 f2-0 f5-0)
                  (set! f0-3 (vector-dot sv-592 s0-0))
                  )
                )
              (when (>= f0-3 0.0)
                (let ((f0-5 (vector-vector-distance-squared (-> s1-0 world-mat trans) s3-0)))
                  (when (or (= gp-0 -1) (< f0-5 f30-0))
                    (set! f30-0 f0-5)
                    (set! gp-0 s2-0)
                    )
                  )
                )
              )
            )
          )
        )
      (when (!= gp-0 -1)
        (let ((s3-1 (-> s4-0 holds gp-0 lower-hold)))
          (when (!= s3-1 -1)
            (if (and (or (zero? (rnd-int-count this 2))
                         (>= 14336.0 (vector-vector-xz-distance-squared (-> this root trans) (target-pos 0)))
                         )
                     (grunt-mech-info-method-9 s4-0 s3-1 this #t)
                     )
                (set! gp-0 s3-1)
                )
            )
          )
        (let ((a1-9 (new 'stack-no-clear 'collide-query)))
          (set! (-> a1-9 start-pos quad) (-> this root trans quad))
          (+! (-> a1-9 start-pos y) 6144.0)
          (vector-!
            (-> a1-9 move-dist)
            (the-as vector (+ (the-as uint (-> s4-0 holds 0 world-mat trans)) (* 192 gp-0)))
            (-> a1-9 start-pos)
            )
          (let ((v1-41 a1-9))
            (set! (-> v1-41 radius) 2048.0)
            (set! (-> v1-41 collide-with) (collide-spec backgnd obstacle hit-by-others-list pusher))
            (set! (-> v1-41 ignore-process0) this)
            (set! (-> v1-41 ignore-process1) #f)
            (set! (-> v1-41 ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1))
            (set! (-> v1-41 action-mask) (collide-action solid))
            )
          (if (>= (fill-and-probe-using-line-sphere *collide-cache* a1-9) 0.0)
              (set! gp-0 -1)
              )
          )
        )
      gp-0
      )
    )
  )

(defmethod grunt-method-184 ((this grunt-mech) (arg0 float))
  (local-vars (v1-5 float))
  (rlet ((acc :class vf)
         (vf0 :class vf)
         (vf1 :class vf)
         (vf2 :class vf)
         )
    (init-vf0-vector)
    (let ((gp-0 (get-enemy-target this)))
      (when gp-0
        (cond
          ((focus-test? gp-0 mech)
           (let ((v1-4 (get-trans gp-0 0))
                 (a1-2 (new 'stack-no-clear 'vector))
                 )
             (vector-! a1-2 v1-4 (-> this root trans))
             (.lvf vf1 (&-> a1-2 quad))
             )
           (.add.w.vf.x vf2 vf0 vf0)
           (.mul.vf vf1 vf1 vf1)
           (.mul.x.vf.x acc vf2 vf1)
           (.add.mul.y.vf.x acc vf2 vf1 acc)
           (.add.mul.z.vf.x vf1 vf2 vf1 acc)
           (.mov v1-5 vf1)
           (let ((f0-0 v1-5)
                 (f1-0 28672.0)
                 )
             (when (>= (* f1-0 f1-0) f0-0)
               (let ((a1-3 (grunt-mech-method-193 this)))
                 (cond
                   ((= a1-3 -1)
                    (go (method-of-object this mech-pre-circling))
                    )
                   (else
                     (set! (-> this hold-id) a1-3)
                     (grunt-mech-info-method-9 *grunt-mech-info* a1-3 this #f)
                     (go (method-of-object this mech-lunge))
                     )
                   )
                 )
               )
             )
           gp-0
           )
          (else
            ((method-of-type grunt grunt-method-184) this arg0)
            )
          )
        )
      )
    )
  )

(defstate mech-lunge (grunt-mech)
  :virtual #t
  :event enemy-event-handler
  :enter (behavior ()
    (logior! (-> self enemy-flags) (enemy-flag lock-focus))
    (let ((v1-2 self))
      (set! (-> v1-2 enemy-flags) (the-as enemy-flag (logclear (-> v1-2 enemy-flags) (enemy-flag enemy-flag37))))
      )
    0
    (let ((v1-4 self))
      (set! (-> v1-4 enemy-flags) (the-as enemy-flag (logclear (-> v1-4 enemy-flags) (enemy-flag enemy-flag36))))
      (set! (-> v1-4 nav callback-info) *nav-enemy-null-callback-info*)
      )
    0
    (nav-enemy-method-167 self)
    (set! (-> self dismount-dest quad) (-> self root trans quad))
    (logclear! (-> self root nav-flags) (nav-flags has-root-sphere))
    )
  :exit (behavior ()
    (logclear! (-> self enemy-flags) (enemy-flag lock-focus))
    (logior! (-> self root nav-flags) (nav-flags has-root-sphere))
    )
  :trans (behavior ()
    (grunt-mech-info-method-9 *grunt-mech-info* (-> self hold-id) self #f)
    )
  :code (behavior ()
    (ja-channel-push! 1 (seconds 0.07))
    (let ((gp-0 (new 'stack-no-clear 'matrix)))
      (quaternion-copy! (the-as quaternion (-> gp-0 vector)) (-> self root quat))
      (set! (-> gp-0 vector 1 quad) (-> self root trans quad))
      (ja-no-eval :group! grunt-mech-lunge-ja :num! (seek! max 0.769) :frame-num 0.0)
      (until (ja-done? 0)
        (let ((s5-0 *grunt-mech-info*))
          (grunt-mech-info-method-10 s5-0)
          (let ((s5-1 (-> s5-0 holds (-> self hold-id))))
            (matrix->quaternion (the-as quaternion (-> gp-0 vector 2)) (-> s5-1 world-mat))
            (let ((f30-0 (lerp-scale 0.0 1.0 (ja-aframe-num 0) 0.0 6.0)))
              (quaternion-slerp!
                (-> self root quat)
                (the-as quaternion (-> gp-0 vector))
                (the-as quaternion (-> gp-0 vector 2))
                f30-0
                )
              (vector-lerp! (-> self root trans) (-> gp-0 vector 1) (-> s5-1 world-mat trans) f30-0)
              )
            )
          )
        (suspend)
        (ja :num! (seek! max 0.769))
        )
      )
    (go-virtual mech-hold)
    )
  :post nav-enemy-simple-post
  )

(defbehavior grunt-mech-hold-post grunt-mech ()
  (let ((gp-0 *grunt-mech-info*))
    (grunt-mech-info-method-10 gp-0)
    (let ((v1-5 (-> gp-0 holds (-> self hold-id)))
          (a0-2 (-> self root))
          )
      (set! (-> a0-2 trans quad) (-> v1-5 world-mat trans quad))
      (matrix->quaternion (-> a0-2 quat) (-> v1-5 world-mat))
      )
    )
  (nav-enemy-simple-post)
  (none)
  )

(defmethod grunt-mech-method-195 ((this grunt-mech) (arg0 vector) (arg1 vector) (arg2 vector))
  (local-vars (v1-13 float))
  (rlet ((acc :class vf)
         (vf0 :class vf)
         (vf1 :class vf)
         (vf2 :class vf)
         )
    (init-vf0-vector)
    (let ((s5-0 (new 'stack-no-clear 'nav-avoid-spheres-params)))
      (vector-! (-> s5-0 current-pos) (-> this root trans) (-> this nav state mesh bounds))
      (vector-normalize-copy! (-> s5-0 travel) arg0 (the-as float arg1))
      (set! (-> s5-0 pref-dir quad) (-> s5-0 travel quad))
      (avoid-spheres-1! (-> this nav) s5-0)
      (when (>= (fabs (vector-dot (the-as vector (-> s5-0 out-travel)) arg2)) 0.0)
        (let ((t0-0 (new 'stack-no-clear 'clamp-travel-vector-to-mesh-return-info)))
          (clamp-vector-to-mesh-no-gaps
            (-> this nav)
            (-> this root trans)
            (-> this nav state current-poly)
            (the-as vector (-> s5-0 out-travel))
            t0-0
            )
          )
        (.lvf vf1 (&-> (-> s5-0 out-travel) 0 quad))
        (.add.w.vf.x vf2 vf0 vf0)
        (.mul.vf vf1 vf1 vf1)
        (.mul.x.vf.x acc vf2 vf1)
        (.add.mul.y.vf.x acc vf2 vf1 acc)
        (.add.mul.z.vf.x vf1 vf2 vf1 acc)
        (.mov v1-13 vf1)
        (let ((f0-3 v1-13)
              (f1-1 14336.0)
              )
          (when (>= f0-3 (* f1-1 f1-1))
            (let ((a1-3 (new 'stack-no-clear 'vector)))
              (set! (-> a1-3 quad) (-> s5-0 out-travel 0 quad))
              (set! (-> a1-3 w) (-> this nav-radius-backup))
              (when (not (add-root-sphere-to-hash! (-> this nav) a1-3 #x80068))
                (let ((s4-1 (new 'stack-no-clear 'vector)))
                  (vector+! s4-1 (-> this root trans) (the-as vector (-> s5-0 out-travel)))
                  (let ((s5-1 (new 'stack-no-clear 'collide-query)))
                    (when (enemy-above-ground? this s5-1 s4-1 (the-as collide-spec (-> this gnd-collide)) 4096.0 122880.0 1024.0)
                      (set! (-> s4-1 y) (-> s5-1 best-other-tri intersect y))
                      (set! (-> this dismount-dest quad) (-> s4-1 quad))
                      #t
                      )
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  )

(defmethod grunt-mech-method-192 ((this grunt-mech))
  (do-navigation-to-destination (-> this nav state) (-> this root trans))
  (let ((a1-1 *target*))
    (if (or (not a1-1) (not (logtest? (focus-status mech) (-> a1-1 focus-status))))
        (return #t)
        )
    )
  (when (logtest? (-> this nav state flags) (nav-state-flag in-mesh))
    (let ((s5-0 *grunt-mech-info*))
      (grunt-mech-info-method-10 s5-0)
      (let* ((v1-15 (-> this nav))
             (a0-7 (-> v1-15 state mesh sphere-hash sphere-array))
             (a1-3 (-> v1-15 sphere-id-array))
             (a2-1 (-> v1-15 state mesh bounds))
             (a3-0 (-> v1-15 root-nav-sphere))
             (t0-0 (-> v1-15 sphere-count))
             )
        (dotimes (t1-0 t0-0)
          (let ((t3-0 (-> a0-7 (-> a1-3 t1-0)))
                (t2-4 (-> v1-15 sphere-array t1-0))
                )
            (vector-! (the-as vector t2-4) (the-as vector t3-0) a2-1)
            (set! (-> t2-4 r) (+ (-> t3-0 r) (-> a3-0 w)))
            )
          )
        )
      0
      (let ((v1-22 (-> s5-0 holds (-> this hold-id)))
            (s5-1 (new 'stack-no-clear 'vector))
            )
        (vector-negate! s5-1 (-> v1-22 world-mat vector 2))
        (set! (-> s5-1 y) 0.0)
        (vector-normalize! s5-1 1.0)
        (countdown (s4-0 3)
          (let ((s3-0 (new 'stack-no-clear 'vector)))
            (vector-rotate-around-y! s3-0 s5-1 (rnd-float-range this -10922.667 10922.667))
            (when (grunt-mech-method-195 this s3-0 (the-as vector (rnd-float-range this 16384.0 24576.0)) s5-1)
              #t
              (goto cfg-16)
              )
            )
          )
        )
      )
    )
  (label cfg-16)
  (let ((a0-15 (-> this root trans)))
    (if (or (>= 0.0 (- (-> a0-15 y) (-> this dismount-dest y)))
            (let ((f0-4 40960.0))
              (< (* f0-4 f0-4) (vector-vector-xz-distance-squared a0-15 (-> this dismount-dest)))
              )
            )
        (return #t)
        )
    )
  #f
  )

;; WARN: Return type mismatch object vs none.
(defmethod grunt-mech-method-194 ((this grunt-mech))
  (send-event *target* 'attack #f (static-attack-info ((id (new-attack-id)) (mode 'grunt))))
  (none)
  )

;; WARN: Return type mismatch object vs none.
(defmethod grunt-mech-method-191 ((this grunt-mech))
  (if (>= (current-time) (-> this state-timeout))
      (go (method-of-object this mech-dismount))
      )
  (none)
  )

(defstate mech-hold (grunt-mech)
  :virtual #t
  :event enemy-event-handler
  :enter (behavior ()
    (set-time! (-> self state-time))
    (logior! (-> self enemy-flags) (enemy-flag lock-focus))
    (set! (-> self root root-prim prim-core collide-as) (collide-spec))
    (stop-looking-at-target! self)
    (set! (-> self state-timeout) (+ (current-time) (rnd-int-range self 450 900)))
    (logclear! (-> self root nav-flags) (nav-flags has-root-sphere))
    )
  :exit (behavior ()
    (logclear! (-> self enemy-flags) (enemy-flag lock-focus))
    (let ((v1-3 (-> self root root-prim)))
      (set! (-> v1-3 prim-core collide-as) (-> self root backup-collide-as))
      (set! (-> v1-3 prim-core collide-with) (-> self root backup-collide-with))
      )
    (logior! (-> self root nav-flags) (nav-flags has-root-sphere))
    )
  :trans (behavior ()
    (if (or (not (grunt-mech-info-method-9 *grunt-mech-info* (-> self hold-id) self #f)) (grunt-mech-method-192 self))
        (go-virtual mech-dismount)
        )
    )
  :code (behavior ()
    (ja-no-eval :group! grunt-mech-grab-ja :num! (seek!) :frame-num 0.0)
    (until (ja-done? 0)
      (suspend)
      (ja :num! (seek!))
      )
    (grunt-mech-method-191 self)
    (let ((gp-0 0))
      0
      (until #f
        (set! gp-0 (rnd-bit self 3 (ash 1 gp-0)))
        (let ((v1-30 gp-0))
          (cond
            ((zero? v1-30)
             (ja-channel-push! 1 (seconds 0.13))
             (countdown (s5-0 (rnd-int-range self 1 2))
               (let ((s4-0 #t))
                 (ja-no-eval :group! grunt-mech-head-butt-ja :num! (seek! (ja-aframe 17.0 0) 0.222) :frame-num 0.0)
                 (until (ja-done? 0)
                   (suspend)
                   (ja :num! (seek! (ja-aframe 17.0 0) 0.222))
                   )
                 (ja-no-eval :group! grunt-mech-head-butt-ja :num! (seek! (ja-aframe 20.0 0)) :frame-num (ja-aframe 17.0 0))
                 (until (ja-done? 0)
                   (when (and s4-0 (>= (ja-aframe-num 0) 18.5))
                     (grunt-mech-method-194 self)
                     (set! s4-0 #f)
                     )
                   (suspend)
                   (ja :num! (seek! (ja-aframe 20.0 0)))
                   )
                 )
               (grunt-mech-method-191 self)
               )
             )
            ((= v1-30 1)
             (ja-channel-push! 1 (seconds 0.13))
             (countdown (s5-1 (rnd-int-range self 1 3))
               (let ((s4-1 #t))
                 (ja-no-eval :group! grunt-mech-punch-left-ja :num! (seek! (ja-aframe 24.0 0) 0.568) :frame-num 0.0)
                 (until (ja-done? 0)
                   (suspend)
                   (ja :num! (seek! (ja-aframe 24.0 0) 0.568))
                   )
                 (ja-no-eval :group! grunt-mech-punch-left-ja
                             :num! (seek! (ja-aframe 28.0 0) 2.0)
                             :frame-num (ja-aframe 24.0 0)
                             )
                 (until (ja-done? 0)
                   (when (and s4-1 (>= (ja-aframe-num 0) 27.0))
                     (grunt-mech-method-194 self)
                     (set! s4-1 #f)
                     )
                   (suspend)
                   (ja :num! (seek! (ja-aframe 28.0 0) 2.0))
                   )
                 )
               (grunt-mech-method-191 self)
               )
             )
            (else
              (ja-channel-push! 1 (seconds 0.13))
              (countdown (s5-2 (rnd-int-range self 1 3))
                (let ((s4-2 #t))
                  (ja-no-eval :group! grunt-mech-double-pound-ja :num! (seek! (ja-aframe 30.0 0) 0.111) :frame-num 0.0)
                  (until (ja-done? 0)
                    (suspend)
                    (ja :num! (seek! (ja-aframe 30.0 0) 0.111))
                    )
                  (ja-no-eval :group! grunt-mech-double-pound-ja
                              :num! (seek! (ja-aframe 32.0 0) 0.5)
                              :frame-num (ja-aframe 30.0 0)
                              )
                  (until (ja-done? 0)
                    (when (and s4-2 (>= (ja-aframe-num 0) 31.0))
                      (grunt-mech-method-194 self)
                      (set! s4-2 #f)
                      )
                    (suspend)
                    (ja :num! (seek! (ja-aframe 32.0 0) 0.5))
                    )
                  )
                (grunt-mech-method-191 self)
                )
              )
            )
          )
        (when (= (rnd-int-count self 4) 3)
          (ja-channel-push! 1 (seconds 0.13))
          (ja-no-eval :group! grunt-mech-idle0-ja :num! (seek! max 0.090909) :frame-num 0.0)
          (until (ja-done? 0)
            (suspend)
            (ja :num! (seek! max 0.090909))
            )
          (grunt-mech-method-191 self)
          )
        )
      )
    #f
    )
  :post grunt-mech-hold-post
  )

(defstate mech-dismount (grunt-mech)
  :virtual #t
  :event enemy-event-handler
  :enter (behavior ()
    (set-time! (-> self state-time))
    (set! (-> self root root-prim prim-core collide-as) (collide-spec))
    (let* ((v1-4 (-> self nav))
           (a1-0 (-> self dismount-dest))
           (f0-0 (-> v1-4 extra-nav-sphere w))
           )
      (set! (-> v1-4 extra-nav-sphere quad) (-> a1-0 quad))
      (set! (-> v1-4 extra-nav-sphere w) f0-0)
      )
    0
    (let ((v1-7 (-> self nav)))
      (set! (-> v1-7 extra-nav-sphere w) (-> self nav-radius-backup))
      )
    0
    (let ((v1-9 (-> self nav)))
      (logior! (-> v1-9 shape nav-flags) (nav-flags has-extra-sphere))
      )
    0
    (logclear! (-> self root nav-flags) (nav-flags has-root-sphere))
    )
  :exit (behavior ()
    (let ((v1-1 (-> self root root-prim)))
      (set! (-> v1-1 prim-core collide-as) (-> self root backup-collide-as))
      (set! (-> v1-1 prim-core collide-with) (-> self root backup-collide-with))
      )
    ;; og:preserve-this fix potential use-after-free bug
    (if (-> self nav)
      (let ((v1-2 (-> self nav)))
        (logclear! (-> v1-2 shape nav-flags) (nav-flags has-extra-sphere))
        ))
    0
    (logior! (-> self root nav-flags) (nav-flags has-root-sphere))
    )
  :code (behavior ()
    (ja-channel-push! 1 (seconds 0.07))
    (let ((gp-0 (new 'stack-no-clear 'matrix)))
      (vector-! (-> gp-0 vector 1) (-> self root trans) (-> self dismount-dest))
      (set! (-> gp-0 vector 1 y) 0.0)
      (vector-normalize! (-> gp-0 vector 1) 1.0)
      (quaternion-look-at! (the-as quaternion (-> gp-0 vector 2)) (-> gp-0 vector 1) *up-vector*)
      (quaternion-copy! (the-as quaternion (-> gp-0 vector)) (-> self root quat))
      (set! (-> gp-0 vector 1 quad) (-> self root trans quad))
      (ja-no-eval :group! grunt-mech-dismount-ja :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (let ((f30-0 (lerp-scale 0.0 1.0 (ja-aframe-num 0) 33.0 41.0)))
          (quaternion-slerp!
            (-> self root quat)
            (the-as quaternion (-> gp-0 vector))
            (the-as quaternion (-> gp-0 vector 2))
            f30-0
            )
          (vector-lerp! (-> self root trans) (-> gp-0 vector 1) (-> self dismount-dest) f30-0)
          )
        (suspend)
        (ja :num! (seek!))
        )
      )
    (let ((v1-32 (-> self root root-prim)))
      (set! (-> v1-32 prim-core collide-as) (-> self root backup-collide-as))
      (set! (-> v1-32 prim-core collide-with) (-> self root backup-collide-with))
      )
    (let ((v1-33 (-> self nav)))
      (logclear! (-> v1-33 shape nav-flags) (nav-flags has-extra-sphere))
      )
    0
    (let ((v1-37 (-> self nav state)))
      (set! (-> v1-37 current-poly) (the-as nav-poly #f))
      )
    0
    (logclear! (-> self nav state flags) (nav-state-flag at-target))
    (ja-no-eval :group! grunt-mech-dismount-land-ja :num! (seek!) :frame-num 0.0)
    (until (ja-done? 0)
      (suspend)
      (ja :num! (seek!))
      )
    (ja-channel-push! 1 (seconds 0.13))
    (go-virtual mech-post-circling)
    )
  :post nav-enemy-simple-post
  )

(defstate mech-post-circling (grunt-mech)
  :virtual #t
  :event enemy-event-handler
  :enter (behavior ()
    ((-> (method-of-type grunt circling) enter))
    (set! (-> self state-timeout) (+ (current-time) (rnd-int-range self 750 1200)))
    )
  :trans (behavior ()
    (let ((a0-1 (handle->process (-> self focus handle))))
      (if a0-1
          (set! (-> self focus-pos quad) (-> (get-trans (the-as process-focusable a0-1) 0) quad))
          )
      )
    (let ((gp-1 (-> self focus aware)))
      (if (or (!= gp-1 3) (not (get-enemy-target self)))
          (set-time! (-> self starting-time))
          )
      (when (time-elapsed? (-> self state-time) (-> self reaction-time))
        (when (>= 1 (the-as int gp-1))
          (nav-enemy-method-161 self)
          (if (-> self enemy-info use-stop-chase)
              (go-virtual stop-chase)
              (go-virtual active)
              )
          )
        (when (= gp-1 (enemy-aware enemy-aware-3))
          (let ((v1-33 (get-enemy-target self)))
            (when v1-33
              (cond
                ((focus-test? v1-33 mech)
                 (when (>= (current-time) (-> self state-timeout))
                   (nav-enemy-method-161 self)
                   (go-hostile self)
                   )
                 )
                (else
                  (when (time-elapsed? (-> self starting-time) (-> self reaction-time))
                    (nav-enemy-method-161 self)
                    (go-hostile self)
                    )
                  )
                )
              )
            )
          )
        (if (= gp-1 (enemy-aware enemy-aware-2))
            (go-stare self)
            )
        (if (or (nav-enemy-method-163 self) (logtest? (enemy-flag enemy-flag41) (-> self enemy-flags)))
            (go-stare2 self)
            )
        )
      )
    )
  :code (-> (method-of-type grunt circling) code)
  :post (-> (method-of-type grunt circling) post)
  )

(defstate mech-pre-circling (grunt-mech)
  :virtual #t
  :event enemy-event-handler
  :enter (behavior ()
    ((-> (method-of-type grunt-mech mech-post-circling) enter))
    (set! (-> self state-timeout) (+ (current-time) (rnd-int-range self 900 1800)))
    )
  :trans (-> (method-of-type grunt-mech mech-post-circling) trans)
  :code (-> (method-of-type grunt-mech mech-post-circling) code)
  :post (-> (method-of-type grunt-mech mech-post-circling) post)
  )
