;;-*-Lisp-*-
(in-package goal)
(bundles "SUN.DGO")
(require "engine/nav/navigate.gc")
(require "engine/util/sync-info.gc")
(require "engine/anim/joint-mod-h.gc")
(require "engine/geometry/path.gc")
(require "engine/common-obs/collectables.gc")

;; DECOMP BEGINS

(deftype puffer (process-drawable)
  ((root                 collide-shape-moving :override)
   (fact                 fact-info-enemy :override)
   (path-index           int32)
   (facing-ry            float)
   (travel-ry            float)
   (travel-speed         float)
   (attack-bottom-y      float)
   (patrol-bottom-y      float)
   (top-y                float)
   (targ-trans-y         float)
   (acc-y                float)
   (travel-turn-speed    float)
   (notice-dist          float)
   (give-up-dist         float)
   (attacking?           symbol)
   (hit-player?          symbol)
   (look-mean?           symbol)
   (cprims-type          uint64)
   (neck                 joint-mod)
   (hit-player-time      time-frame)
   (reaction-delay       time-frame)
   (picked-point-time    time-frame)
   (pick-new-point-delay time-frame)
   (last-on-screen-time  time-frame)
   (buddy                process-drawable)
   (nice-look            lod-set :inline)
   (mean-look            lod-set :inline)
   (dest-pos             vector :inline)
   (sync                 sync-info :inline))
  (:methods
   (puffer-method-20 (_type_ vector) none)
   (puffer-method-21 (_type_) none)
   (puffer-method-22 (_type_) symbol)
   (puffer-method-23 (_type_ symbol) symbol)
   (puffer-method-24 (_type_ vector) symbol)
   (puffer-method-25 (_type_ float) symbol)
   (puffer-method-26 (_type_) none)
   (puffer-method-27 (_type_) none)
   (puffer-method-28 (_type_) none)
   (flip-look! (_type_ symbol) none)
   (puffer-method-30 (_type_) vector)
   (puffer-method-31 (_type_) vector))
  (:states
   puffer-attack
   puffer-die
   puffer-idle
   puffer-patrol))


(defskelgroup *puffer-sg*
  puffer
  puffer-main-lod0-jg
  -1
  ((puffer-main-lod0-mg (meters 20)) (puffer-main-lod1-mg (meters 40)) (puffer-main-lod2-mg (meters 999999)))
  :bounds (static-spherem 0 1 0 5.25)
  :longest-edge (meters 1.2)
  :shadow puffer-main-shadow-mg)

(defskelgroup *puffer-mean-sg*
  puffer
  puffer-mean-lod0-jg
  -1
  ((puffer-mean-lod0-mg (meters 20)) (puffer-mean-lod1-mg (meters 40)) (puffer-mean-lod2-mg (meters 999999)))
  :bounds (static-spherem 0 1 0 5.25)
  :longest-edge (meters 1.2)
  :shadow puffer-main-shadow-mg)

(defbehavior puffer-default-event-handler puffer ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  (case arg2
    (('touch 'attack)
     (when (and (= arg2 'attack) (!= (-> self cprims-type) 2))
       (let* ((gp-0 arg0)
              (v1-7 (if (and (nonzero? gp-0) (type-type? (-> gp-0 type) process-drawable)) gp-0)))
         (when v1-7
           (let ((f0-4 (atan (- (-> (the-as process-drawable v1-7) root trans x) (-> self root trans x))
                             (- (-> (the-as process-drawable v1-7) root trans z) (-> self root trans z)))))
             (quaternion-axis-angle! (-> self root quat) 0.0 1.0 0.0 f0-4))))
       (go puffer-die)
       (return #t))
     (when (= (-> arg0 type) target)
       (when (send-event arg0 'attack (-> arg3 param 0) (static-attack-info ((shove-up (meters 1.5)) (shove-back (meters 2.5)))))
         (set! (-> self hit-player?) #t)
         (set-time! (-> self hit-player-time))
         (set-collide-offense (-> self root) 2 (collide-offense no-offense)))))))

(defbehavior puffer-post puffer ()
  (when (and (-> self hit-player?)
             (or (not *target*)
                 (and (not (logtest? (-> *target* state-flags)
                                     (state-flags being-attacked invulnerable timed-invulnerable invuln-powerup do-not-notice dying)))
                      (time-elapsed? (-> self hit-player-time) (seconds 0.05)))))
    (set-collide-offense (-> self root) 2 (collide-offense normal-attack))
    (set! (-> self hit-player?) #f))
  (transform-post)
  (none))

(defmethod puffer-method-28 ((this puffer))
  (cond
    ((and (-> this draw shadow) (zero? (-> this draw cur-lod)) (logtest? (-> this draw status) (draw-status was-drawn)))
     (let ((s5-0 (new 'stack-no-clear 'collide-tri-result))
           (a1-0 (new 'stack-no-clear 'vector))
           (a2-0 (new 'stack-no-clear 'vector)))
       (set! (-> a1-0 quad) (-> this root trans quad))
       (set-vector! a2-0 0.0 -40960.0 0.0 1.0)
       (cond
         ((>= (fill-and-probe-using-line-sphere *collide-cache*
                                                a1-0
                                                a2-0
                                                8192.0
                                                (collide-kind background cak-3 ground-object)
                                                this
                                                s5-0
                                                (new 'static 'pat-surface :noentity #x1))
              0.0)
          (let ((v1-11 (-> this draw shadow-ctrl))) (logclear! (-> v1-11 settings flags) (shadow-flags disable-draw)))
          0
          (let ((v1-14 (-> this draw shadow-ctrl))) (set! (-> v1-14 settings bot-plane w) (- (+ -12288.0 (-> s5-0 intersect y)))))
          0
          (let ((v1-17 (-> this draw shadow-ctrl))) (set! (-> v1-17 settings top-plane w) (- (+ 4096.0 (-> s5-0 intersect y)))))
          0)
         (else (let ((v1-19 (-> this draw shadow-ctrl))) (logior! (-> v1-19 settings flags) (shadow-flags disable-draw))) 0))))
    (else (let ((v1-21 (-> this draw shadow-ctrl))) (logior! (-> v1-21 settings flags) (shadow-flags disable-draw))) 0))
  (none))

(defmethod puffer-method-24 ((this puffer) (arg0 vector))
  (and (is-in-mesh? (-> this nav) arg0 11468.8) (< (-> arg0 y) (+ (-> this root trans y) (-> this fact notice-top)))))

(defmethod puffer-method-22 ((this puffer))
  (let* ((a1-0 (-> this buddy))
         (v1-0 (if a1-0 (-> a1-0 ppointer 3))))
    (if (and v1-0 (>= 25395.2 (vector-vector-xz-distance (-> this root trans) (-> (the-as process-drawable v1-0) root trans))))
      (return #t)))
  #f)

(defmethod puffer-method-25 ((this puffer) (arg0 float))
  (when *target*
    (let ((gp-0 (target-pos 0)))
      (when (and (not (logtest? (-> *target* state-flags)
                                (state-flags being-attacked invulnerable timed-invulnerable invuln-powerup do-not-notice dying)))
                 (puffer-method-24 this gp-0)
                 (>= (-> gp-0 y) (+ -14336.0 (-> this attack-bottom-y)))
                 (>= (+ 2048.0 (-> this top-y)) (-> gp-0 y)))
        (let ((f30-0 (vector-vector-xz-distance gp-0 (-> this root trans))))
          (when (>= arg0 f30-0)
            (let* ((a0-4 (-> this buddy))
                   (v1-12 (if a0-4 (-> a0-4 ppointer 3))))
              (cond
                (v1-12
                 (if (not (-> (the-as puffer v1-12) attacking?)) (return #t))
                 (if (< f30-0 (vector-vector-xz-distance gp-0 (-> (the-as puffer v1-12) root trans))) (return #t)))
                (else (return #t)))))))))
  #f)

(deftype pick-patrol-point-away-from-buddy-work (structure)
  ((best-path-index int32)
   (best-rating     float)
   (best-dest       vector :inline)
   (pt-dir          vector :inline)
   (buddy-dir       vector :inline)
   (dest            vector :inline)))


(defmethod puffer-method-23 ((this puffer) (arg0 symbol))
  (local-vars (v1-0 process))
  (set! v1-0
        (when arg0
          (let ((a0-1 (-> this buddy))) (set! v1-0 (if a0-1 (-> a0-1 ppointer 3))))
          (if (not v1-0) (set! arg0 #f))
          v1-0))
  (cond
    (arg0
     (let ((s4-0 (-> this path curve num-cverts))
           (s5-0 (new 'stack-no-clear 'inline-array 'vector 5)))
       (set! (-> s5-0 0 x) (the-as float -1))
       (vector-! (-> s5-0 3) (-> this root trans) (-> (the-as process-drawable v1-0) root trans))
       (set! (-> s5-0 3 y) 0.0)
       (vector-normalize! (-> s5-0 3) 1.0)
       (dotimes (s3-0 s4-0)
         (eval-path-curve-div! (-> this path) (-> s5-0 4) (the float s3-0) 'interp)
         (vector-! (-> s5-0 2) (-> s5-0 4) (-> this root trans))
         (when (>= (vector-xz-length (-> s5-0 2)) 10240.0)
           (set! (-> s5-0 2 y) 0.0)
           (vector-normalize! (-> s5-0 2) 1.0)
           (let ((f0-6 (vector-dot (-> s5-0 3) (-> s5-0 2))))
             (when (>= f0-6 0.0)
               (when (or (< (the-as int (-> s5-0 0 x)) 0) (< (-> s5-0 0 y) f0-6))
                 (set! (-> s5-0 0 x) (the-as float s3-0))
                 (set! (-> s5-0 0 y) f0-6)
                 (set! (-> s5-0 1 quad) (-> s5-0 4 quad)))))))
       (when (>= (the-as int (-> s5-0 0 x)) 0)
         (set! (-> this dest-pos quad) (-> s5-0 1 quad))
         (set! (-> this dest-pos y) (-> this root trans y))
         (return #t))))
    (else
     (let* ((s3-1 (-> this path curve num-cverts))
            (s4-1 (new 'stack-no-clear 'vector))
            (s5-1 (rand-vu-int-count s3-1)))
       (while (nonzero? s3-1)
         (+! s3-1 -1)
         (eval-path-curve-div! (-> this path) s4-1 (the float s5-1) 'interp)
         (when (>= (vector-vector-xz-distance s4-1 (-> this root trans)) 10240.0)
           (set! (-> this dest-pos quad) (-> s4-1 quad))
           (set! (-> this dest-pos y) (-> this root trans y))
           (set! (-> this path-index) s5-1)
           (return #t))))))
  #f)

(defmethod puffer-method-20 ((this puffer) (arg0 vector))
  (if (-> this attacking?)
    (set! (-> this travel-speed)
          (seek-with-smooth (-> this travel-speed) 30720.0 (* 8192.0 (seconds-per-frame)) 0.125 40.96))
    (set! (-> this travel-speed)
          (seek-with-smooth (-> this travel-speed) 18432.0 (* 2048.0 (seconds-per-frame)) 0.125 40.96)))
  (nav-control-method-27 (-> this nav))
  (nav-control-method-28 (-> this nav) (the-as collide-kind -1))
  (nav-control-method-13 (-> this nav) arg0 (-> this root transv))
  (let ((f30-0 (* (vector-xz-length (-> this nav travel)) (-> *display* frames-per-second))))
    (let ((f0-11 (atan (-> this nav travel x) (-> this nav travel z)))
          (s5-1 (new 'stack-no-clear 'vector)))
      (if (< (-> this travel-speed) f30-0) (set! f30-0 (-> this travel-speed)))
      (set! (-> s5-1 quad) (-> this nav travel quad))
      (set! (-> this travel-ry)
            (deg-seek-smooth (-> this travel-ry) f0-11 (* (-> this travel-turn-speed) (seconds-per-frame)) 0.125))
      (let* ((f0-16 (* f30-0 (seconds-per-frame)))
             (f28-0 (* 150.0 f0-16))
             (f26-0 -1.0))
        (let ((s4-0 (new 'stack-no-clear 'vector)))
          (set-vector! s4-0 (* (sin (-> this travel-ry)) f28-0) 0.0 (* (cos (-> this travel-ry)) f28-0) 1.0)
          (let ((s3-1 (new 'stack 'clip-travel-vector-to-mesh-return-info)))
            (set! (-> this nav travel quad) (-> s4-0 quad))
            (nav-control-method-24 (-> this nav) f28-0 s3-1)
            (if (-> s3-1 found-boundary) (set! f26-0 (vector-vector-xz-distance (-> s3-1 intersection) (-> this root trans)))))
          (let ((s3-2 (new 'stack-no-clear 'matrix)))
            (when (>= (nav-control-method-23 (-> this nav) s4-0 (the-as check-vector-collision-with-nav-spheres-info s3-2)) 0.0)
              (let ((f0-26 (vector-vector-xz-distance (-> s3-2 vector 1) (-> this root trans))))
                (if (or (< f26-0 0.0) (< f0-26 f26-0)) (set! f26-0 f0-26))))))
        (when (>= f26-0 0.0)
          (let ((f26-1 (- 1.0 (/ f26-0 f28-0))))
            (+! (-> this travel-ry) (* f26-1 (deg- (atan (-> s5-1 x) (-> s5-1 z)) (-> this travel-ry))))))))
    (set-vector! (-> this root transv)
                 (* (sin (-> this travel-ry)) f30-0)
                 (-> this root transv y)
                 (* (cos (-> this travel-ry)) f30-0)
                 1.0))
  (set! (-> this facing-ry)
        (deg-seek-smooth (-> this facing-ry) (-> this travel-ry) (* 32768.0 (seconds-per-frame)) 0.125))
  (puffer-method-27 this)
  (none))

(defmethod puffer-method-27 ((this puffer))
  (let ((f30-0 (-> this patrol-bottom-y)))
    (cond
      ((-> this attacking?)
       (let ((f30-1 (-> this attack-bottom-y)))
         (set! (-> this targ-trans-y) (fmax (fmin (+ 4096.0 (-> (target-pos 0) y)) (-> this top-y)) f30-1)))
       (set! (-> this root transv y)
             (* (/ (-> *display* frames-per-second) 8) (- (-> this targ-trans-y) (-> this root trans y))))
       (when (< 6144.0 (fabs (-> this root transv y)))
         (if (>= (-> this root transv y) 0.0) (set! (-> this root transv y) 6144.0) (set! (-> this root transv y) -6144.0))))
      ((< (-> this root trans y) f30-0)
       (set! (-> this targ-trans-y) (* 0.5 (+ (-> this top-y) (-> this patrol-bottom-y))))
       (set! (-> this root transv y)
             (* (/ (-> *display* frames-per-second) 8) (- (-> this targ-trans-y) (-> this root trans y))))
       (when (< 2048.0 (fabs (-> this root transv y)))
         (if (>= (-> this root transv y) 0.0) (set! (-> this root transv y) 2048.0) (set! (-> this root transv y) -2048.0))))
      (else
       (let ((f0-22 (- (-> this targ-trans-y) (-> this root trans y))))
         (when (or (and (>= f0-22 0.0) (< (-> this acc-y) 0.0)) (and (< f0-22 0.0) (>= (-> this acc-y) 0.0)))
           (when (not (-> this attacking?))
             (cond
               ((>= (-> this acc-y) 0.0)
                (if (< f30-0 (-> this targ-trans-y)) (set! (-> this targ-trans-y) (rand-vu-float-range f30-0 (-> this targ-trans-y)))))
               (else
                (if (< (-> this targ-trans-y) (-> this top-y))
                  (set! (-> this targ-trans-y) (rand-vu-float-range (-> this targ-trans-y) (-> this top-y)))))))
           (set! (-> this acc-y) (- (-> this acc-y)))))
       (+! (-> this root transv y) (* (-> this acc-y) (seconds-per-frame)))
       (let ((f0-37 (* (-> this root transv y) (seconds-per-frame))))
         (cond
           ((>= f0-37 0.0)
            (let ((f1-27 (* 0.0625 (- (-> this top-y) (-> this root trans y)))))
              (if (< f1-27 f0-37) (set! (-> this root transv y) (* f1-27 (-> *display* frames-per-second))))))
           (else
            (let ((f1-29 (* 0.0625 (- f30-0 (-> this root trans y)))))
              (if (< f0-37 f1-29) (set! (-> this root transv y) (* f1-29 (-> *display* frames-per-second)))))))))))
  (none))

(defstate puffer-idle (puffer)
  :event puffer-default-event-handler
  :enter
    (behavior ()
      (set-time! (-> self state-time))
      (set! (-> self attacking?) #f)
      (shut-down! (-> self neck))
      (let ((v1-5 (-> self draw shadow-ctrl))) (logior! (-> v1-5 settings flags) (shadow-flags disable-draw)))
      0)
  :code
    (behavior ()
      (loop
        (if (and (and *target*
                      (>= (-> self fact idle-distance) (vector-vector-distance (-> self root trans) (-> *target* control trans))))
                 (logtest? (-> self draw status) (draw-status was-drawn))
                 (time-elapsed? (-> self state-time) (seconds 0.2)))
          (go puffer-patrol))
        (puffer-method-26 self)
        (suspend)))
  :post puffer-post)

(defstate puffer-patrol (puffer)
  :event puffer-default-event-handler
  :enter
    (behavior ()
      (set-time! (-> self state-time))
      (set! (-> self attacking?) #f)
      (set! (-> self reaction-delay) (rand-vu-int-range (seconds 0.1) (seconds 0.35)))
      (if (not (puffer-method-23 self #f)) (go puffer-idle))
      (set-time! (-> self picked-point-time))
      (set! (-> self pick-new-point-delay) (rand-vu-int-range (seconds 3) (seconds 10)))
      (set-time! (-> self last-on-screen-time)))
  :trans
    (behavior ()
      (if (and (not (and *target*
                         (>= (-> self fact idle-distance) (vector-vector-distance (-> self root trans) (-> *target* control trans)))))
               (time-elapsed? (-> self state-time) (seconds 3)))
        (go puffer-idle))
      (cond
        ((logtest? (-> self draw status) (draw-status was-drawn)) (set-time! (-> self last-on-screen-time)))
        (else (if (time-elapsed? (-> self last-on-screen-time) (seconds 8)) (go puffer-idle))))
      (when (puffer-method-22 self)
        (when (puffer-method-23 self #t)
          (set-time! (-> self picked-point-time))
          (set! (-> self pick-new-point-delay) (rand-vu-int-range (seconds 3) (seconds 10)))))
      (if (and (time-elapsed? (-> self state-time) (-> self reaction-delay)) (puffer-method-25 self (-> self notice-dist)))
        (go puffer-attack))
      (when (or (< (vector-vector-xz-distance (-> self root trans) (-> self dest-pos)) 8192.0)
                (time-elapsed? (-> self picked-point-time) (-> self pick-new-point-delay)))
        (when (puffer-method-23 self #f)
          (set-time! (-> self picked-point-time))
          (set! (-> self pick-new-point-delay) (rand-vu-int-range (seconds 3) (seconds 10)))))
      (puffer-method-20 self (-> self dest-pos))
      (let ((gp-0 (new 'stack-no-clear 'vector)))
        (set-vector! gp-0 (sin (-> self facing-ry)) 0.0 (cos (-> self facing-ry)) 1.0)
        (set-heading-vec-clear-roll-pitch! (-> self root) gp-0))
      (vector-v+! (-> self root trans) (-> self root trans) (-> self root transv))
      (puffer-method-28 self))
  :code
    (behavior ()
      (loop
        (puffer-method-26 self)
        (suspend)))
  :post puffer-post)

(defstate puffer-attack (puffer)
  :event puffer-default-event-handler
  :enter
    (behavior ()
      (set! (-> self attacking?) #t)
      (set-time! (-> self state-time))
      (set! (-> self travel-turn-speed) 21845.334))
  :exit
    (behavior ()
      (shut-down! (-> self neck))
      (set! (-> self attacking?) #f)
      (set! (-> self travel-turn-speed) 16384.0))
  :trans
    (behavior ()
      (if (not (puffer-method-25 self (-> self give-up-dist))) (go puffer-patrol))
      (when *target*
        (if *target*
          (look-at-enemy! (-> *target* neck)
                          (the-as vector (-> (the-as collide-shape-prim-group (-> self root root-prim)) prims 0 prim-core))
                          'attacking
                          self))
        (set-target! (-> self neck) (target-pos 5)))
      (puffer-method-20 self (target-pos 0))
      (let ((gp-2 (new 'stack-no-clear 'vector)))
        (set-vector! gp-2 (sin (-> self facing-ry)) 0.0 (cos (-> self facing-ry)) 1.0)
        (set-heading-vec-clear-roll-pitch! (-> self root) gp-2))
      (vector-v+! (-> self root trans) (-> self root trans) (-> self root transv))
      (puffer-method-28 self))
  :code
    (behavior ()
      (loop
        (puffer-method-26 self)
        (suspend)))
  :post puffer-post)

(defstate puffer-die (puffer)
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (the-as uint
              (case message
                (('death-start) (the-as uint (drop-pickup (-> self fact) #t *entity-pool* (-> self fact) 0)))
                (('death-end)
                 (let ((v0-0 (the-as uint (logior (-> self draw status) (draw-status hidden)))))
                   (set! (-> self draw status) (the-as draw-status v0-0))
                   v0-0)))))
  :code
    (behavior ()
      (cleanup-for-death self)
      (shut-down! (-> self neck))
      (logclear! (-> self mask) (process-mask actor-pause))
      (ja-channel-push! 1 (seconds 0.075))
      (clear-collide-with-as (-> self root))
      (ja-no-eval :group! puffer-die-ja :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!))))
  :post ja-post)

(defmethod puffer-method-21 ((this puffer))
  (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) default-collision-reaction)
    (set! (-> s5-0 no-reaction) (the-as (function collide-shape-moving collide-shape-intersect vector vector none) nothing))
    (let ((s4-0 (new 'process 'collide-shape-prim-group s5-0 (the-as uint 3) 0)))
      (set! (-> s4-0 prim-core collide-as) (collide-kind enemy))
      (set! (-> s4-0 collide-with) (collide-kind target))
      (set-vector! (-> s4-0 local-sphere) 0.0 6144.0 0.0 18432.0)
      (set-root-prim! s5-0 s4-0)
      (let ((s3-0 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 3))))
        (set! (-> s3-0 prim-core collide-as) (collide-kind enemy))
        (set! (-> s3-0 collide-with) (collide-kind target))
        (set! (-> s3-0 prim-core offense) (collide-offense touch))
        (set! (-> s3-0 transform-index) 5)
        (set-vector! (-> s3-0 local-sphere) 0.0 0.0 0.0 4096.0)
        (append-prim s4-0 s3-0))
      (let ((s3-1 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 3))))
        (set! (-> s3-1 prim-core collide-as) (collide-kind enemy))
        (set! (-> s3-1 collide-with) (collide-kind target))
        (set! (-> s3-1 prim-core offense) (collide-offense touch))
        (set! (-> s3-1 transform-index) 3)
        (set-vector! (-> s3-1 local-sphere) 0.0 0.0 0.0 4096.0)
        (append-prim s4-0 s3-1))
      (let ((s3-2 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 3))))
        (set! (-> s3-2 prim-core collide-as) (collide-kind enemy))
        (set! (-> s3-2 collide-with) (collide-kind target))
        (set! (-> s3-2 prim-core offense) (collide-offense touch))
        (set! (-> s3-2 transform-index) 9)
        (set-vector! (-> s3-2 local-sphere) 0.0 0.0 0.0 3072.0)
        (append-prim s4-0 s3-2)))
    (set! (-> s5-0 nav-radius) 12288.0)
    (backup-collide-with-as s5-0)
    (set! (-> this root) s5-0))
  (puffer-method-30 this)
  0
  (none))

(defmethod flip-look! ((this puffer) (arg0 symbol))
  (when (!= arg0 (-> this look-mean?))
    (set! (-> this look-mean?) arg0)
    (if arg0 (lods-assign! (-> this draw) (-> this mean-look)) (lods-assign! (-> this draw) (-> this nice-look))))
  (none))

(defmethod puffer-method-30 ((this puffer))
  (when (!= (-> this cprims-type) 1)
    (set! (-> this cprims-type) (the-as uint 1))
    (let ((v1-3 (the-as basic (-> this root root-prim))))
      (set-vector! (-> (the-as collide-shape-prim v1-3) local-sphere) 0.0 6144.0 0.0 18432.0)
      (let ((v0-0 (-> (the-as (array collide-shape-prim) v1-3) 17 local-sphere)))
        (set! (-> v0-0 x) 0.0)
        (set! (-> v0-0 y) 0.0)
        (set! (-> v0-0 z) 0.0)
        (set! (-> v0-0 w) 4096.0)
        v0-0))))

(defmethod puffer-method-31 ((this puffer))
  (when (!= (-> this cprims-type) 2)
    (set! (-> this cprims-type) (the-as uint 2))
    (let ((v1-3 (the-as basic (-> this root root-prim))))
      (set-vector! (-> (the-as collide-shape-prim v1-3) local-sphere) 0.0 6144.0 0.0 18432.0)
      (let ((v0-0 (-> (the-as (array collide-shape-prim) v1-3) 17 local-sphere)))
        (set! (-> v0-0 x) 0.0)
        (set! (-> v0-0 y) 0.0)
        (set! (-> v0-0 z) 0.0)
        (set! (-> v0-0 w) 7372.8)
        v0-0))))

(defmethod puffer-method-26 ((this puffer))
  (let ((f30-0 (get-current-phase (-> this sync))))
    (if (and (< 0.025 f30-0) (< f30-0 0.525)) (flip-look! this #f) (flip-look! this #t))
    (cond
      ((< f30-0 0.5)
       (cond
         ((= (if (> (-> this skel active-channels) 0) (-> this skel root-channel 0 frame-group)) (-> this draw art-group data 9))
          (cond
            ((-> this attacking?)
             (ja-channel-push! 1 (seconds 0.2))
             (let ((s5-0 (-> this skel root-channel 0)))
               (joint-control-channel-group-eval! s5-0 (the-as art-joint-anim (-> this draw art-group data 11)) num-func-identity)
               (set! (-> s5-0 frame-num) 0.0))
             (let ((a0-10 (-> this skel root-channel 0)))
               (set! (-> a0-10 param 0) (the float (+ (-> a0-10 frame-group data 0 length) -1)))
               (set! (-> a0-10 param 1) 1.0)
               (joint-control-channel-group! a0-10 (the-as art-joint-anim #f) num-func-seek!)))
            ((ja-done? 0)
             (let ((v1-28 (-> this skel root-channel 0)))
               (set! (-> v1-28 num-func) num-func-identity)
               (set! (-> v1-28 frame-num) 0.0))
             (let ((a0-13 (-> this skel root-channel 0)))
               (set! (-> a0-13 param 0) (the float (+ (-> a0-13 frame-group data 0 length) -1)))
               (set! (-> a0-13 param 1) 1.0)
               (joint-control-channel-group! a0-13 (the-as art-joint-anim #f) num-func-seek!)))
            (else
             (let ((a0-14 (-> this skel root-channel 0)))
               (set! (-> a0-14 param 0) (the float (+ (-> a0-14 frame-group data 0 length) -1)))
               (set! (-> a0-14 param 1) 1.0)
               (joint-control-channel-group-eval! a0-14 (the-as art-joint-anim #f) num-func-seek!)))))
         ((= (if (> (-> this skel active-channels) 0) (-> this skel root-channel 0 frame-group)) (-> this draw art-group data 11))
          (cond
            ((not (-> this attacking?))
             (ja-channel-push! 1 (seconds 0.2))
             (let ((s5-1 (-> this skel root-channel 0)))
               (joint-control-channel-group-eval! s5-1 (the-as art-joint-anim (-> this draw art-group data 9)) num-func-identity)
               (set! (-> s5-1 frame-num) 0.0))
             (let ((a0-21 (-> this skel root-channel 0)))
               (set! (-> a0-21 param 0) (the float (+ (-> a0-21 frame-group data 0 length) -1)))
               (set! (-> a0-21 param 1) 1.0)
               (joint-control-channel-group! a0-21 (the-as art-joint-anim #f) num-func-seek!)))
            ((ja-done? 0)
             (let ((v1-64 (-> this skel root-channel 0)))
               (set! (-> v1-64 num-func) num-func-identity)
               (set! (-> v1-64 frame-num) 0.0))
             (let ((a0-24 (-> this skel root-channel 0)))
               (set! (-> a0-24 param 0) (the float (+ (-> a0-24 frame-group data 0 length) -1)))
               (set! (-> a0-24 param 1) 1.0)
               (joint-control-channel-group! a0-24 (the-as art-joint-anim #f) num-func-seek!)))
            (else
             (let ((a0-25 (-> this skel root-channel 0)))
               (set! (-> a0-25 param 0) (the float (+ (-> a0-25 frame-group data 0 length) -1)))
               (set! (-> a0-25 param 1) 1.0)
               (joint-control-channel-group-eval! a0-25 (the-as art-joint-anim #f) num-func-seek!)))))
         ((= (if (> (-> this skel active-channels) 0) (-> this skel root-channel 0 frame-group)) (-> this draw art-group data 14))
          (cond
            ((ja-done? 0)
             (ja-channel-push! 1 (seconds 0.2))
             (cond
               ((-> this attacking?)
                (let ((s5-2 (-> this skel root-channel 0)))
                  (joint-control-channel-group-eval! s5-2 (the-as art-joint-anim (-> this draw art-group data 11)) num-func-identity)
                  (set! (-> s5-2 frame-num) 0.0)))
               (else
                (let ((s5-3 (-> this skel root-channel 0)))
                  (joint-control-channel-group-eval! s5-3 (the-as art-joint-anim (-> this draw art-group data 9)) num-func-identity)
                  (set! (-> s5-3 frame-num) 0.0))))
             (let ((a0-34 (-> this skel root-channel 0)))
               (set! (-> a0-34 param 0) (the float (+ (-> a0-34 frame-group data 0 length) -1)))
               (set! (-> a0-34 param 1) 1.0)
               (joint-control-channel-group! a0-34 (the-as art-joint-anim #f) num-func-seek!)))
            (else
             (let ((a0-35 (-> this skel root-channel 0)))
               (set! (-> a0-35 param 0) (the float (+ (-> a0-35 frame-group data 0 length) -1)))
               (set! (-> a0-35 param 1) 1.0)
               (joint-control-channel-group-eval! a0-35 (the-as art-joint-anim #f) num-func-seek!)))))
         (else
          (ja-channel-push! 1 (seconds 0.2))
          (let ((s5-4 (-> this skel root-channel 0)))
            (joint-control-channel-group-eval! s5-4 (the-as art-joint-anim (-> this draw art-group data 14)) num-func-identity)
            (set! (-> s5-4 frame-num) 0.0))
          (let ((a0-38 (-> this skel root-channel 0)))
            (set! (-> a0-38 param 0) (the float (+ (-> a0-38 frame-group data 0 length) -1)))
            (set! (-> a0-38 param 1) 1.0)
            (joint-control-channel-group! a0-38 (the-as art-joint-anim #f) num-func-seek!)))))
      ((= (if (> (-> this skel active-channels) 0) (-> this skel root-channel 0 frame-group)) (-> this draw art-group data 10))
       (cond
         ((-> this attacking?)
          (ja-channel-push! 1 (seconds 0.2))
          (let ((s5-5 (-> this skel root-channel 0)))
            (joint-control-channel-group-eval! s5-5 (the-as art-joint-anim (-> this draw art-group data 12)) num-func-identity)
            (set! (-> s5-5 frame-num) 0.0))
          (let ((a0-45 (-> this skel root-channel 0)))
            (set! (-> a0-45 param 0) (the float (+ (-> a0-45 frame-group data 0 length) -1)))
            (set! (-> a0-45 param 1) 1.0)
            (joint-control-channel-group! a0-45 (the-as art-joint-anim #f) num-func-seek!)))
         ((ja-done? 0)
          (let ((v1-142 (-> this skel root-channel 0)))
            (set! (-> v1-142 num-func) num-func-identity)
            (set! (-> v1-142 frame-num) 0.0))
          (let ((a0-48 (-> this skel root-channel 0)))
            (set! (-> a0-48 param 0) (the float (+ (-> a0-48 frame-group data 0 length) -1)))
            (set! (-> a0-48 param 1) 1.0)
            (joint-control-channel-group! a0-48 (the-as art-joint-anim #f) num-func-seek!)))
         (else
          (let ((a0-49 (-> this skel root-channel 0)))
            (set! (-> a0-49 param 0) (the float (+ (-> a0-49 frame-group data 0 length) -1)))
            (set! (-> a0-49 param 1) 1.0)
            (joint-control-channel-group-eval! a0-49 (the-as art-joint-anim #f) num-func-seek!)))))
      ((= (if (> (-> this skel active-channels) 0) (-> this skel root-channel 0 frame-group)) (-> this draw art-group data 12))
       (cond
         ((not (-> this attacking?))
          (ja-channel-push! 1 (seconds 0.2))
          (let ((s5-6 (-> this skel root-channel 0)))
            (joint-control-channel-group-eval! s5-6 (the-as art-joint-anim (-> this draw art-group data 10)) num-func-identity)
            (set! (-> s5-6 frame-num) 0.0))
          (let ((a0-56 (-> this skel root-channel 0)))
            (set! (-> a0-56 param 0) (the float (+ (-> a0-56 frame-group data 0 length) -1)))
            (set! (-> a0-56 param 1) 1.0)
            (joint-control-channel-group! a0-56 (the-as art-joint-anim #f) num-func-seek!)))
         ((ja-done? 0)
          (let ((v1-178 (-> this skel root-channel 0)))
            (set! (-> v1-178 num-func) num-func-identity)
            (set! (-> v1-178 frame-num) 0.0))
          (let ((a0-59 (-> this skel root-channel 0)))
            (set! (-> a0-59 param 0) (the float (+ (-> a0-59 frame-group data 0 length) -1)))
            (set! (-> a0-59 param 1) 1.0)
            (joint-control-channel-group! a0-59 (the-as art-joint-anim #f) num-func-seek!)))
         (else
          (let ((a0-60 (-> this skel root-channel 0)))
            (set! (-> a0-60 param 0) (the float (+ (-> a0-60 frame-group data 0 length) -1)))
            (set! (-> a0-60 param 1) 1.0)
            (joint-control-channel-group-eval! a0-60 (the-as art-joint-anim #f) num-func-seek!)))))
      ((= (if (> (-> this skel active-channels) 0) (-> this skel root-channel 0 frame-group)) (-> this draw art-group data 13))
       (cond
         ((ja-done? 0)
          (ja-channel-push! 1 (seconds 0.2))
          (let ((s5-7 (-> this skel root-channel 0)))
            (joint-control-channel-group-eval! s5-7 (the-as art-joint-anim (-> this draw art-group data 10)) num-func-identity)
            (set! (-> s5-7 frame-num) 0.0))
          (let ((a0-68 (-> this skel root-channel 0)))
            (set! (-> a0-68 param 0) (the float (+ (-> a0-68 frame-group data 0 length) -1)))
            (set! (-> a0-68 param 1) 1.0)
            (joint-control-channel-group! a0-68 (the-as art-joint-anim #f) num-func-seek!)))
         (else
          (let ((a0-69 (-> this skel root-channel 0)))
            (set! (-> a0-69 param 0) (the float (+ (-> a0-69 frame-group data 0 length) -1)))
            (set! (-> a0-69 param 1) 1.0)
            (joint-control-channel-group-eval! a0-69 (the-as art-joint-anim #f) num-func-seek!)))))
      (else
       (ja-channel-push! 1 (seconds 0.2))
       (let ((s5-8 (-> this skel root-channel 0)))
         (joint-control-channel-group-eval! s5-8 (the-as art-joint-anim (-> this draw art-group data 13)) num-func-identity)
         (set! (-> s5-8 frame-num) 0.0))
       (let ((a0-72 (-> this skel root-channel 0)))
         (set! (-> a0-72 param 0) (the float (+ (-> a0-72 frame-group data 0 length) -1)))
         (set! (-> a0-72 param 1) 1.0)
         (joint-control-channel-group! a0-72 (the-as art-joint-anim #f) num-func-seek!)))))
  (case (if (> (-> this skel active-channels) 0) (-> this skel root-channel 0 frame-group))
    (((-> this draw art-group data 10) (-> this draw art-group data 12)) (puffer-method-31 this))
    (else (puffer-method-30 this)))
  (none))

(defmethod relocate ((this puffer) (offset int))
  (if (nonzero? (-> this neck)) (&+! (-> this neck) offset))
  (call-parent-method this offset))

(defmethod init-from-entity! ((this puffer) (arg0 entity-actor))
  (local-vars (sv-16 res-tag))
  (set! (-> this cprims-type) (the-as uint 0))
  (set! (-> this attacking?) #f)
  (set! (-> this buddy) #f)
  (set! (-> this hit-player?) #f)
  (set! (-> this look-mean?) #f)
  (set! (-> this travel-turn-speed) 16384.0)
  (puffer-method-21 this)
  (process-drawable-from-entity! this (-> this entity))
  (initialize-skeleton this *puffer-sg* '())
  (set! (-> this draw origin-joint-index) (the-as uint 3))
  (logclear! (-> this mask) (process-mask actor-pause))
  (logior! (-> this mask) (process-mask enemy))
  (setup-lods! (-> this nice-look) *puffer-sg* (-> this draw art-group) (-> this entity))
  (setup-lods! (-> this mean-look) *puffer-mean-sg* (-> this draw art-group) (-> this entity))
  (load-params! (-> this sync) this (the-as uint 2400) 0.0 0.15 0.15)
  (set! (-> this notice-dist) (res-lump-float arg0 'notice-dist :default 57344.0))
  (set! (-> this give-up-dist) (+ 20480.0 (-> this notice-dist)))
  (set! (-> this nav) (new 'process 'nav-control (-> this root) 16 40960.0))
  (logior! (-> this nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7))
  (nav-control-method-26 (-> this nav))
  (set! (-> this path) (new 'process 'path-control this 'path 0.0))
  (logior! (-> this path flags) (path-control-flag display draw-line draw-point draw-text))
  (set! (-> this fact) (new 'process 'fact-info-enemy this (pickup-type eco-pill-random) (-> *FACT-bank* default-pill-inc)))
  (set! (-> this draw shadow-ctrl) (new 'process 'shadow-control 0.0 0.0 614400.0 (the-as float 60) 245760.0))
  (if (<= (-> this path curve num-cverts) 0) (go process-drawable-art-error "no path"))
  (set! (-> this buddy) (the-as process-drawable (entity-actor-lookup arg0 'alt-actor 0)))
  (ja-channel-set! 1)
  (let ((a0-21 (-> this skel root-channel 0)))
    (set! (-> a0-21 param 0) (the float (+ (-> a0-21 frame-group data 0 length) -1)))
    (set! (-> a0-21 param 1) 1.0)
    (joint-control-channel-group! a0-21 (the-as art-joint-anim #f) num-func-seek!))
  (let ((s4-0 (-> this skel root-channel 0)))
    (joint-control-channel-group-eval! s4-0 (the-as art-joint-anim (-> this draw art-group data 9)) num-func-identity)
    (set! (-> s4-0 frame-num) 0.0))
  (set! (-> this facing-ry) (quaternion-y-angle (-> this root quat)))
  (set! (-> this travel-ry) (-> this facing-ry))
  (set! (-> this travel-speed) 18432.0)
  (vector-reset! (-> this root transv))
  (set! (-> this patrol-bottom-y) (-> this root trans y))
  (let ((f28-0 8192.0)
        (f30-0 -8192.0))
    (set! sv-16 (new 'static 'res-tag))
    (let ((v1-54 (res-lump-data arg0 'distance (pointer float) :tag-ptr (& sv-16))))
      (when v1-54
        (set! f28-0 (-> v1-54 0))
        (set! f30-0 (-> v1-54 1))))
    (set! (-> this top-y) (+ (-> this patrol-bottom-y) f28-0))
    (set! (-> this attack-bottom-y) (+ (-> this patrol-bottom-y) f30-0)))
  (set! (-> this root trans y) (rand-vu-float-range (-> this patrol-bottom-y) (-> this top-y)))
  (set! (-> this targ-trans-y) (-> this root trans y))
  (set! (-> this acc-y) 2048.0)
  (let ((v1-59 (new 'process 'joint-mod (joint-mod-handler-mode reset) this 5)))
    (set! (-> this neck) v1-59)
    (set-vector! (-> this neck twist-max) 8192.0 8192.0 0.0 1.0)
    (set! (-> v1-59 up) (the-as uint 1))
    (set! (-> v1-59 nose) (the-as uint 2))
    (set! (-> v1-59 ear) (the-as uint 0))
    (set! (-> v1-59 max-dist) 102400.0)
    (set! (-> v1-59 ignore-angle) 16384.0))
  (update-transforms! (-> this root))
  (go puffer-idle)
  (none))
