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

;; name: hosehead.gc
;; name in dgo: hosehead
;; dgos: SEB, SWB

;; DECOMP BEGINS

(defpart 1455
  :init-specs ((:texture (pal-lightning effects))
    (:birth-func 'birth-func-set-quat)
    (:num 1.0)
    (:scale-x (meters 1))
    (:scale-y (meters 40))
    (:r 128.0 64.0)
    (:g 128.0 64.0)
    (:b 128.0 64.0)
    (:a 128.0)
    (:timer (seconds 0.017))
    (:flags (sp-cpuinfo-flag-2 sp-cpuinfo-flag-3 sp-cpuinfo-flag-14 left-multiply-quat))
    )
  )

(defpart 1456
  :init-specs ((:texture (glow-hotdot effects))
    (:num 1.0)
    (:scale-x (meters 1))
    (:scale-y :copy scale-x)
    (:r 128.0 64.0)
    (:g 128.0 64.0)
    (:b 128.0 64.0)
    (:a 128.0)
    (:rotvel-z (degrees 0.3))
    (:fade-g -1.0666667)
    (:fade-b -1.0666667)
    (:fade-a -8.533334)
    (:timer (seconds 0.017))
    (:flags (sp-cpuinfo-flag-2 sp-cpuinfo-flag-3 sp-cpuinfo-flag-14))
    )
  )

(defpart 1457
  :init-specs ((:texture (glow-hotdot effects))
    (:num 1.0)
    (:scale-x (meters 1))
    (:scale-y :copy scale-x)
    (:r 128.0 64.0)
    (:g 128.0 64.0)
    (:b 128.0 64.0)
    (:a 128.0)
    (:rotvel-z (degrees 0.3))
    (:fade-g -1.0666667)
    (:fade-b -1.0666667)
    (:fade-a -8.533334)
    (:timer (seconds 0.017))
    (:flags (sp-cpuinfo-flag-2 sp-cpuinfo-flag-3 sp-cpuinfo-flag-14))
    )
  )

(deftype hosehead (nav-enemy)
  ((on-wall?                symbol)
   (sentry?                 symbol)
   (shot-by-ruffian?        symbol)
   (on-stop-sentry          function)
   (jump-point              vector        :inline)
   (last-time-dist-changed  time-frame)
   (next-lazer-time         time-frame)
   (fire-beam?              symbol)
   (head-angle              degrees)
   (head-angle-inc          degrees)
   (target-pos              vector        :inline)
   (come-from-notice        symbol)
   (allow-head              symbol)
   (head-joint-mod          joint-mod)
   (joint-ik                joint-mod-ik  4)
   (delta-y-ik              float         4)
   (lazer-dist              float         :offset 740)
   (lazer-pos-sound         vector        :inline)
   (lazer-sound             sound-id)
   (lazer-sound2            sound-id)
   (sync                    sync-eased    :inline)
   (angle-sentry            degrees)
   (lazer-length            float)
   )
  (:state-methods
    ambush-land
    idle-sentry
    active-wall
    notice-wall
    hostile-sentry
    fire
    attack
    )
  (:methods
    (hosehead-method-185 (_type_) none)
    (hosehead-method-186 (_type_) none)
    (hosehead-method-187 (_type_ vector) none)
    (hosehead-method-188 (_type_) none)
    (hosehead-method-189 (_type_) none)
    (hosehead-method-190 (_type_) symbol)
    (hosehead-method-191 (_type_ vector vector) none)
    (hosehead-method-192 (_type_ vector) symbol)
    (hosehead-method-193 (_type_) none)
    (hosehead-method-194 (_type_) none)
    (hosehead-method-195 (_type_) symbol)
    (hosehead-method-196 (_type_) none)
    (hosehead-method-197 (_type_) none)
    )
  )


(defskelgroup skel-hosehead hosehead hosehead-lod0-jg -1
              ((hosehead-lod0-mg (meters 20)) (hosehead-lod1-mg (meters 40)) (hosehead-lod2-mg (meters 999999)))
              :bounds (static-spherem 0 2.25 0 6)
              :shadow hosehead-shadow-mg
              :origin-joint-index 3
              )

(define *hosehead-idle-wall*
  (new 'static 'array idle-control-frame 4
    (new 'static 'idle-control-frame :command (ic-cmd play) :anim #x10 :param0 #x1 :param1 #x1)
    (new 'static 'idle-control-frame)
    (new 'static 'idle-control-frame)
    (new 'static 'idle-control-frame)
    )
  )

(define *hosehead-idle-ground*
  (new 'static 'array idle-control-frame 4
    (new 'static 'idle-control-frame :command (ic-cmd play) :anim #xf :param0 #x1 :param1 #x1)
    (new 'static 'idle-control-frame)
    (new 'static 'idle-control-frame)
    (new 'static 'idle-control-frame)
    )
  )

(define *hosehead-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 #t
                                    :hover-if-no-ground #f
                                    :idle-anim-script #f
                                    :idle-anim 15
                                    :notice-anim 20
                                    :hostile-anim 17
                                    :hit-anim 24
                                    :knocked-anim 18
                                    :knocked-land-anim 19
                                    :die-anim 23
                                    :die-falling-anim 19
                                    :victory-anim 15
                                    :jump-wind-up-anim 7
                                    :jump-in-air-anim 8
                                    :jump-land-anim 9
                                    :neck-joint -1
                                    :look-at-joint 9
                                    :bullseye-joint 6
                                    :sound-hit (static-sound-name "hosehead-hit")
                                    :sound-die (static-sound-name "hosehead-die")
                                    :notice-distance (meters 120)
                                    :notice-distance-delta (meters 10)
                                    :proximity-notice-distance (meters 120)
                                    :default-hit-points 5
                                    :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-giant
                                      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
                                      penetrate-33
                                      penetrate-34
                                      penetrate-35
                                      penetrate-36
                                      penetrate-37
                                      penetrate-38
                                      penetrate-39
                                      penetrate-40
                                      penetrate-41
                                      penetrate-42
                                      penetrate-43
                                      penetrate-44
                                      penetrate-45
                                      penetrate-46
                                      penetrate-47
                                      penetrate-48
                                      penetrate-49
                                      penetrate-50
                                      penetrate-51
                                      penetrate-52
                                      penetrate-53
                                      penetrate-54
                                      penetrate-55
                                      penetrate-56
                                      penetrate-57
                                      penetrate-58
                                      penetrate-59
                                      penetrate-60
                                      penetrate-61
                                      penetrate-62
                                      penetrate-63
                                      )
                                    :movement-gravity (meters -100)
                                    :friction 0.8
                                    :attack-shove-back (meters 3)
                                    :attack-shove-up (meters 2)
                                    :attack-mode 'generic
                                    :attack-damage 2
                                    :recover-gnd-collide-with (collide-spec backgnd crate obstacle hit-by-others-list pusher)
                                    :jump-height-min (meters 0.1)
                                    :knocked-seek-ry-clamp 6371.5557
                                    :knocked-soft-vxz-lo 72089.6
                                    :knocked-soft-vxz-hi 108134.4
                                    :knocked-soft-vy-lo 81920.0
                                    :knocked-soft-vy-hi 122880.0
                                    :knocked-medium-vxz-lo 147456.0
                                    :knocked-medium-vxz-hi 196608.0
                                    :knocked-medium-vy-lo 135168.0
                                    :knocked-medium-vy-hi 151552.0
                                    :knocked-hard-vxz-lo 78643.2
                                    :knocked-hard-vxz-hi 117964.8
                                    :knocked-hard-vy-lo 183500.8
                                    :knocked-hard-vy-hi 209715.2
                                    :knocked-huge-vxz-lo 164659.2
                                    :knocked-huge-vxz-hi 249036.8
                                    :knocked-huge-vy-lo 183500.8
                                    :knocked-huge-vy-hi 217907.2
                                    :knocked-yellow-vxz-lo 16384.0
                                    :knocked-yellow-vxz-hi 32768.0
                                    :knocked-yellow-vy-lo 57344.0
                                    :knocked-yellow-vy-hi 81920.0
                                    :knocked-red-vxz-lo 24576.0
                                    :knocked-red-vxz-hi 196608.0
                                    :knocked-red-vy-lo 94208.0
                                    :knocked-red-vy-hi 151552.0
                                    :knocked-blue-vxz-lo 40960.0
                                    :knocked-blue-vxz-hi 49152.0
                                    :knocked-blue-vy-lo 24576.0
                                    :knocked-blue-vy-hi 81920.0
                                    :shadow-size (meters 1)
                                    :shadow-max-y (meters 1)
                                    :shadow-min-y (meters -1)
                                    :shadow-locus-dist (meters 150)
                                    :gem-joint 9
                                    :gem-seg #x2
                                    :gem-no-seg #x4
                                    :gem-offset (new 'static 'sphere :y 1925.12 :z 1802.24 :r 163840.0)
                                    :callback-info #f
                                    :use-momentum #f
                                    :use-frustration #f
                                    :use-stop-chase #f
                                    :use-circling #f
                                    :use-pacing #f
                                    :walk-anim 5
                                    :turn-anim -1
                                    :run-anim 17
                                    :taunt-anim -1
                                    :run-travel-speed (meters 6)
                                    :run-acceleration (meters 1)
                                    :run-turning-acceleration (meters 16)
                                    :walk-travel-speed (meters 3)
                                    :walk-acceleration (meters 1)
                                    :walk-turning-acceleration (meters 16)
                                    :maximum-rotation-rate (degrees 720)
                                    :notice-nav-radius (meters 20)
                                    :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! (-> *hosehead-nav-enemy-info* fact-defaults) *fact-info-enemy-defaults*)

(defmethod init-enemy-collision! ((this hosehead))
  "Initializes the [[collide-shape-moving]] and any ancillary tasks to make the enemy collide properly"
  (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))
    (let ((s4-0 (new 'process 'collide-shape-prim-group s5-0 (the-as uint 6) 0)))
      (set! (-> s5-0 total-prims) (the-as uint 7))
      (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)
            )
      (set! (-> s4-0 prim-core action) (collide-action solid semi-solid deadly no-standon))
      (set-vector! (-> s4-0 local-sphere) 0.0 0.0 0.0 24576.0)
      (set! (-> s5-0 root-prim) s4-0)
      )
    (let ((v1-12 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-12 prim-core collide-as) (collide-spec enemy))
      (set! (-> v1-12 prim-core collide-with) (collide-spec backgnd jak bot crate hit-by-others-list player-list))
      (set! (-> v1-12 prim-core action) (collide-action solid no-standon))
      (set! (-> v1-12 transform-index) 6)
      (set-vector! (-> v1-12 local-sphere) 0.0 0.0 0.0 5734.4)
      )
    (let ((v1-14 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-14 prim-core collide-as) (collide-spec enemy))
      (set! (-> v1-14 prim-core collide-with) (collide-spec backgnd jak bot crate hit-by-others-list player-list))
      (set! (-> v1-14 prim-core action) (collide-action solid no-standon))
      (set! (-> v1-14 transform-index) 17)
      (set-vector! (-> v1-14 local-sphere) 0.0 0.0 0.0 5734.4)
      )
    (let ((v1-16 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-16 prim-core collide-as) (collide-spec enemy))
      (set! (-> v1-16 prim-core collide-with) (collide-spec backgnd jak bot crate hit-by-others-list player-list))
      (set! (-> v1-16 prim-core action) (collide-action solid no-standon))
      (set! (-> v1-16 transform-index) 9)
      (set-vector! (-> v1-16 local-sphere) 0.0 0.0 0.0 5734.4)
      )
    (let ((v1-18 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-18 prim-core collide-as) (collide-spec enemy))
      (set! (-> v1-18 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> v1-18 prim-core action) (collide-action deadly))
      (set! (-> v1-18 transform-index) 16)
      (set-vector! (-> v1-18 local-sphere) 0.0 -6553.6 0.0 4915.2)
      )
    (let ((v1-20 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-20 prim-core collide-as) (collide-spec enemy))
      (set! (-> v1-20 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> v1-20 prim-core action) (collide-action deadly))
      (set! (-> v1-20 transform-index) 14)
      (set-vector! (-> v1-20 local-sphere) 0.0 6553.6 0.0 4915.2)
      )
    (let ((v1-22 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-22 prim-core collide-with) (collide-spec backgnd obstacle))
      (set! (-> v1-22 prim-core action) (collide-action solid))
      (set-vector! (-> v1-22 local-sphere) 0.0 11468.8 0.0 11468.8)
      )
    (set! (-> s5-0 nav-radius) 6553.6)
    (let ((v1-24 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-24 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-24 prim-core collide-with))
      )
    (set! (-> s5-0 max-iteration-count) (the-as uint 3))
    (set! (-> this root) s5-0)
    )
  0
  (none)
  )

(deftype ik-setup (structure)
  ((elbow-index  int32)
   (hand-dist    float)
   )
  )


(define *hosehead-ik-setup* (new 'static 'inline-array ik-setup 4
                              (new 'static 'ik-setup :elbow-index 14 :hand-dist 8257.536)
                              (new 'static 'ik-setup :elbow-index 16 :hand-dist -8257.536)
                              (new 'static 'ik-setup :elbow-index 20 :hand-dist 5476.352)
                              (new 'static 'ik-setup :elbow-index 23 :hand-dist -5476.352)
                              )
        )

(deftype hosehead-anim-info (structure)
  ((hit-index   int32)
   (land-index  int32)
   )
  :pack-me
  )


(deftype hosehead-global-info (basic)
  ((prev-yellow-hit  int8)
   (prev-blue-hit    int8)
   (prev-knocked     int8)
   (yellow-hit-anim  hosehead-anim-info  2 :inline)
   (blue-hit-anim    hosehead-anim-info  3 :inline :offset  24)
   (knocked-anim     hosehead-anim-info  2 :inline :offset  48)
   )
  )


(define *hosehead-global-info* (new 'static 'hosehead-global-info
                                 :yellow-hit-anim (new 'static 'inline-array hosehead-anim-info 2
                                   (new 'static 'hosehead-anim-info :hit-index 24)
                                   (new 'static 'hosehead-anim-info :hit-index 25)
                                   )
                                 :blue-hit-anim (new 'static 'inline-array hosehead-anim-info 3
                                   (new 'static 'hosehead-anim-info :hit-index 26 :land-index 27)
                                   (new 'static 'hosehead-anim-info :hit-index 28 :land-index 29)
                                   (new 'static 'hosehead-anim-info :hit-index 30 :land-index 31)
                                   )
                                 :knocked-anim (new 'static 'inline-array hosehead-anim-info 2
                                   (new 'static 'hosehead-anim-info :hit-index 32 :land-index 33)
                                   (new 'static 'hosehead-anim-info :hit-index 34 :land-index 35)
                                   )
                                 )
        )

(defmethod enemy-method-77 ((this hosehead) (arg0 enemy-knocked-info))
  (cond
    ((zero? (-> this hit-points))
     (ja-channel-push! 1 (seconds 0.17))
     (let ((a0-2 (-> this skel root-channel 0)))
       (set! (-> a0-2 frame-group) (the-as art-joint-anim (-> this draw art-group data 18)))
       (set! (-> a0-2 param 0)
             (the float (+ (-> (the-as art-joint-anim (-> this draw art-group data 18)) frames num-frames) -1))
             )
       (set! (-> a0-2 param 1) (-> arg0 anim-speed))
       (set! (-> a0-2 frame-num) 0.0)
       (joint-control-channel-group! a0-2 (the-as art-joint-anim (-> this draw art-group data 18)) num-func-seek!)
       )
     #t
     )
    (else
      (case (-> this incoming knocked-type)
        (((knocked-type knocked-type-4))
         (ja-channel-push! 1 (seconds 0.1))
         (let* ((a2-1 (ash 1 (-> *hosehead-global-info* prev-yellow-hit)))
                (v1-18 (rnd-bit this 2 a2-1))
                (a1-8 (-> this draw art-group data (-> *hosehead-global-info* yellow-hit-anim v1-18 hit-index)))
                )
           (set! (-> *hosehead-global-info* prev-yellow-hit) v1-18)
           (let ((a0-15 (-> this skel root-channel 0)))
             (set! (-> a0-15 frame-group) (the-as art-joint-anim a1-8))
             (set! (-> a0-15 param 0) (the float (+ (-> (the-as art-joint-anim a1-8) frames num-frames) -1)))
             (set! (-> a0-15 param 1) (-> arg0 anim-speed))
             (set! (-> a0-15 frame-num) 0.0)
             (joint-control-channel-group! a0-15 (the-as art-joint-anim a1-8) num-func-seek!)
             )
           )
         )
        (((knocked-type knocked-type-6))
         (let* ((a2-3 (ash 1 (-> *hosehead-global-info* prev-blue-hit)))
                (v1-27 (rnd-bit this 3 a2-3))
                (a1-13 (-> this draw art-group data (-> *hosehead-global-info* blue-hit-anim v1-27 hit-index)))
                )
           (set! (-> *hosehead-global-info* prev-blue-hit) v1-27)
           (let ((a0-27 (-> this skel root-channel 0)))
             (set! (-> a0-27 frame-group) (the-as art-joint-anim a1-13))
             (set! (-> a0-27 param 0) (the float (+ (-> (the-as art-joint-anim a1-13) frames num-frames) -1)))
             (set! (-> a0-27 param 1) 1.0)
             (set! (-> a0-27 frame-num) 0.0)
             (joint-control-channel-group! a0-27 (the-as art-joint-anim a1-13) num-func-seek!)
             )
           )
         )
        (else
          (ja-channel-push! 1 (seconds 0.1))
          (let* ((a2-5 (ash 1 (-> *hosehead-global-info* prev-knocked)))
                 (v1-37 (rnd-bit this 2 a2-5))
                 (a1-19 (-> this draw art-group data (-> *hosehead-global-info* knocked-anim v1-37 hit-index)))
                 )
            (set! (-> *hosehead-global-info* prev-knocked) v1-37)
            (let ((a0-39 (-> this skel root-channel 0)))
              (set! (-> a0-39 frame-group) (the-as art-joint-anim a1-19))
              (set! (-> a0-39 param 0) (the float (+ (-> (the-as art-joint-anim a1-19) frames num-frames) -1)))
              (set! (-> a0-39 param 1) (-> arg0 anim-speed))
              (set! (-> a0-39 frame-num) 0.0)
              (joint-control-channel-group! a0-39 (the-as art-joint-anim a1-19) num-func-seek!)
              )
            )
          )
        )
      #t
      )
    )
  )

(defmethod enemy-method-78 ((this hosehead) (arg0 enemy-knocked-info))
  (local-vars (v1-15 knocked-type))
  (cond
    ((zero? (-> this hit-points))
     (ja-channel-push! 1 (seconds 0.17))
     (let ((a0-2 (-> this skel root-channel 0)))
       (set! (-> a0-2 frame-group) (the-as art-joint-anim (-> this draw art-group data 19)))
       (set! (-> a0-2 param 0)
             (the float (+ (-> (the-as art-joint-anim (-> this draw art-group data 19)) frames num-frames) -1))
             )
       (set! (-> a0-2 param 1) (-> arg0 anim-speed))
       (set! (-> a0-2 frame-num) 0.0)
       (joint-control-channel-group! a0-2 (the-as art-joint-anim (-> this draw art-group data 19)) num-func-seek!)
       )
     #t
     )
    ((begin (set! v1-15 (-> this incoming knocked-type)) (= v1-15 (knocked-type knocked-type-6)))
     (let* ((a0-4 (-> *hosehead-global-info* prev-blue-hit))
            (s4-0 (-> this draw art-group data (-> *hosehead-global-info* blue-hit-anim a0-4 land-index)))
            )
       (ja-channel-push! 1 (seconds 0.1))
       (let ((a0-9 (-> this skel root-channel 0)))
         (set! (-> a0-9 frame-group) (the-as art-joint-anim s4-0))
         (set! (-> a0-9 param 0) (the float (+ (-> (the-as art-joint-anim s4-0) frames num-frames) -1)))
         (set! (-> a0-9 param 1) (-> arg0 anim-speed))
         (joint-control-channel-group! a0-9 (the-as art-joint-anim s4-0) num-func-seek!)
         )
       )
     #t
     )
    ((= v1-15 (knocked-type knocked-type-4))
     #f
     )
    (else
      (let* ((a0-11 (-> *hosehead-global-info* prev-knocked))
             (s4-1 (-> this draw art-group data (-> *hosehead-global-info* knocked-anim a0-11 land-index)))
             )
        (ja-channel-push! 1 (seconds 0.1))
        (let ((a0-16 (-> this skel root-channel 0)))
          (set! (-> a0-16 frame-group) (the-as art-joint-anim s4-1))
          (set! (-> a0-16 param 0) (the float (+ (-> (the-as art-joint-anim s4-1) frames num-frames) -1)))
          (set! (-> a0-16 param 1) (-> arg0 anim-speed))
          (joint-control-channel-group! a0-16 (the-as art-joint-anim s4-1) num-func-seek!)
          )
        )
      #t
      )
    )
  )

(defmethod hosehead-method-189 ((this hosehead))
  (let ((a0-2 (handle->process (-> this focus handle))))
    (when a0-2
      (let ((s5-0 (new 'stack-no-clear 'vector)))
        (set! (-> s5-0 quad) (-> (get-trans (the-as process-focusable a0-2) 1) quad))
        (+! (-> s5-0 y) 8192.0)
        (set! (-> this target-pos quad) (-> s5-0 quad))
        )
      )
    )
  0
  (none)
  )

(defmethod hosehead-method-190 ((this hosehead))
  (rlet ((acc :class vf)
         (vf0 :class vf)
         (vf4 :class vf)
         (vf5 :class vf)
         (vf6 :class vf)
         (vf7 :class vf)
         )
    (init-vf0-vector)
    (hosehead-method-189 this)
    (let ((gp-0 (new 'stack-no-clear 'collide-query)))
      (let ((s4-0 (-> gp-0 start-pos)))
        (let ((s3-0 (-> this root trans)))
          (let ((v1-4 (vector-y-quaternion! (new 'stack-no-clear 'vector) (-> this root quat))))
            (let ((a0-4 6144.0))
              (.mov vf7 a0-4)
              )
            (.lvf vf5 (&-> v1-4 quad))
            )
          (.lvf vf4 (&-> s3-0 quad))
          )
        (.add.x.vf.w vf6 vf0 vf0)
        (.mul.x.vf.xyz acc vf5 vf7)
        (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
        (.svf (&-> s4-0 quad) vf6)
        )
      (vector-! (-> gp-0 move-dist) (-> this target-pos) (-> gp-0 start-pos))
      (let ((v1-7 gp-0))
        (set! (-> v1-7 radius) 1024.0)
        (set! (-> v1-7 collide-with) (collide-spec backgnd enemy obstacle))
        (set! (-> v1-7 ignore-process0) #f)
        (set! (-> v1-7 ignore-process1) #f)
        (set! (-> v1-7 ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1))
        (set! (-> v1-7 action-mask) (collide-action solid))
        )
      (< (fill-and-probe-using-line-sphere *collide-cache* gp-0) 0.0)
      )
    )
  )

(defun point-line-distance ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 vector))
  (local-vars (a1-5 float))
  (rlet ((acc :class vf)
         (vf0 :class vf)
         (vf1 :class vf)
         (vf2 :class vf)
         (vf4 :class vf)
         (vf5 :class vf)
         (vf6 :class vf)
         (vf7 :class vf)
         )
    (init-vf0-vector)
    (let ((v1-1 (vector-! (new 'stack-no-clear 'vector) arg1 arg2)))
      (let ((f0-1 (vector-dot v1-1 arg3)))
        (cond
          ((>= 0.0 f0-1)
           0.0
           )
          (else
            (.lvf vf1 (&-> arg3 quad))
            (.add.w.vf.x vf2 vf0 vf0)
            (.mul.vf vf1 vf1 vf1)
            (.mul.x.vf.x acc vf2 vf1)
            (.add.mul.y.vf.x acc vf2 vf1 acc)
            (.add.mul.z.vf.x vf1 vf2 vf1 acc)
            (.mov a1-5 vf1)
            (let ((f0-3 (/ f0-1 a1-5))
                  (a2-2 v1-1)
                  )
              (let ((a1-6 v1-1))
                (let ((t0-0 (- f0-3)))
                  (.mov vf7 t0-0)
                  )
                (.lvf vf5 (&-> arg3 quad))
                (.lvf vf4 (&-> a1-6 quad))
                )
              (.add.x.vf.w vf6 vf0 vf0)
              (.mul.x.vf.xyz acc vf5 vf7)
              (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
              (.svf (&-> a2-2 quad) vf6)
              )
            )
          )
        )
      (set! (-> arg0 quad) (-> v1-1 quad))
      (vector-length v1-1)
      )
    )
  )

(defmethod hosehead-method-197 ((this hosehead))
  (let ((s2-0 (new 'stack-no-clear 'matrix)))
    (let* ((a2-0 (-> this node-list data 12 bone transform))
           (v1-2 (-> a2-0 quad 0))
           (a0-1 (-> a2-0 quad 1))
           (a1-0 (-> a2-0 quad 2))
           (a2-1 (-> a2-0 trans quad))
           )
      (set! (-> s2-0 quad 0) v1-2)
      (set! (-> s2-0 quad 1) a0-1)
      (set! (-> s2-0 quad 2) a1-0)
      (set! (-> s2-0 trans quad) a2-1)
      )
    (new 'stack-no-clear 'matrix)
    (let ((s3-0 (new 'stack-no-clear 'collide-query))
          (s5-0 (new 'stack-no-clear 'vector))
          (s4-0 (new 'stack-no-clear 'vector))
          )
      (seek! (-> this lazer-length) 327680.0 (* 327680.0 (seconds-per-frame)))
      (vector-normalize-copy! s5-0 (-> s2-0 vector 1) (-> this lazer-length))
      (matrix->trans s2-0 s4-0)
      (set! (-> this lazer-dist) (lerp-scale
                                   1.0
                                   0.0
                                   (point-line-distance (-> this lazer-pos-sound) (-> this target-pos) s4-0 s5-0)
                                   0.0
                                   40960.0
                                   )
            )
      (vector-! (-> this lazer-pos-sound) (-> this target-pos) (-> this lazer-pos-sound))
      (set! (-> s3-0 start-pos quad) (-> s4-0 quad))
      (set! (-> s3-0 move-dist quad) (-> s5-0 quad))
      (let ((v1-9 s3-0))
        (set! (-> v1-9 radius) 40.96)
        (set! (-> v1-9 collide-with)
              (collide-spec backgnd jak bot enemy obstacle hit-by-player-list hit-by-others-list player-list)
              )
        (set! (-> v1-9 ignore-process0) #f)
        (set! (-> v1-9 ignore-process1) #f)
        (set! (-> v1-9 ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1))
        (set! (-> v1-9 action-mask) (collide-action solid))
        )
      (let ((f0-7 (fill-and-probe-using-line-sphere *collide-cache* s3-0)))
        (when (>= f0-7 0.0)
          (vector-float*! s5-0 s5-0 f0-7)
          (let* ((s2-2 (-> s3-0 best-other-tri collide-ptr))
                 (s3-1 (if (type? s2-2 collide-shape-prim)
                           s2-2
                           )
                       )
                 )
            (when s3-1
              (if (logtest? (-> (the-as collide-shape-prim s3-1) prim-core collide-as) (collide-spec enemy))
                  (go-hostile this)
                  )
              (if (logtest? (-> (the-as collide-shape-prim s3-1) prim-core collide-as) (collide-spec jak bot))
                  (send-event
                    (-> (the-as collide-shape-prim s3-1) cshape process)
                    'attack
                    #f
                    (static-attack-info ((id (new-attack-id)) (mode 'beam)))
                    )
                  )
              )
            )
          )
        )
      (set! (-> *part-id-table* 1455 init-specs 4 initial-valuef) (vector-length s5-0))
      (draw-beam (-> *part-id-table* 1455) s4-0 s5-0 #f #t)
      (launch-particles (-> *part-id-table* 1456) s4-0)
      (launch-particles (-> *part-id-table* 1457) (vector+! (new 'stack-no-clear 'vector) s5-0 s4-0))
      )
    )
  (let ((s5-1 sound-play-by-spec)
        (s4-1 (static-sound-spec "hosehead-lazer" :volume 0.0 :mask (pitch)))
        )
    (set! (-> s4-1 volume) (the int (* 1024.0 (lerp-scale 1.0 0.4 (-> this lazer-dist) 1.0 0.0))))
    (set! (-> s4-1 pitch-mod) 0)
    (s5-1 s4-1 (-> this lazer-sound) (-> this lazer-pos-sound))
    )
  (let ((s5-2 sound-play-by-spec)
        (s4-2 (static-sound-spec "lazer-sub" :volume 0.0 :mask (pitch)))
        )
    (set! (-> s4-2 volume) (the int (* 1024.0 (lerp-scale 1.0 0.0 (-> this lazer-dist) 1.0 0.5))))
    (set! (-> s4-2 pitch-mod) 0)
    (s5-2 s4-2 (-> this lazer-sound2) (-> this lazer-pos-sound))
    )
  0
  (none)
  )

(defmethod enemy-method-88 ((this hosehead) (arg0 enemy-jump-info))
  (ja-channel-push! 1 (seconds 0.075))
  (let ((a1-2 (-> this draw art-group data (-> this enemy-info jump-land-anim)))
        (a0-4 (-> this skel root-channel 0))
        )
    (set! (-> a0-4 frame-group) (the-as art-joint-anim a1-2))
    (set! (-> a0-4 param 0) (the float (+ (-> (the-as art-joint-anim a1-2) frames num-frames) -1)))
    (set! (-> a0-4 param 1) (-> arg0 anim-speed))
    (set! (-> a0-4 frame-num) 0.0)
    (joint-control-channel-group! a0-4 (the-as art-joint-anim a1-2) num-func-seek!)
    )
  #t
  )

(defmethod general-event-handler ((this hosehead) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  "Handles various events for the enemy
   @TODO - unsure if there is a pattern for the events and this should have a more specific name"
  (case arg2
    (('cue-chase)
     (cond
       ((-> this on-wall?)
        (logclear! (-> this enemy-flags) (enemy-flag use-notice-distance directed directed-ready use-trigger))
        (logior! (-> this enemy-flags) (enemy-flag chase-startup))
        (logclear! (-> this mask) (process-mask actor-pause))
        (go (method-of-object this notice-wall))
        )
       ((-> this sentry?)
        (when (and (-> this next-state) (= (-> this next-state name) 'idle-sentry))
          (logclear! (-> this enemy-flags) (enemy-flag use-notice-distance directed directed-ready use-trigger))
          (logior! (-> this enemy-flags) (enemy-flag chase-startup))
          (logclear! (-> this mask) (process-mask actor-pause))
          (go (method-of-object this hostile-sentry))
          )
        )
       (else
         ((method-of-type nav-enemy general-event-handler) this arg0 arg1 arg2 arg3)
         )
       )
     )
    (('stop-sentry)
     (set! (-> this sentry?) #f)
     #t
     )
    (else
      ((method-of-type nav-enemy general-event-handler) this arg0 arg1 arg2 arg3)
      )
    )
  )

;; WARN: Return type mismatch vector vs none.
(defmethod hosehead-method-186 ((this hosehead))
  (rlet ((acc :class vf)
         (vf0 :class vf)
         (vf4 :class vf)
         (vf5 :class vf)
         (vf6 :class vf)
         (vf7 :class vf)
         )
    (init-vf0-vector)
    (let ((s3-0 (new 'stack-no-clear 'collide-query))
          (gp-0 (new 'stack-no-clear 'vector))
          (s5-0 (new 'stack-no-clear 'vector))
          )
      (let ((s2-0 gp-0))
        (let ((s1-0 (-> this root trans)))
          (let ((v1-2 (vector-z-quaternion! (new 'stack-no-clear 'vector) (-> this root quat))))
            (let ((a0-3 8192.0))
              (.mov vf7 a0-3)
              )
            (.lvf vf5 (&-> v1-2 quad))
            )
          (.lvf vf4 (&-> s1-0 quad))
          )
        (.add.x.vf.w vf6 vf0 vf0)
        (.mul.x.vf.xyz acc vf5 vf7)
        (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
        (.svf (&-> s2-0 quad) vf6)
        )
      (set! (-> s5-0 quad) (-> gp-0 quad))
      (+! (-> gp-0 y) -8192.0)
      (+! (-> s5-0 y) 8192.0)
      (set! (-> s3-0 start-pos quad) (-> gp-0 quad))
      (vector-float*!
        (-> s3-0 move-dist)
        (vector-z-quaternion! (new 'stack-no-clear 'vector) (-> this root quat))
        -16384.0
        )
      (let ((v1-9 s3-0))
        (set! (-> v1-9 radius) 40.96)
        (set! (-> v1-9 collide-with) (collide-spec backgnd))
        (set! (-> v1-9 ignore-process0) #f)
        (set! (-> v1-9 ignore-process1) #f)
        (set! (-> v1-9 ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1))
        (set! (-> v1-9 action-mask) (collide-action solid))
        )
      (let ((f0-7 (fill-and-probe-using-line-sphere *collide-cache* s3-0)))
        (when (>= f0-7 0.0)
          (let ((a1-4 gp-0))
            (let ((v1-12 gp-0))
              (let ((a0-15 (-> s3-0 move-dist)))
                (let ((a2-0 f0-7))
                  (.mov vf7 a2-0)
                  )
                (.lvf vf5 (&-> a0-15 quad))
                )
              (.lvf vf4 (&-> v1-12 quad))
              )
            (.add.x.vf.w vf6 vf0 vf0)
            (.mul.x.vf.xyz acc vf5 vf7)
            (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
            (.svf (&-> a1-4 quad) vf6)
            )
          )
        )
      (set! (-> s3-0 start-pos quad) (-> s5-0 quad))
      (vector-float*!
        (-> s3-0 move-dist)
        (vector-z-quaternion! (new 'stack-no-clear 'vector) (-> this root quat))
        -16384.0
        )
      (let ((v1-16 s3-0))
        (set! (-> v1-16 radius) 40.96)
        (set! (-> v1-16 collide-with) (collide-spec backgnd))
        (set! (-> v1-16 ignore-process0) #f)
        (set! (-> v1-16 ignore-process1) #f)
        (set! (-> v1-16 ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1))
        (set! (-> v1-16 action-mask) (collide-action solid))
        )
      (let ((f0-10 (fill-and-probe-using-line-sphere *collide-cache* s3-0)))
        (when (>= f0-10 0.0)
          (let ((a0-26 s5-0))
            (let ((v1-19 s5-0))
              (let ((a1-7 (-> s3-0 move-dist)))
                (let ((a2-1 f0-10))
                  (.mov vf7 a2-1)
                  )
                (.lvf vf5 (&-> a1-7 quad))
                )
              (.lvf vf4 (&-> v1-19 quad))
              )
            (.add.x.vf.w vf6 vf0 vf0)
            (.mul.x.vf.xyz acc vf5 vf7)
            (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
            (.svf (&-> a0-26 quad) vf6)
            )
          )
        )
      (let ((s2-6 (vector-! (new 'stack-no-clear 'vector) gp-0 s5-0))
            (s1-1 (vector-x-quaternion! (new 'stack-no-clear 'vector) (-> this root quat)))
            (s3-1 (new 'stack-no-clear 'quaternion))
            )
        (let ((s0-0 (new 'stack-no-clear 'matrix)))
          (vector-normalize! s2-6 1.0)
          (quaternion-vector-angle! s3-1 s1-1 -16384.0)
          (quaternion->matrix s0-0 s3-1)
          (vector-rotate*! s2-6 s2-6 s0-0)
          )
        (quaternion-look-at! s3-1 s2-6 *up-vector*)
        (quaternion-pseudo-seek (-> this root quat) (-> this root quat) s3-1 (seconds-per-frame))
        )
      (vector-average! (-> this root trans) gp-0 s5-0)
      )
    (none)
    )
  )

(defmethod hosehead-method-185 ((this hosehead))
  (countdown (s5-0 (length (-> this actor-group 1)))
    (let* ((v1-5 (-> this actor-group 1 data s5-0 actor))
           (a0-4 (if v1-5
                     (-> v1-5 extra process)
                     )
                 )
           )
      (send-event a0-4 'stop-sentry)
      )
    )
  0
  (none)
  )

(defstate idle-sentry (hosehead)
  :virtual #t
  :event enemy-event-handler
  :enter (-> (method-of-type nav-enemy idle) enter)
  :exit (-> (method-of-type nav-enemy idle) exit)
  :trans (behavior ()
    (when (time-elapsed? (-> self state-time) (-> self state-timeout))
      (let ((a0-3 (handle->process (-> self focus handle))))
        (when a0-3
          (let ((f0-0 (vector-vector-xz-distance (get-trans (the-as process-focusable a0-3) 0) (-> self root trans))))
            (if (>= 98304.0 f0-0)
                (hosehead-method-185 self)
                )
            )
          )
        )
      (when (not (-> self sentry?))
        (logior! (-> self enemy-flags) (enemy-flag multi-focus))
        (set! (-> self focus collide-with) (collide-spec jak bot player-list jak-vehicle))
        (let ((gp-1 (-> self on-stop-sentry)))
          (if gp-1
              (script-eval (the-as pair gp-1) :vector (-> self root trans))
              )
          )
        (go-virtual active)
        )
      )
    )
  :code (-> (method-of-type nav-enemy idle) code)
  :post (-> (method-of-type nav-enemy idle) post)
  )

(defstate hostile-sentry (hosehead)
  :virtual #t
  :event enemy-event-handler
  :enter (behavior ()
    ((-> (method-of-type nav-enemy hostile) enter))
    (logior! (-> self skel status) (joint-control-status sync-math))
    (logior! (-> self focus-status) (focus-status dangerous))
    (let* ((v1-7 *game-info*)
           (a0-2 (+ (-> v1-7 attack-id) 1))
           )
      (set! (-> v1-7 attack-id) a0-2)
      (set! (-> self attack-id) a0-2)
      )
    (set! (-> self fire-beam?) #f)
    (set! (-> self allow-head) #t)
    (set! (-> self lazer-length) 0.0)
    (set-time! (-> self state-time))
    )
  :exit (behavior ()
    (sound-stop (-> self lazer-sound))
    (sound-stop (-> self lazer-sound2))
    (logclear! (-> self skel status) (joint-control-status sync-math))
    (set! (-> self allow-head) #f)
    (set! (-> self fire-beam?) #f)
    (if (logtest? (-> self enemy-flags) (enemy-flag dangerous-backup))
        (logior! (-> self focus-status) (focus-status dangerous))
        (logclear! (-> self focus-status) (focus-status dangerous))
        )
    )
  :trans (behavior ()
    (rlet ((acc :class vf)
           (vf0 :class vf)
           (vf4 :class vf)
           (vf5 :class vf)
           (vf6 :class vf)
           (vf7 :class vf)
           )
      (init-vf0-vector)
      (let ((gp-0 (-> self target-pos)))
        (let ((s5-0 (-> self root trans)))
          (let ((v1-2 (vector-z-quaternion! (new 'stack-no-clear 'vector) (-> self root quat))))
            (let ((a0-2 40960.0))
              (.mov vf7 a0-2)
              )
            (.lvf vf5 (&-> v1-2 quad))
            )
          (.lvf vf4 (&-> s5-0 quad))
          )
        (.add.x.vf.w vf6 vf0 vf0)
        (.mul.x.vf.xyz acc vf5 vf7)
        (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
        (.svf (&-> gp-0 quad) vf6)
        )
      (+! (-> self target-pos y) 2867.2)
      (let ((f0-5 (* (-> self angle-sentry) (+ -0.5 (get-norm! (-> self sync) 0)))))
        (if (logtest? (enemy-flag drawn-mirrored) (-> self enemy-flags))
            (set! f0-5 (- f0-5))
            )
        (set! (-> self head-angle) f0-5)
        )
      (when (time-elapsed? (-> self state-time) (-> self state-timeout))
        (let ((a0-8 (handle->process (-> self focus handle))))
          (when a0-8
            (let ((f0-6 (vector-vector-xz-distance (get-trans (the-as process-focusable a0-8) 0) (-> self root trans))))
              (if (>= 98304.0 f0-6)
                  (hosehead-method-185 self)
                  )
              )
            )
          )
        (when (not (-> self sentry?))
          (logior! (-> self enemy-flags) (enemy-flag multi-focus))
          (set! (-> self focus collide-with) (collide-spec jak bot player-list jak-vehicle))
          (let ((gp-2 (-> self on-stop-sentry)))
            (if gp-2
                (script-eval (the-as pair gp-2) :vector (-> self root trans))
                )
            )
          (go-hostile self)
          )
        )
      (set! (-> self fire-beam?) (if (handle->process (-> self focus handle))
                                     #t
                                     #f
                                     )
            )
      (if (not (-> self fire-beam?))
          (set! (-> self lazer-length) 0.0)
          )
      )
    )
  :code (behavior ()
    (let ((f30-0 (rnd-float-range self 0.9 1.1)))
      (ja-channel-push! 1 (seconds 0.01))
      (set! (-> self fire-beam?) #t)
      (until #f
        (ja-no-eval :group! hosehead-shoot-loop-ja :num! (seek! max f30-0) :frame-num 0.0)
        (until (ja-done? 0)
          (suspend)
          (ja :num! (seek! max f30-0))
          )
        (suspend)
        )
      #f
      (sound-stop (-> self lazer-sound))
      (sound-stop (-> self lazer-sound2))
      (ja-no-eval :group! hosehead-shoot-end-ja :num! (seek! max f30-0) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek! max f30-0))
        )
      )
    )
  :post (behavior ()
    (enemy-simple-post)
    (if (-> self fire-beam?)
        (hosehead-method-197 self)
        )
    )
  )

(defmethod hosehead-method-192 ((this hosehead) (arg0 vector))
  (local-vars (a2-7 float) (a2-14 float))
  (rlet ((vf1 :class vf)
         (vf2 :class vf)
         (vf3 :class vf)
         )
    (set! (-> arg0 x) (rnd-float-range this 5607424.0 5812224.0))
    (set! (-> arg0 z) (rnd-float-range this 2027520.0 1961984.0))
    (set! (-> arg0 y) -368680.97)
    (let ((gp-1 (new 'stack-no-clear 'vector)))
      (set! (-> gp-1 quad) (-> arg0 quad))
      (set! (-> gp-1 w) 32768.0)
      (set! *actor-list-length* 0)
      (if #t
          (set! *actor-list-length* (fill-actor-list-for-sphere *actor-hash* (the-as sphere gp-1) *actor-list* 256))
          )
      (when #t
        (let ((a0-5 (-> *collide-player-list* alive-list next0)))
          *collide-player-list*
          (let ((v1-18 (-> a0-5 next0)))
            (while (!= a0-5 (-> *collide-player-list* alive-list-end))
              (let* ((a0-6 (-> (the-as connection a0-5) param1))
                     (a1-4 (-> (the-as collide-shape a0-6) root-prim))
                     )
                (when (logtest? (-> a1-4 prim-core collide-as) (collide-spec jak bot enemy hit-by-others-list player-list))
                  (let ((a1-5 (-> a1-4 prim-core)))
                    (let ((a2-6 a1-5)
                          (a3-1 gp-1)
                          )
                      (.lvf vf2 (&-> a2-6 world-sphere quad))
                      (.lvf vf3 (&-> a3-1 quad))
                      )
                    (.sub.vf vf1 vf3 vf2)
                    (.mul.vf vf1 vf1 vf1)
                    (.add.y.vf.x vf1 vf1 vf1)
                    (.add.z.vf.x vf1 vf1 vf1)
                    (.mov a2-7 vf1)
                    (let ((f0-4 a2-7)
                          (f1-1 (+ (-> a1-5 world-sphere w) (-> gp-1 w)))
                          )
                      (when (< f0-4 (* f1-1 f1-1))
                        (when (< *actor-list-length* 256)
                          (set! (-> *actor-list* *actor-list-length*) (the-as collide-shape a0-6))
                          (set! *actor-list-length* (+ *actor-list-length* 1))
                          )
                        )
                      )
                    )
                  )
                )
              (set! a0-5 v1-18)
              *collide-player-list*
              (set! v1-18 (-> v1-18 next0))
              )
            )
          )
        )
      (when #f
        (let ((a0-8 (-> *collide-hit-by-player-list* alive-list next0)))
          *collide-hit-by-player-list*
          (let ((v1-25 (-> a0-8 next0)))
            (while (!= a0-8 (-> *collide-hit-by-player-list* alive-list-end))
              (let* ((a0-9 (-> (the-as connection a0-8) param1))
                     (a1-16 (-> (the-as collide-shape a0-9) root-prim))
                     )
                (when (logtest? (-> a1-16 prim-core collide-as) (collide-spec jak bot enemy hit-by-others-list player-list))
                  (let ((a1-17 (-> a1-16 prim-core)))
                    (let ((a2-13 a1-17)
                          (a3-2 gp-1)
                          )
                      (.lvf vf2 (&-> a2-13 world-sphere quad))
                      (.lvf vf3 (&-> a3-2 quad))
                      )
                    (.sub.vf vf1 vf3 vf2)
                    (.mul.vf vf1 vf1 vf1)
                    (.add.y.vf.x vf1 vf1 vf1)
                    (.add.z.vf.x vf1 vf1 vf1)
                    (.mov a2-14 vf1)
                    (let ((f0-5 a2-14)
                          (f1-5 (+ (-> a1-17 world-sphere w) (-> gp-1 w)))
                          )
                      (when (< f0-5 (* f1-5 f1-5))
                        (when (< *actor-list-length* 256)
                          (set! (-> *actor-list* *actor-list-length*) (the-as collide-shape a0-9))
                          (set! *actor-list-length* (+ *actor-list-length* 1))
                          )
                        )
                      )
                    )
                  )
                )
              (set! a0-8 v1-25)
              *collide-hit-by-player-list*
              (set! v1-25 (-> v1-25 next0))
              )
            )
          )
        )
      (dotimes (s5-1 *actor-list-length*)
        (let ((v1-30 (-> *actor-list* s5-1)))
          (when (logtest? (-> v1-30 root-prim prim-core collide-as)
                          (collide-spec jak bot enemy hit-by-others-list player-list)
                          )
            (let ((f0-6 (if (= (-> v1-30 process type) target)
                            28672.0
                            20480.0
                            )
                        )
                  )
              (if (>= (* f0-6 f0-6) (vector-vector-xz-distance-squared gp-1 (-> v1-30 trans)))
                  (return #f)
                  )
              )
            )
          )
        )
      )
    #t
    )
  )

;; WARN: Return type mismatch float vs none.
(defmethod hosehead-method-191 ((this hosehead) (arg0 vector) (arg1 vector))
  (cond
    ((logtest? (-> this fact enemy-options) (enemy-option user10))
     (countdown (s3-0 8)
       (if (hosehead-method-192 this arg1)
           (goto cfg-7)
           )
       )
     (label cfg-7)
     (set! (-> arg0 quad) (-> arg1 quad))
     (let ((f0-0 (vector-vector-xz-distance arg1 (math-camera-pos))))
       (+! (-> arg0 y) (lerp-scale 61440.0 102400.0 f0-0 40960.0 245760.0))
       )
     )
    (else
      (set! (-> arg1 quad) (-> this root trans quad))
      (set! (-> arg0 quad) (-> arg1 quad))
      (+! (-> arg0 y) 81920.0)
      )
    )
  (none)
  )

(defstate directed (hosehead)
  :virtual #t
  :enter (behavior ()
    (when (or (logtest? (-> self fact enemy-options) (enemy-option user8))
              (logtest? (-> self fact enemy-options) (enemy-option user10))
              )
      (logior! (-> self draw status) (draw-control-status no-draw))
      (let ((v1-10 (-> self root root-prim)))
        (set! (-> v1-10 prim-core collide-as) (collide-spec))
        (set! (-> v1-10 prim-core collide-with) (collide-spec))
        )
      0
      )
    (let ((t9-0 (-> (method-of-type nav-enemy directed) enter)))
      (if t9-0
          (t9-0)
          )
      )
    )
  )

(defstate ambush (hosehead)
  :virtual #t
  :event enemy-event-handler
  :enter (behavior ()
    (let ((v1-0 self))
      (set! (-> v1-0 enemy-flags) (the-as enemy-flag (logclear (-> v1-0 enemy-flags) (enemy-flag enemy-flag36))))
      (set! (-> v1-0 nav callback-info) *nav-enemy-null-callback-info*)
      )
    0
    (let ((v1-3 self))
      (set! (-> v1-3 enemy-flags) (the-as enemy-flag (logclear (-> v1-3 enemy-flags) (enemy-flag enemy-flag37))))
      )
    0
    (let ((v1-6 (-> self root root-prim)))
      (set! (-> v1-6 prim-core collide-as) (collide-spec))
      (set! (-> v1-6 prim-core collide-with) (collide-spec))
      )
    0
    (when (logtest? (-> self enemy-flags) (enemy-flag enable-on-notice))
      (logclear! (-> self enemy-flags) (enemy-flag enable-on-notice))
      (let ((gp-0 (-> self on-notice)))
        (if gp-0
            (script-eval gp-0 :vector (-> self root trans))
            )
        )
      )
    (logior! (-> self enemy-flags) (enemy-flag alert))
    (let ((gp-1 (new 'stack-no-clear 'vector)))
      (let ((s5-0 (new 'stack-no-clear 'vector)))
        (hosehead-method-191 self gp-1 s5-0)
        (set! (-> self root trans quad) (-> s5-0 quad))
        (set! (-> self jump-point quad) (-> s5-0 quad))
        )
      (let ((a0-13 (enemy-method-97 self)))
        (when a0-13
          (let* ((s5-1 (-> self root))
                 (s2-0
                   (vector-normalize!
                     (vector-! (new 'stack-no-clear 'vector) (get-trans (the-as process-focusable a0-13) 0) (-> s5-1 trans))
                     1.0
                     )
                   )
                 (f0-0 (deg-diff (quaternion-y-angle (-> s5-1 quat)) (vector-y-angle s2-0)))
                 )
            (quaternion-rotate-y! (-> s5-1 quat) (-> s5-1 quat) f0-0)
            )
          )
        )
      (set! (-> self root trans quad) (-> gp-1 quad))
      )
    (transform-post)
    (logior! (-> self focus-status) (focus-status dangerous))
    (vector-reset! (-> self root transv))
    (let* ((v1-37 *game-info*)
           (a0-22 (+ (-> v1-37 attack-id) 1))
           )
      (set! (-> v1-37 attack-id) a0-22)
      (set! (-> self attack-id) a0-22)
      )
    (if (logtest? (enemy-option water) (-> self fact enemy-options))
        (logior! (-> self enemy-flags) (enemy-flag check-water check-water-backup))
        )
    (logclear! (-> self draw status) (draw-control-status no-draw))
    )
  :exit (behavior ()
    (logclear! (-> self focus-status) (focus-status dangerous))
    )
  :trans (behavior ()
    (when (>= 61440.0 (- (-> self root trans y) (-> self jump-point y)))
      (let ((v1-3 (-> self root root-prim)))
        (set! (-> v1-3 prim-core collide-as) (-> self root backup-collide-as))
        (set! (-> v1-3 prim-core collide-with) (-> self root backup-collide-with))
        )
      )
    )
  :code (behavior ()
    (ja-channel-push! 1 (seconds 0.17))
    (ja-no-eval :group! hosehead-jump-down-ja :num! (seek!) :frame-num 0.0)
    (until (ja-done? 0)
      (suspend)
      (ja :num! (seek!))
      )
    (until #f
      (suspend)
      )
    #f
    )
  :post (behavior ()
    (nav-enemy-falling-post)
    (if (logtest? (-> self root status) (collide-status on-surface))
        (go-virtual ambush-land)
        )
    )
  )

(defstate ambush-land (hosehead)
  :virtual #t
  :event enemy-event-handler
  :code (behavior ()
    (ja-channel-push! 1 (seconds 0.17))
    (ja-no-eval :group! hosehead-jump-down-land-ja :num! (seek!) :frame-num 0.0)
    (until (ja-done? 0)
      (suspend)
      (ja :num! (seek!))
      )
    (go-hostile self)
    )
  :post nav-enemy-falling-post
  )

(defstate active-wall (hosehead)
  :virtual #t
  :event enemy-event-handler
  :enter (behavior ()
    (set-time! (-> self state-time))
    (let ((v1-2 self))
      (if (not (logtest? (enemy-flag enemy-flag36) (-> v1-2 enemy-flags)))
          (set! (-> v1-2 enemy-flags) (the-as enemy-flag (logior (enemy-flag enemy-flag38) (-> v1-2 enemy-flags))))
          )
      (set! (-> v1-2 enemy-flags) (the-as enemy-flag (logior (enemy-flag enemy-flag36) (-> v1-2 enemy-flags))))
      (set! (-> v1-2 nav callback-info) (-> v1-2 enemy-info callback-info))
      )
    0
    (let ((v1-5 self))
      (set! (-> v1-5 enemy-flags) (the-as enemy-flag (logior (enemy-flag enemy-flag37) (-> v1-5 enemy-flags))))
      )
    0
    (stop-looking-at-target! self)
    )
  :trans (behavior ()
    '()
    )
  :code (behavior ()
    (ja-channel-push! 1 (seconds 0.05))
    (until #f
      (ja-no-eval :group! hosehead-idle-wall0-ja :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!))
        )
      (suspend)
      )
    #f
    )
  :post nav-enemy-simple-post
  )

;; WARN: Return type mismatch symbol vs none.
(defmethod hosehead-method-196 ((this hosehead))
  (local-vars (sv-768 nav-control) (sv-784 vector) (sv-800 vector))
  (rlet ((acc :class vf)
         (vf0 :class vf)
         (vf4 :class vf)
         (vf5 :class vf)
         (vf6 :class vf)
         (vf7 :class vf)
         )
    (init-vf0-vector)
    (let ((s5-0 (vector-z-quaternion! (new 'stack-no-clear 'vector) (-> this root quat)))
          (f30-0 0.0)
          )
      (vector-float*! s5-0 s5-0 20480.0)
      (dotimes (s4-0 16)
        (let ((s1-0 (new 'stack-no-clear 'vector))
              (s3-0 (new 'stack-no-clear 'vector))
              )
          (vector-rotate-around-y! s1-0 s5-0 (* 182.04445 (the float (+ (* 11 s4-0) -90))))
          (let ((v1-7 s3-0))
            (let ((a0-5 (-> this root trans)))
              (let ((a1-3 s1-0))
                (let ((a2-2 1.0))
                  (.mov vf7 a2-2)
                  )
                (.lvf vf5 (&-> a1-3 quad))
                )
              (.lvf vf4 (&-> a0-5 quad))
              )
            (.add.x.vf.w vf6 vf0 vf0)
            (.mul.x.vf.xyz acc vf5 vf7)
            (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
            (.svf (&-> v1-7 quad) vf6)
            )
          (let ((v1-8 (-> this nav))
                (a0-6 s3-0)
                (a1-4 (new 'stack-no-clear 'nav-find-poly-parms))
                )
            (vector-! (-> a1-4 point) a0-6 (-> v1-8 state mesh bounds))
            (set! (-> a1-4 y-threshold) (-> v1-8 nearest-y-threshold))
            (set! (-> a1-4 ignore) (the-as uint 2))
            (let ((s2-0 (find-poly-containing-point-local (-> v1-8 state mesh) a1-4)))
              (when s2-0
                (let ((f28-0 (vector-dot s1-0 s5-0)))
                  (new 'stack-no-clear 'matrix3)
                  (let ((a1-5 (new 'stack-no-clear 'vector)))
                    (set! (-> a1-5 quad) (-> s3-0 quad))
                    (set! (-> a1-5 w) 8192.0)
                    (when (not (add-root-sphere-to-hash! (-> this nav) a1-5 32))
                      (when (< f30-0 f28-0)
                        (set! f30-0 f28-0)
                        (let ((s0-0 (new 'stack-no-clear 'vector)))
                          (set! sv-784 (new 'stack-no-clear 'vector))
                          (let ((s1-1 (new 'stack 'collide-query)))
                            (set! sv-768 (-> this nav))
                            (set! sv-800 s0-0)
                            (let* ((v1-22 s3-0)
                                   (a0-14 (-> sv-768 state mesh))
                                   (t9-5 (method-of-object a0-14 project-point-onto-plane-of-poly-local))
                                   (a2-6 sv-800)
                                   (t0-1 (vector-! (new 'stack-no-clear 'vector) v1-22 (-> sv-768 state mesh bounds)))
                                   )
                              (t9-5 a0-14 s2-0 a2-6 sv-784 t0-1)
                              )
                            (let ((v1-23 sv-800))
                              (let ((a0-17 (-> sv-768 state mesh bounds)))
                                (.mov.vf.w vf6 vf0)
                                (.lvf vf4 (&-> sv-800 quad))
                                (.lvf vf5 (&-> a0-17 quad))
                                )
                              (.add.vf.xyz vf6 vf4 vf5)
                              (.svf (&-> v1-23 quad) vf6)
                              )
                            0
                            (set! (-> s3-0 y) (-> s0-0 y))
                            (if (enemy-above-ground? this s1-1 s3-0 (collide-spec backgnd) 8192.0 81920.0 1024.0)
                                (set! (-> s3-0 y) (-> s1-1 best-other-tri intersect y))
                                )
                            )
                          )
                        (set! (-> this jump-point quad) (-> s3-0 quad))
                        )
                      )
                    )
                  )
                )
              )
            )
          )
        )
      )
    (none)
    )
  )

(defstate notice-wall (hosehead)
  :virtual #t
  :event enemy-event-handler
  :enter (behavior ()
    (local-vars (sv-688 vector))
    (rlet ((acc :class vf)
           (vf0 :class vf)
           (vf4 :class vf)
           (vf5 :class vf)
           (vf6 :class vf)
           (vf7 :class vf)
           )
      (init-vf0-vector)
      (logclear! (-> self enemy-flags) (enemy-flag alert))
      ((-> (method-of-type nav-enemy notice) enter))
      (let ((v1-4 self))
        (set! (-> v1-4 enemy-flags) (the-as enemy-flag (logclear (-> v1-4 enemy-flags) (enemy-flag enemy-flag36))))
        (set! (-> v1-4 nav callback-info) *nav-enemy-null-callback-info*)
        )
      0
      (let ((v1-7 self))
        (set! (-> v1-7 enemy-flags) (the-as enemy-flag (logclear (-> v1-7 enemy-flags) (enemy-flag enemy-flag37))))
        )
      0
      (set! (-> self on-wall?) #f)
      (idle-control-method-9 (-> self idle-anim-player) *hosehead-idle-ground*)
      (let ((v1-10 (-> self nav)))
        (set! (-> v1-10 nearest-y-threshold) 204800.0)
        )
      0
      (let ((gp-0 #f)
            (f30-0 4096.0)
            )
        (while (not gp-0)
          (let ((s5-0 (new 'stack-no-clear 'vector)))
            (let ((s4-0 (-> self root trans)))
              (let ((v0-2 (vector-z-quaternion! (new 'stack-no-clear 'vector) (-> self root quat))))
                (let ((v1-15 f30-0))
                  (.mov vf7 v1-15)
                  )
                (.lvf vf5 (&-> v0-2 quad))
                )
              (.lvf vf4 (&-> s4-0 quad))
              )
            (.add.x.vf.w vf6 vf0 vf0)
            (.mul.x.vf.xyz acc vf5 vf7)
            (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
            (.svf (&-> s5-0 quad) vf6)
            (let ((v1-16 (-> self nav))
                  (a0-9 s5-0)
                  (a1-4 (new 'stack-no-clear 'nav-find-poly-parms))
                  )
              (vector-! (-> a1-4 point) a0-9 (-> v1-16 state mesh bounds))
              (set! (-> a1-4 y-threshold) (-> v1-16 nearest-y-threshold))
              (set! (-> a1-4 ignore) (the-as uint 2))
              (let ((s2-0 (find-poly-containing-point-local (-> v1-16 state mesh) a1-4)))
                (set! (-> self jump-point quad) (-> s5-0 quad))
                (when s2-0
                  (let ((s3-0 (new 'stack-no-clear 'vector)))
                    (set! sv-688 (new 'stack-no-clear 'vector))
                    (let ((s4-1 (new 'stack 'collide-query)))
                      (let ((s0-0 (-> self nav))
                            (s1-0 s3-0)
                            )
                        (let* ((v1-22 s5-0)
                               (a0-15 (-> s0-0 state mesh))
                               (t9-5 (method-of-object a0-15 project-point-onto-plane-of-poly-local))
                               (a2-2 s1-0)
                               (t0-1 (vector-! (new 'stack-no-clear 'vector) v1-22 (-> s0-0 state mesh bounds)))
                               )
                          (t9-5 a0-15 s2-0 a2-2 sv-688 t0-1)
                          )
                        (vector+! s1-0 s1-0 (-> s0-0 state mesh bounds))
                        )
                      0
                      (set! (-> s5-0 y) (-> s3-0 y))
                      (when (enemy-above-ground? self s4-1 s5-0 (collide-spec backgnd) 8192.0 81920.0 1024.0)
                        (set! (-> s5-0 y) (-> s4-1 best-other-tri intersect y))
                        (set! gp-0 #t)
                        )
                      )
                    )
                  (set! (-> self jump-point quad) (-> s5-0 quad))
                  )
                )
              )
            )
          (set! f30-0 (+ 4096.0 f30-0))
          (when (< 61440.0 f30-0)
            (format #t "!!!!! Hosehead jump point not found~%")
            (set! gp-0 #t)
            )
          )
        )
      )
    )
  :code (behavior ()
    (set! (-> self come-from-notice) #t)
    (ja-channel-push! 1 (seconds 0.05))
    (until #f
      (ja-no-eval :group! hosehead-walk-wall-ja :num! (seek! max 1.5) :frame-num 0.0)
      (until (ja-done? 0)
        (set! (-> self root trans y) (- (-> self root trans y) (* 36864.0 (seconds-per-frame))))
        (hosehead-method-186 self)
        (suspend)
        (ja :num! (seek! max 1.5))
        )
      (when (< (- (-> self root trans y) (-> self jump-point y)) 40960.0)
        (hosehead-method-196 self)
        (set! (-> self enemy-flags)
              (the-as enemy-flag (logclear (-> self enemy-flags) (enemy-flag jump-check-blocked)))
              )
        (send-event self 'jump 0 (-> self jump-point))
        )
      (suspend)
      )
    #f
    )
  :post (behavior ()
    (nav-enemy-simple-post)
    )
  )

(defstate active (hosehead)
  :virtual #t
  :enter (behavior ()
    (if (-> self on-wall?)
        (go-virtual active-wall)
        )
    (let ((t9-1 (-> (method-of-type nav-enemy active) enter)))
      (if t9-1
          (t9-1)
          )
      )
    )
  )

(defstate knocked (hosehead)
  :virtual #t
  :enter (behavior ()
    (if (logtest? (enemy-option water) (-> self fact enemy-options))
        (logior! (-> self enemy-flags) (enemy-flag check-water check-water-backup))
        )
    (let ((t9-0 (-> (method-of-type nav-enemy knocked) enter)))
      (if t9-0
          (t9-0)
          )
      )
    )
  )

(defstate jump (hosehead)
  :virtual #t
  :enter (behavior ()
    (if (logtest? (enemy-option water) (-> self fact enemy-options))
        (logior! (-> self enemy-flags) (enemy-flag check-water check-water-backup))
        )
    (let ((t9-0 (-> (method-of-type nav-enemy jump) enter)))
      (if t9-0
          (t9-0)
          )
      )
    )
  )

(defmethod hosehead-method-195 ((this hosehead))
  (= *target* (handle->process (-> this focus handle)))
  )

(defstate fire (hosehead)
  :virtual #t
  :event enemy-event-handler
  :enter (behavior ()
    (rlet ((acc :class vf)
           (vf0 :class vf)
           (vf4 :class vf)
           (vf5 :class vf)
           (vf6 :class vf)
           (vf7 :class vf)
           )
      (init-vf0-vector)
      (logior! (-> self skel status) (joint-control-status sync-math))
      (logior! (-> self focus-status) (focus-status dangerous))
      (let* ((v1-5 *game-info*)
             (a0-2 (+ (-> v1-5 attack-id) 1))
             )
        (set! (-> v1-5 attack-id) a0-2)
        (set! (-> self attack-id) a0-2)
        )
      (set! (-> self fire-beam?) #f)
      (let ((gp-1 (vector-! (new 'stack-no-clear 'vector) (-> self target-pos) (-> self root trans)))
            (a2-0 (vector-x-quaternion! (new 'stack-no-clear 'vector) (-> self root quat)))
            (s5-0 (new 'stack-no-clear 'vector))
            )
        (set! (-> gp-1 y) 0.0)
        (let ((a1-1 s5-0))
          (let ((v1-8 (-> self target-pos)))
            (let ((a0-6 a2-0))
              (let ((a2-3 (the-as float (if (< 0.0 (vector-dot gp-1 a2-0))
                                            #x47200000
                                            -954204160
                                            )
                                  )
                          )
                    )
                (.mov vf7 a2-3)
                )
              (.lvf vf5 (&-> a0-6 quad))
              )
            (.lvf vf4 (&-> v1-8 quad))
            )
          (.add.x.vf.w vf6 vf0 vf0)
          (.mul.x.vf.xyz acc vf5 vf7)
          (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
          (.svf (&-> a1-1 quad) vf6)
          )
        (set! (-> self head-angle)
              (deg-diff
                (vector-y-angle gp-1)
                (vector-y-angle (vector-! (new 'stack-no-clear 'vector) s5-0 (-> self root trans)))
                )
              )
        )
      (set! (-> self head-angle-inc) (* -1.0 (-> self head-angle)))
      (if (not (hosehead-method-195 self))
          (go-hostile self)
          )
      (set! (-> self lazer-dist) 0.0)
      (set! (-> self lazer-length) 0.0)
      )
    )
  :exit (behavior ()
    (sound-stop (-> self lazer-sound))
    (sound-stop (-> self lazer-sound2))
    (logclear! (-> self skel status) (joint-control-status sync-math))
    (set! (-> self allow-head) #f)
    (set! (-> self fire-beam?) #f)
    (if (logtest? (-> self enemy-flags) (enemy-flag dangerous-backup))
        (logior! (-> self focus-status) (focus-status dangerous))
        (logclear! (-> self focus-status) (focus-status dangerous))
        )
    )
  :code (behavior ()
    (let ((f30-0 (rnd-float-range self 0.9 1.1)))
      (set! (-> self allow-head) #t)
      (ja-channel-push! 1 (seconds 0.1))
      (ja-no-eval :group! hosehead-shoot-start-ja :num! (seek! max f30-0) :frame-num 0.0)
      (until (ja-done? 0)
        (hosehead-method-189 self)
        (suspend)
        (ja :num! (seek! max f30-0))
        )
      (set! (-> self fire-beam?) #t)
      (let ((gp-0 (+ (current-time) (seconds 2))))
        (until #f
          (when (or (< gp-0 (current-time)) (not (-> self fire-beam?)) (not (enemy-method-96 self 8192.0 #t)))
            (set! (-> self fire-beam?) #f)
            (set! (-> self allow-head) #f)
            (goto cfg-13)
            )
          (suspend)
          (+! (-> self head-angle) (* (-> self head-angle-inc) (seconds-per-frame)))
          )
        )
      #f
      (label cfg-13)
      (sound-stop (-> self lazer-sound))
      (sound-stop (-> self lazer-sound2))
      (ja-no-eval :group! hosehead-shoot-end-ja :num! (seek! max f30-0) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek! max f30-0))
        )
      )
    (go-hostile self)
    )
  :post (behavior ()
    (enemy-simple-post)
    (if (-> self fire-beam?)
        (hosehead-method-197 self)
        )
    )
  )

(defstate attack (hosehead)
  :virtual #t
  :event enemy-event-handler
  :enter (behavior ()
    (logior! (-> self focus-status) (focus-status dangerous))
    (let* ((v1-2 *game-info*)
           (v0-0 (+ (-> v1-2 attack-id) 1))
           )
      (set! (-> v1-2 attack-id) v0-0)
      (set! (-> self attack-id) v0-0)
      )
    )
  :exit (behavior ()
    (if (logtest? (-> self enemy-flags) (enemy-flag dangerous-backup))
        (logior! (-> self focus-status) (focus-status dangerous))
        (logclear! (-> self focus-status) (focus-status dangerous))
        )
    )
  :code (behavior ()
    (ja-channel-push! 1 (seconds 0.2))
    (cond
      ((zero? (rnd-int-count self 2))
       (ja-no-eval :group! hosehead-attack1-ja :num! (seek!) :frame-num 0.0)
       (until (ja-done? 0)
         (suspend)
         (ja :num! (seek!))
         )
       )
      (else
        (ja-no-eval :group! hosehead-attack0-ja :num! (seek!) :frame-num 0.0)
        (until (ja-done? 0)
          (suspend)
          (ja :num! (seek!))
          )
        )
      )
    (if (logtest? (-> self enemy-flags) (enemy-flag dangerous-backup))
        (logior! (-> self focus-status) (focus-status dangerous))
        (logclear! (-> self focus-status) (focus-status dangerous))
        )
    (let ((v1-57 (rnd-int-count self 4)))
      (cond
        ((zero? v1-57)
         (ja-no-eval :group! hosehead-idle1-ja :num! (seek!) :frame-num 0.0)
         (until (ja-done? 0)
           (suspend)
           (ja :num! (seek!))
           )
         )
        ((= v1-57 1)
         (ja-no-eval :group! hosehead-idle2-ja :num! (seek!) :frame-num 0.0)
         (until (ja-done? 0)
           (suspend)
           (ja :num! (seek!))
           )
         )
        )
      )
    (go-hostile self)
    )
  :post enemy-simple-post
  )

(defstate hostile (hosehead)
  :virtual #t
  :enter (behavior ()
    (let ((t9-0 (-> (method-of-type nav-enemy hostile) enter)))
      (if t9-0
          (t9-0)
          )
      )
    (nav-enemy-method-166 self)
    (set-time! (-> self last-time-dist-changed))
    (set! (-> self next-lazer-time) 0)
    (set-time! (-> self state-time))
    )
  :exit (behavior ()
    (let ((t9-0 (-> (method-of-type nav-enemy hostile) exit)))
      (if t9-0
          (t9-0)
          )
      )
    (set! (-> self come-from-notice) #f)
    )
  :trans (behavior ()
    (let ((t9-0 (-> (method-of-type nav-enemy hostile) trans)))
      (if t9-0
          (t9-0)
          )
      )
    (hosehead-method-189 self)
    (let ((f30-0 (vector-vector-xz-distance (-> self target-pos) (-> self root trans))))
      (if (and (enemy-method-96 self 6371.5557 #t) (< f30-0 18432.0))
          (go-virtual attack)
          )
      (cond
        ((focus-test? self touch-water under-water)
         (set! (-> self next-lazer-time) 0)
         0
         )
        ((zero? (-> self next-lazer-time))
         (set! (-> self next-lazer-time) (+ (current-time) (the int (* 300.0 (rnd-float-range self 1.0 2.0)))))
         )
        ((>= (current-time) (-> self next-lazer-time))
         (if (and (enemy-method-96 self 3640.889 #t) (and (< 40960.0 f30-0) (hosehead-method-190 self)))
             (go-virtual fire)
             )
         )
        )
      )
    )
  :code (behavior ()
    (ja-channel-push! 1 (seconds 0.2))
    (if (zero? (rnd-int-count self 5))
        (ja :group! hosehead-run1-ja)
        (ja :group! hosehead-run-ja)
        )
    (ja :num-func num-func-identity :frame-num 0.0)
    (let ((f30-0 (rnd-float-range self 0.9 1.1)))
      (until #f
        (suspend)
        (ja :num! (loop! f30-0))
        )
      )
    #f
    )
  :post nav-enemy-chase-post
  )

(defstate notice (hosehead)
  :virtual #t
  :code (behavior ()
    (set! (-> self come-from-notice) #t)
    (ja-channel-push! 1 (seconds 0.075))
    (let ((f30-0 (rnd-float-range self 0.8 1.2)))
      (new 'stack-no-clear 'vector)
      (ja-no-eval :group! (-> self draw art-group data (-> self enemy-info notice-anim))
                  :num! (seek! max f30-0)
                  :frame-num 0.0
                  )
      (until (ja-done? 0)
        (let ((a0-4 (handle->process (-> self focus handle))))
          (if a0-4
              (seek-toward-heading-vec!
                (-> self root)
                (vector-! (new 'stack-no-clear 'vector) (get-trans (the-as process-focusable a0-4) 0) (-> self root trans))
                131072.0
                (seconds 0.05)
                )
              )
          )
        (suspend)
        (ja :num! (seek! max f30-0))
        )
      )
    (react-to-focus self)
    )
  )

(defstate debug-control (hosehead)
  :virtual #t
  :code (behavior ()
    (let ((v1-0 *nav-enemy-debug-control-info*))
      (set! (-> v1-0 steering) 0.0)
      (set! (-> v1-0 throttle) 0.0)
      )
    (ja-channel-push! 1 (seconds 0.2))
    (until #f
      (ja-no-eval :group! hosehead-run1-ja :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!))
        )
      )
    #f
    )
  )

(defmethod hosehead-method-187 ((this hosehead) (arg0 vector))
  (local-vars (sv-128 vector))
  (set! sv-128 (new 'stack-no-clear 'vector))
  (let ((s3-0 (new 'stack-no-clear 'vector))
        (s1-0 (new 'stack-no-clear 'vector))
        (s0-0 (new 'stack-no-clear 'vector))
        (s4-0 (new 'stack-no-clear 'vector))
        (s5-0 (new 'stack-no-clear 'vector))
        )
    (let ((a0-1 (-> this node-list data 9 bone transform)))
      (matrix->trans a0-1 s1-0)
      )
    (vector-z-quaternion! s0-0 (-> this root quat))
    (vector-! sv-128 arg0 s1-0)
    (vector-normalize! sv-128 1.0)
    (rot-zxy-from-vector! s4-0 s0-0)
    (rot-zxy-from-vector! s3-0 sv-128)
    (set! (-> s5-0 x) (fmax -1820.4445 (fmin 1820.4445 (deg- (-> s3-0 x) (-> s4-0 x)))))
    (set! (-> s5-0 y) (fmax -3640.889 (fmin 3640.889 (deg- (-> s3-0 y) (-> s4-0 y)))))
    (set! (-> s5-0 z) 0.0)
    (if (not (logtest? (enemy-flag drawn-mirrored) (-> this enemy-flags)))
        (set! (-> s5-0 y) (- (-> s5-0 y)))
        )
    (+! (-> s5-0 y) (-> this head-angle))
    (let ((s4-1 (new 'stack-no-clear 'quaternion)))
      (quaternion-zxy! s4-1 s5-0)
      (quaternion-pseudo-seek (-> this head-joint-mod quat) (-> this head-joint-mod quat) s4-1 (seconds-per-frame))
      )
    )
  0
  (none)
  )

;; WARN: Return type mismatch quaternion vs none.
(defmethod hosehead-method-188 ((this hosehead))
  (let ((gp-0 (new 'stack-no-clear 'quaternion)))
    (quaternion-identity! gp-0)
    (quaternion-pseudo-seek (-> this head-joint-mod quat) (-> this head-joint-mod quat) gp-0 (seconds-per-frame))
    )
  (none)
  )

(defmethod common-post ((this hosehead))
  "Does a lot of various things relating to interacting with the target
   - tracks when the enemy was last drawn
   - looks at the target and handles attacking
   @TODO Not extremely well understood yet"
  (let ((t9-0 (method-of-type nav-enemy common-post)))
    (t9-0 this)
    )
  (hosehead-method-194 this)
  (dotimes (s5-0 4)
    (enable-set! (-> this joint-ik s5-0) #t)
    )
  (let ((v1-11 (handle->process (-> this focus handle))))
    (if (and (-> this allow-head) v1-11)
        (hosehead-method-187 this (-> this target-pos))
        (hosehead-method-188 this)
        )
    )
  (none)
  )

(defmethod hosehead-method-194 ((this hosehead))
  (rlet ((acc :class vf)
         (vf0 :class vf)
         (vf4 :class vf)
         (vf5 :class vf)
         (vf6 :class vf)
         (vf7 :class vf)
         )
    (init-vf0-vector)
    (let ((s5-0 (new 'stack-no-clear 'collide-query)))
      (let ((v1-0 (-> s5-0 bbox))
            (a0-2 (-> this root trans))
            (a1-0 (new 'stack-no-clear 'vector))
            )
        (set! (-> a1-0 x) 14336.0)
        (set! (-> a1-0 y) 14336.0)
        (set! (-> a1-0 z) 14336.0)
        (set! (-> a1-0 w) 1.0)
        (vector-! (the-as vector v1-0) a0-2 a1-0)
        )
      (let ((v1-2 (-> s5-0 bbox max))
            (a0-4 (-> this root trans))
            (a1-1 (new 'stack-no-clear 'vector))
            )
        (set! (-> a1-1 x) 14336.0)
        (set! (-> a1-1 y) 14336.0)
        (set! (-> a1-1 z) 14336.0)
        (set! (-> a1-1 w) 1.0)
        (vector+! v1-2 a0-4 a1-1)
        )
      (set! (-> s5-0 collide-with) (collide-spec backgnd))
      (set! (-> s5-0 ignore-process0) #f)
      (set! (-> s5-0 ignore-process1) #f)
      (set! (-> s5-0 ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1))
      (fill-using-bounding-box *collide-cache* s5-0)
      (dotimes (s4-0 4)
        (-> this joint-ik s4-0 shoulder-matrix-no-ik)
        (let ((a2-8 (-> this joint-ik s4-0 elbow-matrix-no-ik))
              (v1-15 (new 'stack-no-clear 'vector))
              (s3-0 (new 'stack-no-clear 'vector))
              )
          (set! (-> s3-0 quad) (-> this node-list data 3 bone transform vector 1 quad))
          (new 'stack-no-clear 'vector)
          (let ((s2-0 (new 'stack-no-clear 'vector)))
            (let ((a1-3 v1-15))
              (let ((a0-11 (-> a2-8 trans)))
                (let ((a2-9 (-> a2-8 vector 1)))
                  (let ((a3-2 (-> *hosehead-ik-setup* s4-0 hand-dist)))
                    (.mov vf7 a3-2)
                    )
                  (.lvf vf5 (&-> a2-9 quad))
                  )
                (.lvf vf4 (&-> a0-11 quad))
                )
              (.add.x.vf.w vf6 vf0 vf0)
              (.mul.x.vf.xyz acc vf5 vf7)
              (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
              (.svf (&-> a1-3 quad) vf6)
              )
            (set! (-> s2-0 quad) (-> v1-15 quad))
            (let ((a1-4 (-> s5-0 start-pos)))
              (let ((v1-17 s2-0))
                (let ((a0-13 s3-0))
                  (let ((a2-11 12288.0))
                    (.mov vf7 a2-11)
                    )
                  (.lvf vf5 (&-> a0-13 quad))
                  )
                (.lvf vf4 (&-> v1-17 quad))
                )
              (.add.x.vf.w vf6 vf0 vf0)
              (.mul.x.vf.xyz acc vf5 vf7)
              (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
              (.svf (&-> a1-4 quad) vf6)
              )
            (vector-float*! (-> s5-0 move-dist) s3-0 -24576.0)
            (let ((v1-20 s5-0))
              (set! (-> v1-20 radius) 40.96)
              (set! (-> v1-20 collide-with) (collide-spec backgnd))
              (set! (-> v1-20 ignore-process0) #f)
              (set! (-> v1-20 ignore-process1) #f)
              (set! (-> v1-20 ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1))
              (set! (-> v1-20 action-mask) (collide-action solid))
              )
            (let ((f0-12 (probe-using-line-sphere *collide-cache* s5-0)))
              (when (>= f0-12 0.0)
                (let ((s1-0 (new 'stack-no-clear 'vector)))
                  (let ((v1-24 (-> s5-0 start-pos)))
                    (let ((a0-20 (-> s5-0 move-dist)))
                      (let ((a1-7 f0-12))
                        (.mov vf7 a1-7)
                        )
                      (.lvf vf5 (&-> a0-20 quad))
                      )
                    (.lvf vf4 (&-> v1-24 quad))
                    )
                  (.add.x.vf.w vf6 vf0 vf0)
                  (.mul.x.vf.xyz acc vf5 vf7)
                  (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
                  (.svf (&-> s1-0 quad) vf6)
                  (let* ((f0-14 (- (-> s2-0 y) (-> s1-0 y)))
                         (f0-15 (lerp-scale 1.0 0.0 f0-14 0.0 8192.0))
                         )
                    (- (-> s1-0 y) (-> this root trans y))
                    (let ((f1-5 (vector-dot s3-0 (vector-! (new 'stack-no-clear 'vector) s1-0 (-> this root trans))))
                          (v1-29 s2-0)
                          )
                      (let ((a0-23 s2-0))
                        (let ((a1-11 (* f0-15 f1-5)))
                          (.mov vf7 a1-11)
                          )
                        (.lvf vf5 (&-> s3-0 quad))
                        (.lvf vf4 (&-> a0-23 quad))
                        )
                      (.add.x.vf.w vf6 vf0 vf0)
                      (.mul.x.vf.xyz acc vf5 vf7)
                      (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
                      (.svf (&-> v1-29 quad) vf6)
                      )
                    )
                  )
                )
              )
            (handle-copy! (-> this joint-ik s4-0) s2-0)
            )
          )
        )
      )
    0
    (none)
    )
  )

;; WARN: Return type mismatch symbol vs none.
(defmethod set-incoming-attack-info ((this hosehead) (arg0 process) (arg1 object) (arg2 penetrate) (arg3 attack-info))
  (let ((t9-0 (method-of-type nav-enemy set-incoming-attack-info)))
    (t9-0 this arg0 arg1 arg2 arg3)
    )
  (let ((a1-3 (get-attacker this arg0 arg3)))
    (if (and a1-3 (logtest? (process-mask bot) (-> a1-3 mask)))
        (set! (-> this shot-by-ruffian?) #t)
        (set! (-> this shot-by-ruffian?) #f)
        )
    )
  (none)
  )

(defmethod damage-amount-from-attack ((this hosehead) (arg0 process) (arg1 event-message-block))
  "@returns the amount of damage taken from an attack.  This can come straight off the [[attack-info]] or via [[penetrate-using->damage]]"
  (let* ((t9-0 (method-of-type nav-enemy damage-amount-from-attack))
         (v0-0 (t9-0 this arg0 arg1))
         )
    (if (-> this shot-by-ruffian?)
        (set! v0-0 0)
        )
    v0-0
    )
  )

(defmethod enemy-method-58 ((this hosehead) (arg0 process) (arg1 event-message-block))
  (let* ((t9-0 (method-of-type nav-enemy enemy-method-58))
         (v0-0 (t9-0 this arg0 arg1))
         )
    (if (and (-> this sentry?) (nonzero? (-> this hit-points)) (zero? (-> this fated-time)))
        (set! v0-0 'hit)
        )
    v0-0
    )
  )

(defmethod relocate ((this hosehead) (offset int))
  (if (nonzero? (-> this head-joint-mod))
      (&+! (-> this head-joint-mod) offset)
      )
  (dotimes (v1-4 4)
    (if (nonzero? (-> this joint-ik v1-4))
        (&+! (-> this joint-ik v1-4) offset)
        )
    )
  (call-parent-method this offset)
  )

(defmethod init-enemy! ((this hosehead))
  "Common method called to initialize the enemy, typically sets up default field values and calls ancillary helper methods"
  (local-vars (sv-16 res-tag) (sv-32 res-tag))
  (stack-size-set! (-> this main-thread) 256)
  (set! (-> this on-stop-sentry) #f)
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-hosehead" (the-as (pointer uint32) #f)))
    (the-as pair 0)
    )
  (set! sv-16 (new 'static 'res-tag))
  (let ((a0-5 (res-lump-data (-> this entity) 'trans-offset (pointer float) :tag-ptr (& sv-16))))
    (when a0-5
      (let ((v1-7 (-> this root)))
        (+! (-> v1-7 trans x) (-> a0-5 0))
        (+! (-> v1-7 trans y) (-> a0-5 1))
        (+! (-> v1-7 trans z) (-> a0-5 2))
        )
      )
    )
  (let ((f0-6 (res-lump-float (-> this entity) 'rotoffset)))
    (if (!= f0-6 0.0)
        (quaternion-rotate-local-y! (-> this root quat) (-> this root quat) f0-6)
        )
    )
  (let ((f0-7 (res-lump-float (-> this entity) 'extra-float-param :default 30.0)))
    (set! (-> this angle-sentry) (* 182.04445 f0-7))
    )
  (set! (-> this on-wall?) #f)
  (when (>= (res-lump-value (-> this entity) 'extra-id int :default (the-as uint128 -1) :time -1000000000.0) 0)
    (set! (-> this on-wall?) #t)
    (set! (-> this enemy-flags)
          (the-as enemy-flag (logior (enemy-flag no-initial-move-to-ground) (-> this enemy-flags)))
          )
    )
  (init-enemy-behaviour-and-stats! this *hosehead-nav-enemy-info*)
  (set! (-> this sentry?) (logtest? (-> this fact enemy-options) (enemy-option user9)))
  (when (-> this sentry?)
    (set! (-> this root pause-adjust-distance) 409600.0)
    (set! (-> this on-stop-sentry) (res-lump-struct (-> this entity) 'on-stop-sentry function))
    )
  (let ((v1-34 (-> this nav)))
    (set! (-> v1-34 speed-scale) 1.0)
    )
  0
  (set-gravity-length (-> this root dynam) 327680.0)
  (add-connection
    *part-engine*
    this
    9
    this
    318
    (new 'static 'vector :x 2048.0 :y -40.96 :z 1392.64 :w 163840.0)
    )
  (add-connection
    *part-engine*
    this
    9
    this
    318
    (new 'static 'vector :x -2048.0 :y -40.96 :z 1392.64 :w 163840.0)
    )
  (if (-> this on-wall?)
      (idle-control-method-9 (-> this idle-anim-player) *hosehead-idle-wall*)
      (idle-control-method-9 (-> this idle-anim-player) *hosehead-idle-ground*)
      )
  (set! sv-32 (new 'static 'res-tag))
  (let ((v1-49 (res-lump-data (-> this entity) 'actor-groups pointer :tag-ptr (& sv-32))))
    (cond
      ((and v1-49 (nonzero? (-> sv-32 elt-count)))
       (set! (-> this actor-group) (the-as (pointer actor-group) v1-49))
       (set! (-> this actor-group-count) (the-as int (-> sv-32 elt-count)))
       )
      (else
        (set! (-> this actor-group) (the-as (pointer actor-group) #f))
        (set! (-> this actor-group-count) 0)
        (go process-drawable-art-error "actor-group sewesc")
        )
      )
    )
  (set! (-> this head-joint-mod) (new 'process 'joint-mod (joint-mod-mode joint-set*) this 9))
  (dotimes (s5-1 4)
    (set! (-> this joint-ik s5-1) (new
                                    'process
                                    'joint-mod-ik
                                    this
                                    (-> *hosehead-ik-setup* s5-1 elbow-index)
                                    (-> *hosehead-ik-setup* s5-1 hand-dist)
                                    )
          )
    (set! (-> this joint-ik s5-1 elbow-pole-vector-axis) (the-as uint 2))
    (set! (-> this joint-ik s5-1 elbow-rotation-axis) (the-as uint 0))
    )
  (logior! (-> this joint-ik 0 flags) (joint-mod-ik-flags elbow-trans-neg))
  (logior! (-> this joint-ik 2 flags) (joint-mod-ik-flags elbow-trans-neg))
  (set! (-> this come-from-notice) #t)
  (set! (-> this lazer-sound) (new-sound-id))
  (set! (-> this lazer-sound2) (new-sound-id))
  (let ((a1-22 (new 'stack-no-clear 'sync-info-params)))
    (let ((v1-77 0))
      (if #t
          (set! v1-77 (logior v1-77 1))
          )
      (set! (-> a1-22 sync-type) 'sync-eased)
      (set! (-> a1-22 sync-flags) (the-as sync-flags v1-77))
      )
    (set! (-> a1-22 period) (the-as uint 1200))
    (set! (-> a1-22 entity) (-> this entity))
    (set! (-> a1-22 percent) 0.0)
    (set! (-> a1-22 ease-in) 0.15)
    (set! (-> a1-22 ease-out) 0.15)
    (set! (-> a1-22 pause-in) 0.0)
    (set! (-> a1-22 pause-out) 0.0)
    (initialize! (-> this sync) a1-22)
    )
  0
  (none)
  )

(defmethod go-ambush ((this hosehead))
  (go (method-of-object this ambush))
  )

(defmethod go-hostile ((this hosehead))
  (if (-> this sentry?)
      (go (method-of-object this hostile-sentry))
      (go (method-of-object this hostile))
      )
  )

;; WARN: Return type mismatch object vs none.
(defmethod go-idle ((this hosehead))
  (if (-> this sentry?)
      (go (method-of-object this idle-sentry))
      (go (method-of-object this idle))
      )
  (none)
  )
