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

;; name: crocesc.gc
;; name in dgo: crocesc
;; dgos: LKIDDOGE

;; DECOMP BEGINS

(define *crocadog-escort-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 (new 'static 'array idle-control-frame 2
      (new 'static 'idle-control-frame :command (ic-cmd play) :anim #x3 :param0 #x1 :param1 #x1)
      (new 'static 'idle-control-frame)
      )
    :idle-anim 3
    :notice-anim 3
    :hostile-anim -1
    :hit-anim 3
    :knocked-anim 12
    :knocked-land-anim 13
    :die-anim 3
    :die-falling-anim 3
    :victory-anim -1
    :jump-wind-up-anim 3
    :jump-in-air-anim 3
    :jump-land-anim 3
    :neck-joint 6
    :look-at-joint 6
    :bullseye-joint 4
    :notice-distance (meters 6)
    :notice-distance-delta (meters 10)
    :proximity-notice-distance (meters 6)
    :default-hit-points 100
    :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.7
    :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 3)
    :jump-height-factor 0.5
    :knocked-seek-ry-clamp 2730.6667
    :knocked-soft-vxz-lo 49152.0
    :knocked-soft-vxz-hi 49152.0
    :knocked-soft-vy-lo 40960.0
    :knocked-soft-vy-hi 40960.0
    :knocked-medium-vxz-lo 49152.0
    :knocked-medium-vxz-hi 49152.0
    :knocked-medium-vy-lo 40960.0
    :knocked-medium-vy-hi 40960.0
    :knocked-hard-vxz-lo 49152.0
    :knocked-hard-vxz-hi 49152.0
    :knocked-hard-vy-lo 40960.0
    :knocked-hard-vy-hi 40960.0
    :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 49152.0
    :knocked-yellow-vxz-hi 49152.0
    :knocked-yellow-vy-lo 40960.0
    :knocked-yellow-vy-hi 40960.0
    :knocked-red-vxz-lo 49152.0
    :knocked-red-vxz-hi 49152.0
    :knocked-red-vy-lo 40960.0
    :knocked-red-vy-hi 40960.0
    :knocked-blue-vxz-lo 49152.0
    :knocked-blue-vxz-hi 49152.0
    :knocked-blue-vy-lo 40960.0
    :knocked-blue-vy-hi 40960.0
    :shadow-size (meters 2)
    :shadow-max-y (meters 1)
    :shadow-min-y (meters -1)
    :shadow-locus-dist (meters 150)
    :gem-joint -1
    :gem-offset (new 'static 'sphere :r 163840.0)
    :callback-info #f
    :use-momentum #t
    :use-frustration #t
    :use-stop-chase #f
    :use-circling #f
    :use-pacing #f
    :walk-anim 3
    :turn-anim -1
    :run-anim 3
    :taunt-anim -1
    :run-travel-speed (meters 7)
    :run-acceleration (meters 14)
    :run-turning-acceleration (meters 6)
    :walk-travel-speed (meters 2.2)
    :walk-acceleration (meters 8)
    :walk-turning-acceleration (meters 6)
    :maximum-rotation-rate (degrees 360)
    :notice-nav-radius (meters 0.65)
    :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! (-> *crocadog-escort-nav-enemy-info* fact-defaults) *fact-info-enemy-defaults*)

(defmethod general-event-handler ((this crocadog-escort) (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
    (('attack)
     ((method-of-type bot general-event-handler) this arg0 arg1 arg2 arg3)
     #f
     )
    (('nav-mesh-kill)
     (change-to *default-nav-mesh* this)
     #t
     )
    (else
      ((method-of-type bot general-event-handler) this arg0 arg1 arg2 arg3)
      )
    )
  )

(defmethod get-penetrate-info ((this crocadog-escort))
  "@returns the allowed way(s) this enemy can take damage
@see [[penetrate]] and [[penetrated-by-all&hit-points->penetrated-by]]"
  (let ((v1-1 ((method-of-type bot get-penetrate-info) this)))
    (logior (penetrate jak-yellow-shot jak-red-shot jak-blue-shot) v1-1)
    )
  )

(defmethod bot-method-193 ((this crocadog-escort))
  (let* ((t9-0 (method-of-type bot bot-method-193))
         (v0-0 (t9-0 this))
         )
    (if (and (not v0-0)
             (logtest? (penetrate jak-yellow-shot jak-red-shot jak-blue-shot) (-> this incoming penetrate-using))
             )
        (set! v0-0 #t)
        )
    v0-0
    )
  )

(defmethod enemy-method-79 ((this crocadog-escort) (arg0 int) (arg1 enemy-knocked-info))
  (local-vars (gp-0 symbol))
  (case arg0
    ((3)
     (set! gp-0 (ja-done? 0))
     (let ((f30-0 1.0))
       (if (>= (ja-aframe-num 0) 4.0)
           (set! f30-0 0.25)
           )
       (let ((a0-4 (-> this skel root-channel 0)))
         (set! (-> a0-4 param 0) (the float (+ (-> a0-4 frame-group frames num-frames) -1)))
         (set! (-> a0-4 param 1) f30-0)
         (joint-control-channel-group-eval! a0-4 (the-as art-joint-anim #f) num-func-seek!)
         )
       )
     )
    (else
      (set! gp-0 ((method-of-type bot enemy-method-79) this arg0 arg1))
      )
    )
  gp-0
  )

(defmethod want-exit-vehicle? ((this crocadog-escort) (arg0 vector))
  (let ((s3-0 (handle->process (-> this vehicle-handle))))
    (if (or (not s3-0) (not (-> this nav)))
        (return #f)
        )
    (let ((s4-0 (new 'stack-no-clear 'vector)))
      (compute-seat-position (the-as vehicle s3-0) s4-0 (-> this vehicle-seat-index))
      (vector-! s4-0 s4-0 (-> (the-as vehicle s3-0) root trans))
      (set! (-> s4-0 y) 0.0)
      (vector-normalize! s4-0 (+ 12288.0 (vector-length s4-0)))
      (vector+! s4-0 s4-0 (-> (the-as vehicle s3-0) root trans))
      (let ((s3-1 (new 'stack-no-clear 'collide-query)))
        (when (enemy-above-ground? this s3-1 s4-0 (collide-spec backgnd) 8192.0 81920.0 1024.0)
          (set! (-> s4-0 y) (-> s3-1 best-other-tri intersect y))
          (let ((s3-2 (new 'stack-no-clear 'vector)))
            (do-navigation-to-destination (-> this nav state) (-> this root trans))
            (when (cloest-point-on-mesh (-> this nav) s3-2 s4-0 (the-as nav-poly #f))
              (let ((f0-4 2048.0))
                (when (>= (* f0-4 f0-4) (vector-vector-xz-distance-squared s3-2 s4-0))
                  (set! (-> arg0 quad) (-> s3-2 quad))
                  #t
                  )
                )
              )
            )
          )
        )
      )
    )
  )

(defmethod run-logic? ((this crocadog-escort))
  (or (not (logtest? (process-mask enemy) (-> *setting-control* user-current process-mask)))
      (logtest? (-> this bot-flags) (bot-flags bf09))
      )
  )

(defmethod enemy-method-97 ((this crocadog-escort))
  (let* ((s4-0 (handle->process (-> this attacker-handle)))
         (s5-0 (if (type? s4-0 process-focusable)
                   s4-0
                   )
               )
         )
    (when s5-0
      (when (time-elapsed? (-> this attacker-time) (seconds 3))
        (set! s5-0 (the-as process #f))
        (set! (-> this attacker-handle) (the-as handle #f))
        )
      )
    (handle->process (-> this kid-handle))
    (cond
      (s5-0
        (empty)
        )
      ((begin
         (let ((s4-1 (handle->process (-> this poi-handle))))
           (set! s5-0 (if (type? s4-1 process-focusable)
                          s4-1
                          )
                 )
           )
         s5-0
         )
       (empty)
       )
      (else
        (set! s5-0 (select-focus! this))
        (cond
          (s5-0
            (empty)
            )
          (else
            (let ((s4-2 (handle->process (-> this kid-handle))))
              (set! s5-0 (if (type? s4-2 process-focusable)
                             s4-2
                             )
                    )
              )
            *target*
            (let ((f30-0 -1.0)
                  (f28-0 (vector-vector-distance (target-pos 0) (-> this root trans)))
                  )
              (if s5-0
                  (set! f30-0 (vector-vector-distance (get-trans (the-as process-focusable s5-0) 0) (-> this root trans)))
                  )
              (if (and s5-0 (>= (* 2.0 f28-0) f30-0))
                  (empty)
                  (set! s5-0 *target*)
                  )
              )
            )
          )
        )
      )
    (cond
      (s5-0
        (try-update-focus (-> this focus) (the-as process-focusable s5-0) this)
        (if (and (logtest? (-> this bot-flags) (bot-flags attacked)) (!= (-> s5-0 type) target))
            (logclear! (-> this bot-flags) (bot-flags attacked))
            )
        )
      (else
        (clear-focused (-> this focus))
        (logclear! (-> this bot-flags) (bot-flags attacked))
        )
      )
    s5-0
    )
  )

;; WARN: Return type mismatch object vs symbol.
(defmethod alive? ((this crocadog-escort))
  (let ((t9-0 (method-of-type bot alive?)))
    (the-as symbol (and (t9-0 this) (-> this next-state) (let ((v1-3 (-> this next-state name)))
                                                           (or (= v1-3 'waiting-idle) (= v1-3 'waiting-turn))
                                                           )
                        )
            )
    )
  )

(defmethod init-from-entity! ((this crocadog-escort) (arg0 entity-actor))
  "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that.
This commonly includes things such as:
- stack size
- collision information
- loading the skeleton group / bones
- sounds"
  (stack-size-set! (-> this main-thread) 512)
  ((method-of-type bot init-from-entity!) this arg0)
  (none)
  )

(defmethod init-enemy-collision! ((this crocadog-escort))
  "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 hit-by-others))))
    (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s5-0 reaction) cshape-reaction-default)
    (set! (-> s5-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (set! (-> s5-0 penetrated-by) (penetrate
                                    generic-attack
                                    lunge
                                    flop
                                    punch
                                    spin
                                    roll
                                    uppercut
                                    bonk
                                    tube
                                    vehicle
                                    flut-attack
                                    board
                                    mech-punch
                                    dark-punch
                                    dark-giant
                                    )
          )
    (let ((s4-0 (new 'process 'collide-shape-prim-group s5-0 (the-as uint 1) 0)))
      (set! (-> s5-0 total-prims) (the-as uint 2))
      (set! (-> s4-0 prim-core collide-as) (collide-spec bot))
      (set! (-> s4-0 prim-core collide-with)
            (collide-spec backgnd jak crate civilian enemy obstacle vehicle-sphere hit-by-others-list player-list pusher)
            )
      (set! (-> s4-0 prim-core action) (collide-action solid can-ride no-standon))
      (set-vector! (-> s4-0 local-sphere) 0.0 3276.8 0.0 4505.6)
      (set! (-> s5-0 root-prim) s4-0)
      )
    (let ((v1-13 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-13 prim-core collide-as) (collide-spec bot))
      (set! (-> v1-13 prim-core collide-with)
            (collide-spec backgnd jak crate civilian enemy obstacle vehicle-sphere hit-by-others-list player-list pusher)
            )
      (set! (-> v1-13 prim-core action) (collide-action solid can-ride no-standon))
      (set-vector! (-> v1-13 local-sphere) 0.0 2867.2 0.0 2867.2)
      )
    (set! (-> s5-0 nav-radius) 2662.4)
    (let ((v1-15 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-15 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-15 prim-core collide-with))
      )
    (set! (-> s5-0 max-iteration-count) (the-as uint 3))
    (set! (-> s5-0 event-priority) (the-as uint 1))
    (set! (-> this root) s5-0)
    )
  0
  (none)
  )

(defmethod init! ((this crocadog-escort))
  "Set defaults for various fields."
  (let ((t9-0 (method-of-type bot init!)))
    (t9-0 this)
    )
  (set! (-> this min-speed) 9011.2)
  (set! (-> this max-speed) 28672.0)
  (set! (-> this channel) (gui-channel crocadog))
  (set! (-> this notice-enemy-dist) 24576.0)
  (set! (-> this travel-anim-interp) 0.0)
  (set! (-> this focus-info max-los-dist) 0.0)
  (set-vector! (-> this root scale) 1.2 1.2 1.2 1.0)
  (set! (-> this spot-color) (the-as uint #x5000ff00))
  (set! (-> this kid-handle) (the-as handle #f))
  (set! (-> this vehicle-handle) (the-as handle #f))
  (set-vector! (-> this local-seat-pos) 0.0 819.2 -1638.4 1.0)
  0
  (none)
  )

(defmethod init-enemy! ((this crocadog-escort))
  "Common method called to initialize the enemy, typically sets up default field values and calls ancillary helper methods"
  (init! this)
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-crocadog-escort" (the-as (pointer uint32) #f)))
    (the-as pair 0)
    )
  (init-enemy-behaviour-and-stats! this *crocadog-escort-nav-enemy-info*)
  (let ((v1-7 (-> this neck)))
    (set! (-> v1-7 up) (the-as uint 1))
    (set! (-> v1-7 nose) (the-as uint 2))
    (set! (-> v1-7 ear) (the-as uint 0))
    (set-vector! (-> v1-7 twist-max) 11832.889 11832.889 0.0 1.0)
    (set! (-> v1-7 ignore-angle) 30947.555)
    )
  (let ((t9-4 (method-of-type bot init-enemy!)))
    (t9-4 this)
    )
  (let ((v1-10 (-> this nav)))
    (set! (-> v1-10 sphere-mask) (the-as uint 126))
    )
  0
  (set! (-> this my-simple-focus) (process-spawn simple-focus :to this))
  (set! (-> this draw light-index) (the-as uint 10))
  0
  (none)
  )

(defmethod bot-method-214 ((this crocadog-escort))
  #f
  )

(defmethod check-vehicle-exit ((this crocadog-escort))
  (local-vars (v1-22 enemy-flag))
  (when (focus-test? this pilot)
    (let ((v1-4 (handle->process (-> this vehicle-handle))))
      (when (or (not v1-4) (logtest? (-> (the-as vehicle v1-4) flags) (rigid-body-object-flag dead)))
        (logior! (-> this bot-flags) (bot-flags bf17))
        (logclear! (-> this bot-flags) (bot-flags bf15))
        (logclear! (-> this focus-status) (focus-status pilot-riding pilot))
        (set! (-> this vehicle-seat-index) -1)
        (set! (-> this vehicle-handle) (the-as handle #f))
        (logior! (-> this root nav-flags) (nav-flags has-root-sphere))
        (let* ((s5-0 (-> this root quat))
               (f30-0 (quaternion-y-angle s5-0))
               )
          (quaternion-identity! s5-0)
          (quaternion-rotate-y! s5-0 s5-0 f30-0)
          )
        (let ((v1-21 (-> this enemy-flags)))
          (if (logtest? v1-21 (enemy-flag vulnerable-backup))
              (set! v1-22 (logior v1-21 (enemy-flag vulnerable)))
              (set! v1-22 (logclear v1-21 (enemy-flag vulnerable)))
              )
          )
        (set! (-> this enemy-flags) v1-22)
        (let ((f30-2 (+ 16384.0 (quaternion-y-angle (-> this root quat))))
              (s5-1 (new 'stack-no-clear 'vector))
              )
          (set-vector! s5-1 (sin f30-2) 0.0 (cos f30-2) 1.0)
          (vector-normalize! s5-1 65536.0)
          (send-event
            this
            'attack
            #f
            (static-attack-info
              ((id (new-attack-id)) (vector s5-1) (attacker-velocity s5-1) (knock (knocked-type knocked-type-8)))
              )
            )
          )
        )
      )
    )
  0
  (none)
  )

(defmethod go-hostile ((this crocadog-escort))
  (cond
    ((logtest? (bot-flags bf17) (-> this bot-flags))
     (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 mask) (process-mask collectable))
     (logclear! (-> this enemy-flags) (enemy-flag attackable-backup))
     (logclear! (-> this mask) (process-mask actor-pause))
     (logclear! (-> this enemy-flags) (enemy-flag actor-pause-backup))
     (logior! (-> this focus-status) (focus-status disable))
     (go (method-of-object this knocked-off-vehicle))
     )
    (else
      (react-to-focus this)
      )
    )
  )

;; WARN: Return type mismatch none vs object.
(defmethod react-to-focus ((this crocadog-escort))
  "@TODO - flesh out docs"
  (go-idle-or-move this)
  )

;; WARN: Return type mismatch object vs none.
(defmethod go-waiting-turn ((this crocadog-escort))
  (go (method-of-object this waiting-turn))
  (none)
  )

;; WARN: Return type mismatch object vs none.
(defmethod go-idle-or-move ((this crocadog-escort))
  (if (logtest? (-> this bot-flags) (bot-flags bf15))
      (go (method-of-object this move-to-vehicle))
      (go (method-of-object this waiting-idle))
      )
  (none)
  )

(defmethod play-walk-anim ((this crocadog-escort))
  (with-pp
    (let ((f30-0 (-> this nav state speed)))
      (let ((f0-1 (lerp-scale 0.0 1.0 f30-0 9011.2 28672.0)))
        (seek! (-> this travel-anim-interp) f0-1 (* 4.0 (seconds-per-frame)))
        )
      (let ((f28-0 (-> this travel-anim-interp))
            (v1-7 (if (> (-> this skel active-channels) 0)
                      (-> this skel root-channel 0 frame-group)
                      )
                  )
            )
        (cond
          ((and v1-7 (= v1-7 (-> this draw art-group data 7)))
           (let ((v1-12 (-> this skel root-channel 1)))
             (set! (-> v1-12 frame-interp 1) f28-0)
             (set! (-> v1-12 frame-interp 0) f28-0)
             )
           (let* ((f28-1 (current-cycle-distance (-> this skel)))
                  (f0-5 (quaternion-y-angle (-> this root quat)))
                  (f1-2 (deg- f0-5 (-> this travel-prev-ry)))
                  (f0-8 (fmin 28672.0 (* 0.15707962 (-> pp clock frames-per-second) (fabs f1-2))))
                  (f0-11 (/ (* 7.0 (fmax f30-0 f0-8)) (* 15.0 f28-1)))
                  (a0-10 (-> this skel root-channel 0))
                  )
             (set! (-> a0-10 param 0) f0-11)
             (joint-control-channel-group-eval! a0-10 (the-as art-joint-anim #f) num-func-loop!)
             )
           (let ((a0-11 (-> this skel root-channel 1)))
             (set! (-> a0-11 param 0) 0.0)
             (joint-control-channel-group-eval! a0-11 (the-as art-joint-anim #f) num-func-chan)
             )
           )
          (else
            (ja-channel-push! 2 (seconds 0.15))
            (let ((a0-13 (-> this skel root-channel 0)))
              (set! (-> a0-13 dist) 4206.592)
              (set! (-> a0-13 frame-group) (the-as art-joint-anim (-> this draw art-group data 7)))
              (set! (-> a0-13 param 0) 1.0)
              (joint-control-channel-group! a0-13 (the-as art-joint-anim (-> this draw art-group data 7)) num-func-loop!)
              )
            (let ((a0-14 (-> this skel root-channel 1)))
              (set! (-> a0-14 frame-interp 1) f28-0)
              (set! (-> a0-14 frame-interp 0) f28-0)
              (set! (-> a0-14 dist) 13393.92)
              (set! (-> a0-14 frame-group) (the-as art-joint-anim (-> this draw art-group data 8)))
              (set! (-> a0-14 param 0) 0.0)
              (joint-control-channel-group! a0-14 (the-as art-joint-anim (-> this draw art-group data 8)) num-func-chan)
              )
            )
          )
        )
      )
    (none)
    )
  )

(defmethod damage-amount-from-attack ((this crocadog-escort) (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]]"
  0
  )

(defmethod bot-method-190 ((this crocadog-escort))
  #t
  )

(defmethod enemy-method-78 ((this crocadog-escort) (arg0 enemy-knocked-info))
  (ja-channel-push! 1 (seconds 0.1))
  (let ((a1-2 (-> this draw art-group data (-> this enemy-info knocked-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
  )

;; WARN: Return type mismatch object vs none.
(defmethod go-idle ((this crocadog-escort))
  (cond
    ((task-node-closed? (game-task-node city-escort-kid-resolution))
     (cleanup-for-death this)
     (go (method-of-object this die-fast))
     )
    (else
      (go-idle-or-move this)
      )
    )
  (none)
  )
