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

;; name: kleever-rider.gc
;; name in dgo: kleever-rider
;; dgos: DESRALLY, DESTRACK

(deftype kleever-rider-stack-var0 (structure)
  ((mat0 matrix :inline :offset 0)
   (vec0 vector :inline :offset 64)
   (vec1 vector :inline :offset 80)
   (vec2 vector :inline :offset 96)
   (time uint32         :offset 112)
   )
  )

;; DECOMP BEGINS

(deftype kleever-rider (process-focusable)
  ((vehicle            handle)
   (speech-time        time-frame)
   (accel              vector  :inline)
   (accel-factor       vector  :inline)
   (front-back-interp  float)
   (left-right-interp  float)
   (up-down-interp     float)
   )
  (:state-methods
    idle
    die
    )
  )


(defskelgroup skel-kleever-rider kleever-rider kleever-rider-lod0-jg kleever-rider-idle-ja
              ((kleever-rider-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 4)
              )

;; WARN: Return type mismatch float vs none.
(defbehavior kleever-pilot-trans kleever-rider ()
  (let ((gp-0 (new 'stack-no-clear 'kleever-rider-stack-var0)))
    (let ((a0-1 (handle->process (-> self vehicle))))
      (when a0-1
        (vector-copy! (-> gp-0 vec1) (-> (the-as wvehicle a0-1) lin-acceleration))
        (matrix-copy! (-> gp-0 mat0) (-> (the-as wvehicle a0-1) rbody matrix))
        )
      )
    (set! (-> gp-0 time) (the-as uint (current-time)))
    (set! (-> gp-0 vec2 x) (* 99.29697 (the float (-> gp-0 time))))
    (set! (-> gp-0 vec2 z) (sin (-> gp-0 vec2 x)))
    (set! (-> gp-0 vec2 w) (cos (-> gp-0 vec2 x)))
    (set! (-> gp-0 vec2 y) (seconds-per-frame))
    (set! (-> gp-0 vec0 x) (vector-dot (-> gp-0 vec1) (-> gp-0 mat0 rvec)))
    (set! (-> gp-0 vec0 y) (vector-dot (-> gp-0 vec1) (-> gp-0 mat0 uvec)))
    (set! (-> gp-0 vec0 z) (vector-dot (-> gp-0 vec1) (-> gp-0 mat0 fvec)))
    (let ((f1-6 (+ (* 0.03 (-> gp-0 vec2 z)) (* -1.0 (-> gp-0 vec0 x) (-> self accel-factor x)))))
      (+! (-> self left-right-interp) (* (- f1-6 (-> self left-right-interp)) (fmin 1.0 (* 8.0 (-> gp-0 vec2 y)))))
      )
    (set! (-> self left-right-interp) (fmax -1.0 (fmin 1.0 (-> self left-right-interp))))
    (let ((f1-15 (+ (* 0.03 (-> gp-0 vec2 w)) (* -1.0 (-> gp-0 vec0 z) (-> self accel-factor z)))))
      (+! (-> self front-back-interp) (* (- f1-15 (-> self front-back-interp)) (fmin 1.0 (* 8.0 (-> gp-0 vec2 y)))))
      )
    (set! (-> self front-back-interp) (fmax -1.0 (fmin 1.0 (-> self front-back-interp))))
    (let ((f1-24 (+ (* 0.03 (-> gp-0 vec2 w)) (* -1.0 (-> gp-0 vec0 y) (-> self accel-factor y)))))
      (+! (-> self up-down-interp) (* (- f1-24 (-> self up-down-interp)) (fmin 1.0 (* 8.0 (-> gp-0 vec2 y)))))
      )
    )
  (set! (-> self up-down-interp) (fmax -1.0 (fmin 1.0 (-> self up-down-interp))))
  (none)
  )

;; WARN: Return type mismatch symbol vs none.
;; WARN: new jak 2 until loop case, check carefully
(defbehavior kleever-pilot-wcar-anim-loop kleever-rider ()
  (ja-channel-set! 3)
  (ja :group! kleever-rider-pilot-car-turn-back-ja)
  (ja :chan 1 :group! kleever-rider-pilot-car-turn-front-ja)
  (ja :chan 2 :group! kleever-rider-pilot-car-up-down-ja)
  (until #f
    (let ((f30-0 (* 5.0 (+ 1.0 (-> self left-right-interp)))))
      (ja :num-func num-func-identity :frame-num (ja-aframe f30-0 0))
      (let ((gp-1 (-> self skel root-channel 1)))
        (let ((f0-3 (* 0.5 (+ 1.0 (-> self front-back-interp)))))
          (set! (-> gp-1 frame-interp 1) f0-3)
          (set! (-> gp-1 frame-interp 0) f0-3)
          )
        (set! (-> gp-1 num-func) num-func-identity)
        (set! (-> gp-1 frame-num) (ja-aframe f30-0 1))
        )
      )
    (let ((f0-6 (* 5.0 (- 1.0 (-> self up-down-interp))))
          (gp-2 (-> self skel root-channel 2))
          )
      (let ((f1-7 (fabs (-> self up-down-interp))))
        (set! (-> gp-2 frame-interp 1) f1-7)
        (set! (-> gp-2 frame-interp 0) f1-7)
        )
      (set! (-> gp-2 num-func) num-func-identity)
      (set! (-> gp-2 frame-num) (ja-aframe f0-6 2))
      )
    (suspend)
    )
  #f
  (none)
  )

(defstate idle (kleever-rider)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('race-pass)
       (speech-control-method-12 *speech-control* self (speech-type race-errol-pass))
       )
      (('race-got-passed)
       (speech-control-method-12 *speech-control* self (speech-type race-errol-got-passed))
       )
      (('attack-invinc)
       (go-virtual die)
       )
      )
    )
  :trans (behavior ()
    (kleever-pilot-trans)
    (when (time-elapsed? (-> self speech-time) (seconds 1))
      (set-time! (-> self speech-time))
      (let ((v1-6 (handle->process (-> self vehicle))))
        (if (and v1-6 (< 61440.0 (vector-length (-> (the-as process-drawable v1-6) root transv))))
            (speech-control-method-12 *speech-control* self (speech-type race-errol-ambient))
            )
        )
      )
    )
  :code (behavior ()
    (kleever-pilot-wcar-anim-loop)
    (sleep-code)
    )
  :post ja-post
  )

(defstate die (kleever-rider)
  :virtual #t
  :code (behavior ()
    (cleanup-for-death self)
    )
  )

(defbehavior kleever-rider-init-by-other kleever-rider ((arg0 vehicle))
  (let ((s5-0 (new 'process 'collide-shape self (collide-list-enum hit-by-player))))
    (set! (-> s5-0 penetrated-by) (the-as penetrate -1))
    (let ((v1-3 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-3 prim-core collide-as) (collide-spec bot))
      (set! (-> v1-3 transform-index) 3)
      (set-vector! (-> v1-3 local-sphere) 0.0 0.0 0.0 0.0)
      (set! (-> s5-0 total-prims) (the-as uint 1))
      (set! (-> s5-0 root-prim) v1-3)
      )
    (set! (-> s5-0 nav-radius) (* 0.75 (-> s5-0 root-prim local-sphere w)))
    (let ((v1-6 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-6 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-6 prim-core collide-with))
      )
    (set! (-> self root) s5-0)
    )
  (vector-copy! (-> self root trans) (-> arg0 root trans))
  (quaternion-copy! (-> self root quat) (-> arg0 root quat))
  (set! (-> self level) (level-get *level* 'destrack))
  (initialize-skeleton
    self
    (the-as skeleton-group (art-group-get-by-name *level* "skel-kleever-rider" (the-as (pointer level) #f)))
    (the-as pair 0)
    )
  (logclear! (-> self mask) (process-mask actor-pause))
  (set-time! (-> self speech-time))
  (set! (-> self vehicle) (process->handle arg0))
  (let ((a1-7 (get-best-seat arg0 (-> self root trans) (vehicle-seat-flag vsf0) 0)))
    (when (!= a1-7 -1)
      (put-rider-in-seat arg0 a1-7 self)
      (logior! (-> self focus-status) (focus-status pilot-riding))
      )
    )
  (vector-float*!
    (-> self accel-factor)
    (new 'static 'vector :x 0.000009765625 :y 0.000009765625 :z 0.0000048828124 :w 1.0)
    1.0
    )
  (go-virtual idle)
  )

;; WARN: Return type mismatch process vs kleever-rider.
(defun kleever-rider-spawn ((arg0 process))
  (let ((gp-0 (the-as process #f)))
    (let ((v1-1 (process-spawn kleever-rider arg0 :name "kleever-rider" :to arg0)))
      (if v1-1
          (set! gp-0 (-> v1-1 0))
          )
      )
    (the-as kleever-rider gp-0)
    )
  )

(deftype wland-driver (process-focusable)
  ((vehicle            handle)
   (accel              vector  :inline)
   (accel-factor       vector  :inline)
   (front-back-interp  float)
   (left-right-interp  float)
   (up-down-interp     float)
   )
  (:state-methods
    idle
    die
    )
  )


(defskelgroup skel-wland-driver wland-driver wland-driver-lod0-jg -1
              ((wland-driver-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 4)
              )

;; WARN: Return type mismatch float vs none.
(defbehavior wland-driver-pilot-trans wland-driver ()
  (let ((gp-0 (new 'stack-no-clear 'kleever-rider-stack-var0)))
    (let ((a0-1 (handle->process (-> self vehicle))))
      (when a0-1
        (vector-copy! (-> gp-0 vec1) (-> (the-as wvehicle a0-1) lin-acceleration))
        (matrix-copy! (-> gp-0 mat0) (-> (the-as wvehicle a0-1) rbody matrix))
        )
      )
    (set! (-> gp-0 time) (the-as uint (current-time)))
    (set! (-> gp-0 vec2 x) (* 99.29697 (the float (-> gp-0 time))))
    (set! (-> gp-0 vec2 z) (sin (-> gp-0 vec2 x)))
    (set! (-> gp-0 vec2 w) (cos (-> gp-0 vec2 x)))
    (set! (-> gp-0 vec2 y) (seconds-per-frame))
    (set! (-> gp-0 vec0 x) (vector-dot (-> gp-0 vec1) (-> gp-0 mat0 rvec)))
    (set! (-> gp-0 vec0 y) (vector-dot (-> gp-0 vec1) (-> gp-0 mat0 uvec)))
    (set! (-> gp-0 vec0 z) (vector-dot (-> gp-0 vec1) (-> gp-0 mat0 fvec)))
    (let ((f1-6 (+ (* 0.03 (-> gp-0 vec2 z)) (* -1.0 (-> gp-0 vec0 x) (-> self accel-factor x)))))
      (+! (-> self left-right-interp) (* (- f1-6 (-> self left-right-interp)) (fmin 1.0 (* 8.0 (-> gp-0 vec2 y)))))
      )
    (set! (-> self left-right-interp) (fmax -1.0 (fmin 1.0 (-> self left-right-interp))))
    (let ((f1-15 (+ (* 0.03 (-> gp-0 vec2 w)) (* -1.0 (-> gp-0 vec0 z) (-> self accel-factor z)))))
      (+! (-> self front-back-interp) (* (- f1-15 (-> self front-back-interp)) (fmin 1.0 (* 8.0 (-> gp-0 vec2 y)))))
      )
    (set! (-> self front-back-interp) (fmax -1.0 (fmin 1.0 (-> self front-back-interp))))
    (let ((f1-24 (+ (* 0.03 (-> gp-0 vec2 w)) (* -1.0 (-> gp-0 vec0 y) (-> self accel-factor y)))))
      (+! (-> self up-down-interp) (* (- f1-24 (-> self up-down-interp)) (fmin 1.0 (* 8.0 (-> gp-0 vec2 y)))))
      )
    )
  (set! (-> self up-down-interp) (fmax -1.0 (fmin 1.0 (-> self up-down-interp))))
  (none)
  )

;; WARN: Return type mismatch symbol vs none.
;; WARN: new jak 2 until loop case, check carefully
(defbehavior wland-driver-pilot-wcar-anim-loop wland-driver ()
  (ja-channel-set! 3)
  (ja :group! wland-driver-pilot-car-turn-back-ja)
  (ja :chan 1 :group! wland-driver-pilot-car-turn-front-ja)
  (ja :chan 2 :group! wland-driver-pilot-car-up-down-ja)
  (until #f
    (let ((f30-0 (* 5.0 (+ 1.0 (-> self left-right-interp)))))
      (ja :num-func num-func-identity :frame-num (ja-aframe f30-0 0))
      (let ((gp-1 (-> self skel root-channel 1)))
        (let ((f0-3 (* 0.5 (+ 1.0 (-> self front-back-interp)))))
          (set! (-> gp-1 frame-interp 1) f0-3)
          (set! (-> gp-1 frame-interp 0) f0-3)
          )
        (set! (-> gp-1 num-func) num-func-identity)
        (set! (-> gp-1 frame-num) (ja-aframe f30-0 1))
        )
      )
    (let ((f0-6 (* 5.0 (- 1.0 (-> self up-down-interp))))
          (gp-2 (-> self skel root-channel 2))
          )
      (let ((f1-7 (fabs (-> self up-down-interp))))
        (set! (-> gp-2 frame-interp 1) f1-7)
        (set! (-> gp-2 frame-interp 0) f1-7)
        )
      (set! (-> gp-2 num-func) num-func-identity)
      (set! (-> gp-2 frame-num) (ja-aframe f0-6 2))
      )
    (suspend)
    )
  #f
  (none)
  )

(defstate idle (wland-driver)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('attack-invinc)
       (go-virtual die)
       )
      )
    )
  :trans (behavior ()
    (wland-driver-pilot-trans)
    )
  :code (behavior ()
    (wland-driver-pilot-wcar-anim-loop)
    (sleep-code)
    )
  :post ja-post
  )

(defstate die (wland-driver)
  :virtual #t
  :code (behavior ()
    (cleanup-for-death self)
    )
  )

(defbehavior wland-driver-init-by-other wland-driver ((arg0 vehicle))
  (let ((s5-0 (new 'process 'collide-shape self (collide-list-enum hit-by-player))))
    (set! (-> s5-0 penetrated-by) (the-as penetrate -1))
    (let ((v1-3 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-3 prim-core collide-as) (collide-spec bot))
      (set! (-> v1-3 transform-index) 3)
      (set-vector! (-> v1-3 local-sphere) 0.0 0.0 0.0 0.0)
      (set! (-> s5-0 total-prims) (the-as uint 1))
      (set! (-> s5-0 root-prim) v1-3)
      )
    (set! (-> s5-0 nav-radius) (* 0.75 (-> s5-0 root-prim local-sphere w)))
    (let ((v1-6 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-6 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-6 prim-core collide-with))
      )
    (set! (-> self root) s5-0)
    )
  (vector-copy! (-> self root trans) (-> arg0 root trans))
  (quaternion-copy! (-> self root quat) (-> arg0 root quat))
  (set! (-> self level) (level-get *level* 'destrack))
  (if (not (-> self level))
      (set! (-> self level) (level-get *level* 'desrally))
      )
  (initialize-skeleton
    self
    (the-as skeleton-group (art-group-get-by-name *level* "skel-wland-driver" (the-as (pointer level) #f)))
    (the-as pair 0)
    )
  (logclear! (-> self mask) (process-mask actor-pause))
  (logior! (-> self draw global-effect) (draw-control-global-effect disable-envmap))
  (set! (-> self vehicle) (process->handle arg0))
  (let ((a1-8 (get-best-seat arg0 (-> self root trans) (vehicle-seat-flag vsf0) 0)))
    (when (!= a1-8 -1)
      (put-rider-in-seat arg0 a1-8 self)
      (logior! (-> self focus-status) (focus-status pilot-riding))
      )
    )
  (vector-float*!
    (-> self accel-factor)
    (new 'static 'vector :x 0.000009765625 :y 0.000009765625 :z 0.0000048828124 :w 1.0)
    1.0
    )
  (go-virtual idle)
  )

;; WARN: Return type mismatch process vs wland-driver.
(defun wland-driver-spawn ((arg0 process))
  (let ((gp-0 (the-as process #f)))
    (let ((v1-1 (process-spawn wland-driver arg0 :name "wland-driver" :to arg0)))
      (if v1-1
          (set! gp-0 (-> v1-1 0))
          )
      )
    (the-as wland-driver gp-0)
    )
  )
