;;-*-Lisp-*-
(in-package goal)
(bundles "FIC.DGO" "LAV.DGO" "MIS.DGO" "OGR.DGO" "ROL.DGO")
(require "engine/target/collide-reaction-target.gc")

;; DECOMP BEGINS

(defun racer-collision-reaction ((arg0 control-info) (arg1 collide-shape-intersect) (arg2 vector) (arg3 vector))
  (local-vars (sv-80 vector) (sv-84 vector) (sv-88 (inline-array vector)) (sv-96 int) (sv-104 int))
  (set! sv-80 (new-stack-vector0))
  (set! sv-84 (new-stack-vector0))
  (let ((v1-2 (new 'stack-no-clear 'inline-array 'vector 2)))
    (dotimes (a0-1 2)
      (set! (-> v1-2 a0-1 quad) (the-as uint128 0)))
    (set! sv-88 v1-2))
  (set! sv-96 0)
  (set! sv-104 0)
  (set! (-> sv-88 0 quad) (-> arg3 quad))
  (set! (-> sv-88 1 quad) (-> arg3 quad))
  (let ((a1-3 (new 'stack-no-clear 'vector)))
    (vector-float*! a1-3 (-> arg1 move-vec) (-> arg1 best-u))
    (move-by-vector! arg0 a1-3))
  (set-and-handle-pat! arg0 (-> arg1 best-tri pat))
  (if (= (-> arg0 poly-pat mode) (pat-mode wall)) (set! sv-104 (logior sv-104 1)))
  (if (= (-> arg0 unknown-surface00 mode) 'air) (set! sv-104 (logior sv-104 32)))
  (let ((v1-21 (new 'stack-no-clear 'vector)))
    (set! (-> v1-21 quad) (-> arg1 best-from-prim prim-core world-sphere quad))
    (vector-! sv-80 v1-21 (-> arg1 best-tri intersect)))
  (vector-normalize! sv-80 1.0)
  (set! (-> arg0 coverage) (vector-dot sv-80 (-> arg1 best-tri normal)))
  (when (< (-> arg0 coverage) 0.0)
    (set! (-> arg0 coverage) 0.0)
    (vector-flatten! sv-80 sv-80 (-> arg1 best-tri normal))
    (vector-normalize! sv-80 1.0))
  (if (< (-> arg0 coverage) 0.9999) (set! sv-104 (logior sv-104 24)))
  (let ((v1-31 (-> sv-80 quad))) (set! (-> sv-84 quad) v1-31))
  (if (= (-> arg1 best-u) 0.0) (move-by-vector! arg0 (vector-normalize-copy! (new-stack-vector0) sv-84 3.0)))
  (set! (-> arg0 poly-normal quad) (-> arg1 best-tri normal quad))
  (collide-shape-moving-angle-set! arg0 sv-84 (-> sv-88 0))
  (if (< (-> arg0 poly-angle) -0.2) (set! sv-96 (logior sv-96 16)))
  (let ((s3-1 (< (fabs (-> arg0 surface-angle)) (-> *pat-mode-info* (-> arg0 cur-pat mode) wall-angle))))
    (if s3-1 (set! sv-104 (logior sv-104 2)))
    (when (not (logtest? (-> arg0 prev-status) (cshape-moving-flags onsurf)))
      (set! (-> arg0 ground-impact-vel) (- (vector-dot (-> arg0 transv) (-> arg0 dynam gravity-normal))))
      (set! sv-96 (logior sv-96 2048))
      (when (not s3-1)
        (let ((f30-0 (- 1.0 (-> arg0 surf impact-fric))))
          (when (< f30-0 1.0)
            (let ((s2-1 (new-stack-vector0))
                  (f28-0 (vector-dot (-> arg0 dynam gravity-normal) (-> sv-88 0))))
              0.0
              (vector-! s2-1 (-> sv-88 0) (vector-float*! s2-1 (-> arg0 dynam gravity-normal) f28-0))
              (let* ((f0-18 (vector-length s2-1))
                     (f1-6 f0-18))
                (if (< f28-0 0.0) (set! f28-0 (* f28-0 f30-0)))
                (vector+! (-> sv-88 0)
                          (vector-float*! (-> sv-88 0) (-> arg0 dynam gravity-normal) f28-0)
                          (vector-float*! s2-1 s2-1 (/ f0-18 f1-6)))))))))
    (set! sv-96 (logior sv-96 4))
    (cond
      ((-> arg1 best-to-prim)
       (set! sv-96 (logior sv-96 32))
       (set! (-> arg0 unknown-vector72 quad) (-> arg1 best-tri intersect quad))
       (set! (-> arg0 unknown-vector73 quad) (-> arg0 poly-normal quad))
       (set! (-> arg0 unknown-handle00) (process->handle (-> arg1 best-to-prim cshape process))))
      ((= (-> arg0 poly-pat material) (pat-material waterbottom)))
      (else (set! sv-96 (logior sv-96 4096))))
    (if (and s3-1 (logtest? (collide-action racer-unused) (-> arg0 root-prim prim-core action))) (set! s3-1 #f))
    (cond
      (s3-1
       (set! sv-104 (logior sv-104 4))
       (set! sv-96 (logior sv-96 8))
       (set! (-> arg0 cur-pat mode) 1)
       (set! (-> arg0 unknown-vector70 quad) (-> arg1 best-tri intersect quad))
       (set! (-> arg0 unknown-vector71 quad) (-> arg0 poly-normal quad))
       (set! (-> arg0 wall-pat) (-> arg1 best-tri pat))
       (vector-reflect-flat-above! arg2 (-> sv-88 0) sv-84)
       (cond
         ((not (and (>= (-> arg1 best-from-prim local-sphere w)
                        (vector-dot (-> arg0 ground-poly-normal)
                                    (vector-! (new 'stack-no-clear 'vector) (-> arg1 best-tri intersect) (-> arg0 ground-touch-point))))
                    (and (< 0.0 (vector-dot (-> arg0 ground-poly-normal) arg2))
                         (not (time-elapsed? (-> arg0 unknown-dword10) (seconds 0.3)))
                         (not (logtest? sv-104 32))))))
         (else
          (set! sv-104 (logior sv-104 256))
          (set! sv-104 (logand -65 sv-104))
          (let ((s3-3 (vector-cross! (new 'stack-no-clear 'vector) (-> arg0 poly-normal) (-> arg0 ground-poly-normal))))
            (vector-normalize! s3-3 1.0)
            (vector-float*! arg2 s3-3 (vector-dot (-> sv-88 0) s3-3)))
          (vector+! arg2 arg2 (-> arg0 poly-normal))))
       (let* ((s2-2 (vector-normalize-copy! (new 'stack-no-clear 'vector) (-> sv-88 0) 1.0))
              (s3-4 (new-stack-vector0))
              (f30-1 (vector-dot s2-2 arg2)))
         0.0
         (vector-! s3-4 arg2 (vector-float*! s3-4 s2-2 f30-1))
         (let* ((f1-11 (vector-length s3-4))
                (f0-27 f1-11)
                (f1-12 (* 0.9 f1-11)))
           (vector+! arg2 (vector-float*! arg2 s2-2 f30-1) (vector-float*! s3-4 s3-4 (/ f1-12 f0-27))))))
      (else
       (set! sv-96 (logior sv-96 1))
       (set! (-> arg0 cur-pat mode) 0)
       (if (and (= (-> arg1 best-from-prim prim-id) 6) (not (logtest? sv-104 7)))
         (set! (-> arg0 local-normal quad) (-> sv-84 quad)))
       (vector-reflect-flat! arg2 (-> sv-88 0) sv-84)
       (dotimes (v1-142 16)
         (vector+! arg2 arg2 (-> arg0 poly-normal)))
       (set! sv-96 (logior sv-96 2))
       (set! (-> arg0 ground-touch-point w) 0.0)
       (when (not (logtest? sv-104 15))
         (set! sv-96 (logior sv-96 2))
         (set! (-> arg0 ground-poly-normal quad) (-> arg0 poly-normal quad))
         (set! (-> arg0 unknown-vector53 quad) (-> sv-84 quad))
         (set! (-> arg0 unknown-float60) (vector-dot sv-84 (-> arg0 dynam gravity-normal)))
         (set-time! (-> arg0 unknown-dword10))
         (set! (-> arg0 ground-pat) (-> arg0 poly-pat))
         (set! (-> arg0 ground-touch-point quad) (-> arg1 best-tri intersect quad))
         (set! sv-104 (logior sv-104 2048))
         (if (= (-> arg0 poly-pat material) (pat-material waterbottom)) (set! sv-96 (logior sv-96 1024)))))))
  (logior! (-> arg0 status) sv-96)
  (set! (-> arg0 reaction-flag) (the-as cshape-reaction-flags sv-104))
  (update! (-> arg0 history-data (-> arg0 unknown-halfword00)) arg0 (-> arg1 best-tri intersect) (-> sv-88 1) arg2)
  (set! (-> arg0 unknown-halfword00) (logand (+ (-> arg0 unknown-halfword00) 1) 127))
  (the-as cshape-moving-flags sv-96))
