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

;; name: race-manager.gc
;; name in dgo: race-manager
;; dgos: STD, STC, LERLCHAL, STB, LPRTRACE

(define-extern race-start (function int process symbol process))
(define-extern race-vehicle-entity-hack (function none))
(define-extern start-pilot-recorder (function none))
(declare-type race-bike-a vehicle-city-racer)
(declare-type race-bike-b vehicle-city-racer)
(declare-type race-bike-c vehicle-city-racer)
(declare-type race-bike-d vehicle-race-bike)
(declare-type race-bike-e vehicle-race-bike)
(declare-type bikea bike-base)

;; DECOMP BEGINS

(defun race-find-ground ((arg0 vector) (arg1 vector))
  (rlet ((acc :class vf)
         (vf0 :class vf)
         (vf4 :class vf)
         (vf5 :class vf)
         (vf6 :class vf)
         (vf7 :class vf)
         )
    (init-vf0-vector)
    (let ((s5-0 (new 'stack-no-clear 'collide-query)))
      (set! (-> s5-0 start-pos quad) (-> arg1 quad))
      (vector-reset! (-> s5-0 move-dist))
      (set! (-> s5-0 move-dist y) -81920.0)
      (let ((v1-3 s5-0))
        (set! (-> v1-3 radius) 2048.0)
        (set! (-> v1-3 collide-with) (collide-spec backgnd))
        (set! (-> v1-3 ignore-process0) #f)
        (set! (-> v1-3 ignore-process1) #f)
        (set! (-> v1-3 ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1))
        (set! (-> v1-3 action-mask) (collide-action solid))
        )
      (let ((f0-2 (fill-and-probe-using-line-sphere *collide-cache* s5-0)))
        (when (>= f0-2 0.0)
          (let ((v1-6 (-> s5-0 start-pos)))
            (let ((a0-8 (-> s5-0 move-dist)))
              (let ((a1-2 f0-2))
                (.mov vf7 a1-2)
                )
              (.lvf vf5 (&-> a0-8 quad))
              )
            (.lvf vf4 (&-> v1-6 quad))
            )
          (.add.x.vf.w vf6 vf0 vf0)
          (.mul.x.vf.xyz acc vf5 vf7)
          (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
          (.svf (&-> arg0 quad) vf6)
          #t
          )
        )
      )
    )
  )

(defmethod initialize-mesh ((this race-info))
  (let ((v1-0 (entity-by-name (-> this race-mesh-name))))
    (cond
      (v1-0
        (let ((gp-0 (-> (the-as entity-race-mesh v1-0) race-mesh)))
          (set! (-> this mesh) gp-0)
          (when gp-0
            (let ((s4-0 (-> gp-0 edges 0)))
              (vector-average! (-> this start-sphere) (-> s4-0 left) (-> s4-0 right))
              (+! (-> this start-sphere y) 40960.0)
              (race-find-ground (-> this start-sphere) (-> this start-sphere))
              (+! (-> this start-sphere y) 8192.0)
              (set! (-> this start-sphere r) (* 0.5 (vector-vector-distance (-> s4-0 left) (-> s4-0 right))))
              (let ((v1-6 (new 'stack-no-clear 'vector)))
                (vector-! v1-6 (-> s4-0 right) (-> s4-0 left))
                (set-vector! (-> this start-dir) (-> v1-6 z) 0.0 (- (-> v1-6 x)) 1.0)
                )
              )
            (vector-normalize! (-> this start-dir) 1.0)
            (let* ((a0-8 (+ (-> gp-0 edge-count) -1))
                   (s4-1 (-> gp-0 edges a0-8))
                   )
              (vector-average! (-> this finish-sphere) (-> s4-1 left) (-> s4-1 right))
              (set! (-> this finish-sphere r) (* 0.75 (vector-vector-distance (-> s4-1 left) (-> s4-1 right))))
              (let ((v1-12 (new 'stack-no-clear 'vector)))
                (vector-! v1-12 (-> s4-1 right) (-> s4-1 left))
                (set-vector! (-> this finish-dir) (-> v1-12 z) 0.0 (- (-> v1-12 x)) 1.0)
                )
              )
            (vector-normalize! (-> this finish-dir) 1.0)
            (let ((f0-18 (vector-vector-distance-squared (-> this start-sphere) (-> this finish-sphere)))
                  (f1-2 163840.0)
                  )
              (if (< f0-18 (* f1-2 f1-2))
                  (logior! (-> gp-0 flags) (race-mesh-flags racemeshflag-0))
                  )
              )
            )
          )
        )
      (else
        (set! (-> this mesh) #f)
        )
      )
    )
  0
  (none)
  )

(defmethod begin-lap ((this racer-state) (arg0 race-state))
  (format #t "begin-lap racer ~d~%" (-> this rank))
  (set! (-> this lap-start) (-> arg0 current-time))
  (logior! (-> this flags) (racer-flags in-race))
  0
  (none)
  )

(defmethod end-lap ((this racer-state) (arg0 race-state))
  (+! (-> this lap-count) 1)
  (format #t "end-lap ~d racer ~d~%" (-> this lap-count) (-> this rank))
  (let ((v1-2 4)
        (a0-2 3)
        )
    (while (>= a0-2 0)
      (set! (-> this lap-time-array v1-2) (-> this lap-time-array a0-2))
      (+! a0-2 -1)
      (+! v1-2 -1)
      )
    )
  (let ((v1-5 (- (-> arg0 current-time) (-> this lap-start))))
    (set! (-> this best-lap-time) (the-as uint (min (the-as int (-> this best-lap-time)) (the-as int v1-5))))
    (set! (-> this lap-time-array 0) (the-as float v1-5))
    )
  (when (= (-> this lap-count) (-> arg0 info lap-count))
    (logior! (-> this flags) (racer-flags finished))
    (set! (-> this finish-time) (-> arg0 current-time))
    (set! (-> this finish-count) (-> arg0 finished-count))
    (+! (-> arg0 finished-count) 1)
    (send-event (handle->process (-> this racer)) 'race-finished (-> arg0 info safe-paths))
    (let ((s4-0 (handle->process (-> this racer))))
      (cond
        ((zero? (-> this finish-count))
         (let ((v1-28 (-> this rider)))
           (cond
             ((zero? v1-28)
              (format #t "racer-state::end-lap: play speech race-jak-win~%")
              (speech-control-method-12 *speech-control* (the-as process-drawable s4-0) (speech-type speech-type-38))
              )
             ((= v1-28 1)
              (format #t "racer-state::end-lap: play speech race-daxter-win~%")
              (speech-control-method-12 *speech-control* (the-as process-drawable s4-0) (speech-type speech-type-47))
              )
             ((= v1-28 2)
              (format #t "racer-state::end-lap: play speech race-errol-win~%")
              (speech-control-method-12 *speech-control* (the-as process-drawable s4-0) (speech-type speech-type-55))
              )
             )
           )
         )
        (else
          (case (-> this rider)
            ((2)
             (format #t "racer-state::end-lap: play speech race-errol-lose~%")
             (speech-control-method-12 *speech-control* (the-as process-drawable s4-0) (speech-type speech-type-56))
             )
            )
          )
        )
      )
    )
  (when (and (> (-> this lap-count) 0) (= (-> this lap-count) (+ (-> arg0 info lap-count) -1)))
    (let ((s5-1 (handle->process (-> this racer)))
          (v1-47 (-> this rider))
          )
      (cond
        ((zero? v1-47)
         (format #t "racer-state::end-lap: play speech race-jak-last-lap~%")
         (speech-control-method-12 *speech-control* (the-as process-drawable s5-1) (speech-type speech-type-32))
         )
        ((= v1-47 1)
         (format #t "racer-state::end-lap: play speech race-daxter-last-lap~%")
         (speech-control-method-12 *speech-control* (the-as process-drawable s5-1) (speech-type speech-type-41))
         )
        ((= v1-47 2)
         (format #t "racer-state::end-lap: play speech race-errol-last-lap~%")
         (speech-control-method-12 *speech-control* (the-as process-drawable s5-1) (speech-type speech-type-49))
         )
        )
      )
    )
  0
  (none)
  )

(defmethod update-lap-distance ((this racer-state) (arg0 race-state))
  (local-vars (a0-29 float))
  (rlet ((acc :class vf)
         (vf0 :class vf)
         (vf1 :class vf)
         (vf2 :class vf)
         )
    (init-vf0-vector)
    (let ((s5-0 (new 'stack-no-clear 'matrix3)))
      (-> arg0 info)
      (let ((v1-2 (handle->process (-> this racer))))
        (cond
          (v1-2
            (if (focus-test? (the-as process-focusable v1-2) dead inactive)
                (logior! (-> this flags) (racer-flags dead))
                )
            (set! (-> s5-0 vector 0 quad) (-> (the-as process-focusable v1-2) root trans quad))
            (when (not (logtest? (-> this flags) (racer-flags finished dead)))
              (let ((s3-0 (new 'stack-no-clear 'race-mesh-slice-query)))
                (set! (-> s3-0 search-sphere quad) (-> s5-0 vector 0 quad))
                (set! (-> s3-0 search-sphere r) 0.0)
                (race-mesh-method-13 (-> arg0 info mesh) (the-as race-mesh-slice-query (&-> s3-0 slice-id)))
                (set! (-> this lap-distance-prev) (-> this lap-distance))
                (cond
                  ((>= (-> s3-0 slice-id) 0)
                   (set! (-> this lap-distance) (-> s3-0 lap-dist))
                   (if (not (logtest? (-> this flags) (racer-flags on-track)))
                       (set! (-> this lap-distance-prev) (-> this lap-distance))
                       )
                   (logior! (-> this flags) (racer-flags on-track))
                   )
                  (else
                    (logclear! (-> this flags) (racer-flags on-track))
                    )
                  )
                (cond
                  ((logtest? (-> arg0 info mesh flags) (race-mesh-flags racemeshflag-0))
                   (when (>= (-> s3-0 slice-id) 0)
                     (let ((v1-29 (min 3 (the int (* 4.0 (-> s3-0 lap-dist))))))
                       (when (= v1-29 (logand (+ (-> this lap-quadrant) 1) 3))
                         (set! (-> this lap-quadrant) v1-29)
                         (when (zero? v1-29)
                           (if (logtest? (-> this flags) (racer-flags in-race))
                               (end-lap this arg0)
                               (begin-race arg0)
                               )
                           (begin-lap this arg0)
                           )
                         )
                       )
                     )
                   )
                  ((logtest? (-> this flags) (racer-flags in-race))
                   (let ((v1-39 (new 'stack-no-clear 'vector)))
                     (vector-! (the-as vector (&-> v1-39 x)) (-> this position) (the-as vector (-> arg0 info finish-sphere)))
                     (.lvf vf1 (&-> (the-as vector (&-> v1-39 x)) quad))
                     (.add.w.vf.x vf2 vf0 vf0)
                     (.mul.vf vf1 vf1 vf1)
                     (.mul.x.vf.x acc vf2 vf1)
                     (.add.mul.y.vf.x acc vf2 vf1 acc)
                     (.add.mul.z.vf.x vf1 vf2 vf1 acc)
                     (.mov a0-29 vf1)
                     (let ((f0-7 a0-29)
                           (f1-1 (-> arg0 info finish-sphere r))
                           )
                       (if (and (< f0-7 (* f1-1 f1-1)) (< 0.0 (vector-dot (the-as vector (&-> v1-39 x)) (-> arg0 info finish-dir))))
                           (end-lap this arg0)
                           )
                       )
                     )
                   )
                  (else
                    (when (< 0.0 (-> this lap-distance))
                      (begin-race arg0)
                      (begin-lap this arg0)
                      )
                    )
                  )
                )
              (let ((f0-10 (-> arg0 info ai-max-speed-factor)))
                (if (< (+ (-> arg0 target-pos) (-> this target-pos-offset)) (-> this pos))
                    (set! f0-10 (-> arg0 info ai-min-speed-factor))
                    )
                (seek! (-> this speed-factor) f0-10 (* 0.2 (seconds-per-frame)))
                )
              0
              )
            (if (logtest? (-> this flags) (racer-flags finished))
                (seek! (-> this speed-factor) 0.9 (* 0.2 (seconds-per-frame)))
                )
            (when (logtest? (-> this flags) (racer-flags in-race))
              (dotimes (s3-1 (-> arg0 info decision-point-count))
                (let ((v1-70 (-> arg0 info decision-point-array s3-1)))
                  (if (and (< (-> this lap-distance-prev) (-> v1-70 pos)) (>= (-> this lap-distance) (-> v1-70 pos)))
                      (send-event (handle->process (-> this racer)) 'race-decision-point v1-70)
                      )
                  )
                )
              (set! (-> this pos) (+ (-> this lap-distance) (the float (-> this lap-count))))
              )
            (set! (-> this position quad) (-> s5-0 vector 0 quad))
            )
          (else
            (logior! (-> this flags) (racer-flags dead))
            )
          )
        )
      )
    (when (logtest? (-> this flags) (racer-flags unknown))
      )
    0
    (none)
    )
  )

(defmethod print-laps ((this racer-state) (arg0 race-state) (arg1 string))
  (let ((s4-0 (- (-> arg0 current-time) (-> this lap-start))))
    (format arg1 "lap count ~d~%" (-> this lap-count))
    (format arg1 "best lap ")
    (print-time arg1 (the-as time-frame (-> this best-lap-time)))
    (format arg1 "~%~%")
    (when (logtest? (-> this flags) (racer-flags in-race))
      (format arg1 "this lap ")
      (print-time arg1 (the-as time-frame s4-0))
      )
    )
  (format arg1 "~%")
  (let ((s4-2 (min 5 (-> this lap-count))))
    (dotimes (s3-0 s4-2)
      (format arg1 "lap ~d " s3-0)
      (print-time arg1 (the-as time-frame (-> this lap-time-array s3-0)))
      (format arg1 "~%")
      )
    )
  0
  (none)
  )

(defmethod init-racer! ((this racer-state) (arg0 process-drawable))
  (set! (-> this racer) (process->handle arg0))
  (set! (-> this position quad) (-> arg0 root trans quad))
  (set! (-> this flags) (racer-flags unknown))
  (set! (-> this lap-count) 0)
  (set! (-> this lap-distance) 0.0)
  (set! (-> this lap-quadrant) 3)
  (set! (-> this finish-time) (the-as uint 0))
  (set! (-> this pos) 0.0)
  (set! (-> this target-pos-offset) 0.0)
  (set! (-> this speed-factor) 1.0)
  (set! (-> this finish-count) -1)
  (set! (-> this best-lap-time) (the-as uint #x2dc6c0))
  0
  (none)
  )

(defmethod init-racers! ((this race-state) (arg0 process-drawable))
  (let ((v1-0 (-> this racer-count)))
    (when (< v1-0 10)
      (+! (-> this racer-count) 1)
      (init-racer! (-> this racer-array v1-0) arg0)
      )
    )
  0
  (none)
  )

(defmethod begin-race ((this race-state))
  (format #t "begin-race~%")
  (when (not (logtest? (-> this flags) (race-flags begun)))
    (logior! (-> this flags) (race-flags begun))
    (set-speech-tables! this)
    (send-event (handle->process (-> this manager)) 'begin-race)
    (set-setting! 'sound-mode #f 0.0 0)
    (remove-setting! 'allow-progress)
    (set! (-> this race-start-time) (-> this current-time))
    (let ((s5-0 (handle->process (-> this manager))))
      (set! (-> this hud-timer) (ppointer->handle (process-spawn hud-race-timer :init hud-init-by-other :to s5-0)))
      (set! (-> this hud-position)
            (ppointer->handle (process-spawn hud-race-position :init hud-init-by-other :to s5-0))
            )
      (if (< 1 (-> this info lap-count))
          (set! (-> this hud-lap-counter)
                (ppointer->handle (process-spawn hud-race-lap-counter :init hud-init-by-other :to s5-0))
                )
          )
      (when (logtest? (-> this info flags) (race-info-flags borrow))
        (set! (-> this hud-turbo-counter)
              (ppointer->handle (process-spawn hud-race-turbo-counter :init hud-init-by-other :to s5-0))
              )
        (set-setting! 'race-minimap #f 0.0 (-> this info map-index))
        )
      )
    (dotimes (s5-1 (-> this racer-count))
      (let ((v1-61 (-> this racer-array s5-1)))
        (send-event (handle->process (-> v1-61 racer)) 'begin-race)
        )
      )
    (send-event (handle->process (-> this race-signal)) 'count-go)
    (when (nonzero? (-> this info go-speech))
      (format #t "playing speech ~d~%" (-> this info go-speech))
      (talker-spawn-func
        (-> *talker-speech* (-> this info go-speech))
        *entity-pool*
        (target-pos 0)
        (the-as region #f)
        )
      )
    )
  0
  (none)
  )

(defmethod update-rankings ((this race-state))
  (let ((v1-0 (new 'stack-no-clear 'array 'float 10)))
    (dotimes (a0-1 (-> this racer-count))
      (let ((a1-3 (-> this racer-array a0-1)))
        (cond
          ((logtest? (-> a1-3 flags) (racer-flags finished))
           (set! (-> v1-0 a0-1) (the float (- 1000 (-> a1-3 finish-count))))
           )
          ((logtest? (-> a1-3 flags) (racer-flags in-race))
           (set! (-> v1-0 a0-1) (+ (the float (-> a1-3 lap-count)) (-> a1-3 lap-distance)))
           )
          (else
            (set! (-> v1-0 a0-1) 0.0)
            )
          )
        )
      )
    (let ((a0-4 0)
          (a1-16 1)
          )
      (while (< a1-16 (-> this racer-count))
        (let ((a2-7 (-> this rankings a0-4))
              (a3-1 (-> this rankings a1-16))
              )
          (when (< (-> v1-0 a2-7) (-> v1-0 a3-1))
            (set! (-> this rankings a0-4) a3-1)
            (set! (-> this rankings a1-16) a2-7)
            )
          )
        (+! a0-4 1)
        (+! a1-16 1)
        )
      )
    )
  (dotimes (s5-0 (-> this racer-count))
    (let* ((v1-3 (-> this rankings s5-0))
           (s4-0 (-> this racer-array v1-3))
           )
      (if (and (zero? s5-0) (nonzero? (-> s4-0 rank)))
          (send-event (handle->process (-> s4-0 racer)) 'race-pass)
          )
      (if (and (nonzero? s5-0) (zero? (-> s4-0 rank)))
          (send-event (handle->process (-> s4-0 racer)) 'race-got-passed)
          )
      (set! (-> s4-0 rank) s5-0)
      )
    )
  0
  (none)
  )

(defmethod debug-print-rankings ((this race-state))
  (dotimes (s5-0 (-> this racer-count))
    (let* ((s4-0 (-> this rankings s5-0))
           (s3-0 (-> this racer-array s4-0))
           )
      (when (not (logtest? (-> s3-0 flags) (racer-flags dead)))
        (if (= s4-0 (-> this i-player))
            (format *stdcon* ">>>")
            (format *stdcon* "   ")
            )
        (cond
          ((logtest? (-> s3-0 flags) (racer-flags finished))
           (format *stdcon* " #~d  finished " (+ s4-0 1))
           (cond
             ((zero? s5-0)
              (let ((a1-3 (- (-> s3-0 finish-time) (-> this race-start-time))))
                (print-time *stdcon* (the-as time-frame a1-3))
                )
              )
             (else
               (format *stdcon* "+")
               (let ((a1-7 (- (- (-> s3-0 finish-time) (-> this race-start-time))
                              (- (-> this racer-array (-> this rankings 0) finish-time) (-> this race-start-time))
                              )
                           )
                     )
                 (print-time *stdcon* (the-as time-frame a1-7))
                 )
               )
             )
           (format *stdcon* "~%")
           )
          (else
            (format *stdcon* " #~d  lap ~d  ~f~%" (+ s4-0 1) (+ (-> s3-0 lap-count) 1) (-> s3-0 lap-distance))
            )
          )
        )
      )
    )
  0
  (none)
  )

(defmethod update-racers ((this race-state))
  (let ((s5-0 0))
    (dotimes (s4-0 (-> this racer-count))
      (let ((s3-0 (-> this racer-array s4-0)))
        (update-lap-distance s3-0 this)
        (if (not (logtest? (-> s3-0 flags) (racer-flags finished dead)))
            (+! s5-0 1)
            )
        )
      0
      )
    (if (zero? s5-0)
        (set! (-> this state) (race-state-enum all-dead))
        )
    )
  0
  (none)
  )

(defmethod setup-race ((this race-state))
  (set-setting! 'allow-progress #f 0.0 0)
  (send-event (handle->process (-> this arrow)) 'leave)
  (when (logtest? (-> this info flags) (race-info-flags borrow))
    (send-event *traffic-manager* 'set-target-level 0.0)
    (send-event *traffic-manager* 'set-alert-level 0)
    )
  (send-event (handle->process (-> this race-signal)) 'ready)
  (let ((v1-27 (new 'stack-no-clear 'matrix)))
    (vector-reset! (-> v1-27 vector 2))
    (vector-reset! (-> v1-27 trans))
    (let ((a0-21 (-> this racer-array (-> this i-player))))
      (let ((a3-1 (handle->process (-> a0-21 racer))))
        (if a3-1
            (set! (-> v1-27 vector 0 quad) (-> (the-as process-drawable a3-1) root trans quad))
            )
        )
      (set! (-> v1-27 vector 1 quad) (-> a0-21 start-position quad))
      )
    (cubic-curve-method-9
      (-> this player-intro-curve)
      (the-as vector (-> v1-27 vector))
      (-> v1-27 vector 2)
      (-> v1-27 vector 1)
      (-> v1-27 trans)
      )
    )
  (let ((a0-25 (-> this info hatch-actor-name)))
    (when a0-25
      (let ((a0-26 (process-by-name a0-25 *active-pool*)))
        (send-event a0-26 'open)
        )
      )
    )
  (set! (-> this countdown-start-time) (-> this current-time))
  0
  (none)
  )

(defmethod update ((this race-state))
  (set! (-> this current-time) (the-as uint (current-time)))
  (case (-> this state)
    (((race-state-enum idle))
     (let ((v1-3 (the-as object #t)))
       (when (not (logtest? (-> this flags) (race-flags ready)))
         (dotimes (s5-0 (-> this racer-count))
           (let ((a0-7 (-> this racer-array s5-0)))
             (set! v1-3 (and v1-3 (send-event (handle->process (-> a0-7 racer)) 'test-ready)))
             )
           )
         )
       (when (and v1-3 (not (logtest? (-> this info flags) (race-info-flags city-race))))
         (spawn-race-signal this)
         (set! v1-3 (handle->process (-> this race-signal)))
         )
       (when v1-3
         (setup-race this)
         (set! (-> this state)
               (if (or (logtest? (-> this flags) (race-flags pidax)) (logtest? (-> this info flags) (race-info-flags city-race)))
                   (race-state-enum countdown-start)
                   (race-state-enum player-get-on)
                   )
               )
         )
       )
     )
    (((race-state-enum player-get-on))
     (let* ((f30-0 (* 0.0033333334 (the float (- (-> this current-time) (-> this countdown-start-time)))))
            (s4-0 (handle->process (-> this racer-array (-> this i-player) racer)))
            (s5-1 (if (type? s4-0 process-focusable)
                      s4-0
                      )
                  )
            )
       (cond
         ((< f30-0 1.0)
          (when s5-1
            (cubic-curve-method-10 (-> this player-intro-curve) (-> (the-as process-focusable s5-1) root trans) f30-0)
            (cubic-curve-method-11 (-> this player-intro-curve) (-> (the-as process-focusable s5-1) root transv) f30-0)
            (when (< 0.4 f30-0)
              (when (-> this info start-camera)
                (set-setting! 'entity-name (-> this info start-camera) 0.0 0)
                (if (logtest? (-> this info flags) (race-info-flags show-tutorial))
                    (talker-spawn-func (-> *talker-speech* 377) *entity-pool* (target-pos 0) (the-as region #f))
                    )
                )
              )
            )
          )
         (else
           (set! (-> this state) (race-state-enum player-set-pos))
           )
         )
       )
     )
    (((race-state-enum player-set-pos))
     (let* ((s4-2 (handle->process (-> this racer-array (-> this i-player) racer)))
            (s5-3 (if (type? s4-2 process-focusable)
                      s4-2
                      )
                  )
            )
       (when s5-3
         (cubic-curve-method-10 (-> this player-intro-curve) (-> (the-as process-focusable s5-3) root trans) 1.0)
         (vector-reset! (-> (the-as process-focusable s5-3) root transv))
         )
       )
     (let ((a0-48 (-> this info hatch-actor-name)))
       (when a0-48
         (let ((a0-49 (process-by-name a0-48 *active-pool*)))
           (send-event a0-49 'close)
           )
         )
       )
     (set! (-> this countdown-start-time) (-> this current-time))
     (set! (-> this state) (if (-> this info countdown-scene)
                               (race-state-enum countdown-scene-start)
                               (race-state-enum countdown-start)
                               )
           )
     )
    (((race-state-enum countdown-scene-start))
     (when (>= (the-as uint (- (current-time) (the-as int (-> this countdown-start-time)))) (the-as uint 300))
       (set! (-> this state) (race-state-enum countdown-scene))
       (set! (-> this scene-player)
             (ppointer->handle (process-spawn scene-player :init scene-player-init (-> this info countdown-scene) #t #f))
             )
       )
     )
    (((race-state-enum countdown-scene))
     (cond
       ((handle->process (-> this scene-player))
        (let ((s5-5 (-> this info)))
          (dotimes (s4-3 (-> s5-5 racer-count))
            (let ((v1-95 (-> this racer-array s4-3)))
              (if (logtest? (-> s5-5 racer-array s4-3 flags) (racer-info-flags hide-in-scene))
                  (send-event (handle->process (-> v1-95 racer)) 'hide)
                  )
              )
            )
          )
        )
       (else
         (let ((s5-6 (-> this info)))
           (dotimes (s4-4 (-> s5-6 racer-count))
             (let ((v1-105 (-> this racer-array s4-4)))
               (if (logtest? (-> s5-6 racer-array s4-4 flags) (racer-info-flags hide-in-scene))
                   (send-event (handle->process (-> v1-105 racer)) 'unhide)
                   )
               )
             )
           )
         (set! (-> this state) (race-state-enum countdown-start))
         )
       )
     )
    (((race-state-enum countdown-start))
     (set! (-> this i-countdown) 4)
     (set! (-> this state) (race-state-enum countdown))
     (set! (-> this countdown-start-time) (-> this current-time))
     (remove-setting! 'entity-name)
     )
    (((race-state-enum countdown))
     (let ((f0-3 3.0))
       (if (logtest? (-> this info flags) (race-info-flags city-race))
           (set! f0-3 0.2)
           )
       (let ((v1-127 (+ (the int (* 300.0 f0-3)) (- (-> this countdown-start-time) (-> this current-time)))))
         (cond
           ((>= v1-127 (the int (* 225.0 f0-3)))
            )
           ((>= v1-127 (the int (* 150.0 f0-3)))
            (when (!= (-> this i-countdown) 3)
              (set! (-> this i-countdown) 3)
              (send-event (handle->process (-> this race-signal)) 'count-3)
              )
            )
           ((>= v1-127 (the int (* 75.0 f0-3)))
            (when (!= (-> this i-countdown) 2)
              (set! (-> this i-countdown) 2)
              (send-event (handle->process (-> this race-signal)) 'count-2)
              )
            )
           ((< (the int (* 0.0 f0-3)) v1-127)
            (when (!= (-> this i-countdown) 1)
              (set! (-> this i-countdown) 1)
              (send-event (handle->process (-> this race-signal)) 'count-1)
              )
            )
           (else
             (set! (-> this i-countdown) 0)
             (set! (-> this state) (race-state-enum active))
             (begin-race this)
             )
           )
         )
       )
     (update-racers this)
     )
    (((race-state-enum active))
     (update-racers this)
     (update-rankings this)
     )
    (((race-state-enum all-dead))
     )
    (else
      )
    )
  (dotimes (s5-7 (-> this info turbo-pad-count))
    (let ((s4-5 (-> this info turbo-pad-array s5-7)))
      (if (not (handle->process (-> s4-5 handle)))
          (set! (-> s4-5 handle)
                (process->handle (turbo-pickup-spawn (handle->process (-> this manager)) (-> s4-5 position)))
                )
          )
      )
    )
  0
  (none)
  )

(defmethod spawn-race-signal ((this race-state))
  (rlet ((acc :class vf)
         (vf0 :class vf)
         (vf4 :class vf)
         (vf5 :class vf)
         (vf6 :class vf)
         (vf7 :class vf)
         )
    (init-vf0-vector)
    (when (= (level-status *level* 'lracelit) 'active)
      (let ((s3-0 (-> this info))
            (s5-1 (handle->process (-> this manager)))
            (s4-0 (new 'stack-no-clear 'matrix))
            )
        (vector-float*! (-> s4-0 vector 2) (-> s3-0 start-dir) -1.0)
        (forward-up-nopitch->quaternion
          (the-as quaternion (-> s4-0 vector 1))
          (-> s4-0 vector 2)
          (new 'static 'vector :y 1.0 :w 1.0)
          )
        (let ((a0-7 (-> s4-0 vector)))
          (let ((v1-8 (-> s3-0 start-sphere)))
            (let ((a1-4 (-> s3-0 start-dir)))
              (let ((a2-2 49152.0))
                (.mov vf7 a2-2)
                )
              (.lvf vf5 (&-> a1-4 quad))
              )
            (.lvf vf4 (&-> v1-8 quad))
            )
          (.add.x.vf.w vf6 vf0 vf0)
          (.mul.x.vf.xyz acc vf5 vf7)
          (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
          (.svf (&-> a0-7 0 quad) vf6)
          )
        (+! (-> s4-0 vector 0 y) 22528.0)
        (set! (-> this race-signal)
              (process->handle
                (race-signal-spawn s5-1 (the-as vector (-> s4-0 vector)) (the-as quaternion (-> s4-0 vector 1)))
                )
              )
        )
      )
    0
    (none)
    )
  )

(defmethod initialize ((this race-state) (arg0 process) (arg1 race-info))
  (rlet ((acc :class vf)
         (vf0 :class vf)
         (vf4 :class vf)
         (vf5 :class vf)
         (vf6 :class vf)
         (vf7 :class vf)
         )
    (init-vf0-vector)
    (let ((s3-0 (-> this flags)))
      (mem-set32! (the-as pointer this) 324 0)
      (set! (-> this flags) s3-0)
      )
    (set! (-> this info) arg1)
    (set! (-> this manager) (process->handle arg0))
    (set! (-> this scene-player) (the-as handle #f))
    (set! (-> this hud-timer) (the-as handle #f))
    (set! (-> this hud-lap-counter) (the-as handle #f))
    (set! (-> this hud-turbo-counter) (the-as handle #f))
    (set! (-> this hud-position) (the-as handle #f))
    (set! (-> this arrow) (the-as handle #f))
    (set! (-> this state) (race-state-enum idle))
    (set! (-> this racer-count) 0)
    (set! (-> this finished-count) 0)
    (let ((v1-3 (new 'stack-no-clear 'mystery-race-manager-type)))
      (set! (-> v1-3 vec1 z) 81920.0)
      (set! (-> v1-3 word) 4)
      (set! (-> v1-3 vec0 z) (/ (-> v1-3 vec1 z) -2))
      (set! (-> v1-3 vec0 w) -20480.0)
      (set! (-> v1-3 vec1 x) (/ (-> v1-3 vec1 z) (the float (+ (-> v1-3 word) -1))))
      (set! (-> v1-3 vec1 y) -40960.0)
      (set! (-> v1-3 mat quad 0) (-> arg1 start-sphere quad))
      (set! (-> v1-3 mat vector 1 quad) (-> arg1 start-dir quad))
      (set-vector! (-> v1-3 mat vector 2) (-> v1-3 mat vector 1 z) 0.0 (- (-> v1-3 mat vector 1 x)) 1.0)
      (dotimes (a0-15 (-> arg1 racer-count))
        (let ((a1-8 (/ a0-15 (-> v1-3 word))))
          (let ((a2-4 (- a0-15 (* a1-8 (-> v1-3 word)))))
            (set! (-> v1-3 vec0 x) (+ (-> v1-3 vec0 z) (* (-> v1-3 vec1 x) (the float a2-4))))
            )
          (set! (-> v1-3 vec0 y) (+ (-> v1-3 vec0 w) (* (-> v1-3 vec1 y) (the float a1-8))))
          )
        (let ((a1-13 (-> this racer-array a0-15)))
          (-> arg1 racer-array a0-15)
          (set! (-> v1-3 mat trans quad) (-> v1-3 mat quad 0))
          (let ((t0-0 (-> v1-3 mat trans)))
            (let ((a2-8 (-> v1-3 mat trans)))
              (let ((a3-3 (-> v1-3 mat vector 1)))
                (let ((t1-0 (-> v1-3 vec0 y)))
                  (.mov vf7 t1-0)
                  )
                (.lvf vf5 (&-> a3-3 quad))
                )
              (.lvf vf4 (&-> a2-8 quad))
              )
            (.add.x.vf.w vf6 vf0 vf0)
            (.mul.x.vf.xyz acc vf5 vf7)
            (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
            (.svf (&-> t0-0 quad) vf6)
            )
          (let ((t0-1 (-> v1-3 mat trans)))
            (let ((a2-9 (-> v1-3 mat trans)))
              (let ((a3-4 (-> v1-3 mat vector 2)))
                (let ((t1-1 (-> v1-3 vec0 x)))
                  (.mov vf7 t1-1)
                  )
                (.lvf vf5 (&-> a3-4 quad))
                )
              (.lvf vf4 (&-> a2-9 quad))
              )
            (.add.x.vf.w vf6 vf0 vf0)
            (.mul.x.vf.xyz acc vf5 vf7)
            (.add.mul.w.vf.xyz vf6 vf4 vf0 acc)
            (.svf (&-> t0-1 quad) vf6)
            )
          (set! (-> a1-13 start-position quad) (-> v1-3 mat trans quad))
          (set! (-> a1-13 rank) a0-15)
          (set! (-> a1-13 speed-factor) 1.0)
          )
        (set! (-> this rankings a0-15) a0-15)
        )
      )
    (dotimes (v1-6 (-> this info turbo-pad-count))
      (set! (-> this info turbo-pad-array v1-6 handle) (the-as handle #f))
      )
    (let ((v1-12 (-> *game-info* sub-task-list (-> arg1 task-node))))
      (set! (-> this suck-factor) 0.0)
      (if (not (logtest? (-> arg1 flags) (race-info-flags bbush)))
          (set! (-> this suck-factor) (fmax 0.0 (fmin 1.0 (* 0.2 (+ -4.0 (the float (-> v1-12 death-count)))))))
          )
      (format
        #t
        "race-state::initialize: death-count ~d, suck-factor ~f~%"
        (-> v1-12 death-count)
        (-> this suck-factor)
        )
      )
    0
    (none)
    )
  )

(define *race-state* (new 'static 'race-state))

(define *race-rigid-body-queue* (new 'static 'rigid-body-queue))

(defmethod update ((this race-manager))
  (let ((s5-0 *display-race-marks*))
    (when (logtest? s5-0 (race-marks-controls rmc2040))
      (let ((a0-3 (entity-by-name (-> *race-info-array* *select-race* race-mesh-name))))
        (when a0-3
          (let ((s4-0 (-> (the-as entity-race-mesh a0-3) race-mesh)))
            (when s4-0
              (let ((s3-0 8))
                (dotimes (s2-0 8)
                  (if (logtest? s5-0 s3-0)
                      (debug-draw-path-from-history s4-0 s2-0 0)
                      )
                  (set! s3-0 (* s3-0 2))
                  )
                )
              )
            )
          )
        )
      )
    )
  (let ((v1-14 (new 'stack-no-clear 'inline-array 'vector 5)))
    (let ((a0-6 (-> this race-state info)))
      (set! (-> v1-14 0 quad) (-> a0-6 start-sphere quad))
      (set! (-> v1-14 1 quad) (-> a0-6 start-dir quad))
      )
    (set! (-> v1-14 2 y) 0.0)
    (set! (-> v1-14 2 x) (- (-> v1-14 1 z)))
    (set! (-> v1-14 2 z) (-> v1-14 1 x))
    (vector-float*! (-> v1-14 3) (-> v1-14 2) (-> v1-14 0 w))
    (vector+! (-> v1-14 4) (-> v1-14 0) (-> v1-14 3))
    (vector-! (-> v1-14 5) (-> v1-14 0) (-> v1-14 3))
    )
  0
  (update (-> this race-state))
  0
  )

(defmethod race-manager-method-22 ((this race-manager))
  0
  (none)
  )

(defmethod initialize-race-state ((this race-manager))
  (let ((s5-0 (-> this race-state info)))
    (initialize-mesh s5-0)
    (initialize (-> this race-state) this s5-0)
    )
  (let ((v1-5 *game-info*))
    (set! (-> v1-5 race-position) 0)
    (set! (-> v1-5 race-current-lap-count) 0)
    (set! (-> v1-5 race-total-lap-count) 0)
    (set! (-> v1-5 race-timer) (the-as uint 0))
    (set! (-> v1-5 race-number-turbos) 0)
    )
  0
  0
  (none)
  )

;; ERROR: Unsupported inline assembly instruction kind - [mfc0 v1, Count]
(defmethod initialize-state ((this race-manager))
  (local-vars
    (v1-0 int)
    (sv-352 task-arrow-params)
    (sv-368 (function process type traffic-object-spawn-params process-drawable))
    (sv-384 race-manager)
    (sv-400 process-drawable)
    (sv-416 int)
    )
  (.mfc0 v1-0 Count)
  (rigid-body-queue-manager-spawn *race-rigid-body-queue* this)
  (let* ((gp-0 (-> this race-state))
         (s3-0 (-> gp-0 info))
         )
    (if (or (logtest? (-> s3-0 flags) (race-info-flags pidax))
            (logtest? (continue-flags pilot) (-> *game-info* last-continue flags))
            )
        (logior! (-> gp-0 flags) (race-flags pidax))
        )
    (let ((s4-0 (new 'stack-no-clear 'mystery-traffic-object-spawn-params)))
      (set! (-> s4-0 vector 0 quad) (-> gp-0 info start-sphere quad))
      (set! (-> s4-0 vector 1 quad) (-> gp-0 info start-dir quad))
      (set-vector! (-> s4-0 vector 2) (-> s4-0 vector 1 z) 0.0 (- (-> s4-0 vector 1 x)) 1.0)
      (set! (-> s4-0 params object-type) (traffic-type tt17))
      (set! (-> s4-0 params behavior) (the-as uint 10))
      (set! (-> s4-0 params id) (the-as uint 0))
      (set! (-> s4-0 params nav-mesh) #f)
      (set! (-> s4-0 params nav-branch) #f)
      (set! (-> s4-0 params proc) #f)
      (set! (-> s4-0 params handle) (the-as handle #f))
      (set! (-> s4-0 params user-data) (the-as uint 0))
      (set! (-> s4-0 params flags) (traffic-spawn-flags))
      (set! (-> s4-0 params guard-type) (the-as uint 7))
      (vector-reset! (-> s4-0 params velocity))
      (set! (-> gp-0 i-player) 0)
      (forward-up-nopitch->quaternion
        (-> s4-0 params rotation)
        (-> s4-0 vector 1)
        (new 'static 'vector :y 1.0 :w 1.0)
        )
      (set! (-> gp-0 race-signal) (the-as handle #f))
      (cond
        ((and *debug-segment* *target* *race-record-path*)
         (let ((s2-0 (the-as race-racer-info #f)))
           (dotimes (v1-18 (-> s3-0 racer-count))
             (let* ((a0-13 (-> s3-0 racer-array v1-18))
                    (a1-6 (-> a0-13 rider))
                    )
               (if (or (zero? a1-6) (= a1-6 1))
                   (set! s2-0 a0-13)
                   )
               )
             )
           (if (not s2-0)
               (format 0 "race-manager::initialize-state: no player found~%")
               )
           (when s2-0
             (set! (-> s4-0 params id) (the-as uint 0))
             (set! (-> gp-0 i-player) 0)
             (set! (-> s4-0 params position quad) (-> *target* control trans quad))
             (quaternion-copy! (-> s4-0 params rotation) (-> *target* control quat))
             (+! (-> s4-0 params position y) 12288.0)
             (set! (-> s4-0 params behavior) (the-as uint 4))
             (logclear! (-> s4-0 params flags) (traffic-spawn-flags trsflags-01))
             (let ((s5-1 (vehicle-spawn this (type-from-race-vehicle-type (-> s2-0 vehicle)) (-> s4-0 params))))
               (when s5-1
                 (init-racers! gp-0 s5-1)
                 (send-event *target* 'change-mode 'pilot s5-1 0 #t)
                 (start-pilot-recorder)
                 )
               (if (not s5-1)
                   (format 0 "failed to spawn racebike~%")
                   )
               )
             )
           )
         )
        (else
          (set! (-> gp-0 racer-count) (-> s3-0 racer-count))
          (dotimes (s2-1 (-> s3-0 racer-count))
            (let ((s0-0 (-> gp-0 racer-array s2-1))
                  (s1-0 (-> s3-0 racer-array s2-1))
                  )
              36
              (set! (-> s4-0 params position quad) (-> s0-0 start-position quad))
              (set! (-> s4-0 params id) (the-as uint s2-1))
              (set! (-> s4-0 params user-data) (-> s1-0 rider))
              (logior! (-> s4-0 params flags) (traffic-spawn-flags trsflags-01))
              (let ((v1-48 (-> s1-0 rider)))
                (cond
                  ((or (zero? v1-48) (= v1-48 1))
                   (set! (-> gp-0 i-player) s2-1)
                   (when (not (or (logtest? (-> gp-0 flags) (race-flags pidax sleep))
                                  (logtest? (-> s3-0 flags) (race-info-flags city-race))
                                  )
                              )
                     (set! sv-352 (new 'stack-no-clear 'task-arrow-params))
                     (set! (-> sv-352 pos quad) (-> gp-0 info player-intro-pos quad))
                     (quaternion-identity! (-> sv-352 quat))
                     (set! (-> sv-352 flags) (task-arrow-flags))
                     (set! (-> sv-352 map-icon) (the-as uint 15))
                     (let ((t9-11 task-arrow-spawn)
                           (a1-17 this)
                           )
                       (set! (-> gp-0 arrow) (process->handle (t9-11 sv-352 a1-17)))
                       )
                     (set! (-> s4-0 params position quad) (-> gp-0 info player-intro-pos quad))
                     (+! (-> s4-0 params position y) 12288.0)
                     )
                   (logclear! (-> s4-0 params flags) (traffic-spawn-flags trsflags-01))
                   (set! sv-416 37)
                   sv-416
                   )
                  ((= v1-48 2)
                   (set! sv-416 38)
                   sv-416
                   )
                  (else
                    (set! sv-416 36)
                    sv-416
                    )
                  )
                )
              (when (not (and (logtest? (-> gp-0 flags) (race-flags sleep))
                              (logtest? (-> s1-0 flags) (racer-info-flags hide-in-scene))
                              )
                         )
                (set! sv-368 vehicle-spawn)
                (set! sv-384 this)
                (let ((a1-18 (type-from-race-vehicle-type (-> s1-0 vehicle)))
                      (a2-3 (-> s4-0 params))
                      )
                  (set! sv-400 (sv-368 sv-384 a1-18 a2-3))
                  )
                (when sv-400
                  (let ((a0-52 *minimap*)
                        (t9-14 (method-of-type minimap add-icon!))
                        (a1-19 sv-400)
                        (a3-0 #f)
                        (t0-0 #t)
                        (t1-0 0)
                        )
                    (t9-14 a0-52 a1-19 (the-as uint sv-416) (the-as int a3-0) (the-as vector t0-0) t1-0)
                    )
                  (init-racer! s0-0 sv-400)
                  (set! (-> s0-0 rider) (-> s1-0 rider))
                  (set! (-> s0-0 target-pos-offset)
                        (* (-> s3-0 ai-spread-factor) (+ (the float (-> s1-0 seek-offset)) (* -3.33 (-> gp-0 suck-factor))))
                        )
                  (when (and (= s2-1 (-> gp-0 i-player)) (logtest? (-> gp-0 flags) (race-flags pidax)))
                    (let ((v1-91 'pilot))
                      (if (= (-> s1-0 rider) 1)
                          (set! v1-91 'pilot-daxter)
                          )
                      (send-event *target* 'change-mode v1-91 sv-400 0 #t)
                      )
                    )
                  )
                (if (not sv-400)
                    (format 0 "failed to spawn racebike~%")
                    )
                )
              )
            )
          )
        )
      )
    )
  0
  0
  (none)
  )

(defmethod save-score ((this race-manager) (arg0 float))
  (local-vars (sv-32 int))
  (let* ((s5-0 (-> this race-state info score))
         (s3-0 0)
         (s2-0 (-> *highscore-info-array* s5-0))
         )
    (let ((s0-0 (get-game-score-ref *game-info* (the-as int s5-0)))
          (s1-0 (new 'stack-no-clear 'array 'int8 4))
          )
      (dotimes (v1-5 4)
        (set! (-> s1-0 v1-5) 0)
        )
      (set! sv-32 0)
      (while (< sv-32 8)
        (let ((v1-13 (get-rank s2-0 (-> s0-0 sv-32))))
          (+! (-> s1-0 v1-13) 1)
          )
        (set! sv-32 (+ sv-32 1))
        )
      (dotimes (v1-20 4)
        (if (< 1 (-> s1-0 v1-20))
            (set! s3-0 v1-20)
            )
        )
      )
    (let* ((v1-24 (get-rank s2-0 arg0))
           (s2-2 (max 0 (- v1-24 s3-0)))
           )
      (when (> (the-as uint s2-2) 0)
        (set! (-> this finish-sound-id) (the-as sound-id 1))
        (cond
          ((= v1-24 3)
           (talker-spawn-func (-> *talker-speech* 374) *entity-pool* (target-pos 0) (the-as region #f))
           )
          ((= v1-24 2)
           (talker-spawn-func (-> *talker-speech* 375) *entity-pool* (target-pos 0) (the-as region #f))
           )
          ((= v1-24 1)
           (talker-spawn-func (-> *talker-speech* 376) *entity-pool* (target-pos 0) (the-as region #f))
           )
          )
        )
      (game-info-method-28 *game-info* (the-as game-score s5-0) arg0)
      ;; og:preserve-this just give the skill directly
      (#cond
        (PC_PORT
          (send-event *target* 'get-pickup (pickup-type skill) (* (the float s2-2) (-> *FACT-bank* super-skill-inc))))
        (#t
          (let ((gp-1 (new 'static 'fact-info)))
            (set! (-> gp-1 options) (actor-option))
            (logior! (-> gp-1 options) (actor-option suck-in))
            (birth-pickup-at-point
              (camera-pos)
              (pickup-type skill)
              (* (the float s2-2) (-> *FACT-bank* super-skill-inc))
              #t
              *entity-pool*
              gp-1
              )
            )
          )
        )
      )
    )
  0
  (none)
  )

(defmethod stop-speech ((this race-manager))
  (set-action!
    *gui-control*
    (gui-action stop)
    (the-as sound-id 1)
    (gui-channel guard)
    (gui-action none)
    (the-as string #f)
    (the-as (function gui-connection symbol) #f)
    (the-as process #f)
    )
  (set-action!
    *gui-control*
    (gui-action stop)
    (the-as sound-id 1)
    (gui-channel background)
    (gui-action none)
    (the-as string #f)
    (the-as (function gui-connection symbol) #f)
    (the-as process #f)
    )
  0
  (none)
  )

(defmethod draw-message-continue ((this race-manager))
  (when (= (get-status *gui-control* (-> this message-id)) (gui-status active))
    (let ((gp-1
            (new 'stack 'font-context *font-default-matrix* 70 20 0.0 (font-color orange) (font-flags shadow kerning))
            )
          )
      (let ((v1-4 gp-1))
        (set! (-> v1-4 scale) 0.7)
        )
      (let ((v1-5 gp-1))
        (set! (-> v1-5 width) (the float 225))
        )
      (let ((v1-6 gp-1))
        (set! (-> v1-6 height) (the float 70))
        )
      (set! (-> gp-1 origin x) (the float (- 256 (the int (/ (-> gp-1 width) 2)))))
      (set! (-> gp-1 origin y) 320.0)
      (set! (-> gp-1 flags) (font-flags shadow kerning middle middle-vert large))
      (let ((s5-0 print-game-text))
        (format (clear *temp-string*) (lookup-text! *common-text* (text-id progress-x-to-continue) #f) 1)
        (s5-0 *temp-string* gp-1 #f 44 (bucket-id progress))
        )
      )
    )
  0
  (none)
  )

(defmethod draw-message-retry ((this race-manager))
  (when (= (get-status *gui-control* (-> this message-id)) (gui-status active))
    (let ((gp-1
            (new 'stack 'font-context *font-default-matrix* 70 20 0.0 (font-color orange) (font-flags shadow kerning))
            )
          )
      (let ((v1-4 gp-1))
        (set! (-> v1-4 scale) 0.7)
        )
      (let ((v1-5 gp-1))
        (set! (-> v1-5 width) (the float 240))
        )
      (let ((v1-6 gp-1))
        (set! (-> v1-6 height) (the float 35))
        )
      (set! (-> gp-1 origin x) (the float (- 256 (the int (/ (-> gp-1 width) 2)))))
      (set! (-> gp-1 origin y) 320.0)
      (set! (-> gp-1 flags) (font-flags shadow kerning middle middle-vert large))
      (let ((s5-0 print-game-text))
        (format (clear *temp-string*) (lookup-text! *common-text* (text-id try-again?) #f) 1)
        (s5-0 *temp-string* gp-1 #f 44 (bucket-id progress))
        )
      (+! (-> gp-1 origin y) 35.0)
      (let ((s5-1 print-game-text))
        (format (clear *temp-string*) (lookup-text! *common-text* (text-id yes-no-prompt) #f) 1)
        (s5-1 *temp-string* gp-1 #f 44 (bucket-id progress))
        )
      )
    )
  0
  (none)
  )

(defbehavior race-manager-event-handler race-manager ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  (case arg2
    (('die)
     (go-virtual die)
     )
    (('force-start)
     (let ((v0-0 (the-as object (logior (-> self race-state flags) (race-flags ready)))))
       (set! (-> self race-state flags) (the-as race-flags v0-0))
       v0-0
       )
     )
    (('begin-race)
     (send-event (ppointer->process (-> self parent)) 'fail-on-death #t)
     )
    (('win)
     0
     )
    (('lose)
     0
     )
    )
  )

(defstate idle (race-manager)
  :virtual #t
  :event race-manager-event-handler
  :code (behavior ()
    (cond
      ((logtest? (-> self race-state flags) (race-flags sleep))
       (initialize-race-state self)
       (initialize-state self)
       (until #f
         (suspend)
         )
       #f
       )
      (else
        (set-setting! 'music 'race 0.0 0)
        (set-setting! 'sound-mode #f 0.0 2)
        (let ((gp-0 (-> self race-state info)))
          (when (logtest? (-> gp-0 flags) (race-info-flags borrow))
            (set-setting! 'borrow (-> gp-0 borrow) 0.0 0)
            (while (!= (level-status *level* 'lracelit) 'active)
              (suspend)
              )
            (while (!= (level-status *level* (-> gp-0 borrow-level)) 'active)
              (suspend)
              )
            )
          )
        (while (not (and *target* (or (not (focus-test? *target* teleporting)) (focus-test? *target* pilot))))
          (suspend)
          )
        (initialize-race-state self)
        (initialize-state self)
        (suspend)
        (let ((gp-1 (-> self race-state info)))
          (when (and (-> gp-1 countdown-scene) (not (logtest? (-> self race-state flags) (race-flags pidax))))
            (dotimes (s5-2 (-> gp-1 racer-count))
              (let ((v1-42 (-> self race-state racer-array s5-2)))
                (if (and (logtest? (-> gp-1 racer-array s5-2 flags) (racer-info-flags hide-in-scene))
                         (!= s5-2 (-> self race-state i-player))
                         )
                    (send-event (handle->process (-> v1-42 racer)) 'hide)
                    )
                )
              )
            )
          )
        (when (and *debug-segment* *target* *race-record-path*)
          (until #f
            (update self)
            (suspend)
            )
          #f
          )
        )
      )
    (go-virtual active)
    )
  )

(defstate active (race-manager)
  :virtual #t
  :event race-manager-event-handler
  :code sleep-code
  :post (behavior ()
    (update self)
    (let ((gp-0 (-> self race-state racer-array (-> self race-state i-player)))
          (s5-0 (-> self race-state))
          )
      (set! (-> s5-0 target-pos) (-> gp-0 pos))
      (let ((v1-5 *game-info*))
        (set! (-> v1-5 race-position) (-> gp-0 rank))
        (set! (-> v1-5 race-current-lap-count) (min (+ (-> gp-0 lap-count) 1) (-> self race-state info lap-count)))
        (set! (-> v1-5 race-total-lap-count) (-> self race-state info lap-count))
        (let ((a0-12 (-> s5-0 current-time)))
          (if (logtest? (-> gp-0 flags) (racer-flags finished))
              (set! a0-12 (-> gp-0 finish-time))
              )
          (let ((a0-13 (the-as int (- a0-12 (-> s5-0 race-start-time)))))
            (if (not (logtest? (-> s5-0 flags) (race-flags begun)))
                (set! a0-13 0)
                )
            (set! (-> v1-5 race-timer) (the-as uint a0-13))
            )
          )
        )
      (when (logtest? (-> gp-0 flags) (racer-flags in-race))
        (cond
          ((logtest? (-> gp-0 flags) (racer-flags on-track))
           (set-time! (-> self player-on-track-time))
           )
          (else
            (when (time-elapsed? (-> self player-on-track-time) (seconds 1))
              (let ((v1-16 (handle->process (-> gp-0 racer))))
                (when v1-16
                  (when (logtest? (-> (the-as vehicle-racer v1-16) flags) (rigid-body-object-flag on-ground))
                    (if (send-event *target* 'attack-invinc #f (static-attack-info ((id (new-attack-id)) (mode 'instant-death))))
                        (go-virtual fail)
                        )
                    )
                  )
                )
              )
            )
          )
        )
      (if (or (logtest? (-> gp-0 flags) (racer-flags dead)) (not *target*) (focus-test? *target* dead))
          (go-virtual fail)
          )
      (when (logtest? (-> gp-0 flags) (racer-flags finished))
        (when (not (logtest? (-> gp-0 flags) (racer-flags saved-score)))
          (logior! (-> gp-0 flags) (racer-flags saved-score))
          (let ((f0-2 (* 0.0033333334 (the float (- (-> gp-0 finish-time) (-> s5-0 race-start-time))))))
            (save-score self f0-2)
            )
          )
        (send-event (ppointer->process (-> self parent)) 'allow-fail #f)
        (if (not (logtest? (-> self race-state info flags) (race-info-flags borrow)))
            (set-setting! 'sound-mode #f 0.0 2)
            )
        (set! (-> self message-id)
              (add-process *gui-control* self (gui-channel supertitle) (gui-action play) "fail" 81920.0 0)
              )
        (when #t
          (if (zero? (-> gp-0 finish-count))
              (go-virtual win)
              (go-virtual lose)
              )
          )
        )
      )
    )
  )

(defstate win (race-manager)
  :virtual #t
  :event race-manager-event-handler
  :code (behavior ()
    (if (zero? (-> self finish-sound-id))
        (set! (-> self finish-sound-id)
              (add-process *gui-control* *target* (gui-channel background) (gui-action play) "miss001" -99.0 0)
              )
        )
    (send-event (ppointer->process (-> self parent)) 'race-win)
    (send-event (handle->process (-> self race-state hud-timer)) 'force-hide)
    (send-event (handle->process (-> self race-state hud-lap-counter)) 'force-hide)
    (send-event (handle->process (-> self race-state hud-turbo-counter)) 'force-hide)
    (process-spawn hud-race-final-stats :init hud-init-by-other :to self)
    (set-time! (-> self state-time))
    (when (logtest? (-> self race-state info flags) (race-info-flags complete-immediately))
      (send-event (ppointer->process (-> self parent)) 'complete)
      (sleep-code)
      )
    ;; og:preserve-this auto-save when a race is won
    (#when PC_PORT
      (auto-save-user))
    (until #f
      (cond
        ((logtest? (-> self race-state info flags) (race-info-flags retryable))
         (draw-message-retry self)
         (when (time-elapsed? (-> self state-time) (seconds 0.5))
           (cond
             ((cpad-pressed? 0 confirm)
              (stop-speech self)
              (send-event (ppointer->process (-> self parent)) 'retry-immediately)
              (sleep-code)
              )
             ((cpad-pressed? 0 triangle)
              (stop-speech self)
              (send-event (ppointer->process (-> self parent)) 'fail-immediately)
              (sleep-code)
              )
             )
           )
         )
        (else
          (draw-message-continue self)
          (when (time-elapsed? (-> self state-time) (seconds 0.5))
            (when (cpad-pressed? 0 confirm)
              (stop-speech self)
              (send-event (ppointer->process (-> self parent)) 'complete)
              (sleep-code)
              )
            )
          )
        )
      (suspend)
      )
    #f
    )
  :post (behavior ()
    (update self)
    )
  )

(defstate lose (race-manager)
  :virtual #t
  :event race-manager-event-handler
  :code (behavior ()
    (if (zero? (-> self finish-sound-id))
        (set! (-> self finish-sound-id)
              (add-process *gui-control* *target* (gui-channel background) (gui-action play) "lose1" -99.0 0)
              )
        )
    (send-event (ppointer->process (-> self parent)) 'race-lose)
    (send-event (handle->process (-> self race-state hud-timer)) 'force-hide)
    (send-event (handle->process (-> self race-state hud-lap-counter)) 'force-hide)
    (send-event (handle->process (-> self race-state hud-turbo-counter)) 'force-hide)
    (process-spawn hud-race-final-stats :init hud-init-by-other :to self)
    (set-time! (-> self state-time))
    (until #f
      (draw-message-retry self)
      (-> self race-state info)
      (when (time-elapsed? (-> self state-time) (seconds 0.5))
        (cond
          ((cpad-pressed? 0 confirm)
           (stop-speech self)
           (send-event (ppointer->process (-> self parent)) 'retry-immediately)
           (sleep-code)
           )
          ((cpad-pressed? 0 triangle)
           (stop-speech self)
           (send-event (ppointer->process (-> self parent)) 'fail-immediately)
           (sleep-code)
           )
          )
        )
      (suspend)
      )
    #f
    )
  :post (behavior ()
    (update self)
    )
  )

(defstate fail (race-manager)
  :virtual #t
  :event race-manager-event-handler
  :code (behavior ()
    (send-event (handle->process (-> self race-state hud-timer)) 'force-hide)
    (send-event (handle->process (-> self race-state hud-lap-counter)) 'force-hide)
    (send-event (handle->process (-> self race-state hud-turbo-counter)) 'force-hide)
    (set-time! (-> self state-time))
    (until #f
      (suspend)
      )
    #f
    )
  )

(defstate die (race-manager)
  :virtual #t
  :code (behavior ()
    '()
    )
  )

(define *race-manager* (the-as (pointer race-manager) #f))

(defmethod deactivate ((this race-manager))
  "Make a process dead, clean it up, remove it from the active pool, and return to dead pool."
  (persist-with-delay *setting-control* 'music-volume (seconds 3) 'music-volume 'abs 0.0 0)
  (send-event *traffic-manager* 'restore-default-settings)
  (call-parent-method this)
  (none)
  )

;; WARN: Return type mismatch object vs none.
(defbehavior race-manager-init-by-other race-manager ((arg0 race-info) (arg1 symbol))
  ;; og:preserve-this changed from 512
  (stack-size-set! (-> self main-thread) 1024)
  (race-vehicle-entity-hack)
  (set! (-> self race-state) *race-state*)
  (set! (-> self race-state info) arg0)
  (set! (-> self race-state flags) (race-flags))
  (set! *race-manager* (the-as (pointer race-manager) (process->ppointer self)))
  (set! (-> arg0 manager) (process->handle self))
  (set! (-> self finish-sound-id) (new 'static 'sound-id))
  (if arg1
      (logior! (-> self race-state flags) (race-flags sleep))
      )
  (go-virtual idle)
  (none)
  )

;; ERROR: Unsupported inline assembly instruction kind - [mfc0 s5, Count]
;; ERROR: Unsupported inline assembly instruction kind - [mfc0 v1, Count]
(defun race-start ((arg0 int) (arg1 process) (arg2 symbol))
  (local-vars (v1-13 int) (s5-0 int))
  (let ((s2-0 (-> *race-info-array* arg0))
        (gp-0 (the-as process #f))
        )
    (.mfc0 s5-0 Count)
    (when (not (handle->process (-> s2-0 manager)))
      (format #t "starting race-manager~%")
      (if (not arg1)
          (set! arg1 (the-as process *entity-pool*))
          )
      (let ((v1-9 (process-spawn race-manager s2-0 arg2 :to (the-as process-tree arg1))))
        (when v1-9
          (set! gp-0 (-> v1-9 0))
          (.mfc0 v1-13 Count)
          (format #t "race-manager started in ~f ms~%" (* 0.0000033333333 (the float (- v1-13 s5-0))))
          )
        )
      )
    gp-0
    )
  )

;; WARN: Return type mismatch symbol vs none.
(defun race-kill ()
  (kill-by-type race-manager *active-pool*)
  (none)
  )

(defun type-from-race-vehicle-type ((arg0 uint))
  (let ((v1-0 arg0))
    (cond
      ((zero? v1-0)
       race-bike-a
       )
      ((= v1-0 1)
       race-bike-b
       )
      ((= v1-0 2)
       race-bike-c
       )
      ((= v1-0 3)
       race-bike-d
       )
      ((= v1-0 4)
       race-bike-e
       )
      (else
        bikea
        )
      )
    )
  )

(defun race-vehicle-entity-hack ()
  (with-pp
    (let ((a1-0 *race-vehicle-entity*)
          (a0-0 pp)
          )
      (process-entity-set! a0-0 a1-0)
      )
    0
    (none)
    )
  )

;; WARN: Return type mismatch entity vs none.
(defun race-level-activate ((arg0 level))
  (format 0 "race-level-activate~%")
  (cond
    ((> (-> arg0 entity length) 0)
     (set! *race-vehicle-entity* (the-as entity-actor (-> arg0 entity data 0 entity)))
     )
    (else
      (dotimes (s5-0 10)
        (format 0 "ERROR: race-level-startup: level ~s has no entities!!~%" (-> arg0 name))
        )
      (set! *race-vehicle-entity* #f)
      )
    )
  (none)
  )

;; WARN: Return type mismatch symbol vs none.
(defun race-level-deactivate ()
  (set! *race-vehicle-entity* #f)
  (none)
  )
