;;-*-Lisp-*-
(in-package goal)
(bundles "SWA.DGO")
(require "engine/common-obs/nav-enemy.gc")

;; note: changed for high fps

(declare-type kermit nav-enemy)

;; DECOMP BEGINS

(defpartgroup group-kermit-charging-up
  :id 298
  :bounds (static-bspherem 0 5 0 5)
  :parts
  ((sp-item 1359 :fade-after (meters 140) :falloff-to (meters 140) :binding 1356)
   (sp-item 1359 :fade-after (meters 140) :falloff-to (meters 140) :binding 1357)
   (sp-item 1359 :fade-after (meters 140) :falloff-to (meters 140) :binding 1358)
   (sp-item 1360)
   (sp-item 1361 :fade-after (meters 120) :falloff-to (meters 120))
   (sp-item 1362 :fade-after (meters 120) :falloff-to (meters 120))
   (sp-item 1363 :fade-after (meters 120) :falloff-to (meters 120))
   (sp-item 1358 :fade-after (meters 30) :falloff-to (meters 30) :flags (start-dead))
   (sp-item 1357 :fade-after (meters 60) :falloff-to (meters 60) :flags (start-dead))
   (sp-item 1356 :fade-after (meters 80) :falloff-to (meters 80) :flags (start-dead))
   (sp-item 1358 :fade-after (meters 90) :falloff-to (meters 90) :flags (start-dead))
   (sp-item 1357 :fade-after (meters 100) :falloff-to (meters 100) :flags (start-dead))
   (sp-item 1356 :fade-after (meters 110) :falloff-to (meters 110) :flags (start-dead))
   (sp-item 1358 :fade-after (meters 120) :falloff-to (meters 120) :flags (start-dead))
   (sp-item 1357 :fade-after (meters 120) :falloff-to (meters 120) :flags (start-dead))))

(defpart 1360
  :init-specs
  ((:texture (middot effects))
   (:num 0.1 1.0)
   (:x (meters -0.75) (meters 1.5))
   (:y (meters 0.5))
   (:z (meters -0.75) (meters 1.5))
   (:scale-x (meters 1.5) (meters 1.4))
   (:scale-y :copy scale-x)
   (:r 32.0)
   (:g 32.0)
   (:b 192.0)
   (:a 64.0)
   (:vel-y (meters 0.016666668) (meters 0.016666668))
   (:fade-a -0.2)
   (:timer (seconds 1))
   (:flags (bit2 bit3))))

(defpart 1359
  :init-specs
  ((:texture (starflash effects))
   (:num 0.05 0.1)
   (:x (meters -0.75) (meters 1.5))
   (:y (meters 0.5))
   (:z (meters -0.75) (meters 1.5))
   (:scale-x (meters 1.5) (meters 0.4))
   (:scale-y :copy scale-x)
   (:r 64.0)
   (:g 64.0)
   (:b 192.0)
   (:a 96.0)
   (:vel-y (meters 0.01) (meters 0.01))
   (:fade-a 0.0)
   (:timer (seconds 1))
   (:flags (bit2 bit3))))

(defpart 1356
  :init-specs
  ((:texture (lightning effects))
   (:num 1.0)
   (:sound (static-sound-spec "eco-blue-spark1" :num 0.05 :volume 70.0))
   (:scale-x (meters 0.5) (meters 1.5))
   (:rot-x 4)
   (:rot-z (degrees 0) (degrees 360))
   (:scale-y (meters 0.2) (meters 0.1))
   (:r 64.0)
   (:g 64.0)
   (:b 128.0)
   (:a 128.0)
   (:fade-a -1.6)
   (:timer (seconds 0.3))
   (:flags (bit2 bit3))
   (:next-time (seconds 0.035))
   (:next-launcher 1364)))

(defpart 1357
  :init-specs
  ((:texture (lightning2 effects))
   (:num 1.0)
   (:sound (static-sound-spec "eco-blue-spark2" :num 0.075 :volume 100.0))
   (:scale-x (meters 0.5) (meters 1.5))
   (:rot-x 4)
   (:rot-z (degrees 0) (degrees 360))
   (:scale-y (meters 0.2) (meters 0.1))
   (:r 64.0)
   (:g 64.0)
   (:b 128.0)
   (:a 128.0)
   (:fade-a -1.6)
   (:timer (seconds 0.3))
   (:flags (bit2 bit3))
   (:next-time (seconds 0.035))
   (:next-launcher 1364)))

(defpart 1358
  :init-specs
  ((:texture (lightning3 effects))
   (:num 1.0)
   (:sound (static-sound-spec "eco-blue-spark3" :num 0.05 :volume 70.0))
   (:scale-x (meters 0.5) (meters 1.5))
   (:rot-x 4)
   (:rot-z (degrees 0) (degrees 360))
   (:scale-y (meters 0.2) (meters 0.1))
   (:r 64.0)
   (:g 64.0)
   (:b 128.0)
   (:a 128.0)
   (:fade-a -1.6)
   (:timer (seconds 0.3))
   (:flags (bit2 bit3))
   (:next-time (seconds 0.035))
   (:next-launcher 1364)))

(defpart 1361
  :init-specs
  ((:texture (lightning effects))
   (:num 0.1 0.5)
   (:x (meters -0.5) (meters 1))
   (:y (meters 0.5))
   (:z (meters -0.5) (meters 1))
   (:scale-x (meters 1.5) (meters 1.5))
   (:rot-x 4)
   (:rot-z (degrees 10) (degrees 160))
   (:scale-y (meters 0.2) (meters 0.1))
   (:r 128.0)
   (:g 128.0)
   (:b 255.0)
   (:a 128.0)
   (:fade-a -1.6)
   (:timer (seconds 0.305))
   (:flags (bit2 bit3))
   (:next-time (seconds 0.035))
   (:next-launcher 1364)))

(defpart 1362
  :init-specs
  ((:texture (lightning2 effects))
   (:num 0.2 0.4)
   (:x (meters -0.5) (meters 1))
   (:y (meters 0.5))
   (:z (meters -0.5) (meters 1))
   (:scale-x (meters 1.5) (meters 1.5))
   (:rot-x 4)
   (:rot-z (degrees 10) (degrees 160))
   (:scale-y (meters 0.2) (meters 0.1))
   (:r 128.0)
   (:g 128.0)
   (:b 255.0)
   (:a 128.0)
   (:fade-a -1.6)
   (:timer (seconds 0.305))
   (:flags (bit2 bit3))
   (:next-time (seconds 0.035))
   (:next-launcher 1364)))

(defpart 1363
  :init-specs
  ((:texture (lightning3 effects))
   (:num 0.3 0.1)
   (:x (meters -0.5) (meters 1))
   (:y (meters 0.5))
   (:z (meters -0.5) (meters 1))
   (:scale-x (meters 1.5) (meters 1.5))
   (:rot-x 4)
   (:rot-z (degrees 10) (degrees 160))
   (:scale-y (meters 0.2) (meters 0.1))
   (:r 128.0)
   (:g 128.0)
   (:b 255.0)
   (:a 128.0)
   (:fade-a -1.6)
   (:timer (seconds 0.305))
   (:flags (bit2 bit3))
   (:next-time (seconds 0.035))
   (:next-launcher 1364)))

(defpart 1364
  :init-specs ((:r 64.0) (:g 64.0) (:fade-r -1.0) (:fade-g -1.0) (:fade-a -2.0)))

(defpartgroup group-kermit-charged-up
  :id 299
  :flags (use-local-clock)
  :bounds (static-bspherem 0 0 0 8)
  :parts ((sp-item 1365 :period (seconds 0.05) :length (seconds 0.017))))

(defpart 1365
  :init-specs
  ((:texture (starflash effects))
   (:num 1.0 1.0)
   (:scale-x (meters 0.1) (meters 0.3))
   (:rot-z (degrees 0) (degrees 360))
   (:scale-y :copy scale-x)
   (:r 70.0 16.0)
   (:g 70.0 16.0)
   (:b 70.0)
   (:a 128.0)
   (:vel-y (meters 0.04) (meters 0.04))
   (:rotvel-z (degrees -1.2) (degrees 2.4))
   (:accel-y (meters -0.0026666666))
   (:friction 0.99)
   (:timer (seconds 0.25))
   (:flags (bit2))
   (:userdata 0.0)
   (:conerot-x (degrees 20) (degrees 50.000004))
   (:conerot-y (degrees 0) (degrees 360))))

(defpartgroup group-kermit-pulse
  :id 300
  :bounds (static-bspherem 0 0 0 8)
  :parts
  ((sp-item 1368 :flags (launch-asap) :binding 1366)
   (sp-item 1366 :flags (start-dead launch-asap) :binding 1367)
   (sp-item 1367 :flags (start-dead))
   (sp-item 1367 :flags (start-dead))))

(defpart 1368
  :init-specs
  ((:texture (hotdot effects))
   (:num 1.0)
   (:scale-x (meters 3))
   (:scale-y :copy scale-x)
   (:r 32.0 32.0)
   (:g 96.0 32.0)
   (:b 128.0 64.0)
   (:a 128.0)
   (:timer (seconds 10))
   (:flags (bit3))
   (:func 'sparticle-track-root)
   (:next-time (seconds 0.017))
   (:next-launcher 1369)))

(defpart 1369
  :init-specs
  ((:scale-x (meters 2.5) (meters 1.5))
   (:scale-y :copy scale-x)
   (:a 100.0 28.0)
   (:next-time (seconds 0.017))
   (:next-launcher 1369)))

(defpart 1366
  :init-specs
  ((:texture (hotdot effects))
   (:num 2.0)
   (:y (meters 4) (meters 16))
   (:z (meters 0))
   (:scale-x (meters 1.5))
   (:scale-y :copy scale-x)
   (:r 32.0 32.0)
   (:g 96.0 32.0)
   (:b 128.0 64.0)
   (:a 64.0)
   (:omega 0.0 65536.0)
   (:vel-x (meters 0.053333335))
   (:vel-y (meters 0.053333335))
   (:vel-z (meters 0.002))
   (:timer (seconds 10))
   (:flags (bit2 bit3 bit7))
   (:next-time (seconds 1))
   (:next-launcher 1370)))

(defpart 1370
  :init-specs ((:vel-z (meters 0))))

(defpart 1367
  :init-specs
  ((:texture (hotdot effects))
   (:num 1.0)
   (:scale-x (meters 0.85))
   (:scale-y :copy scale-x)
   (:r 32.0)
   (:g 96.0 32.0)
   (:b 96.0 64.0)
   (:a 128.0)
   (:scalevel-x (meters -0.00075757573))
   (:scalevel-y :copy scalevel-x)
   (:fade-g -0.16)
   (:fade-a -0.14222223)
   (:timer (seconds 5))
   (:flags (bit2 bit3))))

(defpartgroup group-kermit-pulse-impact
  :id 301
  :duration (seconds 0.017)
  :bounds (static-bspherem 0 0 0 3)
  :parts ((sp-item 1371) (sp-item 1372)))

(defpart 1371
  :init-specs
  ((:texture (bigpuff effects))
   (:num 8.0)
   (:x (meters -0.1) (meters 0.2))
   (:y (meters -0.1) (meters 0.2))
   (:z (meters -0.1) (meters 0.2))
   (:scale-x (meters 1.2) (meters 0.9))
   (:rot-z (degrees 0) (degrees 360))
   (:scale-y :copy scale-x)
   (:r 64.0)
   (:g 192.0 64.0)
   (:b 192.0 64.0)
   (:a 64.0 64.0)
   (:vel-y (meters 0.011666667) (meters 0.00083333335))
   (:scalevel-x (meters 0.01))
   (:rotvel-z (degrees -0.2) (degrees 0.4))
   (:scalevel-y :copy scalevel-x)
   (:fade-g -2.1333334)
   (:fade-a -0.64)
   (:friction 0.96)
   (:timer (seconds 0.5))
   (:flags (bit2 bit3))
   (:next-time (seconds 0.1))
   (:next-launcher 1373)
   (:launchrot-x (degrees 0) (degrees 180))
   (:launchrot-y (degrees 0) (degrees 360))
   (:rotate-y (degrees 0))))

(defpart 1373
  :init-specs ((:fade-r -3.2) (:fade-g 1.0) (:fade-b 1.0) (:next-time (seconds 0.1)) (:next-launcher 1374)))

(defpart 1374
  :init-specs ((:fade-r 0.0) (:fade-g 0.0) (:fade-b 0.0)))

(defpart 1372
  :init-specs
  ((:texture (middot effects))
   (:num 32.0)
   (:x (meters -0.1) (meters 0.2))
   (:y (meters -0.1) (meters 0.2))
   (:z (meters -0.1) (meters 0.2))
   (:scale-x (meters 0.1) (meters 0.1))
   (:rot-z (degrees 0) (degrees 360))
   (:scale-y :copy scale-x)
   (:r 64.0)
   (:g 192.0 64.0)
   (:b 192.0 64.0)
   (:a 64.0 64.0)
   (:vel-y (meters 0.006666667) (meters 0.06666667))
   (:rotvel-z (degrees -1.9999999) (degrees 3.9999998))
   (:fade-g -2.1333334)
   (:fade-a -1.4222223)
   (:accel-y (meters -0.00066666666))
   (:friction 0.93)
   (:timer (seconds 0.3))
   (:flags (bit2 bit3))
   (:next-time (seconds 0.1))
   (:next-launcher 1373)
   (:launchrot-x (degrees 0) (degrees 360))
   (:launchrot-y (degrees 0) (degrees 360))
   (:rotate-y (degrees 0))))

(deftype joint-mod-tracker (basic)
  ((target-pos               vector :inline)
   (target-pos-func          (function vector vector))
   (inv-forward-scale-factor float)
   (forward-scale-control    float)
   (forward-scale-max        float)
   (process                  kermit)
   (enable                   symbol)
   (up-axis                  int8)
   (forward-axis             int8))
  (:methods
   (new (symbol type kermit int function int int) _type_)))


(defmethod relocate ((this joint-mod-tracker) (offset int))
  (&+! (-> this process) offset)
  this)

(defun build-matrix-from-up-and-forward-axes! ((arg0 matrix) (arg1 vector) (arg2 int) (arg3 vector) (arg4 int))
  (let ((s1-0 (new 'stack-no-clear 'vector))
        (s5-0 (new 'stack-no-clear 'vector)))
    (let ((s3-0 (vector-normalize-copy! (new 'stack-no-clear 'vector) arg3 1.0)))
      (vector-cross! s1-0 arg1 s3-0)
      (vector-normalize! s1-0 1.0)
      (vector-cross! s5-0 s3-0 s1-0)
      (if (!= (mod (+ arg2 1) 3) arg4) (vector-negate-in-place! s1-0))
      (set! (-> arg0 vector 0 quad) (-> s1-0 quad))
      (set! (-> arg0 vector 1 quad) (-> s1-0 quad))
      (set! (-> arg0 vector 2 quad) (-> s1-0 quad))
      (set! (-> arg0 vector arg4 quad) (-> s3-0 quad)))
    (set! (-> arg0 vector arg2 quad) (-> s5-0 quad)))
  (set! (-> arg0 vector 0 w) 0.0)
  (set! (-> arg0 vector 1 w) 0.0)
  (set! (-> arg0 vector 2 w) 0.0)
  (set! (-> arg0 vector 3 quad) (-> *null-vector* quad))
  arg0)

(defun joint-mod-tracker-callback ((arg0 cspace) (arg1 transformq))
  (let ((s4-0 (the-as joint-mod-tracker (-> arg0 param1))))
    (cond
      ((-> s4-0 enable)
       (let ((t9-0 (-> s4-0 target-pos-func))) (if t9-0 (t9-0 (-> s4-0 target-pos))))
       (let ((s3-0 (-> s4-0 target-pos))
             (s5-1 (vector-matrix*! (new 'stack-no-clear 'vector) (-> arg1 trans) (-> arg0 parent bone transform))))
         (let* ((s2-1 (vector-! (new 'stack-no-clear 'vector) s3-0 s5-1))
                (f30-0 (vector-length s2-1)))
           (build-matrix-from-up-and-forward-axes! (-> arg0 bone transform)
                                                   *y-vector*
                                                   (-> s4-0 up-axis)
                                                   s2-1
                                                   (-> s4-0 forward-axis))
           (let ((f0-3 (fmin (* f30-0 (-> s4-0 inv-forward-scale-factor) (-> s4-0 forward-scale-control)) (-> s4-0 forward-scale-max)))
                 (v1-10 (-> arg0 bone transform vector (-> s4-0 forward-axis))))
             (vector-float*! v1-10 v1-10 f0-3)
             (set! (-> v1-10 w) 0.0)))
         (set! (-> arg0 bone transform vector 3 quad) (-> s5-1 quad)))
       (set-vector! (-> arg0 bone scale) 1.0 1.0 1.0 1.0))
      (else
       (set! (-> arg1 scale data (-> s4-0 forward-axis)) (-> s4-0 forward-scale-control))
       (cspace<-parented-transformq-joint! arg0 arg1))))
  (none))

(defmethod new joint-mod-tracker ((allocation symbol) (type-to-make type) (arg0 kermit) (arg1 int) (arg2 function) (arg3 int) (arg4 int))
  (let ((v0-0 (object-new allocation type-to-make (the-as int (-> type-to-make size)))))
    (set! (-> v0-0 process) arg0)
    (set! (-> v0-0 target-pos-func) (the-as (function vector vector) arg2))
    (set! (-> v0-0 up-axis) arg3)
    (set! (-> v0-0 forward-axis) arg4)
    (set! (-> v0-0 inv-forward-scale-factor) 0.0)
    (set! (-> v0-0 forward-scale-control) 1.0)
    (set! (-> v0-0 forward-scale-max) 1.0)
    (set! (-> v0-0 enable) #t)
    (let ((v1-5 (-> arg0 node-list data arg1)))
      (set! (-> v1-5 param0) joint-mod-tracker-callback)
      (set! (-> v1-5 param1) v0-0))
    v0-0))

(deftype kermit-pulse (process-drawable)
  ((root            collide-shape-moving :override)
   (parent-override (pointer kermit) :overlay-at parent)
   (self-override   kermit-pulse :overlay-at self)
   (sound-id        sound-id))
  (:states
   kermit-pulse-idle
   kermit-pulse-impact))


(defstate kermit-pulse-idle (kermit-pulse)
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('touch 'attack) (send-event proc 'attack (-> block param 0) (new 'static 'attack-info)) (go kermit-pulse-impact))))
  :enter
    (behavior ()
      (set-time! (-> self state-time)))
  :exit
    (behavior ()
      (sound-stop (-> self sound-id)))
  :code
    (behavior ()
      (while (not (time-elapsed? (-> self state-time) (seconds 4)))
        (sound-play "kermit-loop" :id (-> self sound-id) :position (the-as symbol (-> self root trans)))
        (spawn (-> self part) (-> self root trans))
        (find-ground-and-draw-shadow (-> self root trans)
                                     (the-as vector #f)
                                     8192.0
                                     (collide-kind background)
                                     (the-as process-drawable #f)
                                     0.0
                                     81920.0)
        (suspend))
      (cleanup-for-death self))
  :post
    (behavior ()
      (update-transforms! (-> self root))))

(defstate kermit-pulse-impact (kermit-pulse)
  :code
    (behavior ()
      (sound-play "get-shocked")
      (process-spawn part-tracker
                     :init
                     part-tracker-init
                     group-kermit-pulse-impact
                     -1
                     #f
                     #f
                     #f
                     (-> self root trans)
                     :to
                     *entity-pool*)
      (cleanup-for-death self)))

(defbehavior kermit-pulse-init-by-other kermit-pulse ((arg0 vector) (arg1 entity-actor))
  (logclear! (-> self mask) (process-mask enemy attackable))
  (logior! (-> self mask) (process-mask projectile))
  (set! (-> self entity) arg1)
  (let ((s5-0 (new 'process 'collide-shape-moving self (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-sphere s5-0 (the-as uint 0))))
      (set! (-> s4-0 prim-core collide-as) (collide-kind enemy))
      (set! (-> s4-0 collide-with) (collide-kind target))
      (set! (-> s4-0 prim-core action) (collide-action solid))
      (set! (-> s4-0 prim-core offense) (collide-offense indestructible))
      (set-vector! (-> s4-0 local-sphere) 0.0 0.0 0.0 2867.2)
      (set-root-prim! s5-0 s4-0))
    (set! (-> s5-0 nav-radius) (* 0.75 (-> s5-0 root-prim local-sphere w)))
    (backup-collide-with-as s5-0)
    (set! (-> self root) s5-0))
  (set! (-> self root trans quad) (-> arg0 quad))
  (set! (-> self root quat vec quad) (-> self parent-override 0 collide-info quat vec quad))
  (vector-identity! (-> self root scale))
  (vector-reset! (-> self root transv))
  (set! (-> self sound-id) (new-sound-id))
  (set! (-> self part) (create-launch-control group-kermit-pulse self))
  (go kermit-pulse-idle)
  (none))

(defun spawn-kermit-pulse ((arg0 kermit) (arg1 vector) (arg2 entity))
  (process-spawn kermit-pulse arg1 arg2 :to arg0)
  0
  (none))

(deftype kermit (nav-enemy)
  ((child-override   (pointer kermit-pulse) :overlay-at child)
   (rotate-dir       vector :inline)
   (charging-part    sparticle-launch-control)
   (airborne         symbol)
   (tongue-control   joint-mod-tracker)
   (tongue-pulse-pos float)
   (miss-count       int8)
   (charged-up       symbol)
   (sound-id         sound-id))
  (:states
   kermit-attack
   kermit-chase
   kermit-chase-new-position
   kermit-give-up
   kermit-idle
   kermit-notice
   kermit-patrol
   kermit-retract-tongue
   kermit-tongue-stuck))


(defmethod relocate ((this kermit) (offset int))
  (if (nonzero? (-> this tongue-control)) (&+! (-> this tongue-control) offset))
  (if (nonzero? (-> this charging-part)) (&+! (-> this charging-part) offset))
  (the-as kermit ((method-of-type nav-enemy relocate) this offset)))

(defmethod deactivate ((this kermit))
  (if (nonzero? (-> this charging-part)) (kill-and-free-particles (-> this charging-part)))
  ((method-of-type nav-enemy deactivate) this)
  (none))

(defskelgroup *kermit-sg*
  kermit
  kermit-lod0-jg
  kermit-idle-ja
  ((kermit-lod0-mg (meters 20)) (kermit-lod1-mg (meters 40)) (kermit-lod2-mg (meters 999999)))
  :bounds (static-spherem 0 -1 0 3)
  :longest-edge (meters 2))

(defbehavior kermit-enable-tongue kermit ()
  (set! (-> self tongue-control enable) #t)
  (set! (-> self draw bounds w) 81920.0)
  0
  (none))

(defbehavior kermit-disable-tongue kermit ()
  (set! (-> self tongue-control enable) #f)
  (set! (-> self draw bounds w) 12288.0)
  0
  (none))

(defun kermit-tongue-pos ((arg0 kermit))
  (-> arg0 node-list data 24 bone transform vector 3))

(defun kermit-get-head-dir-xz ((arg0 kermit) (arg1 vector))
  (set! (-> arg1 quad) (-> arg0 node-list data 8 bone transform vector 2 quad))
  (set! (-> arg1 y) 0.0)
  (vector-xz-normalize! arg1 1.0))

(defun kermit-get-head-dir ((arg0 kermit) (arg1 vector))
  (set! (-> arg1 quad) (-> arg0 node-list data 8 bone transform vector 2 quad))
  (vector-normalize! arg1 1.0))

(defun kermit-player-target-pos ()
  (target-pos 26))

(defun kermit-get-tongue-target-callback ((arg0 vector))
  (set! (-> arg0 quad) (-> (kermit-player-target-pos) quad))
  arg0)

(defbehavior kermit-check-tongue-is-clear? kermit ()
  (let* ((gp-0 (kermit-tongue-pos self))
         (v1-1 (-> self tongue-control target-pos))
         (s5-1 (vector-! (new 'stack-no-clear 'vector) v1-1 gp-0))
         (t2-0 (new 'stack 'collide-tri-result))
         (f30-0 (fill-and-probe-using-line-sphere *collide-cache*
                                                  gp-0
                                                  s5-1
                                                  409.6
                                                  (collide-kind background cak-2 crate enemy wall-object projectile ground-object)
                                                  self
                                                  t2-0
                                                  (new 'static 'pat-surface :noentity #x1)))
         (gp-1 (< f30-0 0.0)))
    (set! (-> self tongue-control forward-scale-max)
          (if gp-1 2.0 (* (vector-length s5-1) f30-0 (-> self tongue-control inv-forward-scale-factor))))
    gp-1))

(defbehavior kermit-check-to-hit-player? kermit ((arg0 float))
  (let* ((s5-0 (kermit-tongue-pos self))
         (v1-0 (kermit-player-target-pos))
         (s4-1 (vector-! (new 'stack-no-clear 'vector) v1-0 s5-0))
         (f30-0 (vector-length s4-1))
         (s5-1 (new 'stack-no-clear 'vector))
         (f0-0 f30-0)
         (s5-2 (vector-float*! s5-1 s4-1 (/ 1.0 f0-0)))
         (v0-5 (>= (vector-dot (kermit-get-head-dir-xz self (new 'stack-no-clear 'vector)) s5-2) (cos arg0))))
    (and (< f30-0 49152.0) v0-5)))

(defbehavior kermit-set-nav-mesh-target kermit ((arg0 vector))
  (let* ((gp-0 (target-pos 0))
         (s5-1 (vector-! (new 'stack-no-clear 'vector) arg0 gp-0)))
    (vector-length s5-1)
    (let* ((a0-4 (vector-normalize-copy! (new 'stack-no-clear 'vector) s5-1 40960.0))
           (v1-2 (vector+! (new 'stack-no-clear 'vector) gp-0 a0-4))
           (v0-3 (-> self nav target-pos)))
      (set! (-> v0-3 quad) (-> v1-2 quad))
      v0-3)))

(defbehavior kermit-short-hop kermit ()
  (ja-no-eval :group! kermit-hop-ja :num! (seek!) :frame-num 0.0)
  (until (ja-done? 0)
    (let ((f0-4 (ja-aframe-num 0)))
      (if (>= f0-4 4.0) (set! (-> self airborne) #t))
      (if (>= f0-4 14.0) (set! (-> self airborne) #f)))
    (suspend)
    (ja :num! (seek!)))
  #f)

(defbehavior kermit-long-hop kermit ()
  (ja-no-eval :group! kermit-longhop-ja :num! (seek!) :frame-num 0.0)
  (until (ja-done? 0)
    (let ((f0-4 (ja-aframe-num 0)))
      (if (>= f0-4 7.0) (set! (-> self airborne) #t))
      (if (>= f0-4 29.0) (set! (-> self airborne) #f)))
    (suspend)
    (ja :num! (seek!)))
  #f)

(defbehavior kermit-hop kermit ((arg0 float))
  (ja-channel-push! 1 (seconds 0.1))
  (set! (-> self rotate-speed) 1820444.5)
  (let ((f0-2 (fmin arg0 (vector-vector-distance (-> self collide-info trans) (-> self nav target-pos)))))
    (cond
      ((< 16384.0 f0-2) (set! (-> self target-speed) (* (/ (-> *display* frames-per-second) 22) f0-2)) (kermit-long-hop))
      (else (set! (-> self target-speed) (* (/ (-> *display* frames-per-second) 10) f0-2)) (kermit-short-hop))))
  (set! (-> self airborne) #f)
  #f)

(defbehavior kermit-set-rotate-dir-to-nav-target kermit ()
  (cond
    ((logtest? (nav-control-flags navcf19) (-> self nav flags))
     (vector-! (-> self rotate-dir) (-> self nav target-pos) (-> self collide-info trans)))
    (else (let ((v0-1 (-> self rotate-dir))) (set! (-> v0-1 quad) (-> self nav travel quad)) v0-1))))

(defbehavior kermit-set-rotate-dir-to-player kermit ()
  (vector-! (-> self rotate-dir) (target-pos 0) (-> self nav target-pos)))

nav-enemy-default-event-handler

(defmethod common-post ((this kermit))
  (call-parent-method this)
  (when (-> this charged-up))
  0
  (none))

(defbehavior kermit-simple-post kermit ()
  (nav-enemy-simple-post)
  (none))

(defbehavior kermit-post kermit ()
  (cond
    ((-> self airborne)
     (nav-control-method-11 (-> self nav) (-> self nav target-pos))
     (set! (-> self collide-info transv x) (-> self nav travel x))
     (set! (-> self collide-info transv y) 0.0)
     (set! (-> self collide-info transv z) (-> self nav travel z))
     (let ((f0-5 (fmin (-> self target-speed) (* (vector-xz-length (-> self collide-info transv)) (-> *display* frames-per-second)))))
       (vector-xz-normalize! (-> self collide-info transv) f0-5))
     (seek-toward-heading-vec! (-> self collide-info) (-> self rotate-dir) (-> self rotate-speed) (seconds 0.05))
     (vector-v++! (-> self collide-info transv) (compute-acc-due-to-gravity (-> self collide-info) (new-stack-vector0) 0.0))
     (integrate-for-enemy-with-move-to-ground! (-> self collide-info)
                                               (-> self collide-info transv)
                                               (collide-kind background)
                                               8192.0
                                               #t
                                               #f
                                               #f)
     (nav-enemy-common-post))
    (else (set! (-> self collide-info transv quad) (-> *null-vector* quad)) (kermit-simple-post)))
  (none))

(defbehavior kermit-get-new-patrol-point kermit ()
  (nav-enemy-get-new-patrol-point)
  (let ((v0-1 (-> self nav target-pos))) (set! (-> v0-1 quad) (-> self nav destination-pos quad)) v0-1))

(defstate kermit-idle (kermit)
  :event nav-enemy-default-event-handler
  :enter
    (behavior ()
      (set! (-> self notice-time) 0)
      0)
  :trans
    (behavior ()
      (if (and *target*
               (>= (-> self enemy-info idle-distance)
                   (vector-vector-distance (-> self collide-info trans) (-> *target* control trans))))
        (go kermit-patrol)))
  :code
    (behavior ()
      (kermit-disable-tongue)
      (ja :group! kermit-idle-ja :num! min)
      (loop
        (ja :num! (loop!))
        (suspend)))
  :post ja-post)

(defstate kermit-patrol (kermit)
  :event nav-enemy-default-event-handler
  :enter
    (behavior ()
      (set-time! (-> self state-time))
      (set-mode! (-> self neck) (joint-mod-handler-mode flex-blend))
      (kermit-get-new-patrol-point)
      (nav-control-method-11 (-> self nav) (-> self nav target-pos)))
  :trans
    (behavior ()
      (if (and (or (not *target*)
                   (< (-> self enemy-info idle-distance) (vector-vector-distance (-> self collide-info trans) (-> *target* control trans))))
               (time-elapsed? (-> self state-time) (seconds 1)))
        (go kermit-idle))
      (kermit-set-rotate-dir-to-nav-target)
      (if (and (not (-> self airborne)) (nav-enemy-test-point-in-nav-mesh? (target-pos 0))) (go kermit-notice))
      (if (logtest? (nav-control-flags navcf19) (-> self nav flags)) (kermit-get-new-patrol-point)))
  :code
    (behavior ()
      (loop
        (ja-no-eval :group! kermit-idle-ja :num! (seek! max 3.0) :frame-num 0.0)
        (until (ja-done? 0)
          (suspend)
          (ja :num! (seek! max 3.0)))
        (kermit-hop 20480.0)))
  :post kermit-post)

(defstate kermit-notice (kermit)
  :event nav-enemy-default-event-handler
  :enter
    (behavior ()
      (set-mode! (-> self neck) (joint-mod-handler-mode look-at)))
  :trans
    (behavior ()
      (kermit-set-rotate-dir-to-player))
  :code
    (behavior ()
      (ja-channel-push! 1 (seconds 0.1))
      (set-mode! (-> self neck) (joint-mod-handler-mode look-at))
      (kermit-hop 0.0)
      (go kermit-chase))
  :post kermit-post)

(defstate kermit-give-up (kermit)
  :event nav-enemy-default-event-handler
  :enter
    (behavior ()
      (set-mode! (-> self neck) (joint-mod-handler-mode flex-blend)))
  :code
    (behavior ()
      (go kermit-patrol))
  :post kermit-simple-post)

(defstate kermit-chase-new-position (kermit)
  :event nav-enemy-default-event-handler
  :enter
    (behavior ()
      (set-time! (-> self state-time))
      (set! (-> self miss-count) 0)
      (let* ((a1-1 (kermit-get-head-dir-xz self (new 'stack-no-clear 'vector)))
             (gp-0 (vector-rotate-around-y! (new 'stack-no-clear 'vector) a1-1 16384.0))
             (s5-0 (new 'stack-no-clear 'vector))
             (v1-2 #f))
        (let ((s4-0 0))
          (while (and (not v1-2) (< s4-0 4))
            (let ((f0-0 (rand-vu-float-range -40960.0 40960.0))) (vector+*! s5-0 (-> self collide-info trans) gp-0 f0-0))
            (kermit-set-nav-mesh-target s5-0)
            (set! v1-2 (nav-enemy-test-point-in-nav-mesh? (-> self nav target-pos)))
            (+! s4-0 1)))
        (if (not v1-2) (kermit-set-nav-mesh-target (-> self collide-info trans))))
      (nav-control-method-11 (-> self nav) (-> self nav target-pos)))
  :trans
    (behavior ()
      (when (not (-> self airborne))
        (if (or (time-elapsed? (-> self state-time) (seconds 3))
                (and (logtest? (nav-control-flags navcf19) (-> self nav flags)) (time-elapsed? (-> self state-time) (seconds 0.5))))
          (go kermit-chase))))
  :code
    (behavior ()
      (ja-channel-push! 1 (seconds 0.17))
      (dotimes (gp-0 3)
        (ja-no-eval :group! kermit-idle-ja :num! (seek! max 4.0) :frame-num 0.0)
        (until (ja-done? 0)
          (suspend)
          (ja :num! (seek! max 4.0))))
      (loop
        (kermit-hop 81920.0)
        (nop!)))
  :post kermit-post)

(defstate kermit-chase (kermit)
  :event nav-enemy-default-event-handler
  :enter
    (behavior ()
      (set-time! (-> self state-time))
      (set-mode! (-> self neck) (joint-mod-handler-mode look-at))
      (kermit-set-nav-mesh-target (-> self collide-info trans))
      (nav-control-method-11 (-> self nav) (-> self nav target-pos)))
  :trans
    (behavior ()
      (kermit-set-nav-mesh-target (-> self collide-info trans))
      (kermit-set-rotate-dir-to-player)
      (if (nav-enemy-test-point-in-nav-mesh? (target-pos 0)) (set-time! (-> self state-time)))
      (kermit-tongue-pos self)
      (let ((v1-5 (kermit-player-target-pos))) (set! (-> self tongue-control target-pos quad) (-> v1-5 quad)))
      (when (not (-> self airborne))
        (if (or (not *target*)
                (< (-> self enemy-info idle-distance) (vector-vector-distance (-> self collide-info trans) (-> *target* control trans))))
          (go kermit-patrol))
        (let ((gp-1 (kermit-check-to-hit-player? 3640.889))
              (v1-17 (kermit-check-tongue-is-clear?)))
          (when gp-1
            (if v1-17 (go kermit-attack) (go kermit-chase-new-position))))
        (if (time-elapsed? (-> self state-time) (seconds 3)) (go kermit-give-up))))
  :code
    (behavior ()
      (ja-channel-push! 1 (seconds 0.17))
      (loop
        (ja-no-eval :group! kermit-idle-ja :num! (seek! max 3.0) :frame-num 0.0)
        (until (ja-done? 0)
          (suspend)
          (ja :num! (seek! max 3.0)))
        (if (not (kermit-check-to-hit-player? 3640.889)) (kermit-hop 81920.0))))
  :post kermit-post)

(defstate kermit-attack (kermit)
  :event nav-enemy-default-event-handler
  :code
    (behavior ()
      (ja-channel-push! 1 (seconds 0.17))
      (set! (-> self tongue-control forward-scale-control) 0.0)
      (kermit-enable-tongue)
      (let ((s5-0 #f)
            (gp-0 #f))
        (let ((f30-0 1.0))
          (ja-no-eval :group! kermit-lash-ja :num! (seek!) :frame-num 0.0)
          (until (ja-done? 0)
            (set! (-> self tongue-control target-pos quad) (-> (kermit-player-target-pos) quad))
            (when (and (not s5-0) (>= (ja-aframe-num 0) 14.0))
              (set! s5-0 #t)
              (set! gp-0 (kermit-check-to-hit-player? 3640.889))
              (if (not gp-0) (set! f30-0 0.8)))
            (when s5-0
              (if (and (not gp-0) (= (-> self tongue-control forward-scale-control) f30-0)) (go kermit-retract-tongue))
              (seek! (-> self tongue-control forward-scale-control) f30-0 0.25))
            (suspend)
            (ja :num! (seek!))))
        (cond
          (gp-0
           (level-hint-spawn (text-id swamp-kermit-tongue-hint) "sksp0143" (the-as entity #f) *entity-pool* (game-task none))
           (level-hint-spawn (text-id swamp-kermit-flee) "sksp0151" (the-as entity #f) *entity-pool* (game-task none))
           (go kermit-tongue-stuck))
          (else (go kermit-retract-tongue)))))
  :post kermit-simple-post)

(defstate kermit-tongue-stuck (kermit)
  :event nav-enemy-default-event-handler
  :enter
    (behavior ()
      (set! (-> self miss-count) 0)
      (set! (-> self tongue-control forward-scale-control) 1.0)
      (kermit-enable-tongue)
      (set! (-> self tongue-pulse-pos) 0.0)
      (spawn-kermit-pulse self (kermit-tongue-pos self) (-> self entity)))
  :exit
    (behavior ()
      (sound-stop (-> self sound-id))
      (let ((v1-0 (-> self child-override))) (if v1-0 (deactivate (-> v1-0 0)))))
  :trans
    (behavior ()
      (let ((s5-0 (kermit-player-target-pos))
            (gp-0 (kermit-tongue-pos self)))
        (if (or (< 73728.0 (vector-vector-distance s5-0 gp-0))
                (or (not (kermit-check-tongue-is-clear?)) (not (-> self child-override))))
          (go kermit-retract-tongue))
        (seek! (-> self tongue-pulse-pos) 1.0 (* 0.3 (seconds-per-frame)))
        (when (and (-> self child-override)
                   (let ((v1-9 (-> self child-override))) (= (-> (if v1-9 (-> v1-9 0 self-override)) type) kermit-pulse)))
          (let* ((v1-13 (-> self child-override))
                 (s4-0 (if v1-13 (-> v1-13 0 self-override)))
                 (v1-15 (vector-lerp! (new 'stack-no-clear 'vector) gp-0 s5-0 (-> self tongue-pulse-pos))))
            (set! (-> s4-0 root trans quad) (-> v1-15 quad))))
        (send-event *target* 'tongue gp-0)))
  :code
    (behavior ()
      (ja-channel-push! 1 (seconds 0.1))
      (loop
        (ja-no-eval :group! kermit-turn-ja :num! (seek!) :frame-num 0.0)
        (until (ja-done? 0)
          (sound-play "kermit-stretch" :id (-> self sound-id) :position (the-as symbol (-> self collide-info trans)))
          (suspend)
          (ja :num! (seek!)))))
  :post
    (behavior ()
      (seek-to-point-toward-point! (-> self collide-info) (target-pos 0) (-> self rotate-speed) (seconds 0.05))
      (kermit-simple-post)))

(defstate kermit-retract-tongue (kermit)
  :event nav-enemy-default-event-handler
  :enter
    (behavior ()
      (set-time! (-> self state-time))
      (set! (-> self charged-up) #f)
      (+! (-> self miss-count) 1))
  :exit
    (behavior ()
      (set! (-> self tongue-control forward-scale-control) 0.0)
      (kermit-disable-tongue))
  :trans
    (behavior ()
      (kermit-set-nav-mesh-target (-> self collide-info trans))
      (kermit-set-rotate-dir-to-player)
      (when (not (-> self airborne))
        (when (time-elapsed? (-> self state-time) (seconds 2.5))
          (kill-and-free-particles (-> self charging-part))
          (set! (-> self charged-up) #t)
          (go kermit-chase))))
  :code
    (behavior ()
      (ja-channel-push! 1 (seconds 0.1))
      (ja-no-eval :group! kermit-miss-ja :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (if (>= (ja-aframe-num 0) 3.0) (seek! (-> self tongue-control forward-scale-control) 0.0 0.125))
        (suspend)
        (ja :num! (seek!)))
      (set! (-> self tongue-control forward-scale-control) 0.0)
      (kermit-disable-tongue)
      (loop
        (ja-channel-push! 1 (seconds 0.1))
        (ja-no-eval :group! kermit-idle-ja :num! (seek! max 4.0) :frame-num 0.0)
        (until (ja-done? 0)
          (suspend)
          (ja :num! (seek! max 4.0)))
        (kermit-hop 0.0)))
  :post kermit-post)

(define *kermit-nav-enemy-info*
  (new 'static
       'nav-enemy-info
       :idle-anim 4
       :walk-anim -1
       :turn-anim -1
       :notice-anim -1
       :run-anim -1
       :jump-anim 6
       :jump-land-anim -1
       :victory-anim -1
       :taunt-anim -1
       :die-anim 11
       :neck-joint 8
       :player-look-at-joint 5
       :run-travel-speed (meters 6)
       :run-rotate-speed (degrees 10000)
       :run-acceleration (meters 1)
       :run-turn-time (seconds 0.05)
       :walk-travel-speed (meters 3)
       :walk-rotate-speed (degrees 10000)
       :walk-acceleration (meters 1)
       :walk-turn-time (seconds 0.05)
       :attack-shove-back (meters 3)
       :attack-shove-up (meters 2)
       :shadow-size (meters 2)
       :notice-nav-radius (meters 10)
       :nav-nearest-y-threshold (meters 10)
       :notice-distance (meters 30)
       :stop-chase-distance (meters 40)
       :frustration-distance (meters 8)
       :frustration-time (seconds 4)
       :die-anim-hold-frame 10000000000.0
       :jump-land-anim-end-frame 10000000000.0
       :jump-height-min (meters 1)
       :jump-height-factor 0.5
       :jump-start-anim-speed 1.0
       :shadow-max-y (meters 1)
       :shadow-min-y (meters -1)
       :shadow-locus-dist (meters 150)
       :use-align #f
       :draw-shadow #t
       :move-to-ground #f
       :hover-if-no-ground #f
       :use-momentum #f
       :use-flee #f
       :use-proximity-notice #f
       :use-jump-blocked #f
       :use-jump-patrol #f
       :gnd-collide-with (collide-kind background)
       :debug-draw-neck #f
       :debug-draw-jump #f))

(defmethod init-from-entity! ((this kermit) (arg0 entity-actor))
  (logior! (-> this mask) (process-mask enemy))
  (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) default-collision-reaction)
    (set! (-> s4-0 no-reaction) (the-as (function collide-shape-moving collide-shape-intersect vector vector none) nothing))
    (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 1) 0)))
      (set! (-> s3-0 prim-core collide-as) (collide-kind enemy))
      (set! (-> s3-0 collide-with) (collide-kind target))
      (set! (-> s3-0 prim-core action) (collide-action solid))
      (set-vector! (-> s3-0 local-sphere) 0.0 0.0 0.0 16384.0)
      (set-root-prim! s4-0 s3-0)
      (let ((s2-0 (new 'process 'collide-shape-prim-sphere s4-0 (the-as uint 3))))
        (set! (-> s2-0 prim-core collide-as) (collide-kind enemy))
        (set! (-> s2-0 collide-with) (collide-kind target))
        (set! (-> s2-0 prim-core action) (collide-action solid))
        (set! (-> s2-0 prim-core offense) (collide-offense touch))
        (set! (-> s2-0 transform-index) 3)
        (set-vector! (-> s2-0 local-sphere) 0.0 0.0 0.0 3072.0)
        (append-prim s3-0 s2-0)))
    (set! (-> s4-0 nav-radius) (* 0.75 (-> s4-0 root-prim local-sphere w)))
    (backup-collide-with-as s4-0)
    (set! (-> this collide-info) s4-0))
  (process-drawable-from-entity! this arg0)
  (initialize-skeleton this *kermit-sg* '())
  (set! (-> this draw origin-joint-index) (the-as uint 3))
  (set! (-> this airborne) #f)
  (init-defaults! this *kermit-nav-enemy-info*)
  (set-vector! (-> this neck twist-max) 3640.889 3640.889 0.0 1.0)
  (set! (-> this neck up) (the-as uint 1))
  (set! (-> this neck nose) (the-as uint 2))
  (set! (-> this neck ear) (the-as uint 0))
  (set! (-> this neck max-dist) 102400.0)
  (set! (-> this neck ignore-angle) 16384.0)
  (set! (-> this miss-count) 0)
  (set! (-> this tongue-control) (new 'process 'joint-mod-tracker this 24 kermit-get-tongue-target-callback 1 2))
  (let ((f0-16 49152.0)) (set! (-> this tongue-control inv-forward-scale-factor) (/ 1.0 f0-16)))
  (set! (-> this tongue-control forward-scale-control) 0.0)
  (set! (-> this tongue-control forward-scale-max) 2.0)
  (set! (-> this tongue-control enable) #f)
  (set! (-> this charged-up) #t)
  (set! (-> this part) (create-launch-control group-kermit-charged-up this))
  (set! (-> this charging-part) (create-launch-control group-kermit-charging-up this))
  (set! (-> this sound-id) (new-sound-id))
  (go kermit-idle)
  (none))
