;;-*-Lisp-*-
(in-package goal)
(bundles "ENGINE.CGO" "GAME.CGO")
(require "engine/collide/collide-shape.gc")

;; DECOMP BEGINS

(defmethod on-platform ((this collide-shape) (arg0 collide-shape) (arg1 collide-overlap-result))
  "Are we on the platform? Returns #t/#f and also sets an overlap result."
  (let ((v1-0 arg1)) (set! (-> v1-0 best-dist) 0.0) (set! (-> v1-0 best-from-prim) #f) (set! (-> v1-0 best-to-prim) #f))
  (set! (-> arg1 best-dist) 122.88)
  (let ((s5-0 (-> this root-prim))
        (s4-0 (-> arg0 root-prim)))
    (when (and (logtest? (-> s5-0 collide-with) (-> s4-0 prim-core collide-as))
               (logtest? (-> s5-0 prim-core action) (collide-action rider-plat-sticky))
               (logtest? (-> s4-0 prim-core action) (collide-action rider-target)))
      (let ((f0-4 (- (- (vector-vector-distance (the-as vector (-> s5-0 prim-core)) (the-as vector (-> s4-0 prim-core)))
                        (-> s5-0 prim-core world-sphere w))
                     (-> s4-0 prim-core world-sphere w))))
        (if (< f0-4 122.88) (on-platform-test s5-0 s4-0 arg1 f0-4)))))
  (< (-> arg1 best-dist) 122.88))

(defmethod on-platform-test ((this collide-shape-prim) (arg0 collide-shape-prim) (arg1 collide-overlap-result) (arg2 float))
  (format 0 "ERROR: collide-shape-prim::on-platform-test was called illegally!~%")
  (none))

(defmethod on-platform-test ((this collide-shape-prim-group) (arg0 collide-shape-prim) (arg1 collide-overlap-result) (arg2 float))
  "Check if we're on the platform for a prim group."
  (let ((s3-0 (-> arg0 prim-core collide-as)))
    (dotimes (s2-0 (-> this num-prims))
      (let ((s1-0 (-> this prims s2-0)))
        ;; check collide kind
        (when (and (logtest? (-> s1-0 collide-with) s3-0) (logtest? (-> s1-0 prim-core action) (collide-action rider-plat-sticky)))
          ;; check dist
          (let ((f0-2 (- (- (vector-vector-distance (the-as vector (-> s1-0 prim-core)) (the-as vector (-> arg0 prim-core)))
                            (-> s1-0 prim-core world-sphere w))
                         (-> arg0 prim-core world-sphere w))))
            ;; dist close enough, check!
            (if (< f0-2 122.88) (on-platform-test s1-0 arg0 arg1 f0-2)))))))
  (none))

(defmethod on-platform-test ((this collide-shape-prim-mesh) (arg0 collide-shape-prim) (arg1 collide-overlap-result) (arg2 float))
  "check if we're on the platform for a mesh."
  (case (-> arg0 type)
    ;; mesh to group
    ((collide-shape-prim-group)
     (let ((s3-0 (-> this collide-with)))
       (dotimes (s2-0 (-> (the-as collide-shape-prim-group arg0) num-prims))
         (let ((s1-0 (-> (the-as collide-shape-prim-group arg0) prims s2-0)))
           (when (and (logtest? s3-0 (-> s1-0 prim-core collide-as)) (logtest? (-> s1-0 prim-core action) (collide-action rider-target)))
             (let ((f0-2 (- (- (vector-vector-distance (the-as vector (-> this prim-core)) (the-as vector (-> s1-0 prim-core)))
                               (-> this prim-core world-sphere w))
                            (-> s1-0 prim-core world-sphere w))))
               (if (< f0-2 122.88) (on-platform-test this s1-0 arg1 f0-2))))))))
    ;; mesh to sphere. use the collide-mesh-cache.
    ((collide-shape-prim-sphere)
     (let ((s3-1 (-> this mesh)))
       (when s3-1
         (let ((s2-1 *collide-mesh-cache*))
           (when (!= (-> this mesh-cache-id) (-> s2-1 id))
             (let ((v1-17 (allocate! s2-1 (* 96 (-> s3-1 num-tris)))))
               (cond
                 (v1-17
                  (set! (-> this mesh-cache-tris) (the-as (inline-array collide-mesh-cache-tri) v1-17))
                  (set! (-> this mesh-cache-id) (-> s2-1 id))
                  (populate-cache! s3-1
                                   (the-as collide-mesh-cache-tri (-> this mesh-cache-tris))
                                   (-> this cshape process node-list data (-> this transform-index) bone transform)))
                 (else (return #f))))))
         (let* ((s2-2 (new 'stack-no-clear 'collide-tri-result))
                (f0-4 (sphere-on-platform-test s3-1
                                               (the-as collide-mesh-cache-tri (-> this mesh-cache-tris))
                                               s2-2
                                               (the-as vector (-> arg0 prim-core))
                                               (-> arg1 best-dist))))
           (when (< f0-4 (-> arg1 best-dist))
             (set! (-> arg1 best-dist) f0-4)
             (set! (-> arg1 best-from-prim) this)
             (set! (-> arg1 best-to-prim) arg0)
             (set! (-> arg1 best-from-tri vertex 0 quad) (-> s2-2 vertex 0 quad))
             (set! (-> arg1 best-from-tri vertex 1 quad) (-> s2-2 vertex 1 quad))
             (set! (-> arg1 best-from-tri vertex 2 quad) (-> s2-2 vertex 2 quad))
             (set! (-> arg1 best-from-tri intersect quad) (-> s2-2 intersect quad))
             (set! (-> arg1 best-from-tri normal quad) (-> s2-2 normal quad))
             (set! (-> arg1 best-from-tri pat) (-> s2-2 pat))))))))
  (none))

(defmethod add-rider! ((this collide-sticky-rider-group) (arg0 process-drawable))
  "Add a rider to this platform."
  (let ((gp-0 (the-as collide-sticky-rider #f)))
    (cond
      ((< (-> this num-riders) (-> this allocated-riders))
       (set! gp-0 (-> this rider (-> this num-riders)))
       (+! (-> this num-riders) 1)
       (let ((v1-6 gp-0)) (set! (-> v1-6 rider-handle) (the-as handle arg0)) (set! (-> v1-6 sticky-prim) #f)))
      (else (format 0 "ERROR: Exeeded max number of riders!~%")))
    gp-0))

(defmethod detect-riders! ((this collide-shape))
  "See who is riding us."
  (let ((s5-0 (-> this riders)))
    (when s5-0
      (let* ((v1-0 *collide-mesh-cache*)
             (a0-1 (-> v1-0 id)))
        (set! (-> v1-0 used-size) (the-as uint 0))
        (let ((a0-2 (the-as int (+ a0-1 1))))
          (b! (zero? (the-as uint a0-2)) cfg-3 :likely-delay (set! a0-2 1))
          (label cfg-3)
          (set! (-> v1-0 id) (the-as uint a0-2))))
      (set! (-> s5-0 num-riders) 0)
      0
      (let ((s4-0 (-> this root-prim collide-with)))
        (when (logtest? s4-0 (collide-kind target))
          (let ((v1-7 (-> *collide-player-list* alive-list next0)))
            *collide-player-list*
            (let ((s3-0 (-> v1-7 next0)))
              (while (!= v1-7 (-> *collide-player-list* alive-list-end))
                (let* ((s2-0 (-> (the-as connection v1-7) param1))
                       (v1-8 (-> (the-as collide-shape s2-0) root-prim)))
                  (when (logtest? s4-0 (-> v1-8 prim-core collide-as))
                    (when (and (logtest? (-> v1-8 prim-core action) (collide-action rider-target))
                               (!= (-> this process) (-> (the-as collide-shape s2-0) process)))
                      (let ((s1-0 (new 'stack-no-clear 'collide-overlap-result)))
                        (when (on-platform this (the-as collide-shape s2-0) s1-0)
                          (let ((s4-1 (add-rider! s5-0 (the-as process-drawable (process->handle (-> (the-as collide-shape s2-0) process))))))
                            (when s4-1
                              (let ((a0-11 (-> s1-0 best-from-prim)))
                                (set! (-> s4-1 sticky-prim) a0-11)
                                (let ((s1-1 (-> (the-as process-drawable (-> this process)) node-list data (-> a0-11 transform-index) bone transform)))
                                  (set! (-> s4-1 prim-ry) (matrix-y-angle s1-1))
                                  (let ((s0-0 (new 'stack-no-clear 'matrix)))
                                    (matrix-4x4-inverse! s0-0 s1-1)
                                    (vector-matrix*! (-> s4-1 rider-local-pos) (-> (the-as collide-shape s2-0) trans) s0-0))))
                              (send-event (-> this process) 'ridden s4-1)))
                          (set! s4-0 (-> this root-prim collide-with)))))))
                (set! v1-7 s3-0)
                *collide-player-list*
                (set! s3-0 (-> s3-0 next0))))))
        (when (logtest? s4-0 (collide-kind cak-1 cak-2 cak-3))
          (when (logtest? s4-0 (collide-kind cak-1))
            (let ((v1-37 (-> *collide-hit-by-player-list* alive-list next0)))
              *collide-hit-by-player-list*
              (let ((s3-1 (-> v1-37 next0)))
                (while (!= v1-37 (-> *collide-hit-by-player-list* alive-list-end))
                  (let* ((s2-1 (-> (the-as connection v1-37) param1))
                         (v1-38 (-> (the-as collide-shape s2-1) root-prim)))
                    (when (logtest? s4-0 (-> v1-38 prim-core collide-as))
                      (when (and (logtest? (-> v1-38 prim-core action) (collide-action rider-target))
                                 (!= (-> this process) (-> (the-as collide-shape s2-1) process)))
                        (let ((s1-2 (new 'stack-no-clear 'collide-overlap-result)))
                          (when (on-platform this (the-as collide-shape s2-1) s1-2)
                            (let ((s4-2 (add-rider! s5-0 (the-as process-drawable (process->handle (-> (the-as collide-shape s2-1) process))))))
                              (when s4-2
                                (let ((a0-30 (-> s1-2 best-from-prim)))
                                  (set! (-> s4-2 sticky-prim) a0-30)
                                  (let ((s1-3 (-> this process node-list data (-> a0-30 transform-index) bone transform)))
                                    (set! (-> s4-2 prim-ry) (matrix-y-angle s1-3))
                                    (let ((s0-1 (new 'stack-no-clear 'matrix)))
                                      (matrix-4x4-inverse! s0-1 s1-3)
                                      (vector-matrix*! (-> s4-2 rider-local-pos) (-> (the-as collide-shape s2-1) trans) s0-1))))
                                (send-event (-> this process) 'ridden s4-2)))
                            (set! s4-0 (-> this root-prim collide-with)))))))
                  (set! v1-37 s3-1)
                  *collide-hit-by-player-list*
                  (set! s3-1 (-> s3-1 next0))))))
          (when (logtest? s4-0 (collide-kind cak-2))
            (let ((v1-66 (-> *collide-usually-hit-by-player-list* alive-list next0)))
              *collide-usually-hit-by-player-list*
              (let ((s3-2 (-> v1-66 next0)))
                (while (!= v1-66 (-> *collide-usually-hit-by-player-list* alive-list-end))
                  (let* ((s2-2 (-> (the-as connection v1-66) param1))
                         (v1-67 (-> (the-as collide-shape s2-2) root-prim)))
                    (when (logtest? s4-0 (-> v1-67 prim-core collide-as))
                      (when (and (logtest? (-> v1-67 prim-core action) (collide-action rider-target))
                                 (!= (-> this process) (-> (the-as collide-shape s2-2) process)))
                        (let ((s1-4 (new 'stack-no-clear 'collide-overlap-result)))
                          (when (on-platform this (the-as collide-shape s2-2) s1-4)
                            (let ((s4-3 (add-rider! s5-0 (the-as process-drawable (process->handle (-> (the-as collide-shape s2-2) process))))))
                              (when s4-3
                                (let ((a0-49 (-> s1-4 best-from-prim)))
                                  (set! (-> s4-3 sticky-prim) a0-49)
                                  (let ((s1-5 (-> this process node-list data (-> a0-49 transform-index) bone transform)))
                                    (set! (-> s4-3 prim-ry) (matrix-y-angle s1-5))
                                    (let ((s0-2 (new 'stack-no-clear 'matrix)))
                                      (matrix-4x4-inverse! s0-2 s1-5)
                                      (vector-matrix*! (-> s4-3 rider-local-pos) (-> (the-as collide-shape s2-2) trans) s0-2))))
                                (send-event (-> this process) 'ridden s4-3)))
                            (set! s4-0 (-> this root-prim collide-with)))))))
                  (set! v1-66 s3-2)
                  *collide-usually-hit-by-player-list*
                  (set! s3-2 (-> s3-2 next0))))))
          (when (logtest? s4-0 (collide-kind cak-3))
            (let ((v1-94 (-> *collide-hit-by-others-list* alive-list next0)))
              *collide-hit-by-others-list*
              (let ((s3-3 (-> v1-94 next0)))
                (while (!= v1-94 (-> *collide-hit-by-others-list* alive-list-end))
                  (let* ((s2-3 (-> (the-as connection v1-94) param1))
                         (v1-95 (-> (the-as collide-shape s2-3) root-prim)))
                    (when (logtest? s4-0 (-> v1-95 prim-core collide-as))
                      (when (and (logtest? (-> v1-95 prim-core action) (collide-action rider-target))
                                 (!= (-> this process) (-> (the-as collide-shape s2-3) process)))
                        (let ((s1-6 (new 'stack-no-clear 'collide-overlap-result)))
                          (when (on-platform this (the-as collide-shape s2-3) s1-6)
                            (let ((s4-4 (add-rider! s5-0 (the-as process-drawable (process->handle (-> (the-as collide-shape s2-3) process))))))
                              (when s4-4
                                (let ((a0-68 (-> s1-6 best-from-prim)))
                                  (set! (-> s4-4 sticky-prim) a0-68)
                                  (let ((s1-7 (-> this process node-list data (-> a0-68 transform-index) bone transform)))
                                    (set! (-> s4-4 prim-ry) (matrix-y-angle s1-7))
                                    (let ((s0-3 (new 'stack-no-clear 'matrix)))
                                      (matrix-4x4-inverse! s0-3 s1-7)
                                      (vector-matrix*! (-> s4-4 rider-local-pos) (-> (the-as collide-shape s2-3) trans) s0-3))))
                                (send-event (-> this process) 'ridden s4-4)))
                            (set! s4-0 (-> this root-prim collide-with)))))))
                  (set! v1-94 s3-3)
                  *collide-hit-by-others-list*
                  (set! s3-3 (-> s3-3 next0)))))
            #f))))))

(defmethod pull-riders! ((this collide-shape))
  "Move our riders."
  (let ((s5-0 (-> this riders)))
    (when s5-0
      (let ((s4-0 (new 'stack-no-clear 'pull-rider-info)))
        (countdown (s3-0 (-> s5-0 num-riders))
          (let* ((v1-2 (-> s5-0 rider s3-0))
                 (a0-1 (-> v1-2 rider-handle)))
            (when (handle->process a0-1)
              (set! (-> s4-0 rider) v1-2)
              (set! (-> s4-0 rider-cshape) (the-as collide-shape-moving (-> (the-as process-drawable (-> a0-1 process 0)) root)))
              (let ((a0-5 (-> v1-2 sticky-prim)))
                (when a0-5
                  (let ((s2-0 (-> this process node-list data (-> a0-5 transform-index) bone transform)))
                    (let ((s1-0 (-> s4-0 rider-dest)))
                      (vector-matrix*! s1-0 (-> v1-2 rider-local-pos) s2-0)
                      (vector-float*! s1-0 s1-0 (/ 1.0 (-> s1-0 w))))
                    (set! (-> s4-0 rider-delta-ry) (deg- (matrix-y-angle s2-0) (-> s4-0 rider prim-ry))))
                  (pull-rider! this s4-0)))))))
      #f)))

(defmethod pull-rider! ((this collide-shape) (arg0 pull-rider-info))
  "Move a rider."
  (local-vars (at-0 int) (sv-160 (function collide-shape-moving float collide-kind none)))
  (rlet ((vf0 :class vf)
         (vf1 :class vf)
         (vf2 :class vf))
    (init-vf0-vector)
    (let ((gp-0 (-> arg0 rider-cshape)))
      (let ((s3-0 (new 'stack-no-clear 'vector))
            (s4-0 (new 'stack-no-clear 'vector)))
        (set! (-> s4-0 quad) (-> gp-0 trans quad))
        (vector-! s3-0 (-> arg0 rider-dest) s4-0)
        (cond
          ((logtest? (-> this root-prim prim-core action) (collide-action rider-plat))
           (let ((s1-0 (-> this root-prim prim-core collide-as)))
             (set! (-> this root-prim prim-core collide-as) (collide-kind))
             (let ((s0-0 gp-0))
               (set! sv-160 (method-of-object s0-0 fill-cache-for-shape!))
               (let ((a1-3 (+ 8192.0 (vector-length s3-0)))
                     (a2-0 (-> gp-0 root-prim collide-with)))
                 (sv-160 s0-0 a1-3 a2-0)))
             (set! (-> this root-prim prim-core collide-as) s1-0))
           (let ((s2-1 (new 'stack-no-clear 'vector)))
             (set! (-> s2-1 quad) (-> s3-0 quad))
             (let ((v1-12 s2-1))
               (.lvf vf1 (&-> s2-1 quad))
               (let ((f0-2 (-> *display* frames-per-second))) (.mov at-0 f0-2))
               (.mov vf2 at-0)
               (.mov.vf.w vf1 vf0)
               (.mul.x.vf.xyz vf1 vf1 vf2)
               (.svf (&-> v1-12 quad) vf1))
             (cond
               ((type-type? (-> gp-0 type) collide-shape-moving)
                (let ((s3-1 (-> gp-0 status))) (integrate-and-collide! gp-0 s2-1) (set! (-> gp-0 status) s3-1)))
               (else (integrate-and-collide! gp-0 s2-1)))))
          (else (move-by-vector! gp-0 s3-0)))
        (when (type-type? (-> gp-0 type) collide-shape-moving)
          (let ((v1-18 (new 'stack-no-clear 'vector)))
            (vector-! v1-18 (-> gp-0 trans) s4-0)
            (vector-float*! (-> gp-0 rider-last-move) v1-18 (-> *display* frames-per-second)))
          (set-time! (-> gp-0 rider-time))))
      (let ((f0-4 (-> arg0 rider-delta-ry))) (if (!= f0-4 0.0) (send-event (-> gp-0 process) 'rotate-y-angle f0-4))))
    (none)))

(defmethod alloc-riders ((this collide-shape) (arg0 int))
  (if (-> this riders)
    (format 0 "ERROR: colide-shape::alloc-riders is being called multiple times!~%")
    (set! (-> this riders) (new 'process 'collide-sticky-rider-group arg0)))
  (none))
