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

;; name: trajectory.gc
;; name in dgo: trajectory
;; dgos: GAME

;; DECOMP BEGINS

(defmethod compute-trans-at-time ((this trajectory) (arg0 float) (arg1 vector))
  (vector+float*! arg1 (-> this initial-position) (-> this initial-velocity) arg0)
  (+! (-> arg1 y) (* (/ arg0 2) arg0 (-> this gravity)))
  arg1
  )

(defmethod compute-transv-at-time ((this trajectory) (arg0 float) (arg1 vector))
  (vector-copy! arg1 (-> this initial-velocity))
  (+! (-> arg1 y) (* arg0 (-> this gravity)))
  arg1
  )

(defmethod compute-time-until-apex ((this trajectory))
  (/ (- (-> this initial-velocity y)) (-> this gravity))
  )

(defmethod setup-from-to-duration! ((this trajectory) (arg0 vector) (arg1 vector) (arg2 float) (arg3 float))
  (vector-copy! (-> this initial-position) arg0)
  (set! (-> this gravity) arg3)
  (set! (-> this time) arg2)
  (let ((f0-3 (/ (vector-vector-xz-distance arg1 arg0) arg2)))
    (vector-! (-> this initial-velocity) arg1 arg0)
    (vector-xz-normalize! (-> this initial-velocity) f0-3)
    )
  (set! (-> this initial-velocity y) (- (/ (- (-> arg1 y) (-> arg0 y)) arg2) (* (/ arg2 2) (-> this gravity))))
  0
  (none)
  )

(defmethod setup-from-to-xz-vel! ((this trajectory) (arg0 vector) (arg1 vector) (arg2 float) (arg3 float))
  (let ((f0-1 (/ (vector-vector-xz-distance arg1 arg0) arg2)))
    (setup-from-to-duration! this arg0 arg1 f0-1 arg3)
    )
  0
  (none)
  )

(defmethod setup-from-to-y-vel! ((this trajectory) (arg0 vector) (arg1 vector) (arg2 float) (arg3 float))
  (let* ((f0-0 arg2)
         (f1-3 (- (* f0-0 f0-0) (* 2.0 (- (-> arg0 y) (-> arg1 y)) arg3)))
         (f0-3 900.0)
         )
    (when (>= f1-3 0.0)
      (let ((f0-4 (sqrtf f1-3)))
        (set! f0-3 (fmax (/ (- (- arg2) f0-4) arg3) (/ (+ (- arg2) f0-4) arg3)))
        )
      )
    (setup-from-to-duration! this arg0 arg1 f0-3 arg3)
    )
  0
  (none)
  )

(defmethod setup-from-to-height! ((this trajectory) (arg0 vector) (arg1 vector) (arg2 float) (arg3 float))
  (let* ((f0-1 (+ arg2 (fmax (-> arg0 y) (-> arg1 y))))
         (f1-4 (* 2.0 (- (-> arg0 y) f0-1) arg3))
         (f0-4 4096.0)
         )
    (if (< 0.0 f1-4)
        (set! f0-4 (sqrtf f1-4))
        )
    (setup-from-to-y-vel! this arg0 arg1 f0-4 arg3)
    )
  0
  (none)
  )

;; WARN: Function (method 16 trajectory) has a return type of none, but the expression builder found a return statement.
(defmethod setup-from-to-duration-and-height! ((this trajectory) (arg0 vector) (arg1 vector) (arg2 float) (arg3 float))
  (let ((f0-1 (- (-> arg1 y) (-> arg0 y))))
    (cond
      ((= f0-1 0.0)
       (let ((t9-0 (method-of-type trajectory setup-from-to-duration!))
             (v1-2 arg2)
             (f0-3 (* -8.0 arg3))
             (f1-3 arg2)
             )
         (t9-0 this arg0 arg1 v1-2 (/ f0-3 (* f1-3 f1-3)))
         )
       (return 0)
       )
      ((and (< 0.0 f0-1) (< 0.0 arg3) (< arg3 f0-1))
       (set! arg3 f0-1)
       )
      ((and (< f0-1 0.0) (< arg3 0.0) (< f0-1 arg3))
       (set! arg3 f0-1)
       )
      )
    (let* ((f1-14 (/ (- arg3 f0-1) arg3))
           (f0-6 -2.0)
           (f1-18 (/ (- 1.0 f1-14) (- arg2 (* arg2 (sqrtf f1-14)))))
           (f0-8 (* f0-6 (* f1-18 f1-18) arg3))
           )
      (setup-from-to-duration! this arg0 arg1 arg2 f0-8)
      )
    )
  0
  (none)
  )

(method-set!
  trajectory
  17
  (if *debug-segment*
      (lambda ((arg0 trajectory))
        (let ((s5-0 (new 'stack-no-clear 'vector))
              (s4-0 (new 'stack-no-clear 'vector))
              (s3-0 10)
              )
          (vector-copy! s4-0 (-> arg0 initial-position))
          (dotimes (s2-0 s3-0)
            (vector-copy! s5-0 s4-0)
            (let ((f0-1 (* (-> arg0 time) (/ (+ 1.0 (the float s2-0)) (the float s3-0)))))
              (compute-trans-at-time arg0 f0-1 s4-0)
              )
            (add-debug-line
              #t
              (bucket-id debug-no-zbuf1)
              s5-0
              s4-0
              (new 'static 'rgba :r #xff :a #x80)
              #f
              (the-as rgba -1)
              )
            )
          )
        0
        (none)
        )
      nothing
      )
  )

(defmethod initialize ((this impact-control) (arg0 process-drawable) (arg1 int) (arg2 float) (arg3 collide-spec))
  (set! (-> this start-time) (the-as uint (current-time)))
  (set! (-> this process) (process->ppointer arg0))
  (set! (-> this joint) arg1)
  (set! (-> this radius) arg2)
  (set! (-> this collide-with) (logclear arg3 (collide-spec water)))
  (set! (-> this trans 0 quad) (the-as uint128 0))
  (set! (-> this trans 1 quad) (the-as uint128 0))
  this
  )

(defmethod update-from-cspace ((this impact-control))
  (when (>= (-> this joint) 0)
    (vector-copy! (-> this trans 1) (-> this trans 0))
    (vector<-cspace! (-> this trans 0) (-> this process 0 node-list data (-> this joint)))
    (vector-! (-> this dir) (-> this trans 0) (-> this trans 1))
    )
  0
  (none)
  )

(defmethod impact-control-method-11 ((this impact-control) (arg0 collide-query) (arg1 process) (arg2 pat-surface))
  (vector-copy! (-> arg0 start-pos) (-> this trans 1))
  (vector-copy! (-> arg0 move-dist) (-> this dir))
  (let ((v1-2 (ppointer->process (-> this process)))
        (a0-6 arg0)
        )
    (set! (-> a0-6 radius) (-> this radius))
    (set! (-> a0-6 collide-with) (-> this collide-with))
    (set! (-> a0-6 ignore-process0) v1-2)
    (set! (-> a0-6 ignore-process1) #f)
    (set! (-> a0-6 ignore-pat) arg2)
    (set! (-> a0-6 action-mask) (collide-action solid))
    )
  (let ((f30-0 (fill-and-probe-using-line-sphere *collide-cache* arg0)))
    (when (and arg1 (>= f30-0 0.0) (>= 0.0 (vector-dot (-> arg0 best-other-tri normal) (-> this dir))))
      (let ((s3-0 (new 'stack-no-clear 'touching-shapes-entry))
            (v1-12 (as-type (-> arg0 best-other-tri collide-ptr) collide-shape-prim))
            )
        (set! (-> s3-0 cshape1) #f)
        (set! (-> s3-0 cshape2) (if v1-12
                                    (-> (the-as collide-shape-prim v1-12) cshape)
                                    )
              )
        (set! (-> s3-0 resolve-u) (the int f30-0))
        (set! (-> s3-0 head) #f)
        (send-event
          arg1
          'impact-control
          :from (if v1-12
              (-> (the-as collide-shape-prim v1-12) cshape process)
              arg1
              )
          #f
          s3-0
          this
          arg0
          )
        )
      )
    f30-0
    )
  )

(defmethod initialize ((this point-tracker) (arg0 vector) (arg1 vector))
  (set! (-> this trans 0 quad) (-> arg0 quad))
  (vector-copy! (-> this trans 1) arg1)
  this
  )

(defmethod point-tracker-method-10 ((this point-tracker) (arg0 vector) (arg1 vector) (arg2 vector) (arg3 float))
  (cond
    ((>= 0.0 arg3)
     (vector-copy! arg0 arg1)
     )
    ((>= arg3 1.0)
     (vector-copy! arg0 arg2)
     )
    (else
      (let ((a1-2 (vector+float*! arg0 arg2 (vector-! (new 'stack-no-clear 'vector) arg1 arg2) (- 1.0 arg3))))
        (vector-lerp! arg0 a1-2 arg2 arg3)
        )
      )
    )
  arg0
  )

(defmethod point-tracker-method-11 ((this point-tracker) (arg0 vector) (arg1 vector) (arg2 vector) (arg3 float))
  (with-pp
    (let ((v1-1 (point-tracker-method-10 this (new 'stack-no-clear 'vector) arg1 arg2 arg3)))
      (vector-! arg0 v1-1 arg1)
      )
    (vector-float*! arg0 arg0 (-> pp clock frames-per-second))
    arg0
    )
  )

;; WARN: Return type mismatch process vs process-focusable.
(defmethod combo-tracker-method-13 ((this combo-tracker) (arg0 handle) (arg1 vector) (arg2 float) (arg3 vector) (arg4 float))
  (the-as process-focusable (cond
                              ((send-event (handle->process arg0) 'combo)
                               (as-type (handle->process arg0) process-focusable)
                               )
                              (else
                                (let ((s1-0 (new 'stack-no-clear 'vector))
                                      (s2-1 (new 'stack 'boxed-array collide-shape 32))
                                      )
                                  (sphere<-vector+r! (the-as sphere s1-0) arg1 arg2)
                                  (set! (-> s2-1 length) (fill-actor-list-for-box
                                                           *actor-hash*
                                                           s1-0
                                                           (the-as (pointer collide-shape) (-> s2-1 data))
                                                           (-> s2-1 allocated-length)
                                                           )
                                        )
                                  (as-type
                                    (find-nearest-focusable
                                      (the-as (array collide-shape) s2-1)
                                      arg1
                                      arg2
                                      (if (= arg4 65536.0)
                                          (search-info-flag crate enemy combo)
                                          (search-info-flag crate enemy prefer-angle cull-angle combo)
                                          )
                                      (search-info-flag)
                                      arg3
                                      (the-as vector #f)
                                      arg4
                                      )
                                    process-focusable
                                    )
                                  )
                                )
                              )
          )
  )

(defmethod combo-tracker-method-12 ((this combo-tracker) (arg0 vector) (arg1 vector) (arg2 process) (arg3 time-frame))
  (initialize this arg0 arg1)
  (set! (-> this target) (process->handle arg2))
  (set! (-> this move-start-time) arg3)
  this
  )

(defmethod point-tracker-method-11 ((this combo-tracker) (arg0 vector) (arg1 vector) (arg2 vector) (arg3 float))
  (local-vars (at-0 int))
  (with-pp
    (rlet ((vf0 :class vf)
           (vf1 :class vf)
           (vf2 :class vf)
           )
      (init-vf0-vector)
      (let ((v1-1 (point-tracker-method-10 this (new 'stack-no-clear 'vector) arg1 arg2 arg3)))
        (vector-! arg0 v1-1 arg1)
        )
      (let ((a1-4 (new 'stack-no-clear 'event-message-block)))
        (set! (-> a1-4 from) (process->ppointer pp))
        (set! (-> a1-4 num-params) 0)
        (set! (-> a1-4 message) 'nav-control)
        (let ((s4-1 (as-type (send-event-function (handle->process (-> this target)) a1-4) nav-control)))
          (when s4-1
            (let ((a2-3 ((method-of-type nav-control find-poly-containing-point-1) (the-as nav-control s4-1) arg1)))
              (if a2-3
                  ((method-of-type nav-control clamp-vector-to-mesh-cross-gaps)
                   (the-as nav-control s4-1)
                   arg1
                   a2-3
                   arg0
                   2048.0
                   #f
                   (the-as clamp-travel-vector-to-mesh-return-info #f)
                   )
                  (set! (-> arg0 quad) (the-as uint128 0))
                  )
              )
            )
          )
        )
      (let ((v1-12 arg0))
        (.lvf vf1 (&-> arg0 quad))
        (let ((f0-0 (-> pp clock frames-per-second)))
          (.mov at-0 f0-0)
          )
        (.mov vf2 at-0)
        (.mov.vf.w vf1 vf0)
        (.mul.x.vf.xyz vf1 vf1 vf2)
        (.svf (&-> v1-12 quad) vf1)
        )
      arg0
      )
    )
  )

(defun traj2d-calc-initial-speed-using-tilt ((arg0 traj2d-params))
  (let ((f0-4 (* (- (* (-> arg0 x) (tan (-> arg0 initial-tilt))) (-> arg0 y)) (/ 2.0 (-> arg0 gravity)))))
    (cond
      ((< 0.0 f0-4)
       (set! (-> arg0 time) (sqrtf f0-4))
       (set! (-> arg0 initial-speed) (/ (-> arg0 x) (* (-> arg0 time) (cos (-> arg0 initial-tilt)))))
       #t
       )
      (else
        (set! (-> arg0 time) 0.0)
        (set! (-> arg0 initial-speed) 0.0)
        #f
        )
      )
    )
  )

(defun traj3d-calc-initial-velocity-using-tilt ((arg0 traj3d-params))
  (vector-! (-> arg0 diff) (-> arg0 dest) (-> arg0 src))
  (let ((s5-0 (new 'stack-no-clear 'traj2d-params)))
    (let ((v1-1 (-> arg0 diff)))
      (set! (-> s5-0 x) (sqrtf (+ (* (-> v1-1 x) (-> v1-1 x)) (* (-> v1-1 z) (-> v1-1 z)))))
      )
    (set! (-> s5-0 y) (-> arg0 diff y))
    (set! (-> s5-0 gravity) (-> arg0 gravity))
    (set! (-> s5-0 initial-tilt) (-> arg0 initial-tilt))
    (cond
      ((traj2d-calc-initial-speed-using-tilt s5-0)
       (set! (-> arg0 time) (-> s5-0 time))
       (let* ((f26-0 (atan (-> arg0 diff x) (-> arg0 diff z)))
              (f30-0 (-> arg0 initial-tilt))
              (f24-0 (cos f30-0))
              (f28-0 (-> s5-0 initial-speed))
              )
         (set! (-> arg0 initial-speed) f28-0)
         (set! (-> arg0 initial-velocity x) (* f28-0 f24-0 (sin f26-0)))
         (set! (-> arg0 initial-velocity z) (* f28-0 f24-0 (cos f26-0)))
         (set! (-> arg0 initial-velocity y) (* f28-0 (sin f30-0)))
         )
       (set! (-> arg0 initial-velocity w) 1.0)
       #t
       )
      (else
        (set! (-> arg0 time) 0.0)
        (set! (-> arg0 initial-speed) 0.0)
        (vector-reset! (-> arg0 initial-velocity))
        #f
        )
      )
    )
  )

(defmethod cubic-curve-method-9 ((this cubic-curve) (arg0 vector) (arg1 vector) (arg2 vector) (arg3 vector))
  (set! (-> this vec 0 quad) (-> arg0 quad))
  (vector-copy! (-> this mat uvec) arg1)
  (let ((v1-2 (new 'stack-no-clear 'trajectory)))
    (vector-! (-> v1-2 initial-velocity) arg2 arg0)
    (vector-float*! (-> v1-2 initial-position) (-> v1-2 initial-velocity) 3.0)
    (vector+*! (-> v1-2 initial-position) (-> v1-2 initial-position) arg1 -2.0)
    (vector-! (-> v1-2 initial-position) (-> v1-2 initial-position) arg3)
    (vector-copy! (-> this mat fvec) (-> v1-2 initial-position))
    (vector-float*! (-> v1-2 initial-position) (-> v1-2 initial-velocity) -2.0)
    (vector+! (-> v1-2 initial-position) (-> v1-2 initial-position) arg1)
    (vector+! (-> v1-2 initial-position) (-> v1-2 initial-position) arg3)
    (vector-copy! (-> this mat trans) (-> v1-2 initial-position))
    )
  (dotimes (v1-5 4)
    (set! (-> this vec v1-5 w) 0.0)
    )
  0
  (none)
  )

(defmethod cubic-curve-method-10 ((this cubic-curve) (arg0 vector) (arg1 float))
  (let ((v1-0 (new 'stack-no-clear 'trajectory)))
    (let ((f0-1 (* arg1 arg1)))
      (set-vector! (-> v1-0 initial-position) 1.0 arg1 f0-1 (* f0-1 arg1))
      )
    (vector-matrix*! arg0 (-> v1-0 initial-position) (the-as matrix (-> this vec)))
    )
  (set! (-> arg0 w) 1.0)
  arg0
  )

(defmethod cubic-curve-method-11 ((this cubic-curve) (arg0 vector) (arg1 float))
  (let ((v1-0 (new 'stack-no-clear 'trajectory)))
    (set-vector! (-> v1-0 initial-position) 0.0 1.0 (* 2.0 arg1) (* 3.0 arg1 arg1))
    (vector-matrix*! arg0 (-> v1-0 initial-position) (the-as matrix (-> this vec)))
    )
  (set! (-> arg0 w) 1.0)
  arg0
  )

(defmethod cubic-curve-method-12 ((this cubic-curve) (arg0 vector) (arg1 float))
  (let ((v1-0 (new 'stack-no-clear 'trajectory)))
    (set-vector! (-> v1-0 initial-position) 0.0 0.0 2.0 (* 6.0 arg1))
    (vector-matrix*! arg0 (-> v1-0 initial-position) (the-as matrix (-> this vec)))
    )
  (set! (-> arg0 w) 1.0)
  arg0
  )

(defmethod debug-draw-curve ((this cubic-curve))
  (let ((s5-0 (new 'stack-no-clear 'trajectory))
        (s4-0 10)
        )
    (cubic-curve-method-10 this (-> s5-0 initial-velocity) 0.0)
    (add-debug-x #t (bucket-id debug-no-zbuf1) (-> s5-0 initial-velocity) *color-red*)
    (dotimes (s3-0 s4-0)
      (vector-copy! (-> s5-0 initial-position) (-> s5-0 initial-velocity))
      (let ((f0-2 (/ (+ 1.0 (the float s3-0)) (the float s4-0))))
        (cubic-curve-method-10 this (-> s5-0 initial-velocity) f0-2)
        )
      (add-debug-x #t (bucket-id debug-no-zbuf1) (-> s5-0 initial-velocity) *color-red*)
      (add-debug-line
        #t
        (bucket-id debug-no-zbuf1)
        (-> s5-0 initial-position)
        (-> s5-0 initial-velocity)
        *color-red*
        #f
        (the-as rgba -1)
        )
      )
    )
  (add-debug-vector
    #t
    (bucket-id debug-no-zbuf1)
    (cubic-curve-method-10 this (new 'stack-no-clear 'vector) 0.0)
    (cubic-curve-method-11 this (new 'stack-no-clear 'vector) 0.0)
    (meters 0.00024414062)
    *color-white*
    )
  (add-debug-vector
    #t
    (bucket-id debug-no-zbuf1)
    (cubic-curve-method-10 this (new 'stack-no-clear 'vector) 1.0)
    (vector-negate! (new 'stack-no-clear 'vector) (cubic-curve-method-11 this (new 'stack-no-clear 'vector) 1.0))
    (meters 0.00024414062)
    *color-white*
    )
  0
  (none)
  )
