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

;; name: bot.gc
;; name in dgo: bot
;; dgos: DESOASIS

;; DECOMP BEGINS

(defmethod run-logic? ((this bot))
  "Should this process be run? Checked by execute-process-tree."
  #t
  )

(defmethod debug-draw-spot ((this bot) (arg0 bot-spot) (arg1 rgba))
  (add-debug-sphere #t (bucket-id debug) (-> arg0 center) (-> arg0 center w) arg1)
  )

(defmethod bot-method-198 ((this bot) (arg0 int) (arg1 (pointer uint8)) (arg2 int))
  (let* ((s2-0 (-> this spot-color))
         (s1-0 s2-0)
         )
    (if (>= arg2 0)
        (set! s1-0 (logior (logand (the-as uint #xffffff) s2-0)
                           (shl (the-as uint (the int (* 0.375 (the float (logand (shr s2-0 24) 255))))) 24)
                           )
              )
        )
    (dotimes (s0-0 arg0)
      (let* ((v1-5 (-> arg1 s0-0))
             (a1-2 (-> this course spots v1-5))
             )
        (debug-draw-spot this a1-2 (if (= v1-5 arg2)
                                       (the-as rgba s2-0)
                                       (the-as rgba s1-0)
                                       )
                         )
        )
      )
    )
  #f
  )

;; WARN: Return type mismatch symbol vs none.
(defmethod bot-method-196 ((this bot))
  (let ((s5-0 (-> this course)))
    (countdown (s4-0 (-> s5-0 spot-count))
      (let ((s3-0 (-> s5-0 spots s4-0)))
        (debug-draw-spot this s3-0 (the-as rgba (-> this spot-color)))
        (format (clear *temp-string*) "~d" s4-0)
        (let ((a2-2 *temp-string*))
          (add-debug-text-3d
            #t
            (bucket-id debug-no-zbuf1)
            a2-2
            (-> s3-0 center)
            (font-color white)
            (the-as vector2h #f)
            )
          )
        )
      )
    )
  (none)
  )

(defmethod outside-spot-radius? ((this bot) (arg0 bot-spot) (arg1 vector) (arg2 symbol))
  (if (not arg0)
      (set! arg0 (-> this spot))
      )
  (if (not arg1)
      (set! arg1 (-> this root trans))
      )
  (let ((f0-0 (vector-vector-xz-distance (-> arg0 center) arg1)))
    (if arg2
        (set! f0-0 (+ 819.2 f0-0))
        )
    (>= (-> arg0 center w) f0-0)
    )
  )

(defmethod player-blocking-spot? ((this bot) (arg0 bot-spot))
  (let ((f0-0 (-> arg0 blocked-xz-dist)))
    (and (!= f0-0 0.0) (>= (* f0-0 f0-0) (vector-vector-xz-distance-squared (target-pos 0) (-> arg0 center))))
    )
  )

(defmethod choose-spot ((this bot) (arg0 int) (arg1 (pointer uint8)))
  (let ((gp-0 0))
    (let ((f30-0 -1.0)
          (s3-0 (-> this root trans))
          )
      (countdown (s2-0 arg0)
        (let ((s1-0 (-> this course spots (-> arg1 s2-0))))
          (when (not (player-blocking-spot? this s1-0))
            (let ((f0-0 (vector-vector-xz-distance s3-0 (-> s1-0 center))))
              (when (or (< f30-0 0.0) (< f0-0 f30-0))
                (set! f30-0 f0-0)
                (set! gp-0 s2-0)
                )
              )
            )
          )
        )
      )
    gp-0
    )
  )

(defmethod find-and-damage-attackers ((this bot) (arg0 process-focusable) (arg1 event-message-block))
  "Find things that have attacked us, then deal damage back.
   This is used for attacks that damage both the player and the enemy,
   like hitting a guard with a jetboard."
  0
  )

;; WARN: Return type mismatch symbol vs none.
(defmethod bot-method-199 ((this bot))
  (logclear! (-> this bot-flags) (bot-flag attacked))
  (let ((v1-5 (as-type (handle->process (-> this attacker-handle)) process-focusable)))
    (if (and v1-5 (= (-> v1-5 type) target))
        (set! (-> this attacker-handle) (the-as handle #f))
        )
    )
  (none)
  )

(defmethod bot-method-205 ((this bot))
  (let ((gp-0 #f))
    (let ((v1-0 (-> this incoming penetrate-using)))
      (cond
        ((logtest? (penetrate jak-red-shot) v1-0)
         (when *target*
           (let ((s5-0 (new 'stack-no-clear 'vector))
                 (s3-0 (-> *target* gun fire-dir-out))
                 )
             (vector-! s5-0 (-> this root trans) (target-pos 0))
             (set! (-> s5-0 y) 0.0)
             (vector-normalize! s5-0 1.0)
             (set! (-> s3-0 y) 0.0)
             (vector-normalize! s3-0 1.0)
             (if (or (< 28672.0 (vector-vector-xz-distance (-> this root trans) (target-pos 0)))
                     (< (vector-dot s3-0 s5-0) (cos 3640.889))
                     )
                 (set! gp-0 #t)
                 )
             )
           )
         )
        ((and (logtest? (penetrate dark-skin) v1-0) (not (logtest? (penetrate dark-punch) v1-0)))
         (set! gp-0 #t)
         )
        )
      )
    gp-0
    )
  )

(defmethod bot-method-202 ((this bot))
  (local-vars (a2-5 float) (a2-12 float))
  (rlet ((vf1 :class vf)
         (vf2 :class vf)
         (vf3 :class vf)
         )
    (cond
      ((< 0.0 (-> this notice-enemy-dist))
       (let ((s5-0 (new 'stack-no-clear 'connection-pers))
             (cspec (collide-spec enemy hit-by-others-list))
             )
         (set! (-> (the-as sphere (-> s5-0 param)) quad) (-> this root trans quad))
         (set! (-> s5-0 param 3) (-> this notice-enemy-dist))
         (set! (-> s5-0 next) #f)
         (set! (-> s5-0 key) 409600000.0)
         (set! (-> s5-0 update-time) 0)
         (set! *actor-list-length* 0)
         (if (logtest? (the-as int cspec) (collide-spec hit-by-others-list))
             (set! *actor-list-length*
                   (fill-actor-list-for-box *actor-hash* (the-as vector (-> s5-0 param)) *actor-list* 256)
                   )
             )
         (when (logtest? (the-as int cspec) (collide-spec player-list))
           (let ((a0-5 (-> *collide-player-list* alive-list next0)))
             *collide-player-list*
             (let ((v1-13 (-> a0-5 next0)))
               (while (!= a0-5 (-> *collide-player-list* alive-list-end))
                 (let* ((a0-6 (-> (the-as connection a0-5) param1))
                        (a1-1 (-> (the-as collide-shape a0-6) root-prim))
                        )
                   (when (logtest? (the-as int cspec) (-> a1-1 prim-core collide-as))
                     (let ((a1-2 (-> a1-1 prim-core)))
                       (let ((a2-4 a1-2)
                             (a3-1 (the-as object (-> s5-0 param)))
                             )
                         (.lvf vf2 (&-> a2-4 world-sphere quad))
                         (.lvf vf3 (&-> (the-as sphere 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-5 vf1)
                       (let ((f0-3 a2-5)
                             (f1-2 (+ (-> a1-2 world-sphere w) (the-as float (-> s5-0 param 3))))
                             )
                         (when (< f0-3 (* f1-2 f1-2))
                           (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-13)
                 *collide-player-list*
                 (set! v1-13 (-> v1-13 next0))
                 )
               )
             )
           )
         (when (logtest? (the-as int cspec) (collide-spec hit-by-player-list))
           (let ((a0-8 (-> *collide-hit-by-player-list* alive-list next0)))
             *collide-hit-by-player-list*
             (let ((v1-21 (-> a0-8 next0)))
               (while (!= a0-8 (-> *collide-hit-by-player-list* alive-list-end))
                 (let* ((a0-9 (-> (the-as connection a0-8) param1))
                        (a1-13 (-> (the-as collide-shape a0-9) root-prim))
                        )
                   (when (logtest? (the-as int cspec) (-> a1-13 prim-core collide-as))
                     (let ((a1-14 (-> a1-13 prim-core)))
                       (let ((a2-11 a1-14)
                             (a3-2 (the-as object (-> s5-0 param)))
                             )
                         (.lvf vf2 (&-> a2-11 world-sphere quad))
                         (.lvf vf3 (&-> (the-as sphere 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-12 vf1)
                       (let ((f0-4 a2-12)
                             (f1-6 (+ (-> a1-14 world-sphere w) (the-as float (-> s5-0 param 3))))
                             )
                         (when (< f0-4 (* f1-6 f1-6))
                           (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-21)
                 *collide-hit-by-player-list*
                 (set! v1-21 (-> v1-21 next0))
                 )
               )
             )
           )
         (dotimes (s3-0 *actor-list-length*)
           (let ((v1-26 (-> *actor-list* s3-0)))
             (when (logtest? (the-as int cspec) (-> v1-26 root-prim prim-core collide-as))
               (let ((a1-26 (as-type (-> v1-26 process) process-focusable)))
                 (when a1-26
                   (set-next-focus! this (the-as enemy a1-26) (the-as enemy-best-focus (&-> s5-0 next)))
                   (if (-> s5-0 next)
                       (return #t)
                       )
                   )
                 )
               )
             )
           )
         )
       #f
       )
      (else
        #f
        )
      )
    )
  )

(defmethod handle-incoming-attack! ((this bot)
                                   (arg0 process-drawable)
                                   (arg1 event-message-block)
                                   (arg2 penetrate)
                                   (arg3 attack-info)
                                   (arg4 touching-shapes-entry)
                                   )
  "Set up this enemy to handle an incoming attack event."
  (let ((t9-0 (method-of-type nav-enemy handle-incoming-attack!)))
    (t9-0 this arg0 arg1 arg2 arg3 arg4)
    )
  (logclear! (-> this bot-flags) (bot-flag bf03 bf04))
  (let ((s5-0 (as-type (handle->process (-> this incoming attacker-handle)) process-focusable)))
    (when s5-0
      (cond
        ((= (-> s5-0 type) target)
         (logior! (-> this bot-flags) (bot-flag bf04))
         (cond
           ((bot-method-205 this)
            (logior! (-> this bot-flags) (bot-flag bf03))
            )
           (else
             (+! (-> this hit-by-player-count) 1)
             (when (not (bot-method-202 this))
               (logior! (-> this bot-flags) (bot-flag attacked))
               (cond
                 ((attacked-by-player? this (the-as process-focusable s5-0))
                  (set! (-> this attacker-handle) (process->handle s5-0))
                  (set-time! (-> this attacker-time))
                  )
                 (else
                   (logclear! (-> this bot-flags) (bot-flag attacked))
                   )
                 )
               )
             )
           )
         )
        ((type? s5-0 enemy)
         (+! (-> this hit-by-enemy-count) 1)
         (when (attacked-by-player? this (the-as process-focusable s5-0))
           (if (logtest? (-> this bot-flags) (bot-flag attacked))
               (bot-method-199 this)
               )
           (set! (-> this attacker-handle) (process->handle s5-0))
           (set-time! (-> this attacker-time))
           )
         )
        )
      )
    )
  (none)
  )

(defmethod get-damage-from-attack ((this bot) (arg0 object) (arg1 event-message-block))
  "Compute hit point damage for an attack message."
  (let* ((t9-0 (method-of-type nav-enemy get-damage-from-attack))
         (v0-0 (t9-0 this arg0 arg1))
         (v1-1 (-> this bot-flags))
         )
    (cond
      ((logtest? v1-1 (bot-flag bf03 too-far-fail bf09))
       0.0
       )
      ((logtest? v1-1 (bot-flag bf10))
       (-> this hit-points)
       )
      (else
        (if (and (logtest? (-> this bot-flags) (bot-flag bf04)) (not (logtest? (-> this bot-flags) (bot-flag attacked))))
            (set! v0-0 0.0)
            )
        v0-0
        )
      )
    )
  )

(defmethod msg-for-incoming-attack ((this bot) (arg0 process) (arg1 event-message-block) (arg2 float))
  "Given an attack message, what do we do next? Returns a message name that should be sent to self."
  (let* ((t9-0 (method-of-type nav-enemy msg-for-incoming-attack))
         (v0-0 (t9-0 this arg0 arg1 arg2))
         )
    (if (logtest? (-> this bot-flags) (bot-flag bf03))
        (set! v0-0 #f)
        )
    v0-0
    )
  )

(defmethod clear-poi ((this bot))
  (let ((s5-0 (as-type (handle->process (-> this poi-handle)) process-focusable)))
    (when s5-0
      (set! (-> this poi-handle) (the-as handle #f))
      (if (= (as-type (handle->process (-> this focus handle)) process-focusable) s5-0)
          (clear-focused (-> this focus))
          )
      )
    )
  (none)
  )

(defmethod attacked-by-player? ((this bot) (arg0 process-focusable))
  (and (and arg0 (not (logtest? (-> arg0 focus-status) (focus-status disable dead ignore grabbed))))
       (or (logtest? (process-mask enemy) (-> arg0 mask))
           (and (logtest? (-> arg0 mask) (process-mask target)) (logtest? (-> this bot-flags) (bot-flag attacked)))
           )
       )
  )

;; WARN: Return type mismatch int vs enemy-aware.
(defmethod get-awareness-of-proc ((this bot) (arg0 process-focusable) (arg1 enemy-best-focus))
  "Check what the enemies awareness of this pfoc would be. Optionally return more awareness stats in enemy-best-focus."
  (the-as enemy-aware 3)
  )

;; WARN: Return type mismatch int vs enemy-aware.
(defmethod modify-awareness ((this bot) (arg0 enemy-aware))
  "Apply modifications to awareness based on the reaction time of an enemy and other settings."
  (the-as enemy-aware 3)
  )

;; WARN: Return type mismatch object vs process.
(defmethod update-focus ((this bot))
  "Potentially update the focus, if there is something better to focus on."
  (local-vars (s5-1 process))
  (let ((s5-0 (-> this focus)))
    (cond
      ((logtest? (enemy-flag lock-focus) (-> this enemy-flags))
       (set! s5-1 (handle->process (-> s5-0 handle)))
       )
      (else
        (find-best-focus this)
        (set! s5-1 (handle->process (-> s5-0 handle)))
        )
      )
    )
  (let ((s4-0 #f))
    (when (or (logtest? (bot-flag bf18) (-> this bot-flags))
              (and (the-as process-focusable s5-1) (attacked-by-player? this (the-as process-focusable s5-1)))
              )
      (set-time! (-> this danger-time))
      (set! s4-0 #t)
      )
    (the-as
      process
      (when (nonzero? (-> this swivel-joint-mod))
        (if (and s4-0 (the-as process-focusable s5-1) (logtest? (-> this bot-flags) (bot-flag bf11)))
            (bot-method-234 this (get-trans (the-as process-focusable s5-1) 3))
            (bot-method-233 this)
            )
        )
      )
    )
  )

(defmethod find-best-focus ((this bot))
  "Search for the best thing to focus on."
  (let ((v1-3 (as-type (handle->process (-> this attacker-handle)) process-focusable)))
    (when v1-3
      (cond
        ((= (-> v1-3 type) target)
         (when (or (not (logtest? (-> this bot-flags) (bot-flag attacked)))
                   (time-elapsed? (-> this attacker-time) (seconds 1.5))
                   )
           (if (logtest? (-> this bot-flags) (bot-flag attacked))
               (bot-method-199 this)
               )
           (set! v1-3 (the-as process-focusable #f))
           (set! (-> this attacker-handle) (the-as handle #f))
           )
         )
        (else
          (when (time-elapsed? (-> this attacker-time) (seconds 6))
            (set! v1-3 (the-as process-focusable #f))
            (set! (-> this attacker-handle) (the-as handle #f))
            )
          )
        )
      )
    (let ((a0-21 (-> this focus-mode))
          (s5-1 (the-as process #f))
          )
      (cond
        ((zero? a0-21)
         (cond
           (v1-3
             (set! s5-1 v1-3)
             )
           ((begin (set! s5-1 (bot-method-201 this)) s5-1)
            (empty)
            )
           (else
             (set! s5-1 (as-type (handle->process (-> this poi-handle)) process-focusable))
             (if s5-1
                 (empty)
                 (set! s5-1 *target*)
                 )
             )
           )
         )
        ((= a0-21 1)
         (cond
           (v1-3
             (set! s5-1 v1-3)
             )
           (else
             (set! s5-1 (as-type (handle->process (-> this poi-handle)) process-focusable))
             (cond
               (s5-1
                 (empty)
                 )
               ((begin (set! s5-1 (bot-method-201 this)) s5-1)
                (empty)
                )
               (else
                 (set! s5-1 *target*)
                 )
               )
             )
           )
         )
        )
      (cond
        (s5-1
          (focus-on! (-> this focus) (the-as process-focusable s5-1) this)
          (if (and (logtest? (-> this bot-flags) (bot-flag attacked)) (!= (-> s5-1 type) target))
              (logclear! (-> this bot-flags) (bot-flag attacked))
              )
          )
        (else
          (clear-focused (-> this focus))
          (logclear! (-> this bot-flags) (bot-flag attacked))
          )
        )
      s5-1
      )
    )
  )

(defmethod bot-method-201 ((this bot))
  (local-vars (a2-5 float) (a2-12 float))
  (rlet ((vf1 :class vf)
         (vf2 :class vf)
         (vf3 :class vf)
         )
    (let ((s4-0 544)
          (gp-0 (new 'stack-no-clear 'enemy-best-focus))
          )
      (let ((s3-0 (new 'stack-no-clear 'vector))
            (f0-0 (-> this notice-enemy-dist))
            )
        (set! (-> gp-0 proc) #f)
        (set! (-> gp-0 rating) 409600000.0)
        (set! (-> gp-0 aware) (enemy-aware unaware))
        (when (< 0.0 f0-0)
          (vector-copy! s3-0 (-> this root trans))
          (set! (-> s3-0 w) (-> this notice-enemy-dist))
          (set! *actor-list-length* 0)
          (if (logtest? s4-0 512)
              (set! *actor-list-length* (fill-actor-list-for-box *actor-hash* s3-0 *actor-list* 256))
              )
          (when (logtest? s4-0 1024)
            (let ((a0-5 (-> *collide-player-list* alive-list next0)))
              *collide-player-list*
              (let ((v1-14 (-> a0-5 next0)))
                (while (!= a0-5 (-> *collide-player-list* alive-list-end))
                  (let* ((a0-6 (-> (the-as connection a0-5) param1))
                         (a1-1 (-> (the-as collide-shape a0-6) root-prim))
                         )
                    (when (logtest? (the-as collide-spec s4-0) (-> a1-1 prim-core collide-as))
                      (let ((a1-2 (-> a1-1 prim-core)))
                        (let ((a2-4 a1-2)
                              (a3-1 s3-0)
                              )
                          (.lvf vf2 (&-> a2-4 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-5 vf1)
                        (let ((f0-2 a2-5)
                              (f1-3 (+ (-> a1-2 world-sphere w) (-> s3-0 w)))
                              )
                          (when (< f0-2 (* f1-3 f1-3))
                            (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-14)
                  *collide-player-list*
                  (set! v1-14 (-> v1-14 next0))
                  )
                )
              )
            )
          (when (logtest? s4-0 256)
            (let ((a0-8 (-> *collide-hit-by-player-list* alive-list next0)))
              *collide-hit-by-player-list*
              (let ((v1-22 (-> a0-8 next0)))
                (while (!= a0-8 (-> *collide-hit-by-player-list* alive-list-end))
                  (let* ((a0-9 (-> (the-as connection a0-8) param1))
                         (a1-13 (-> (the-as collide-shape a0-9) root-prim))
                         )
                    (when (logtest? (the-as collide-spec s4-0) (-> a1-13 prim-core collide-as))
                      (let ((a1-14 (-> a1-13 prim-core)))
                        (let ((a2-11 a1-14)
                              (a3-2 s3-0)
                              )
                          (.lvf vf2 (&-> a2-11 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-12 vf1)
                        (let ((f0-3 a2-12)
                              (f1-7 (+ (-> a1-14 world-sphere w) (-> s3-0 w)))
                              )
                          (when (< f0-3 (* f1-7 f1-7))
                            (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-22)
                  *collide-hit-by-player-list*
                  (set! v1-22 (-> v1-22 next0))
                  )
                )
              )
            )
          (dotimes (s3-1 *actor-list-length*)
            (let ((v1-27 (-> *actor-list* s3-1)))
              (when (logtest? (the-as collide-spec s4-0) (-> v1-27 root-prim prim-core collide-as))
                (let ((a1-26 (as-type (-> v1-27 process) process-focusable)))
                  (if (and a1-26
                           a1-26
                           (not (logtest? (-> (the-as process-focusable a1-26) focus-status) (focus-status disable dead)))
                           )
                      (set-next-focus! this (the-as enemy a1-26) gp-0)
                      )
                  )
                )
              )
            )
          )
        )
      (-> gp-0 proc)
      )
    )
  )

(defmethod set-next-focus! ((this bot) (arg0 enemy) (arg1 enemy-best-focus))
  (let ((v1-0 (new 'stack-no-clear 'vector)))
    (vector-! v1-0 (-> arg0 root trans) (-> this root trans))
    (let ((f0-0 (vector-length v1-0)))
      (when (and (>= (-> this notice-enemy-dist) f0-0) (< f0-0 (-> arg1 rating)) (>= 24576.0 (fabs (-> v1-0 y))))
        (set! (-> arg1 rating) f0-0)
        (set! (-> arg1 proc) arg0)
        arg0
        )
      )
    )
  )

(defmethod alive? ((this bot))
  (and (not (focus-test? this dead grabbed)) (and (!= (-> this hit-points) 0.0) (zero? (-> this fated-time))))
  )

;; WARN: Return type mismatch int vs search-info-flag.
(defmethod get-search-info-flag ((this bot))
  "Get search-info-flag for this process."
  (the-as search-info-flag 0)
  )

;; WARN: disable def twice: 272. This may happen when a cond (no else) is nested inside of another conditional, but it should be rare.
(defmethod event-handler ((this bot) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  "Commmon handler for events."
  (local-vars (v0-0 object))
  (case arg2
    (('combo)
     #f
     )
    (('query)
     (case (-> arg3 param 0)
       (('waypoint)
        (-> this waypoint waypoint-id)
        )
       (else
         ((method-of-type nav-enemy event-handler) this arg0 arg1 arg2 arg3)
         )
       )
     )
    (('request)
     (case (-> arg3 param 0)
       (('waypoint)
        (set! (-> this waypoint-request) (the-as int (-> arg3 param 1)))
        #t
        )
       (('health-meter)
        (cond
          ((-> arg3 param 1)
           (set! v0-0 (logior (-> this bot-flags) (bot-flag bf06)))
           (set! (-> this bot-flags) (the-as bot-flag v0-0))
           )
          (else
            (set! v0-0 (logclear (-> this bot-flags) (bot-flag bf06)))
            (set! (-> this bot-flags) (the-as bot-flag v0-0))
            )
          )
        v0-0
        )
       (('too-far-fail)
        (when (not (logtest? (-> this bot-flags) (bot-flag too-far-fail bf09)))
          (logior! (-> this bot-flags) (bot-flag bf09))
          (logclear! (-> this enemy-flags) (enemy-flag vulnerable vulnerable-backup))
          (logclear! (-> this focus-status) (focus-status dangerous))
          (logclear! (-> this enemy-flags) (enemy-flag dangerous-backup))
          (logclear! (-> this enemy-flags) (enemy-flag attackable attackable-backup))
          (logclear! (-> this mask) (process-mask actor-pause))
          (logclear! (-> this enemy-flags) (enemy-flag actor-pause-backup))
          (go (method-of-object this failed))
          )
        )
       (('move-to-vehicle)
        (let ((a0-17 (the-as object (-> arg3 param 2))))
          (cond
            ((>= (the-as int a0-17) 0)
             (let ((v1-27 (the-as object (-> arg3 param 1))))
               (cond
                 ((focus-test? this pilot)
                  (if (= (-> this vehicle-seat-index) (the-as uint a0-17))
                      (= (the-as uint v1-27) (handle->process (-> this vehicle-handle)))
                      )
                  )
                 (else
                   (set! (-> this vehicle-seat-index) (the-as int a0-17))
                   (set! (-> this vehicle-handle) (process->handle (the-as uint v1-27)))
                   (logior! (-> this bot-flags) (bot-flag bf15))
                   #t
                   )
                 )
               )
             )
            (else
              (when (not (focus-test? this pilot))
                (set! (-> this vehicle-seat-index) -1)
                (set! (-> this vehicle-handle) (the-as handle #f))
                (logclear! (-> this bot-flags) (bot-flag bf15))
                #t
                )
              )
            )
          )
        )
       (('exit-vehicle)
        (when (focus-test? this pilot)
          (let ((v1-41 (-> arg3 param 1))
                (s5-1 (-> arg3 param 2))
                )
            (cond
              (v1-41
                (logior! (-> this bot-flags) (bot-flag bf16))
                (when (and (>= (the-as int s5-1) 0) (!= s5-1 (-> this nav-mesh-index)))
                  (change-to (nav-mesh-from-res-tag (-> this entity) 'nav-mesh-actor (the-as int s5-1)) this)
                  (set! (-> this nav-mesh-index) (the-as int s5-1))
                  )
                )
              (else
                (logclear! (-> this bot-flags) (bot-flag bf16))
                )
              )
            )
          #t
          )
        )
       (('slave-id)
        (set! (-> this slave-id) (the-as int (-> arg3 param 1)))
        #t
        )
       (else
         ((method-of-type nav-enemy event-handler) this arg0 arg1 arg2 arg3)
         )
       )
     )
    (('notify)
     (case (-> arg3 param 0)
       (('attack)
        (when (as-type (-> arg3 param 1) process-focusable)
          (logior! (-> this enemy-flags) (enemy-flag victory))
          (set-time! (-> this hit-focus-time))
          )
        #t
        )
       (('mission-failed)
        (logior! (-> this bot-flags) (bot-flag bf09))
        (logclear! (-> this bot-flags) (bot-flag bf06))
        #t
        )
       (('follow-dir)
        (vector-copy! (-> this follow-dir) (the-as vector (-> arg3 param 1)))
        #t
        )
       (else
         ((method-of-type nav-enemy event-handler) this arg0 arg1 arg2 arg3)
         )
       )
     )
    (('set-task)
     (let ((a1-11 (/ (the-as int (-> arg3 param 0)) 8)))
       (logior! (-> this bot-task-bits) (ash 1 a1-11))
       )
     #t
     )
    (('clear-task)
     (let ((a1-13 (/ (the-as int (-> arg3 param 0)) 8)))
       (logclear! (-> this bot-task-bits) (ash 1 a1-13))
       )
     #t
     )
    (('skip)
     (skip-waypoint this)
     )
    (('change-mode)
     (when (= (-> arg3 param 0) 'grab)
       (set! v0-0 (alive? this))
       (if (and (the-as symbol v0-0) (-> arg3 param 1))
           (logior! (-> this focus-status) (focus-status grabbed))
           )
       v0-0
       )
     )
    (('end-mode)
     (case (-> arg3 param 0)
       (('grab)
        (when (focus-test? this grabbed)
          (logclear! (-> this focus-status) (focus-status grabbed))
          #t
          )
        )
       )
     )
    (('hide)
     (cond
       ((-> arg3 param 0)
        (go (method-of-object this hidden))
        )
       (else
         (if (and (-> this next-state) (= (-> this next-state name) 'hidden))
             (go-state-for-focused this)
             )
         )
       )
     )
    (('draw)
     (cond
       ((-> arg3 param 0)
        (set! v0-0 (logclear (-> this draw status) (draw-control-status no-draw)))
        (set! (-> this draw status) (the-as draw-control-status v0-0))
        )
       (else
         (set! v0-0 (logior (-> this draw status) (draw-control-status no-draw)))
         (set! (-> this draw status) (the-as draw-control-status v0-0))
         )
       )
     v0-0
     )
    (else
      ((method-of-type nav-enemy event-handler) this arg0 arg1 arg2 arg3)
      )
    )
  )

(defmethod send-attack-from-tshape ((this bot) (arg0 process) (arg1 touching-shapes-entry) (arg2 uint))
  "Send an attack from this enemy to something else."
  (cond
    ((and (= (-> arg0 type) target) (not (logtest? (-> this bot-flags) (bot-flag attacked))))
     (when (send-event arg0 'shove #f (static-attack-info :mask (vehicle-impulse-factor) ((id (new-attack-id))
                                                                                          (damage 0.0)
                                                                                          (vehicle-damage-factor 1.0)
                                                                                          (vehicle-impulse-factor 1.0)
                                                                                          (shove-back (meters 2))
                                                                                          (shove-up (meters 1.5))
                                                                                          )
                                                          )
                       )
       (set! (-> this root penetrated-by) (the-as penetrate -1))
       (reset-penetrate-later! this)
       #t
       )
     )
    (else
      (when (send-event
              arg0
              'attack
              arg1
              (static-attack-info :mask (vehicle-impulse-factor) ((id arg2)
                                                                  (damage 2.0)
                                                                  (vehicle-damage-factor 1.0)
                                                                  (vehicle-impulse-factor 1.0)
                                                                  (shove-back (-> this enemy-info attack-shove-back))
                                                                  (shove-up (-> this enemy-info attack-shove-up))
                                                                  (mode (-> this enemy-info attack-mode))
                                                                  )
                                  )
              )
        (on-attack this (the-as process-focusable arg0))
        #t
        )
      )
    )
  )

(defmethod enemy-touched-handler ((this bot) (arg0 process) (arg1 event-message-block))
  "General handler for when anything touches an enemy (automatic response)."
  (cond
    ((and (-> this next-state) (let ((v1-3 (-> this next-state name)))
                                 (or (= v1-3 'knocked) (= v1-3 'jump))
                                 )
          )
     ((method-of-type nav-enemy enemy-touched-handler) this arg0 arg1)
     )
    (else
      (when (!= (-> arg0 type) target)
        (let ((s3-0 (-> arg1 param 0))
              (v1-6 (as-type arg0 process-focusable))
              )
          (cond
            ((and (focus-test? this dangerous)
                  (logtest? (process-mask enemy) (-> arg0 mask))
                  (and v1-6
                       (not (logtest? (-> (the-as process-focusable v1-6) focus-status) (focus-status disable dead ignore grabbed)))
                       )
                  ((method-of-type touching-shapes-entry prims-touching-action?)
                   (the-as touching-shapes-entry s3-0)
                   (-> this root)
                   (collide-action deadly)
                   (collide-action)
                   )
                  )
             (let ((a3-2 (if ((method-of-type touching-shapes-entry prims-touching-action?)
                              (the-as touching-shapes-entry s3-0)
                              (-> this root)
                              (collide-action persistent-attack)
                              (collide-action)
                              )
                             (-> this persistent-attack-id)
                             (-> this attack-id)
                             )
                         )
                   )
               (send-attack-from-tshape this arg0 (the-as touching-shapes-entry s3-0) a3-2)
               )
             )
            (else
              (send-event arg0 'touch (-> arg1 param 0))
              )
            )
          )
        )
      )
    )
  )

(defun bot-simple-check-too-far ((arg0 bot))
  (let ((s5-0 0))
    (let ((f0-0 (vector-vector-xz-distance (-> *target* control trans) (-> arg0 root trans)))
          (f1-0 (-> arg0 too-far-warn-dist))
          )
      (when (>= f0-0 f1-0)
        (if (>= (- f0-0 f1-0) (-> arg0 too-far-fail-dist-delta))
            (set! s5-0 2)
            (set! s5-0 1)
            )
        )
      )
    s5-0
    )
  )

;; WARN: Return type mismatch symbol vs none.
(defmethod bot-method-216 ((this bot))
  (when (not (channel-active? this (gui-channel none)))
    (let ((a1-2 (get-next-speech-idx
                  (-> this course too-far-warn-speeches)
                  this
                  (-> this course speeches)
                  (bot-speech-info-flag)
                  )
                )
          )
      (when (>= a1-2 0)
        (play-speech-by-id this a1-2)
        #t
        )
      )
    )
  (none)
  )

(defun bot-check-too-far-always-okay ()
  0
  )

(defmethod bot-check-too-far ((this bot))
  (let ((gp-0 0))
    (let ((v1-0 (-> this delay-too-far-check)))
      (cond
        ((> v1-0 0)
         (set! (-> this delay-too-far-check) (+ v1-0 -1))
         )
        ((and (zero? v1-0) *target* (not (logtest? (-> this focus-status) (focus-status grabbed))))
         (let ((t9-0 (the-as object (-> this waypoint check-too-far))))
           (if (not (the-as symbol t9-0))
               (set! t9-0 (-> this course default-check-too-far))
               )
           (when (the-as symbol t9-0)
             (cond
               ((logtest? (the-as int t9-0) 1)
                (set! gp-0 ((the-as (function bot int) (-> (the-as symbol t9-0) value)) this))
                )
               ((= (rtype-of (the-as symbol t9-0)) function)
                (set! gp-0 ((the-as (function bot int) t9-0) this))
                )
               )
             )
           )
         (if (and (= gp-0 1)
                  (nonzero? (-> this started-warning-time))
                  (time-elapsed? (-> this started-warning-time) (the-as time-frame (-> this warn-to-fail-timeout)))
                  )
             (set! gp-0 2)
             )
         (case gp-0
           ((1)
            (if (zero? (-> this started-warning-time))
                (set-time! (-> this started-warning-time))
                )
            (if (and (>= (current-time) (-> this next-too-far-warn-time)) (bot-method-216 this))
                (set! (-> this next-too-far-warn-time) (+ (current-time) (rnd-time-frame
                                                                           this
                                                                           (the-as time-frame (-> this warn-min-delay))
                                                                           (the-as time-frame (-> this warn-max-delay))
                                                                           )
                                                          )
                      )
                )
            )
           )
         )
        )
      )
    (when (zero? gp-0)
      (set! (-> this started-warning-time) 0)
      0
      )
    (= gp-0 2)
    )
  )

;; WARN: Return type mismatch time-frame vs none.
(defmethod reset-warn-time ((this bot))
  (set! (-> this started-warning-time) 0)
  (set! (-> this next-too-far-warn-time) (+ (current-time) (rnd-time-frame
                                                             this
                                                             (the-as time-frame (-> this warn-min-delay))
                                                             (the-as time-frame (-> this warn-max-delay))
                                                             )
                                            )
        )
  (none)
  )

(defmethod enemy-common-post ((this bot))
  "Common implementation of post. Runs ja-post."
  (set! (-> this travel-prev-ry) (-> this travel-prev-ry1))
  (set! (-> this travel-prev-ry1) (quaternion-y-angle (-> this root quat)))
  (let ((f0-3 (/ (-> this hit-points) (-> this enemy-info default-hit-points))))
    (if (nonzero? (-> this fated-time))
        (set! f0-3 0.0)
        )
    (set! (-> *game-info* bot-health (-> this bot-health-index)) f0-3)
    )
  (cond
    ((logtest? (-> this bot-flags) (bot-flag bf06))
     (if (and (not (handle->process (-> this health-handle))) *target*)
         (bot-method-228 this)
         )
     )
    (else
      (send-event (handle->process (-> this health-handle)) 'hide-and-die)
      )
    )
  (when (not (nav-enemy-method-185 this))
    (let ((a1-2 (new 'stack-no-clear 'overlaps-others-params)))
      (set! (-> a1-2 options) (overlaps-others-options))
      (set! (-> a1-2 collide-with-filter) (the-as collide-spec -1))
      (set! (-> a1-2 tlist) *touching-list*)
      (find-overlapping-shapes (-> this root) a1-2)
      )
    )
  (let ((t9-5 (method-of-type nav-enemy enemy-common-post)))
    (t9-5 this)
    )
  (when (not (logtest? (-> this bot-flags) (bot-flag bf09)))
    (let ((t9-6 (-> this waypoint on-update)))
      (if t9-6
          (t9-6 this)
          )
      )
    )
  (if (and (bot-check-too-far this) (not (logtest? (-> this bot-flags) (bot-flag bf09))))
      (go (method-of-object this failed))
      )
  (if (not (logtest? (-> this bot-flags) (bot-flag bf09)))
      (ai-task-control-method-10 (-> this ai-ctrl) this)
      )
  (if (logtest? (-> this bot-flags) (bot-flag bf02))
      (bot-method-204 this)
      )
  (if (logtest? *display-bot-marks* (bot-marks-controls bmc08))
      (bot-method-196 this)
      )
  (none)
  )

(defmethod scene-play ((this bot) (arg0 scene) (arg1 symbol))
  (when (and (process-grab? this #t) (or arg1 (process-grab? *target* #t)))
    (process-grab? this #f)
    (if (not arg1)
        (process-grab? *target* #f)
        )
    (set! (-> this scene-player-handle)
          (ppointer->handle (process-spawn scene-player :init scene-player-init arg0 #t #f :name "scene-player"))
          )
    #t
    )
  )

(defmethod scene-stop ((this bot))
  (when (not (handle->process (-> this scene-player-handle)))
    (process-release? this)
    #t
    )
  )

;; WARN: Return type mismatch symbol vs none.
(defmethod bot-method-223 ((this bot))
  (let ((v1-1 (-> this course speeches)))
    (countdown (a0-2 (-> this course speech-count))
      (let ((a1-1 (-> v1-1 a0-2)))
        (logclear! (-> a1-1 flags) (bot-speech-info-flag playing))
        )
      )
    )
  (none)
  )

(defmethod play-speech-by-id ((this bot) (arg0 int))
  (let* ((gp-0 (-> this course))
         (s5-0 (-> gp-0 speeches arg0))
         )
    (logior! (-> s5-0 flags) (bot-speech-info-flag playing))
    (let* ((t2-0 (-> s5-0 hold-time))
           (a1-4
             (add-process
               *gui-control*
               this
               (-> this channel)
               (gui-action play)
               (-> s5-0 name)
               -99.0
               (the-as time-frame t2-0)
               )
             )
           (v1-5 (-> gp-0 speech-tunings (-> s5-0 tuning-id)))
           )
      (sound-params-set!
        *gui-control*
        a1-4
        (-> v1-5 trans?)
        (-> v1-5 fo-min)
        (-> v1-5 fo-max)
        (-> v1-5 fo-curve)
        -1.0
        )
      )
    )
  )

(defmethod play-speech-by-name ((this bot) (arg0 string))
  (add-process *gui-control* this (-> this channel) (gui-action play) arg0 -99.0 (seconds 0.3))
  )

(defmethod course-speech-ended? ((this bot) (arg0 int))
  (let ((v1-2 (-> this course speeches arg0)))
    (= (get-status
         *gui-control*
         (lookup-gui-connection-id *gui-control* (-> v1-2 name) (gui-channel none) (gui-action none))
         )
       (gui-status unknown)
       )
    )
  )

(defmethod course-speech-playing? ((this bot) (arg0 int))
  (let ((v1-2 (-> this course speeches arg0)))
    (logtest? (-> v1-2 flags) (bot-speech-info-flag playing))
    )
  )

(defmethod channel-active? ((this bot) (arg0 gui-channel))
  (if (= arg0 (gui-channel none))
      (set! arg0 (-> this channel))
      )
  (nonzero? (get-status *gui-control* (lookup-gui-connection-id *gui-control* (the-as string #f) arg0 (gui-action none)))
            )
  )

(defmethod bot-method-232 ((this bot) (arg0 gui-channel) (arg1 symbol))
  (if (= arg0 (gui-channel none))
      (set! arg0 (-> this channel))
      )
  (if arg1
      (set-action!
        *gui-control*
        (gui-action stop)
        (the-as sound-id 1)
        arg0
        (gui-action none)
        (the-as string #f)
        (lambda :behavior bot
          ((arg0 gui-connection))
          (let* ((v1-0 self)
                 (s5-0 (-> v1-0 course speeches))
                 )
            (countdown (s4-0 (-> v1-0 course speech-count))
              (let ((s3-0 (-> s5-0 s4-0)))
                (if (string= (-> s3-0 name) (-> arg0 name))
                    (return (not (logtest? (-> s3-0 flags) (bot-speech-info-flag sf01))))
                    )
                )
              )
            )
          #t
          )
        (the-as process #f)
        )
      (set-action!
        *gui-control*
        (gui-action stop)
        (the-as sound-id 1)
        arg0
        (gui-action none)
        (the-as string #f)
        (the-as (function gui-connection symbol) #f)
        (the-as process #f)
        )
      )
  )

(defmethod go-to-waypoint! ((this bot) (arg0 int) (arg1 symbol))
  (let* ((v1-0 (-> this course))
         (a0-2 (-> v1-0 waypoints length))
         )
    (dotimes (a2-1 a0-2)
      (let ((s4-0 (-> v1-0 waypoints a2-1)))
        (when (= (-> s4-0 waypoint-id) arg0)
          (set! (-> this waypoint) s4-0)
          (set! (-> this waypoint-bits) (waypoint-bits))
          (set-time! (-> this waypoint-time0))
          (set! (-> this too-far-warn-dist) (-> this too-far-warn-dist-default))
          (set! (-> this too-far-fail-dist-delta) (-> this too-far-fail-dist-delta-default))
          (let ((s3-0 (-> s4-0 nav-mesh-index)))
            (when (and (>= s3-0 0) (!= (-> this nav-mesh-index) s3-0))
              (change-to (nav-mesh-from-res-tag (-> this entity) 'nav-mesh-actor s3-0) this)
              (set! (-> this nav-mesh-index) s3-0)
              )
            )
          (when arg1
            (let ((s5-1 (-> s4-0 on-skipping-here)))
              (when s5-1
                (process-entity-status! this (entity-perm-status no-kill) #t)
                (s5-1 this)
                )
              )
            )
          (let ((t9-4 (-> s4-0 on-set)))
            (if t9-4
                (t9-4 this)
                )
            )
          (return #f)
          )
        )
      )
    )
  (go process-drawable-art-error "bad waypoint id")
  )

(defmethod skip-waypoint ((this bot))
  (let ((s5-0 (-> this waypoint skip-to)))
    (when (>= s5-0 0)
      (bot-method-232 this (gui-channel none) #f)
      (set! (-> this delay-too-far-check) 10)
      (go-to-waypoint! this s5-0 #t)
      )
    )
  )

;; WARN: Return type mismatch nav-enemy vs bot.
(defmethod relocate ((this bot) (offset int))
  (if (nonzero? (-> this ai-ctrl))
      (&+! (-> this ai-ctrl) offset)
      )
  (if (nonzero? (-> this task))
      (&+! (-> this task) offset)
      )
  (if (nonzero? (-> this swivel-joint-mod))
      (&+! (-> this swivel-joint-mod) offset)
      )
  (the-as bot ((method-of-type nav-enemy relocate) this offset))
  )

(defmethod deactivate ((this bot))
  "Make a process dead, clean it up, remove it from the active pool, and return to dead pool."
  (send-event (handle->process (-> this health-handle)) 'hide-and-die)
  (if (nonzero? (-> this ai-ctrl))
      (ai-task-control-method-9 (-> this ai-ctrl))
      )
  ((method-of-type nav-enemy deactivate) this)
  (none)
  )

(defmethod init-fields! ((this bot))
  (set! (-> this master-handle) (the-as handle #f))
  (set! (-> this health-handle) (the-as handle #f))
  (set! (-> this scene-player-handle) (the-as handle #f))
  (set! (-> this poi-handle) (the-as handle #f))
  (set! (-> this attacker-handle) (the-as handle #f))
  (set! (-> this vehicle-handle) (the-as handle #f))
  (set! (-> this focus-mode) 0)
  (set! (-> this hit-invuln-ignore-me-delay) (the-as uint 180))
  (set! (-> this warn-to-fail-timeout) (the-as uint #x34bc))
  (set! (-> this warn-min-delay) (the-as uint 2400))
  (set! (-> this warn-max-delay) (the-as uint 4200))
  (set! (-> this vehicle-seat-index) -1)
  (set! (-> this nav-mesh-index) -1)
  (set! (-> this too-far-warn-dist-default) 184320.0)
  (set! (-> this too-far-fail-dist-delta-default) 122880.0)
  (logior! (-> this bot-flags) (bot-flag bf11))
  (set! (-> this delay-too-far-check) 10)
  (set! (-> this focus collide-with) (collide-spec jak enemy hit-by-others-list player-list))
  (set! (-> this spot-color) (the-as uint #x500000ff))
  (set-vector! (-> this follow-dir) 0.0 0.0 1.0 1.0)
  0
  (none)
  )

(defmethod init-enemy! ((this bot))
  "Typical place for shared init code. Runs from entity or process style init."
  (process-entity-status! this (entity-perm-status bit-4) #t)
  (set! (-> this ai-ctrl) (new 'process 'ai-task-control *bot-task-pool*))
  (logclear! (-> this mask) (process-mask enemy))
  (logior! (-> this mask) (process-mask bot))
  (logior! (-> this enemy-flags) (enemy-flag cam-attack-mode dislike-combo))
  (logclear! (-> this enemy-flags) (enemy-flag attackable attackable-backup))
  (logior! (-> this focus-status) (focus-status disable))
  (let ((v1-11 (-> this nav)))
    (set! (-> v1-11 sphere-mask) (the-as uint 78))
    )
  0
  (logclear! (-> this root nav-flags) (nav-flags has-extra-sphere))
  (let ((v1-15 (-> this nav)))
    (set! (-> v1-15 speed-scale) 1.0)
    )
  0
  (set-gravity-length (-> this root dynam) 573440.0)
  (let ((a2-3 (res-lump-value (-> this entity) 'task-actor uint128 :time -1000000000.0)))
    (if (nonzero? a2-3)
        (set! (-> this task) (new 'process 'game-task-control (the-as game-task-actor a2-3)))
        )
    )
  (set! (-> this task-node) (task-node-by-name (the-as string ((method-of-type res-lump get-property-struct)
                                                               (-> this entity)
                                                               'task-name
                                                               'interp
                                                               -1000000000.0
                                                               ""
                                                               (the-as (pointer res-tag) #f)
                                                               *res-static-buf*
                                                               )
                                                       )
                                               )
        )
  (let ((s5-1 (res-lump-value (-> this entity) 'bot-course uint128 :default (the-as uint128 -1) :time -1000000000.0))
        )
    (if (< (the-as int s5-1) 0)
        (go process-drawable-art-error "no course")
        )
    (let ((s5-2 (-> *bot-course-table* course s5-1)))
      (set! (-> this course) s5-2)
      (+! (-> s5-2 retry-cookie) 1)
      (mem-copy! (the-as pointer (-> this spot)) (the-as pointer (-> s5-2 spots 0)) 20)
      (let ((v1-35 (-> s5-2 waypoints 0)))
        (set! (-> this nav-mesh-index) (-> v1-35 nav-mesh-index))
        (go-to-waypoint! this (-> v1-35 waypoint-id) #f)
        )
      )
    )
  0
  (none)
  )

(defmethod bot-method-226 ((this bot))
  (when (logtest? (-> this bot-flags) (bot-flag bf00))
    (let ((a1-0 (handle->process (-> this focus handle))))
      (and a1-0
           (= (-> this focus aware) (enemy-aware hostile))
           (attacked-by-player? this (the-as process-focusable a1-0))
           (not (logtest? (-> this focus-status) (focus-status grabbed)))
           )
      )
    )
  )

(defmethod bot-method-235 ((this bot) (arg0 symbol))
  (let ((gp-0 (-> this focus-info))
        (v1-1 (current-time))
        (s3-0 (handle->process (-> this focus handle)))
        )
    (when (or (!= v1-1 (-> gp-0 update-time)) (!= (the-as process-focusable s3-0) (-> gp-0 fproc)))
      (set! (-> gp-0 update-time) v1-1)
      (set! (-> gp-0 fproc) (the-as process-focusable s3-0))
      (set! (-> gp-0 los) 0)
      (when (the-as process-focusable s3-0)
        (vector-copy! (-> gp-0 pos) (get-trans (the-as process-focusable s3-0) 0))
        (vector-copy! (-> gp-0 bullseye) (get-trans (the-as process-focusable s3-0) 3))
        (vector-z-quaternion! (-> gp-0 my-facing-xz-dir) (-> this root quat))
        (set! (-> gp-0 my-facing-xz-dir y) 0.0)
        (vector-normalize! (-> gp-0 my-facing-xz-dir) 1.0)
        (set! (-> gp-0 my-facing-ry) (atan (-> gp-0 my-facing-xz-dir x) (-> gp-0 my-facing-xz-dir z)))
        (vector-! (-> gp-0 bullseye-xz-dir) (-> gp-0 bullseye) (-> this root trans))
        (let ((v1-11 (-> gp-0 bullseye-xz-dir)))
          (set! (-> gp-0 bullseye-xz-dist) (sqrtf (+ (* (-> v1-11 x) (-> v1-11 x)) (* (-> v1-11 z) (-> v1-11 z)))))
          )
        (set! (-> gp-0 bullseye-xz-dir y) 0.0)
        (vector-normalize! (-> gp-0 bullseye-xz-dir) 1.0)
        (set! (-> gp-0 bullseye-ry) (atan (-> gp-0 bullseye-xz-dir x) (-> gp-0 bullseye-xz-dir z)))
        (set! (-> gp-0 ry-diff) (deg- (-> gp-0 bullseye-ry) (-> gp-0 my-facing-ry)))
        )
      )
    (when (and arg0 s3-0 (zero? (-> gp-0 los)))
      (let ((s4-1 (new 'stack-no-clear 'collide-query)))
        (vector-copy! (-> s4-1 start-pos) (-> this root trans))
        (+! (-> s4-1 start-pos y) 8192.0)
        (vector-! (-> s4-1 move-dist) (-> gp-0 bullseye) (-> s4-1 start-pos))
        (let ((f0-19 (fmax 1.0 (+ -1638.4 (vector-length (-> s4-1 move-dist))))))
          (cond
            ((< f0-19 (-> gp-0 max-los-dist))
             (vector-normalize! (-> s4-1 move-dist) f0-19)
             (let ((v1-23 s4-1))
               (set! (-> v1-23 radius) 2048.0)
               (set! (-> v1-23 collide-with) (collide-spec backgnd obstacle hit-by-others-list pusher))
               (set! (-> v1-23 ignore-process0) this)
               (set! (-> v1-23 ignore-process1) #f)
               (set! (-> v1-23 ignore-pat) (-> this root pat-ignore-mask))
               (set! (-> v1-23 action-mask) (collide-action solid))
               )
             (cond
               ((>= (fill-and-probe-using-line-sphere *collide-cache* s4-1) 0.0)
                (set! (-> gp-0 los) 3)
                0
                )
               (else
                 (let ((s3-3 1))
                   (when (not (logtest? (-> this bot-flags) (bot-flag attacked)))
                     (let ((a0-31 *target*))
                       (when a0-31
                         (vector+! (-> s4-1 move-dist) (-> s4-1 move-dist) (-> s4-1 start-pos))
                         (if (>= 16384.0 (vector-segment-distance-point!
                                           (get-trans a0-31 3)
                                           (-> s4-1 start-pos)
                                           (-> s4-1 move-dist)
                                           (the-as vector #f)
                                           )
                                 )
                             (set! s3-3 4)
                             )
                         )
                       )
                     )
                   (set! (-> gp-0 los) s3-3)
                   )
                 )
               )
             )
            (else
              (set! (-> gp-0 los) 2)
              )
            )
          )
        )
      )
    )
  0
  (none)
  )

(defmethod bot-method-194 ((this bot) (arg0 bot-turn-info) (arg1 process-focusable) (arg2 float))
  (let ((s5-0 (-> this root)))
    (quaternion-copy! (-> arg0 src-quat) (-> s5-0 quat))
    (vector-z-quaternion! (-> arg0 facing-dir) (-> s5-0 quat))
    (set! (-> arg0 facing-ry) (atan (-> arg0 facing-dir x) (-> arg0 facing-dir z)))
    (vector-copy! (-> arg0 targ-pos) (get-trans arg1 3))
    (set! (-> arg0 targ-ry)
          (atan (- (-> arg0 targ-pos x) (-> s5-0 trans x)) (- (-> arg0 targ-pos z) (-> s5-0 trans z)))
          )
    (let ((a0-7 (get-transv arg1)))
      (vector+*! (-> arg0 predicted-targ-pos) (-> arg0 targ-pos) a0-7 arg2)
      )
    (set! (-> arg0 predicted-targ-ry) (atan
                                        (- (-> arg0 predicted-targ-pos x) (-> s5-0 trans x))
                                        (- (-> arg0 predicted-targ-pos z) (-> s5-0 trans z))
                                        )
          )
    )
  (set! (-> arg0 ry-diff) (deg- (-> arg0 targ-ry) (-> arg0 facing-ry)))
  (set! (-> arg0 predicted-ry-diff) (deg- (-> arg0 predicted-targ-ry) (-> arg0 facing-ry)))
  )

(defmethod bot-method-220 ((this bot))
  (let ((s5-0 #f))
    (when *target*
      (let ((a1-0 (-> *target* control trans))
            (v1-4 (-> this root))
            (f0-0 14336.0)
            )
        (when (>= (* f0-0 f0-0) (vector-vector-distance-squared (-> v1-4 trans) a1-0))
          (let ((v1-8 (-> *target* control transv)))
            (when (>= (sqrtf (+ (* (-> v1-8 x) (-> v1-8 x)) (* (-> v1-8 z) (-> v1-8 z)))) 2048.0)
              (if (logtest? (-> this nav state flags) (nav-state-flag avoiding-sphere))
                  (set! s5-0 #t)
                  )
              )
            )
          )
        )
      )
    (let* ((f0-8 (-> this player-blocking))
           (f0-10 (if s5-0
                      (seek f0-8 1.0 (seconds-per-frame))
                      (seek f0-8 0.0 (seconds-per-frame))
                      )
                  )
           )
      (set! (-> this player-blocking) f0-10)
      (= f0-10 1.0)
      )
    )
  )

;; WARN: Return type mismatch symbol vs object.
(defmethod check-jump-blocked? ((this bot) (arg0 enemy-jump-info))
  "Is this jump blocked by something?"
  (let ((v1-0 (new 'stack-no-clear 'vector)))
    (vector-copy! v1-0 (-> arg0 dest-pos))
    (set! (-> v1-0 w) (-> this nav-radius-backup))
    (check-sphere-blocked! (-> this nav) v1-0 #x10006a)
    )
  )

(defmethod bot-method-234 ((this bot) (arg0 vector))
  (let ((s1-0 (new 'stack-no-clear 'vector))
        (s3-0 (new 'stack-no-clear 'vector))
        (v1-0 (new 'stack-no-clear 'vector))
        (s2-0 (new 'stack-no-clear 'vector))
        (s4-0 (new 'stack-no-clear 'vector))
        (s5-0 (new 'stack-no-clear 'vector))
        )
    (vector-copy! v1-0 (-> this root trans))
    (+! (-> v1-0 y) 9216.0)
    (vector-! s1-0 arg0 v1-0)
    (vector-normalize! s1-0 1.0)
    (vector-z-quaternion! s2-0 (-> this root quat))
    (rot-zxy-from-vector! s4-0 s2-0)
    (rot-zxy-from-vector! s3-0 s1-0)
    (set! (-> s5-0 x) (fmax -3640.889 (fmin 3640.889 (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)
    (let ((s4-1 (new 'stack-no-clear 'quaternion)))
      (quaternion-zxy! s4-1 s5-0)
      (quaternion-pseudo-seek
        (-> this swivel-joint-mod quat)
        (-> this swivel-joint-mod quat)
        s4-1
        (seconds-per-frame)
        )
      )
    )
  0
  (none)
  )

(defmethod bot-method-233 ((this bot))
  (let ((gp-0 (new 'stack-no-clear 'quaternion)))
    (quaternion-identity! gp-0)
    (quaternion-pseudo-seek
      (-> this swivel-joint-mod quat)
      (-> this swivel-joint-mod quat)
      gp-0
      (seconds-per-frame)
      )
    )
  )

(defmethod play-next-speech ((this bot))
  (when (not (channel-active? this (gui-channel none)))
    (let ((a1-2 (get-next-speech-idx
                  (-> this course attack-player-speeches)
                  this
                  (-> this course speeches)
                  (bot-speech-info-flag)
                  )
                )
          )
      (if (>= a1-2 0)
          (play-speech-by-id this a1-2)
          )
      )
    )
  )

;; WARN: Return type mismatch bot-flag vs none.
(defmethod set-fail-flag ((this bot))
  (logior! (-> this bot-flags) (bot-flag too-far-fail))
  (none)
  )

;; WARN: Return type mismatch bot-flag vs none.
(defmethod bot-method-209 ((this bot))
  (logclear! (-> this enemy-flags) (enemy-flag vulnerable vulnerable-backup))
  (logclear! (-> this enemy-flags) (enemy-flag attackable attackable-backup))
  (logclear! (-> this mask) (process-mask actor-pause))
  (logclear! (-> this enemy-flags) (enemy-flag actor-pause-backup))
  (logior! (-> this bot-flags) (bot-flag bf09))
  (let ((s5-0 #t))
    (let ((a0-6 (handle->process (-> this master-handle))))
      (cond
        (a0-6
          (if (not (send-event a0-6 'notify 'mission-failed))
              (set! s5-0 #f)
              )
          )
        (else
          (when (-> this task-node)
            (let* ((v1-23 (-> *game-info* sub-task-list (-> this task-node task)))
                   (v1-25 (if (-> v1-23 manager)
                              (-> v1-23 manager manager)
                              (the-as handle #f)
                              )
                          )
                   )
              (if v1-25
                  (send-event (handle->process v1-25) 'fail)
                  )
              )
            )
          )
        )
      )
    (if s5-0
        (logior! (-> this bot-flags) (bot-flag failed bf13))
        )
    )
  (none)
  )

(defmethod bot-method-212 ((this bot))
  (if (logtest? (-> this bot-flags) (bot-flag failed))
      (cam-move-to-bot this)
      )
  (none)
  )

;; WARN: Return type mismatch object vs none.
(defmethod cam-move-to-bot ((this bot))
  (cond
    ((logtest? (-> this bot-flags) (bot-flag bf13))
     (logclear! (-> this bot-flags) (bot-flag bf13))
     (logior! (-> this bot-flags) (bot-flag bf14))
     (let ((s4-0 (-> this move-dest)))
       (set-cam-height this s4-0)
       (let ((s5-0 (new 'stack-no-clear 'vector)))
         (vector-! s5-0 s4-0 (-> this root trans))
         (set-setting! 'string-max-height 'abs (-> s5-0 y) 0)
         (set-setting! 'string-min-height 'abs (-> s5-0 y) 0)
         (let ((f30-0 (sqrtf (+ (* (-> s5-0 x) (-> s5-0 x)) (* (-> s5-0 z) (-> s5-0 z))))))
           (set-setting! 'string-max-length 'abs f30-0 0)
           (set-setting! 'string-min-length 'abs f30-0 0)
           )
         )
       )
     (set-setting! 'immediate-string-min-max #f 0.0 0)
     (set! (-> *ACTOR-bank* birth-max) 1000)
     )
    ((logtest? (-> this bot-flags) (bot-flag bf14))
     (logclear! (-> this bot-flags) (bot-flag bf14))
     (send-event *camera* 'change-target this)
     (send-event *camera* 'teleport-to-vector-start-string (-> this move-dest))
     )
    )
  (none)
  )

(defmethod set-cam-height ((this bot) (arg0 vector))
  (set-vector! arg0 0.0 12288.0 28672.0 1.0)
  (vector<-cspace+vector! arg0 (-> this node-list data 2) arg0)
  (if (focus-test? this under-water)
      (set! (-> arg0 y) (+ (get-water-height this) (-> *setting-control* cam-current target-height)))
      )
  )

;; WARN: Return type mismatch focus-status vs none.
(defmethod bot-method-203 ((this bot))
  (logior! (-> this bot-flags) (bot-flag bf02))
  (set-time! (-> this hit-invuln-starting-time))
  (logclear! (-> this enemy-flags) (enemy-flag vulnerable))
  (if (nonzero? (-> this hit-invuln-ignore-me-delay))
      (logior! (-> this focus-status) (focus-status ignore))
      )
  (if (nonzero? (-> this hit-invuln-focus-disable-delay))
      (logior! (-> this focus-status) (focus-status disable))
      )
  (none)
  )

;; WARN: Return type mismatch bot-flag vs none.
(defmethod bot-method-204 ((this bot))
  (local-vars (a2-7 enemy-flag))
  (let ((a1-0 (-> this hit-invuln-starting-time))
        (v1-0 #t)
        )
    (if (not (logtest? (-> this enemy-flags) (enemy-flag vulnerable)))
        (set! v1-0 (cond
                     ((time-elapsed? a1-0 (seconds 0.6))
                      (let ((a2-6 (-> this enemy-flags)))
                        (if (logtest? a2-6 (enemy-flag vulnerable-backup))
                            (set! a2-7 (logior a2-6 (enemy-flag vulnerable)))
                            (set! a2-7 (logclear a2-6 (enemy-flag vulnerable)))
                            )
                        )
                      (set! (-> this enemy-flags) a2-7)
                      v1-0
                      )
                     (else
                       #f
                       )
                     )
              )
        )
    (if (focus-test? this ignore)
        (set! v1-0 (cond
                     ((time-elapsed? a1-0 (the-as time-frame (-> this hit-invuln-ignore-me-delay)))
                      (logclear! (-> this focus-status) (focus-status ignore))
                      v1-0
                      )
                     (else
                       #f
                       )
                     )
              )
        )
    (if (focus-test? this disable)
        (set! v1-0 (cond
                     ((time-elapsed? a1-0 (the-as time-frame (-> this hit-invuln-focus-disable-delay)))
                      (logclear! (-> this focus-status) (focus-status disable))
                      v1-0
                      )
                     (else
                       #f
                       )
                     )
              )
        )
    (if v1-0
        (logclear! (-> this bot-flags) (bot-flag bf02))
        )
    )
  (none)
  )

(defmethod bot-method-228 ((this bot))
  0
  (none)
  )

(defmethod coin-flip? ((this bot))
  "Return #t half the time, #f the other."
  #f
  )

(defmethod bot-method-193 ((this bot) (arg0 vector) (arg1 vector) (arg2 vector) (arg3 vector) (arg4 vector) (arg5 float))
  (let* ((f1-1 (* arg5 arg5))
         (f0-2 (* arg5 f1-1))
         )
    (let ((f2-3 (- (+ 1.0 (* -3.0 arg5) (* 3.0 f1-1)) f0-2))
          (f3-7 (+ (* 3.0 f0-2) (* -6.0 f1-1) (* 3.0 arg5)))
          (f1-3 (+ (* -3.0 f0-2) (* 3.0 f1-1)))
          )
      (vector-float*! arg0 arg1 f2-3)
      (vector+*! arg0 arg0 (vector+! (new 'stack-no-clear 'vector) arg1 arg2) f3-7)
      (vector+*! arg0 arg0 (vector+! (new 'stack-no-clear 'vector) arg3 arg4) f1-3)
      )
    (vector+*! arg0 arg0 arg3 f0-2)
    )
  0
  (none)
  )
