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

;; name: needle-fish.gc
;; name in dgo: needle-fish
;; dgos: SEA

(declare-type needle-fish nav-enemy)

;; DECOMP BEGINS

(defskelgroup skel-needle-fish needle-fish needle-fish-lod0-jg -1
              ((needle-fish-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 1 0 3)
              )

(defskelgroup skel-needle-fish-needle needle-fish needle-fish-needle-lod0-jg needle-fish-needle-idle-ja
              ((needle-fish-needle-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 1 0 2)
              )

(deftype needle-fish-shot (projectile-bounce)
  ((scale  float)
   )
  )


(defmethod projectile-method-25 ((this needle-fish-shot))
  (let ((f0-0 (-> this scale)))
    (set-vector! (-> this root scale) f0-0 f0-0 f0-0 1.0)
    )
  (seek! (-> this scale) 0.0 (seconds-per-frame))
  (ja-post)
  0
  (none)
  )

;; WARN: Return type mismatch sound-id vs none.
(defmethod play-impact-sound ((this needle-fish-shot) (arg0 projectile-options))
  (with-pp
    (case arg0
      (((projectile-options po0 po1))
       (when (nonzero? (-> this sound-id))
         (when *sound-player-enable*
           (let ((gp-0 (the-as sound-rpc-set-param (get-sound-buffer-entry))))
             (set! (-> gp-0 command) (sound-command set-param))
             (set! (-> gp-0 id) (-> this sound-id))
             (let ((a1-1 (-> this root trans)))
               (let ((s5-1 pp))
                 (when (= a1-1 #t)
                   (if (and s5-1 (type? s5-1 process-drawable) (nonzero? (-> (the-as process-drawable s5-1) root)))
                       (set! a1-1 (-> (the-as process-drawable s5-1) root trans))
                       (set! a1-1 (the-as vector #f))
                       )
                   )
                 )
               (sound-trans-convert (-> gp-0 params trans) a1-1)
               )
             (set! (-> gp-0 params mask) (the-as uint 32))
             (-> gp-0 id)
             )
           )
         )
       )
      )
    (none)
    )
  )

(defmethod setup-collision! ((this needle-fish-shot))
  (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum hit-by-player))))
    (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s5-0 reaction)
          (the-as (function control-info collide-query vector vector collide-status) cshape-reaction-just-move)
          )
    (set! (-> s5-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (set! (-> s5-0 penetrate-using) (penetrate enemy-yellow-shot))
    (let ((s4-0 (new 'process 'collide-shape-prim-group s5-0 (the-as uint 2) 0)))
      (set! (-> s5-0 total-prims) (the-as uint 3))
      (set! (-> s4-0 prim-core collide-as) (collide-spec projectile))
      (set! (-> s4-0 prim-core collide-with)
            (collide-spec backgnd jak bot crate civilian enemy obstacle vehicle-sphere hit-by-others-list player-list)
            )
      (set! (-> s4-0 prim-core action) (collide-action solid))
      (set-vector! (-> s4-0 local-sphere) 0.0 0.0 0.0 819.2)
      (set! (-> s5-0 root-prim) s4-0)
      )
    (let ((v1-13 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-13 prim-core collide-as) (collide-spec projectile))
      (set! (-> v1-13 prim-core collide-with)
            (collide-spec backgnd jak bot crate civilian enemy obstacle vehicle-sphere hit-by-others-list player-list)
            )
      (set! (-> v1-13 prim-core action) (collide-action solid deadly))
      (set-vector! (-> v1-13 local-sphere) 0.0 0.0 0.0 819.2)
      )
    (let ((v1-15 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-15 prim-core collide-as) (collide-spec projectile))
      (set! (-> v1-15 prim-core collide-with)
            (collide-spec jak bot crate civilian enemy vehicle-sphere hit-by-others-list player-list)
            )
      (set! (-> v1-15 prim-core action) (collide-action deadly))
      (set-vector! (-> v1-15 local-sphere) 0.0 0.0 0.0 2457.6)
      )
    (set! (-> s5-0 nav-radius) (* 0.75 (-> s5-0 root-prim local-sphere w)))
    (let ((v1-18 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-18 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-18 prim-core collide-with))
      )
    (set! (-> s5-0 max-iteration-count) (the-as uint 1))
    (set! (-> s5-0 event-self) 'touched)
    (set! (-> this root) s5-0)
    )
  (set! (-> this root pat-ignore-mask)
        (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noproj #x1 :noendlessfall #x1 :board #x1)
        )
  (none)
  )

;; WARN: Return type mismatch float vs none.
(defmethod init-proj-settings! ((this needle-fish-shot))
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-needle-fish-needle" (the-as (pointer level) #f)))
    (the-as pair 0)
    )
  (let ((t9-2 (method-of-type projectile-bounce init-proj-settings!)))
    (t9-2 this)
    )
  (let ((a1-3 (vector-normalize-copy! (new 'stack-no-clear 'vector) (-> this root transv) 1.0)))
    (forward-up->quaternion (-> this root quat) a1-3 *y-vector*)
    )
  (set! (-> this attack-mode) 'needle-fish-shot)
  (set! (-> this max-speed) 163840.0)
  (set-gravity-length (-> this root dynam) 245760.0)
  (set! (-> this scale) 1.0)
  (none)
  )

;; WARN: Return type mismatch (pointer process) vs (pointer needle-fish-shot).
(defun spawn-needle-fish-projectile ((arg0 needle-fish) (arg1 vector) (arg2 vector) (arg3 float))
  (let ((s5-0 (new 'stack-no-clear 'projectile-init-by-other-params)))
    (let ((a1-2 (vector-normalize-copy! (new 'stack-no-clear 'vector) arg2 arg3)))
      (set! (-> s5-0 ent) (-> arg0 entity))
      (set! (-> s5-0 charge) 1.0)
      (set! (-> s5-0 options) (projectile-options))
      (logclear! (-> s5-0 options) (projectile-options po14 po15 po16))
      (set! (-> s5-0 notify-handle) (process->handle arg0))
      (set! (-> s5-0 owner-handle) (the-as handle #f))
      (set! (-> s5-0 target-handle) (the-as handle #f))
      (set! (-> s5-0 target-pos quad) (the-as uint128 0))
      (set! (-> s5-0 ignore-handle) (process->handle arg0))
      (let* ((v1-11 *game-info*)
             (a0-12 (+ (-> v1-11 attack-id) 1))
             )
        (set! (-> v1-11 attack-id) a0-12)
        (set! (-> s5-0 attack-id) a0-12)
        )
      (set! (-> s5-0 timeout) (seconds 4))
      (vector-copy! (-> s5-0 pos) arg1)
      (vector-normalize-copy! (-> s5-0 vel) a1-2 arg3)
      )
    (the-as (pointer needle-fish-shot) (spawn-projectile needle-fish-shot s5-0 arg0 *default-dead-pool*))
    )
  )

(deftype needle-fish-chain-physics (chain-physics)
  ()
  )


(defmethod apply-gravity ((this needle-fish-chain-physics) (arg0 vector) (arg1 int) (arg2 process-drawable))
  (with-pp
    (vector-float*!
      arg0
      (-> this gravity)
      (* 4096.0 (-> pp clock time-adjust-ratio) (lerp-scale 0.01 0.1 (the float arg1) 0.0 5.0))
      )
    (vector+float*! arg0 arg0 (the-as vector (+ (the-as uint (-> this chain-joints 0 velocity)) (* arg1 64))) 0.2)
    0
    (none)
    )
  )

(defmethod chain-physics-method-14 ((this needle-fish-chain-physics) (arg0 vector) (arg1 int))
  (vector-float*!
    arg0
    (the-as vector (+ (the-as uint (-> this chain-joints 0 velocity)) (* (+ arg1 1) 64)))
    (lerp-scale 0.4 0.9 (the float arg1) 0.0 4.0)
    )
  0
  (none)
  )

(defmethod chain-physics-method-16 ((this needle-fish-chain-physics) (arg0 int))
  (if (zero? arg0)
      0.0
      5461.3335
      )
  )

(define *needle-fish-spike-tbl*
  (new 'static 'boxed-array :type int32 22 31 30 9 20 32 19 16 41 36 34 42 8 21 38 33 37 40 18 17 43 35)
  )

(define *needle-fish-chain-setup* (new 'static 'boxed-array :type chain-physics-setup
                                    (new 'static 'chain-physics-setup :joint-index 26)
                                    (new 'static 'chain-physics-setup :joint-index 27)
                                    (new 'static 'chain-physics-setup :joint-index 28)
                                    (new 'static 'chain-physics-setup :joint-index 29)
                                    )
        )

(deftype needle-fish (nav-enemy)
  ((scared-timer      time-frame)
   (tail              needle-fish-chain-physics)
   (tail-initialized  symbol)
   (tail-clock        float)
   (tail-blend        float)
   )
  (:state-methods
    attack
    explode
    )
  )


(define *fact-info-needle-fish-defaults* (new 'static 'fact-info-enemy-defaults :idle-distance (meters 80)))

(define *needle-fish-nav-enemy-info*
  (new 'static 'nav-enemy-info
    :use-die-falling #t
    :use-victory #f
    :use-jump-blocked #f
    :debug-draw-neck #f
    :jump-debug-draw #f
    :move-to-ground #f
    :hover-if-no-ground #f
    :idle-anim-script (new 'static 'inline-array idle-control-frame 3
      (new 'static 'idle-control-frame :command (idle-control-cmd push) :param0 30)
      (new 'static 'idle-control-frame
        :command (idle-control-cmd play)
        :anim #x2
        :param0 5
        :param1 5
        :param2 '((new 'static 'bfloat :data 1.0) (new 'static 'bfloat :data 1.0))
        )
      (new 'static 'idle-control-frame)
      )
    :idle-anim 2
    :notice-anim 3
    :hostile-anim 4
    :hit-anim 3
    :knocked-anim 3
    :knocked-land-anim 3
    :die-anim 3
    :die-falling-anim 3
    :victory-anim -1
    :jump-wind-up-anim -1
    :jump-in-air-anim -1
    :jump-land-anim -1
    :neck-joint 6
    :look-at-joint 6
    :bullseye-joint 4
    :sound-hit (static-sound-name "needle-fish-hit")
    :sound-die (static-sound-name "needle-fish-die")
    :notice-distance (meters 20)
    :notice-distance-delta (meters 10)
    :proximity-notice-distance (meters 5)
    :default-hit-points 1.0
    :gnd-collide-with (collide-spec backgnd)
    :overlaps-others-collide-with-filter (collide-spec jak bot player-list)
    :penetrate-knocked (penetrate
      touch
      generic-attack
      lunge
      flop
      punch
      spin
      roll
      uppercut
      bonk
      tube
      vehicle
      flut-attack
      board
      mech
      mech-punch
      mech-bonk
      dark-skin
      dark-punch
      dark-bomb
      dark-smack
      flut
      shield
      explode
      jak-yellow-shot
      jak-red-shot
      jak-blue-shot
      jak-dark-shot
      enemy-yellow-shot
      enemy-dark-shot
      eco-yellow
      eco-red
      eco-blue
      eco-green
      knocked
      jak-red-shockwave
      jak-dark-nuke
      jak-dark-blackhole
      emp-blast
      penetrate38
      penetrate39
      penetrate40
      penetrate41
      penetrate42
      penetrate43
      penetrate44
      penetrate45
      penetrate46
      penetrate47
      penetrate48
      penetrate49
      penetrate50
      penetrate51
      penetrate52
      penetrate53
      penetrate54
      penetrate55
      penetrate56
      penetrate57
      penetrate58
      penetrate59
      penetrate60
      penetrate61
      penetrate64
      penetrate63
      )
    :movement-gravity (meters -100)
    :friction 0.96
    :attack-shove-back (meters 5)
    :attack-shove-up (meters 3)
    :attack-mode 'generic
    :attack-damage 2
    :recover-gnd-collide-with (collide-spec backgnd crate obstacle hit-by-others-list pusher)
    :knocked-can-land-timeout (seconds 0.5)
    :knocked-recover-timeout (seconds 2)
    :ragdoll-blend-out-time (seconds 0.25)
    :ragdoll-rotate-velocity-mult 1.0
    :jump-height-min (meters 3)
    :jump-height-factor 0.5
    :knocked-seek-ry-clamp 364.0889
    :knocked-soft-vxz-lo (meters 17.6)
    :knocked-soft-vxz-hi (meters 26.4)
    :knocked-soft-vy-lo (meters 20)
    :knocked-soft-vy-hi (meters 30)
    :knocked-medium-vxz-lo (meters 36)
    :knocked-medium-vxz-hi (meters 48)
    :knocked-medium-vy-lo (meters 33)
    :knocked-medium-vy-hi (meters 37)
    :knocked-hard-vxz-lo (meters 19.2)
    :knocked-hard-vxz-hi (meters 28.8)
    :knocked-hard-vy-lo (meters 44.8)
    :knocked-hard-vy-hi (meters 51.2)
    :knocked-huge-vxz-lo (meters 40.2)
    :knocked-huge-vxz-hi (meters 60.8)
    :knocked-huge-vy-lo (meters 44.8)
    :knocked-huge-vy-hi (meters 53.2)
    :knocked-yellow-vxz-lo (meters 10)
    :knocked-yellow-vxz-hi (meters 12)
    :knocked-yellow-vy-lo (meters 14)
    :knocked-yellow-vy-hi (meters 20)
    :knocked-red-vxz-lo (meters 6)
    :knocked-red-vxz-hi (meters 48)
    :knocked-red-vy-lo (meters 23)
    :knocked-red-vy-hi (meters 37)
    :knocked-blue-vxz-lo (meters 10)
    :knocked-blue-vxz-hi (meters 12)
    :knocked-blue-vy-lo (meters 6)
    :knocked-blue-vy-hi (meters 20)
    :ragdoll-info #f
    :shadow-size (meters 2)
    :shadow-max-y (meters 1)
    :shadow-min-y (meters -1)
    :shadow-locus-dist (meters 150)
    :gem-joint -1
    :gem-offset (new 'static 'sphere :r 163840.0)
    :knocked-off #t
    :callback-info #f
    :use-momentum #f
    :use-frustration #f
    :use-stop-chase #f
    :use-circling #f
    :use-pacing #f
    :walk-anim 3
    :turn-anim -1
    :run-anim 3
    :taunt-anim -1
    :run-travel-speed (meters 4)
    :run-acceleration (meters 0.1)
    :run-turning-acceleration (meters 20)
    :walk-travel-speed (meters 2)
    :walk-acceleration (meters 6)
    :walk-turning-acceleration (meters 2)
    :maximum-rotation-rate (degrees 360)
    :notice-nav-radius (meters 2)
    :frustration-distance (meters 8)
    :frustration-time (seconds 4)
    :blocked-time (seconds 0.3)
    :circle-dist-lo 20480.0
    :circle-dist-hi 61440.0
    :nav-mesh #f
    )
  )

(set! (-> *needle-fish-nav-enemy-info* fact-defaults) *fact-info-needle-fish-defaults*)

(defmethod init-enemy-collision! ((this needle-fish))
  "Typical place to construct collision shapes"
  (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player))))
    (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s5-0 reaction) cshape-reaction-default)
    (set! (-> s5-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (set! (-> s5-0 penetrated-by) (penetrate
                                    generic-attack
                                    lunge
                                    flop
                                    punch
                                    spin
                                    roll
                                    uppercut
                                    bonk
                                    tube
                                    flut-attack
                                    board
                                    mech-punch
                                    dark-punch
                                    dark-smack
                                    flut
                                    )
          )
    (let ((s4-0 (new 'process 'collide-shape-prim-group s5-0 (the-as uint 1) 0)))
      (set! (-> s5-0 total-prims) (the-as uint 2))
      (set! (-> s4-0 prim-core collide-as) (collide-spec enemy))
      (set! (-> s4-0 prim-core collide-with)
            (collide-spec backgnd jak bot crate obstacle hit-by-others-list player-list pusher)
            )
      (set! (-> s4-0 prim-core action) (collide-action solid deadly no-standon))
      (set-vector! (-> s4-0 local-sphere) 0.0 4096.0 0.0 6144.0)
      (set! (-> s5-0 root-prim) s4-0)
      )
    (let ((v1-13 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-13 prim-core collide-as) (collide-spec enemy))
      (set! (-> v1-13 prim-core collide-with) (collide-spec backgnd obstacle hit-by-others-list pusher))
      (set! (-> v1-13 prim-core action) (collide-action solid deadly no-standon))
      (set-vector! (-> v1-13 local-sphere) 0.0 4096.0 0.0 5734.4)
      )
    (set! (-> s5-0 nav-radius) 8192.0)
    (let ((v1-15 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-15 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-15 prim-core collide-with))
      )
    (set! (-> s5-0 max-iteration-count) (the-as uint 3))
    (set! (-> this root) s5-0)
    )
  0
  (none)
  )

(defun needle-fish-joint-mod-tail ((arg0 cspace) (arg1 transformq))
  (let* ((s4-0 (-> arg0 param1))
         (f0-0 4.0)
         (t9-0 sin)
         (f1-0 65536.0)
         (f2-0 (-> (the-as needle-fish s4-0) tail-clock))
         (f0-3 (t9-0 (* f1-0 (/ (- f2-0 (* (the float (the int (/ f2-0 f0-0))) f0-0)) f0-0))))
         (f0-4 (* 4551.1113 f0-3))
         (s3-0 (new 'stack-no-clear 'quaternion))
         )
    (let ((a2-1 (quaternion-vector-angle! (new 'stack-no-clear 'quaternion) *z-vector* f0-4)))
      (quaternion-normalize! (quaternion*! s3-0 (-> arg1 quat) a2-1))
      )
    (quaternion-slerp! (-> arg1 quat) (-> arg1 quat) s3-0 (-> (the-as needle-fish s4-0) tail-blend))
    )
  (cspace<-parented-transformq-joint! arg0 arg1)
  (none)
  )

(defstate active (needle-fish)
  :virtual #t
  :post nav-enemy-simple-post
  )

(defstate notice (needle-fish)
  :virtual #t
  :enter (behavior ()
    (let ((t9-0 (-> (method-of-type nav-enemy notice) enter)))
      (if t9-0
          (t9-0)
          )
      )
    (go-virtual hostile)
    )
  )

(defstate stare (needle-fish)
  :virtual #t
  :code (behavior ()
    (ja-channel-push! 1 (seconds 0.1))
    (until #f
      (ja-no-eval :group! needle-fish-swim0-ja :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!))
        )
      )
    #f
    )
  )

(defstate hostile (needle-fish)
  :virtual #t
  :trans (behavior ()
    (let ((t9-0 (-> (method-of-type nav-enemy hostile) trans)))
      (if t9-0
          (t9-0)
          )
      )
    (when (time-elapsed? (-> self state-time) (seconds 0.1))
      (cond
        ((and (< (vector-vector-xz-distance (-> self root trans) (-> self focus-pos)) 81920.0) (get-focus! self))
         (go-virtual attack)
         )
        ((< (vector-vector-xz-distance (-> self root trans) (-> self focus-pos)) 24576.0)
         (go-stare self)
         )
        )
      )
    )
  :post (behavior ()
    (let ((v1-0 (new 'stack-no-clear 'vector))
          (a0-0 (-> self focus-pos))
          )
      (vector-! v1-0 (-> self root trans) a0-0)
      (let ((f0-0 (vector-length v1-0))
            (f1-0 16384.0)
            )
        (when (< f1-0 f0-0)
          (vector-float*! v1-0 v1-0 (/ (+ -4096.0 f1-0) f0-0))
          (vector+! v1-0 a0-0 v1-0)
          (let ((a0-2 (-> self nav state)))
            (logclear! (-> a0-2 flags) (nav-state-flag directional-mode))
            (logior! (-> a0-2 flags) (nav-state-flag target-poly-dirty))
            (vector-copy! (-> a0-2 target-pos) v1-0)
            )
          0
          )
        )
      )
    (nav-enemy-method-187 self)
    )
  )

(defstate attack (needle-fish)
  :virtual #t
  :event enemy-event-handler
  :enter (behavior ()
    (logior! (-> self focus-status) (focus-status dangerous))
    (set-time! (-> self state-time))
    )
  :exit (behavior ()
    (logclear! (-> self focus-status) (focus-status dangerous))
    )
  :trans (behavior ()
    (when (time-elapsed? (-> self state-time) (-> self reaction-time))
      (let ((v1-3 (-> self focus aware)))
        (if (or (>= 2 (the-as int v1-3)) (= v1-3 (enemy-aware flee)) (not (get-focus! self)))
            (go-stare self)
            )
        )
      (if (< (vector-vector-xz-distance (-> self root trans) (-> self focus-pos)) 12288.0)
          (go-virtual explode)
          )
      )
    )
  :code (behavior ()
    (ja-channel-push! 1 (seconds 0.1))
    (ja-no-eval :group! needle-fish-spikes0-ja :num! (seek!) :frame-num 0.0)
    (until (ja-done? 0)
      (suspend)
      (ja :num! (seek!))
      )
    (until #f
      (ja-no-eval :group! needle-fish-swim-spikes0-ja :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!))
        )
      )
    #f
    )
  :post (behavior ()
    (nav-enemy-chase-post)
    )
  )

(defstate explode (needle-fish)
  :virtual #t
  :enter (behavior ()
    (let ((v1-1 (-> self root root-prim)))
      (set! (-> v1-1 prim-core collide-as) (collide-spec))
      (set! (-> v1-1 prim-core collide-with) (collide-spec))
      )
    0
    (logior! (-> self draw status) (draw-control-status no-draw))
    (sound-play "nfish-explode")
    (dotimes (gp-1 (-> *needle-fish-spike-tbl* length))
      (let* ((a1-1 (-> self node-list data (-> *needle-fish-spike-tbl* gp-1)))
             (s5-1 (vector<-cspace! (new 'stack-no-clear 'vector) a1-1))
             (s4-1 (vector-! (new 'stack-no-clear 'vector) s5-1 (-> self root trans)))
             )
        (vector-normalize! s4-1 1.0)
        (spawn-needle-fish-projectile self s5-1 s4-1 163840.0)
        )
      )
    (let ((gp-2 (new 'stack-no-clear 'explosion-init-params)))
      (vector-copy! (-> gp-2 spawn-point) (-> self root trans))
      (quaternion-identity! (-> gp-2 spawn-quat))
      (set! (-> gp-2 radius) 20480.0)
      (set! (-> gp-2 scale) 1.0)
      (set! (-> gp-2 group) (-> *part-group-id-table* 221))
      (set! (-> gp-2 collide-with)
            (collide-spec backgnd jak crate civilian enemy obstacle vehicle-sphere hit-by-others-list player-list pusher)
            )
      (set! (-> gp-2 damage) 2.0)
      (set! (-> gp-2 damage-scale) 1.0)
      (set! (-> gp-2 vehicle-damage-factor) 1.0)
      (set! (-> gp-2 vehicle-impulse-factor) 1.0)
      (set! (-> gp-2 ignore-proc) (process->handle #f))
      (explosion-spawn gp-2 (the-as process-drawable *default-pool*))
      )
    )
  :code (behavior ()
    (while (-> self child)
      (suspend)
      )
    (cleanup-for-death self)
    )
  )

(defmethod should-flee-from? ((this needle-fish) (arg0 process-focusable))
  "Return if this enemy should flee from the process."
  (< (current-time) (-> this scared-timer))
  )

(defmethod go-stare ((this needle-fish))
  (set! (-> this scared-timer) (+ (current-time) (the int (* 300.0 (rnd-float-range this 2.0 4.0)))))
  (go-flee this)
  )

(defmethod event-handler ((this needle-fish) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  "Commmon handler for events."
  (case arg2
    (('hit 'hit-flinch 'hit-knocked)
     (go (method-of-object this explode))
     )
    (else
      ((method-of-type nav-enemy event-handler) this arg0 arg1 arg2 arg3)
      )
    )
  )

(defmethod enemy-touched-handler ((this needle-fish) (arg0 process) (arg1 event-message-block))
  "General handler for when anything touches an enemy (automatic response)."
  (if (= arg0 *target*)
      (go (method-of-object this explode))
      ((method-of-type nav-enemy enemy-touched-handler) this arg0 arg1)
      )
  )

(defmethod enemy-common-post ((this needle-fish))
  "Common implementation of post. Runs ja-post."
  (when (not (-> this tail-initialized))
    (set! (-> this tail-initialized) #t)
    (initialize-chain-joints (-> this tail))
    )
  (update (-> this tail) this)
  (let ((a0-4 (handle->process (-> this focus handle))))
    (if a0-4
        (vector-copy! (-> this focus-pos) (get-trans (the-as process-focusable a0-4) 3))
        )
    )
  (+! (-> this tail-clock)
      (* (lerp-scale 1.0 10.0 (vector-length (-> this root transv)) 0.0 16384.0) (seconds-per-frame))
      )
  ((method-of-type nav-enemy enemy-common-post) this)
  (none)
  )

;; WARN: Return type mismatch nav-enemy vs needle-fish.
(defmethod relocate ((this needle-fish) (offset int))
  (if (nonzero? (-> this tail))
      (&+! (-> this tail) offset)
      )
  (the-as needle-fish ((method-of-type nav-enemy relocate) this offset))
  )

(defmethod init-enemy! ((this needle-fish))
  "Typical place for shared init code. Runs from entity or process style init."
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-needle-fish" (the-as (pointer level) #f)))
    (the-as pair 0)
    )
  (setup-enemy! this *needle-fish-nav-enemy-info*)
  (set! (-> this tail) (new 'process 'needle-fish-chain-physics))
  (chain-physics-initialize this (-> this tail) 25 1638.4 *needle-fish-chain-setup*)
  (set! (-> this tail-initialized) #f)
  (set! (-> this tail-clock) 0.0)
  (set! (-> this tail-blend) 1.0)
  (let ((a0-6 (-> this node-list data 25)))
    (set! (-> a0-6 param0) needle-fish-joint-mod-tail)
    (set! (-> a0-6 param1) this)
    )
  (set-vector! (-> this root scale) 1.0 0.5 1.0 1.0)
  (set! (-> this scared-timer) 0)
  (setup-masks (-> this draw) 3 0)
  0
  (none)
  )

(deftype sew-needle-fish (needle-fish)
  ()
  )
