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

;; name: los-control.gc
;; name in dgo: los-control
;; dgos: GAME

;; DECOMP BEGINS

(define *los-time-offset* (the-as time-frame 0))

(defmethod los-control-method-13 ((this los-control) (arg0 collide-query) (arg1 vector) (arg2 int) (arg3 float))
  (vector-copy! (-> arg0 move-dist) arg1)
  (vector-length-max! (-> arg0 move-dist) (-> this max-check-distance))
  (set! (-> arg0 radius) arg3)
  (set! (-> arg0 collide-with) (the-as collide-spec (logand (the-as collide-spec arg2) (-> this collide-with))))
  (fill-using-line-sphere *collide-cache* arg0)
  (let ((f30-0 (probe-using-line-sphere *collide-cache* arg0))
        (f28-0 (vector-length arg1))
        )
    (cond
      ((>= f30-0 0.0)
       (quad-copy! (the-as pointer (-> this last-collide-result)) (the-as pointer (-> arg0 best-other-tri)) 6)
       (* f30-0 f28-0)
       )
      (else
        f28-0
        )
      )
    )
  )

(defmethod los-control-method-9 ((this los-control) (arg0 process-focusable) (arg1 vector) (arg2 float) (arg3 float))
  (local-vars (a0-22 int) (a0-24 int) (sv-592 vector))
  (rlet ((vf0 :class vf)
         (vf4 :class vf)
         (vf5 :class vf)
         (vf6 :class vf)
         )
    (init-vf0-vector)
    (let* ((v1-1 (-> *perf-stats* data 56))
           (a0-1 (-> v1-1 ctrl))
           )
      (+! (-> v1-1 count) 1)
      (b! (zero? a0-1) cfg-2 :delay (nop!))
      (.mtc0 Perf 0)
      (.sync.l)
      (.sync.p)
      (.mtpc pcr0 0)
      (.mtpc pcr1 0)
      (.sync.l)
      (.sync.p)
      (.mtc0 Perf a0-1)
      )
    (.sync.l)
    (.sync.p)
    (label cfg-2)
    0
    (when (and (time-elapsed? (-> this last-check-time) (-> this check-interval))
               (-> this src-proc)
               (or arg0 (-> this dst-proc))
               )
      (let ((s1-0 (as-type (handle->process (-> this src-proc)) process-focusable)))
        (when s1-0
          (if (and (not arg0) (not arg1))
              (set! arg0 (as-type (handle->process (-> this dst-proc)) process-focusable))
              )
          (when (or (the-as process arg0) arg1)
            (set! sv-592 (new 'stack-no-clear 'vector))
            (let ((v1-24 (-> (get-trans (the-as process-focusable s1-0) 10) quad)))
              (set! (-> sv-592 quad) v1-24)
              )
            (let ((s0-2 (new 'stack-no-clear 'collide-query)))
              (if (not arg1)
                  (set! arg1 (get-trans arg0 3))
                  )
              (vector-copy! (-> s0-2 start-pos) sv-592)
              (set! (-> s0-2 ignore-process0) s1-0)
              (set! (-> s0-2 ignore-process1) (the-as process arg0))
              (set! (-> s0-2 ignore-pat) (-> (the-as process-focusable s1-0) root pat-ignore-mask))
              (set! (-> s0-2 action-mask) (collide-action solid semi-solid))
              (let ((s2-1 (new 'stack-no-clear 'vector)))
                (.lvf vf4 (&-> arg1 quad))
                (.lvf vf5 (&-> sv-592 quad))
                (.mov.vf.w vf6 vf0)
                (.sub.vf.xyz vf6 vf4 vf5)
                (.svf (&-> s2-1 quad) vf6)
                (let ((f30-0 (vector-length s2-1)))
                  (let ((f0-0 (los-control-method-13 this s0-2 s2-1 -2 arg3)))
                    (if (< f0-0 f30-0)
                        (vector-normalize! s2-1 f0-0)
                        )
                    )
                  (if (< (los-control-method-13 this s0-2 s2-1 1 arg2) f30-0)
                      (set-time! (-> this last-lost-los))
                      (set-time! (-> this last-gained-los))
                      )
                  )
                )
              )
            (set-time! (-> this last-check-time))
            )
          )
        )
      )
    (let ((v1-45 (-> *perf-stats* data 56)))
      (b! (zero? (-> v1-45 ctrl)) cfg-45 :delay (nop!))
      (.mtc0 Perf 0)
      (.sync.l)
      (.sync.p)
      (.mfpc a0-22 pcr0)
      (+! (-> v1-45 accum0) a0-22)
      (.mfpc a0-24 pcr1)
      (+! (-> v1-45 accum1) a0-24)
      )
    (label cfg-45)
    0
    0
    (none)
    )
  )

(defmethod should-check-los? ((this los-control) (arg0 time-frame))
  (and (time-elapsed? (-> this last-lost-los) (+ (-> this check-interval) arg0))
       (not (time-elapsed? (-> this last-gained-los) (-> this check-interval)))
       )
  )

(defmethod los-control-method-11 ((this los-control) (arg0 time-frame))
  (and (time-elapsed? (-> this last-gained-los) (+ (-> this check-interval) arg0))
       (not (time-elapsed? (-> this last-lost-los) (-> this check-interval)))
       )
  )

(defmethod init-los! ((this los-control) (arg0 process-focusable) (arg1 time-frame) (arg2 float) (arg3 collide-spec))
  (set! (-> this src-proc) (process->handle arg0))
  (set! (-> this dst-proc) (the-as handle #f))
  (set! (-> this last-lost-los) 0)
  (set! (-> this last-gained-los) 0)
  (set! (-> this last-check-time) 0)
  (set! (-> this check-interval) (+ arg1 *los-time-offset*))
  (set! (-> this max-check-distance) arg2)
  (set! (-> this collide-with) arg3)
  (set! *los-time-offset* (the-as time-frame (mod (+ *los-time-offset* (seconds 0.045)) 30)))
  0
  (none)
  )
