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

;; name: target-pilot.gc
;; name in dgo: target-pilot
;; dgos: CWI

(deftype collide-query-with-5vec (structure)
  "A custom type"
  ((cquery collide-query :inline)
   (vec    vector 5 :inline)
   )
  )

;; added for hijack lines cheat
(define *jak-hijack-speeches* (new 'static 'boxed-array :type string
    "jak040" "jak041" "jak042" "jak044" "jak045" "jak046"
    "jak047" "jak048" "jak049" "jak050" "jak051" "jak052"
    "jak053" "jak054" "jak055"
    )
  )

(define *civ-hijack-speeches* (new 'static 'boxed-array :type string
    "cit051" "cit053" "cit055" "cit056" "cit057" "cit058"
    )
  )

;; DECOMP BEGINS

(define *pilot-mods* (new 'static 'surface :name 'empty :seek0 1.0 :seek90 1.0 :seek180 1.0 :fric 1.0))

;; WARN: disable def twice: 124. This may happen when a cond (no else) is nested inside of another conditional, but it should be rare.
(defbehavior target-pilot-handler target ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  (cond
    ((and (= arg2 'query) (= (-> arg3 param 0) 'mode))
     'pilot
     )
    (else
      (case arg2
        (('end-mode)
         (let ((v1-4 (-> self pilot)))
           (when (nonzero? v1-4)
             (let ((a0-5 (handle->process (-> v1-4 vehicle))))
               (if a0-5
                   (put-rider-in-seat (the-as vehicle a0-5) (-> v1-4 seat-index) (the-as process-focusable #f))
                   )
               )
             )
           )
         enter-state
         (process->handle arg0)
         (go target-pilot-get-off)
         )
        (('change-mode)
         (case (-> arg3 param 0)
           (('grab)
            (when (not (focus-test? self dead))
              (if (not (-> arg3 param 1))
                  #t
                  (go target-pilot-grab)
                  )
              )
            )
           (('normal)
            enter-state
            (process->handle arg0)
            (go target-pilot-get-off)
            )
           (('gun)
            (if (logtest? (-> self game features) (game-feature gun))
                (target-gun-init (the-as pickup-type (-> arg3 param 2)))
                )
            )
           )
         )
        (('swim)
         #f
         )
        (('clone-anim)
         (go target-pilot-clone-anim (process->handle (the-as process (-> arg3 param 0))))
         )
        (('get-vehicle)
         (if (nonzero? (-> self pilot))
             (handle->process (-> self pilot vehicle))
             )
         )
        (('attack 'attack-or-shove 'attack-invinc)
         (target-attacked
           arg2
           (the-as attack-info (-> arg3 param 1))
           arg0
           (the-as touching-shapes-entry (-> arg3 param 0))
           target-pilot-hit
           )
         )
        (('vehicle-hit)
         (speech-control-method-12 *speech-control* self (if (-> self pilot as-daxter?)
                                                             (speech-type speech-type-42)
                                                             (speech-type speech-type-33)
                                                             )
                                   )
         )
        (('vehicle-got-hit)
         (speech-control-method-12 *speech-control* self (if (-> self pilot as-daxter?)
                                                             (speech-type speech-type-43)
                                                             (speech-type speech-type-34)
                                                             )
                                   )
         )
        (else
          (target-standard-event-handler arg0 arg1 arg2 arg3)
          )
        )
      )
    )
  )

(defbehavior target-pilot-pidax-enter target ()
  (set! (-> self pilot art-group-backup) (-> self draw art-group))
  (set! (-> self draw art-group) (-> self sidekick 0 draw art-group))
  (logior! (-> self draw status) (draw-control-status no-draw-bounds2))
  (send-event (ppointer->process (-> self sidekick)) 'matrix 'indax)
  )

(defbehavior target-pilot-pidax-exit target ()
  (ja-channel-set! 0)
  (set! (-> self draw art-group) (the-as art-group (-> self pilot art-group-backup)))
  (logclear! (-> self draw status) (draw-control-status no-draw-bounds2))
  (send-event (ppointer->process (-> self sidekick)) 'matrix #f)
  )

;; WARN: Return type mismatch none vs object.
(defbehavior target-pilot-exit target ()
  (when (not (and (-> self next-state) (let ((v1-3 (-> self next-state name)))
                                         (or (= v1-3 'target-pilot-stance)
                                             (= v1-3 'target-pilot-impact)
                                             (= v1-3 'target-pilot-get-off)
                                             (= v1-3 'target-pilot-grab)
                                             (= v1-3 'target-pilot-clone-anim)
                                             (= v1-3 'target-pilot-hit)
                                             (= v1-3 'target-pilot-death)
                                             )
                                         )
                  )
             )
    (let ((v1-4 (-> self manipy)))
      (when v1-4
        (deactivate (-> v1-4 0))
        (set! (-> self manipy) (the-as (pointer manipy) #f))
        )
      )
    (if (-> self pilot as-daxter?)
        (target-pilot-pidax-exit)
        )
    (let ((v1-11 (-> self pilot)))
      (when (nonzero? v1-11)
        (set! (-> self control nav-radius) (-> v1-11 backup-nav-radius))
        (let ((gp-0 (handle->process (-> v1-11 vehicle))))
          (when gp-0
            (remove-rider (the-as vehicle gp-0) self)
            (send-event gp-0 'player-get-off)
            )
          )
        )
      )
    (set! (-> self neck flex-blend) 1.0)
    (let ((v1-22 (-> self control root-prim)))
      (set! (-> v1-22 prim-core collide-as) (-> self control backup-collide-as))
      (set! (-> v1-22 prim-core collide-with) (-> self control backup-collide-with))
      )
    (logclear! (-> self focus-status) (focus-status pilot-riding pilot))
    (logclear! (-> self control root-prim prim-core action) (collide-action stuck-wall-escape))
    (set! (-> self control mod-surface) *walk-mods*)
    (logclear! (-> self state-flags) (state-flags sf6))
    (enable-set! (-> self arm-ik 0) #f)
    (enable-set! (-> self arm-ik 1) #f)
    (set! (-> self control dynam gravity-max) (-> self control standard-dynamics gravity-max))
    (set! (-> self control dynam gravity-length) (-> self control standard-dynamics gravity-length))
    (let ((v1-43 (-> self node-list data)))
      (set! (-> v1-43 0 param0) (the-as (function cspace transformq none) cspace<-transformq+trans!))
      (set! (-> v1-43 0 param1) (the-as basic (-> self control trans)))
      (set! (-> v1-43 0 param2) (the-as basic (-> self control cspace-offset)))
      )
    (target-collide-set! 'normal 0.0)
    (set! (-> self control reaction) target-collision-reaction)
    (set! (-> self control cspace-offset quad) (the-as uint128 0))
    (target-exit)
    )
  )

;; WARN: Return type mismatch int vs object.
(defbehavior target-pilot-init target ((arg0 handle) (arg1 symbol))
  (target-exit)
  (if (zero? (-> self pilot))
      (set! (-> self pilot) (new 'process 'pilot-info))
      )
  (let ((s5-0 (-> self pilot)))
    (set! (-> s5-0 backup-nav-radius) (-> self control nav-radius))
    (set! (-> s5-0 gun?) #t)
    (set! (-> s5-0 enable-cam-side-shift) #f)
    (set! (-> s5-0 as-daxter?) arg1)
    (set! (-> s5-0 entity) #f)
    (set! (-> s5-0 cam-side-shift) 0.0)
    (if (-> self pilot as-daxter?)
        (target-pilot-pidax-enter)
        )
    (cond
      ((handle->process arg0)
       (set! (-> s5-0 vehicle) arg0)
       )
      (else
        (break!)
        0
        )
      )
    (let ((s4-1 (handle->process (-> s5-0 vehicle))))
      (when s4-1
        (set! (-> s5-0 entity) (-> s4-1 entity))
        (set! (-> s5-0 gun?) (logtest? (-> (the-as vehicle s4-1) info flags) 32))
        (set! (-> s5-0 enable-cam-side-shift) (logtest? (-> (the-as vehicle s4-1) info flags) 128))
        (send-event
          (ppointer->process (-> (the-as vehicle s4-1) parent))
          'player-got-on-vehicle-child
          (the-as vehicle s4-1)
          )
        (set! (-> s5-0 stance) (vehicle-method-72 (the-as vehicle s4-1)))
        (let ((s3-0 (get-seat-count (the-as vehicle s4-1))))
          (dotimes (s2-0 s3-0)
            (let ((a0-20 (get-rider-in-seat (the-as vehicle s4-1) s2-0)))
              ;; og:preserve-this added for hijack lines cheat
              (when (and a0-20 (or (type-type? (-> a0-20 type) citizen-norm-rider) (type-type? (-> a0-20 type) crimson-guard-rider)))
                (let ((cheat? (pc-cheats? (-> *pc-settings* cheats) hijack-lines))
                      (chance? (rand-vu-percent? (-> *pc-cheat-state* hijack-speech-chance))))
                  (when (and cheat? chance?)
                    (add-process *gui-control* self (gui-channel jak) (gui-action play)
                      (-> *jak-hijack-speeches* (rand-vu-int-range 0 (1- (-> *jak-hijack-speeches* length)))) -99.0 0)
                    (if (type-type? (-> a0-20 type) citizen-norm-rider)
                      (add-process *gui-control* self (gui-channel jak) (gui-action play)
                        (-> *civ-hijack-speeches* (rand-vu-int-range 0 (1- (-> *civ-hijack-speeches* length)))) -99.0 0)
                      )
                    )
                  )
                )
              (if (and a0-20 (send-event a0-20 'knocked-off))
                  (put-rider-in-seat (the-as vehicle s4-1) s2-0 (the-as process-focusable #f))
                  )
              )
            )
          )
        ;; og:preserve-this cast
        (let ((v1-43 (get-best-seat-for-vehicle (the-as vehicle s4-1) (-> self control trans) 1 1)))
          (set! (-> s5-0 seat-index) (max 0 v1-43))
          )
        (cond
          ((-> s5-0 as-daxter?)
           (set! (-> s5-0 left-right-accel-factor) 0.0000012207031)
           (set! (-> s5-0 front-back-accel-factor) 0.0000012207031)
           (set! (-> s5-0 up-down-accel-factor) 0.0000012207031)
           )
          ((zero? (-> s5-0 stance))
           (set! (-> s5-0 left-right-accel-factor) 0.0000012207031)
           (set! (-> s5-0 front-back-accel-factor) 0.0000012207031)
           (set! (-> s5-0 up-down-accel-factor) 0.00000051879886)
           )
          (else
            (set! (-> s5-0 left-right-accel-factor) 0.0000012207031)
            (set! (-> s5-0 front-back-accel-factor) 0.0000012207031)
            (set! (-> s5-0 up-down-accel-factor) 0.00000061035155)
            )
          )
        )
      )
    (when (not (-> s5-0 gun?))
      (if arg1
          (logior! (-> self control current-surface flags) (surface-flag gun-fast-exit))
          )
      (target-gun-end-mode arg1)
      )
    )
  (set! (-> self board latch?) #f)
  (set! (-> self control reaction) target-collision-reaction)
  (set! (-> self control transv quad) (the-as uint128 0))
  (set! (-> self control ctrl-xz-vel) 0.0)
  (logior! (-> self focus-status) (focus-status pilot))
  (set! (-> self control bend-target) 0.0)
  (let ((v1-73 (-> self node-list data)))
    (set! (-> v1-73 0 param0) (the-as (function cspace transformq none) cspace<-transformq+world-trans!))
    (set! (-> v1-73 0 param1) (the-as basic (-> self control trans)))
    (set! (-> v1-73 0 param2) (the-as basic (-> self control cspace-offset)))
    )
  (let ((v1-75 (-> self control root-prim)))
    (set! (-> v1-75 prim-core collide-as) (collide-spec))
    (set! (-> v1-75 prim-core collide-with) (collide-spec))
    )
  0
  (set! (-> self control root-prim prim-core collide-as) (collide-spec jak-vehicle))
  (set! (-> self neck flex-blend) 0.0)
  (set! (-> self control status) (collide-status))
  0
  )

(defbehavior pilot-on-ground? target ()
  (logtest? (-> self control status) (collide-status on-surface))
  )

(defbehavior target-pilot-post target ()
  (local-vars (v1-55 symbol) (a0-44 object) (a0-56 int) (a0-58 int))
  (let* ((v1-1 (-> *perf-stats* data 17))
         (a0-0 (-> v1-1 ctrl))
         )
    (+! (-> v1-1 count) 1)
    (b! (zero? a0-0) cfg-2 :delay (nop!))
    (.mtc0 Perf 0)
    (.sync.l)
    (.sync.p)
    (.mtpc pcr0 0)
    (.mtpc pcr1 0)
    (.sync.l)
    (.sync.p)
    (.mtc0 Perf a0-0)
    )
  (.sync.l)
  (.sync.p)
  (label cfg-2)
  0
  (let ((f30-0 (-> self clock clock-ratio)))
    (let ((gp-1 (max 1 (the int (-> self clock time-adjust-ratio)))))
      (update-rates! (-> self clock) (/ f30-0 (the float gp-1)))
      (b! #t cfg-4 :delay (nop!))
      (label cfg-3)
      (+! gp-1 -1)
      (set! (-> self control remaining-ctrl-iterations) gp-1)
      (flag-setup)
      (build-conversions (-> self control transv))
      (do-rotations1)
      (do-rotations2)
      (reverse-conversions (-> self control transv))
      (vector-!
        (-> self control cspace-offset)
        (-> self control draw-offset)
        (-> self control anim-collide-offset-world)
        )
      (let ((a1-5 (new 'stack-no-clear 'overlaps-others-params)))
        (set! (-> a1-5 options) (overlaps-others-options oo0))
        (set! (-> a1-5 collide-with-filter) (the-as collide-spec -1))
        (set! (-> a1-5 tlist) *touching-list*)
        (find-overlapping-shapes (-> self control) a1-5)
        )
      (post-flag-setup)
      (label cfg-4)
      (b! (nonzero? gp-1) cfg-3 :delay (nop!))
      )
    (update-rates! (-> self clock) f30-0)
    )
  (let* ((gp-2 (-> self pilot))
         (s5-0 (handle->process (-> gp-2 vehicle)))
         )
    (when s5-0
      (compute-seat-position (the-as vehicle s5-0) (-> self control trans) (-> gp-2 seat-index))
      (set! (-> self control transv quad) (-> (the-as vehicle s5-0) root transv quad))
      (quaternion-copy! (-> self control quat) (-> (the-as vehicle s5-0) root quat))
      (quaternion-copy! (-> self control quat-for-control) (-> self control quat))
      (quaternion-copy! (-> self control dir-targ) (-> self control quat))
      (let ((s4-0 (-> self alt-cam-pos)))
        (when (not (focus-test? self dead))
          (let ((s3-0 (new 'stack-no-clear 'collide-query-with-5vec)))
            (set! (-> s3-0 vec 2 x) 0.0)
            (set! (-> s3-0 vec 2 y) 20480.0)
            (let ((a0-18 (-> self node-list data 0 bone transform)))
              (set! (-> s3-0 vec 1 quad) (-> a0-18 vector 2 quad))
              )
            (set! (-> s3-0 vec 1 y) 0.0)
            (vector-rotate90-around-y! (-> s3-0 vec 1) (-> s3-0 vec 1))
            (vector-normalize! (-> s3-0 vec 1) 1.0)
            (set! (-> s3-0 vec 0 quad) (-> self control trans quad))
            (when (-> gp-2 enable-cam-side-shift)
              (let ((s2-0 0))
                (b! #t cfg-22 :delay (nop!))
                (label cfg-14)
                (let ((v1-48 (-> s3-0 cquery)))
                  (set! (-> v1-48 radius) 2048.0)
                  (set! (-> v1-48 collide-with) (collide-spec backgnd))
                  (set! (-> v1-48 ignore-process0) #f)
                  (set! (-> v1-48 ignore-process1) #f)
                  (set! (-> v1-48 ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1))
                  (set! (-> v1-48 action-mask) (collide-action solid))
                  )
                (set! (-> s3-0 cquery start-pos quad) (-> s3-0 vec 0 quad))
                (vector-float*! (-> s3-0 cquery move-dist) (-> s3-0 vec 1) (-> s3-0 vec 2 y))
                (let ((f0-10 (fill-and-probe-using-line-sphere *collide-cache* (-> s3-0 cquery))))
                  (let ((v1-54 (>= f0-10 0.0)))
                    (b! (not v1-54) cfg-19 :likely-delay (set! v1-55 v1-54))
                    )
                  (set! v1-55 (= (-> s3-0 cquery best-other-tri pat mode) (pat-mode wall)))
                  (label cfg-19)
                  (when v1-55
                    (+! (-> s3-0 vec 2 x) (* -1.0 (-> s3-0 vec 2 y) (- 1.0 f0-10)))
                    0
                    )
                  )
                (set! (-> s3-0 vec 2 y) (* -1.0 (-> s3-0 vec 2 y)))
                (+! s2-0 1)
                (label cfg-22)
                (b! (< s2-0 2) cfg-14)
                )
              (set! (-> s3-0 vec 2 x)
                    (* (-> s3-0 vec 2 x) (fmax 0.25 (fmin 1.0 (* 0.000008138021 (vector-length (-> self control transv))))))
                    )
              (seek! (-> gp-2 cam-side-shift) (-> s3-0 vec 2 x) (* 16384.0 (seconds-per-frame)))
              )
            (set! (-> s4-0 x) (+ (-> s3-0 vec 0 x) (* (-> gp-2 cam-side-shift) (-> s3-0 vec 1 x))))
            (set! (-> s4-0 z) (+ (-> s3-0 vec 0 z) (* (-> gp-2 cam-side-shift) (-> s3-0 vec 1 z))))
            (set! (-> s4-0 y) (fmax (fmin (-> s4-0 y) (+ 2048.0 (-> s3-0 vec 0 y))) (+ -2048.0 (-> s3-0 vec 0 y))))
            )
          0
          )
        )
      (let ((s4-1 (new 'stack-no-clear 'matrix)))
        (vehicle-method-117 (the-as vehicle s5-0) (the-as vector (-> s4-1 vector)) (-> gp-2 seat-index) 0)
        (vehicle-method-117 (the-as vehicle s5-0) (-> s4-1 vector 1) (-> gp-2 seat-index) 1)
        (enable-set! (-> self arm-ik 0) #t)
        (enable-set! (-> self arm-ik 1) #t)
        (handle-copy! (-> self arm-ik 0) (the-as vector (-> s4-1 vector)))
        (handle-copy! (-> self arm-ik 1) (-> s4-1 vector 1))
        )
      )
    )
  (when *debug-segment*
    (let ((gp-3 (-> *display* frames (-> *display* on-screen) profile-array data 0))
          (v1-97 'target-post)
          (s5-1 *profile-target-post-color*)
          )
      (let ((a0-43 *dproc*))
        (b! (not a0-43) cfg-30 :likely-delay (set! a0-44 a0-43))
        )
      (set! a0-44 *debug-segment*)
      (label cfg-30)
      (when a0-44
        (let ((s4-2 (-> gp-3 data (-> gp-3 count))))
          (let ((s3-1 (-> gp-3 base-time)))
            (set! (-> s4-2 name) v1-97)
            (set! (-> s4-2 start-time) (the-as int (- (timer-count (the-as timer-bank #x10000800)) (the-as uint s3-1))))
            )
          (set! (-> s4-2 depth) (the-as uint (-> gp-3 depth)))
          (set! (-> s4-2 color) s5-1)
          (set! (-> gp-3 segment (-> gp-3 depth)) s4-2)
          )
        (+! (-> gp-3 count) 1)
        (+! (-> gp-3 depth) 1)
        (set! (-> gp-3 max-depth) (max (-> gp-3 max-depth) (-> gp-3 depth)))
        )
      )
    0
    )
  (ja-post)
  (when *debug-segment*
    (let ((gp-4 (-> *display* frames (-> *display* on-screen) profile-array data 0)))
      (when (and *dproc* *debug-segment*)
        (let* ((v1-121 (+ (-> gp-4 depth) -1))
               (s5-2 (-> gp-4 segment v1-121))
               (s4-3 (-> gp-4 base-time))
               )
          (when (>= v1-121 0)
            (set! (-> s5-2 end-time) (the-as int (- (timer-count (the-as timer-bank #x10000800)) (the-as uint s4-3))))
            (+! (-> gp-4 depth) -1)
            )
          )
        )
      )
    0
    )
  (joint-points)
  (update-transforms (-> self control))
  (do-target-gspot)
  (target-powerup-process)
  (let ((v1-130 (-> *perf-stats* data 17)))
    (b! (zero? (-> v1-130 ctrl)) cfg-43 :delay (nop!))
    (.mtc0 Perf 0)
    (.sync.l)
    (.sync.p)
    (.mfpc a0-56 pcr0)
    (+! (-> v1-130 accum0) a0-56)
    (.mfpc a0-58 pcr1)
    (+! (-> v1-130 accum1) a0-58)
    )
  (label cfg-43)
  0
  0
  (none)
  )
