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

;; name: traffic-manager.gc
;; name in dgo: traffic-manager
;; dgos: CWI

;; DECOMP BEGINS

(define *traffic-engine* (the-as traffic-engine #f))

(define *traffic-fast-spawn* #f)

(deftype traffic-manager (process)
  ((traffic-engine    traffic-engine)
   (fast-spawn        symbol)
   (dark-guard-ratio  int32)
   (spawn-params      traffic-object-spawn-params  :inline)
   )
  (:state-methods
    idle
    active
    )
  (:methods
    (update (_type_) none)
    (spawn-all (_type_) none)
    (kill-excess-once (_type_) none)
    (kill-all-inactive (_type_) none)
    (reset-and-init (_type_) none)
    (init-params (_type_) none)
    )
  )


(defun draw-city-info ((arg0 city-level-info) (arg1 vis-grid-pos))
  "@unused - but would be cool to revive! TODO"
  (let ((v1-0 (-> arg0 grid-info box)))
    (add-debug-box #t (bucket-id debug2) (-> v1-0 min) (-> v1-0 max) *color-yellow*)
    )
  (debug-draw-grid (-> arg0 grid-info) *color-gray*)
  (debug-draw-cell (-> arg0 grid-info) arg1 *color-red*)
  (let* ((v1-8 (+ (-> arg1 x)
                  (* (-> arg1 z) (-> arg0 grid-info dimension-array 0))
                  (* (* (-> arg1 y) (-> arg0 grid-info dimension-array 0)) (-> arg0 grid-info dimension-array 2))
                  )
               )
         (v1-10 (-> arg0 cell-array v1-8))
         )
    (add-debug-sphere #t (bucket-id debug2) (-> v1-10 sphere) (-> v1-10 sphere r) *color-green*)
    )
  0
  (none)
  )

(defmethod update ((this traffic-manager))
  (update-traffic (-> this traffic-engine))
  (kill-excess-once this)
  (spawn-all this)
  (if *debug-segment*
      (debug-unused (-> this traffic-engine))
      )
  (if *display-traffic-height-map*
      (debug-draw *traffic-height-map* (target-pos 0))
      )
  (when *display-trail-graph*
    (let ((a0-7 *trail-graph*))
      (if a0-7
          (debug-draw a0-7)
          )
      )
    )
  0
  (none)
  )

(defmethod kill-excess-once ((this traffic-manager))
  (let ((type-i 0))
    (while (< (the-as uint type-i) (the-as uint 21))
      (let ((traffic (-> this traffic-engine object-type-info-array type-i)))
        (when (logtest? (-> traffic flags) (traffic-type-flags trtflags-1))
          (let ((total-count (+ (-> traffic active-count) (-> traffic inactive-count))))
            (when (< (-> traffic want-count) total-count)
              (let ((a0-10 (handle->process (get-from-inactive-by-type
                                              (-> this traffic-engine tracker-array (-> traffic tracker-index))
                                              (the-as traffic-type type-i)
                                              )
                                            )
                           )
                    )
                (if a0-10
                    (deactivate a0-10)
                    )
                )
              )
            )
          )
        )
      (+! type-i 1)
      )
    )
  0
  (none)
  )

(defmethod kill-all-inactive ((this traffic-manager))
  (let ((s5-0 0))
    (while (< (the-as uint s5-0) (the-as uint 21))
      (let ((s4-0 (-> this traffic-engine object-type-info-array s5-0)))
        (countdown (s3-0 (-> s4-0 inactive-count))
          (let ((a0-6 (handle->process (get-from-inactive-by-type
                                         (-> this traffic-engine tracker-array (-> s4-0 tracker-index))
                                         (the-as traffic-type s5-0)
                                         )
                                       )
                      )
                )
            (if a0-6
                (deactivate a0-6)
                )
            )
          )
        )
      (+! s5-0 1)
      )
    )
  0
  (none)
  )

(defmethod spawn-all ((this traffic-manager))

  ;; og:preserve-this rewritten to remove asm branches

  ;; (let ((s5-0 0))
  ;;   (b! #t cfg-4 :delay (nop!))
  ;;   (label cfg-1)
  ;;   (let ((s4-0 (-> this traffic-engine object-type-info-array s5-0)))
  ;;     (logclear! (-> s4-0 flags) (traffic-type-flags trtflags-3))
  ;;     (if (= (level-status *level* (-> s4-0 level)) 'active)
  ;;         (logior! (-> s4-0 flags) (traffic-type-flags trtflags-3))
  ;;         )
  ;;     )
  ;;   (+! s5-0 1)
  ;;   (label cfg-4)
  ;;   (b! (< s5-0 21) cfg-1)
  ;;   )
  (dotimes (i 21)
    (let ((s4-0 (-> this traffic-engine object-type-info-array i)))
      (logclear! (-> s4-0 flags) (traffic-type-flags trtflags-3))
      (if (= (level-status *level* (-> s4-0 level)) 'active)
          (logior! (-> s4-0 flags) (traffic-type-flags trtflags-3))
          )
      )
    )
  ;; (let ((max-to-spawn 1)
  ;;       (spawned-nb 0)
  ;;       (spawn-mask #x1fffff)
  ;;       )
  ;;   (if (-> this fast-spawn)
  ;;       (set! max-to-spawn 120)
  ;;       )
  ;;   (b! #t cfg-36 :delay (nop!))
  ;;   (label cfg-8)
  ;;   (let* ((spawn-params (-> this spawn-params))
  ;;          (spawn-type (-> spawn-params object-type))
  ;;          )
  ;;     (when (logtest? spawn-mask (ash 1 spawn-type))
  ;;       (let ((s0-0 (-> this traffic-engine object-type-info-array spawn-type)))
  ;;         (let ((v1-21 (+ (-> s0-0 active-count) (-> s0-0 inactive-count))))
  ;;           (b!
  ;;             (not (and (logtest? (-> s0-0 flags) (traffic-type-flags trtflags-1))
  ;;                       (logtest? (-> s0-0 flags) (traffic-type-flags trtflags-3))
  ;;                       (< v1-21 (-> s0-0 want-count))
  ;;                       )
  ;;                  )
  ;;             cfg-29
  ;;             :delay (nop!)
  ;;             )
  ;;           (set! (-> spawn-params flags) (logand -9 (-> spawn-params flags)))
  ;;           (b!
  ;;             (not (and (= (-> spawn-params object-type) (traffic-type crimson-guard-1))
  ;;                       (> (-> this dark-guard-ratio) 0)
  ;;                       (zero? (mod v1-21 (-> this dark-guard-ratio)))
  ;;                       )
  ;;                  )
  ;;             cfg-25
  ;;             :delay (empty-form)
  ;;             )
  ;;           )
  ;;         (logior! (-> spawn-params flags) 8)
  ;;         (label cfg-25)
  ;;         (let ((traffic-obj (traffic-object-spawn this spawn-params)))
  ;;           (b! (not traffic-obj) cfg-27 :delay (nop!))
  ;;           (add-object (-> this traffic-engine) spawn-type traffic-obj)
  ;;           )
  ;;         (+! (-> s0-0 reserve-count) -1)
  ;;         )
  ;;       (+! (-> spawn-params id) 1)
  ;;       (+! spawned-nb 1)
  ;;       (b! #t cfg-28 :delay (nop!))
  ;;       (label cfg-27)
  ;;       (format #t "traffic-manager: unable to spawn~%")
  ;;       (b! #t cfg-41 :delay (nop!))
  ;;       (label cfg-28)
  ;;       (b! #t cfg-33 :delay (nop!))
  ;;       (label cfg-29)
  ;;       (set! spawn-mask (logclear spawn-mask (ash 1 spawn-type)))
  ;;       )
  ;;     (label cfg-33)
  ;;     (let ((next-spawn-type (the-as int (+ spawn-type 1))))
  ;;       (if (>= (the-as uint next-spawn-type) (the-as uint 21))
  ;;           (set! next-spawn-type 0)
  ;;           )
  ;;       (set! (-> spawn-params object-type) (the-as traffic-type next-spawn-type))
  ;;       )
  ;;     )
  ;;   (label cfg-36)
  ;;   (b! (and (< spawned-nb max-to-spawn) (nonzero? spawn-mask)) cfg-8 :delay (nop!))
  ;;   )
  ;; (label cfg-41)
  ;; (set! (-> this fast-spawn) #f)
  (let ((max-to-spawn 1)
        (spawned-nb 0)
        (spawn-mask #x1fffff)
        )
    (if (-> this fast-spawn)
        (set! max-to-spawn 120)
        )
    (while (and (< spawned-nb max-to-spawn) (nonzero? spawn-mask))
      (let* ((spawn-params (-> this spawn-params))
            (spawn-type (-> spawn-params object-type))
            )
        (when (logtest? spawn-mask (ash 1 spawn-type))
          (let ((s0-0 (-> this traffic-engine object-type-info-array spawn-type)))
            (let ((v1-21 (+ (-> s0-0 active-count) (-> s0-0 inactive-count))))
              (cond
                ((and (logtest? (-> s0-0 flags) (traffic-type-flags trtflags-1))
                      (logtest? (-> s0-0 flags) (traffic-type-flags trtflags-3))
                      (< v1-21 (-> s0-0 want-count)))
                  (logclear! (-> spawn-params flags) (traffic-spawn-flags dark-guard))
                  (when (and (= (-> spawn-params object-type) (traffic-type crimson-guard-1))
                             (> (-> this dark-guard-ratio) 0)
                             (zero? (mod v1-21 (-> this dark-guard-ratio))))
                    (logior! (-> spawn-params flags) (traffic-spawn-flags dark-guard)))
                  (let ((traffic-obj (traffic-object-spawn this spawn-params)))
                    (cond
                      (traffic-obj
                        (add-object (-> this traffic-engine) spawn-type traffic-obj)
                        (+! (-> s0-0 reserve-count) -1)
                        (+! (-> spawn-params id) 1)
                        (+! spawned-nb 1)
                        )
                      (else
                        (format #t "traffic-manager: unable to spawn~%")
                        (goto cfg-41)))
                    )
                  )
                (else
                  (set! spawn-mask (logclear spawn-mask (ash 1 spawn-type))))
                )
              )
            )
          )
        (let ((next-spawn-type (the-as int (+ spawn-type 1))))
          (if (>= (the-as uint next-spawn-type) (the-as uint 21))
              (set! next-spawn-type 0)
              )
          (set! (-> spawn-params object-type) (the-as traffic-type next-spawn-type))
          )
        )
      )
    )
  (label cfg-41)
  (set! (-> this fast-spawn) #f)
  0
  0
  (none)
  )

;; WARN: Return type mismatch process vs process-drawable.
(defun vehicle-spawn ((arg0 process) (arg1 type) (arg2 traffic-object-spawn-params))
  (let ((gp-0 (the-as process #f)))
    (let* ((s3-0 (get-process *default-dead-pool* arg1 #x4000))
           (v1-1 (when s3-0
                   (let ((t9-1 (method-of-type process activate)))
                     (t9-1 s3-0 arg0 (symbol->string (-> arg1 symbol)) (the-as pointer #x70004000))
                     )
                   (run-now-in-process s3-0 vehicle-init-by-other arg2)
                   (-> s3-0 ppointer)
                   )
                 )
           )
      (if v1-1
          (set! gp-0 (-> v1-1 0))
          )
      )
    (if (and gp-0 (logtest? (-> arg2 flags) (traffic-spawn-flags trsflags-01)))
        (vehicle-method-137 (the-as vehicle gp-0) arg2)
        )
    (the-as process-drawable gp-0)
    )
  )

;; WARN: Return type mismatch process vs process-drawable.
(defun citizen-spawn ((arg0 process) (arg1 type) (arg2 traffic-object-spawn-params))
  (let ((gp-0 (the-as process #f)))
    (let* ((s3-0 (get-process *default-dead-pool* arg1 #x4000))
           (v1-1 (when s3-0
                   (let ((t9-1 (method-of-type process activate)))
                     (t9-1 s3-0 arg0 (symbol->string (-> arg1 symbol)) (the-as pointer #x70004000))
                     )
                   (run-now-in-process s3-0 citizen-init-by-other arg2)
                   (-> s3-0 ppointer)
                   )
                 )
           )
      (if v1-1
          (set! gp-0 (-> v1-1 0))
          )
      )
    (the-as process-drawable gp-0)
    )
  )

(defun traffic-object-spawn ((arg0 process) (arg1 traffic-object-spawn-params))
  (let ((v0-0 (the-as process-drawable #f)))
    (case (-> arg1 object-type)
      (((traffic-type bikea))
       (set! v0-0 (vehicle-spawn arg0 bikea arg1))
       )
      (((traffic-type bikeb))
       (set! v0-0 (vehicle-spawn arg0 bikeb arg1))
       )
      (((traffic-type bikec))
       (set! v0-0 (vehicle-spawn arg0 bikec arg1))
       )
      (((traffic-type cara))
       (set! v0-0 (vehicle-spawn arg0 cara arg1))
       )
      (((traffic-type carb))
       (set! v0-0 (vehicle-spawn arg0 carb arg1))
       )
      (((traffic-type carc))
       (set! v0-0 (vehicle-spawn arg0 carc arg1))
       )
      (((traffic-type guard-bike))
       (set! v0-0 (vehicle-spawn arg0 guard-bike arg1))
       )
      (((traffic-type hellcat))
       (set! v0-0 (vehicle-spawn arg0 hellcat arg1))
       )
      (((traffic-type citizen-norm-1))
       (set! v0-0 (citizen-spawn arg0 citizen-norm arg1))
       )
      (((traffic-type citizen-chick))
       (set! v0-0 (citizen-spawn arg0 citizen-chick arg1))
       )
      (((traffic-type citizen-fat))
       (set! v0-0 (citizen-spawn arg0 citizen-fat arg1))
       )
      (((traffic-type citizen-norm-2))
       (set! v0-0 (citizen-spawn arg0 citizen-norm arg1))
       )
      (((traffic-type metalhead-predator))
       (set! v0-0 (citizen-spawn arg0 metalhead-predator arg1))
       )
      (((traffic-type metalhead-grunt))
       (set! v0-0 (citizen-spawn arg0 metalhead-grunt arg1))
       )
      (((traffic-type metalhead-flitter))
       (set! v0-0 (citizen-spawn arg0 metalhead-flitter arg1))
       )
      (((traffic-type crimson-guard-1))
       (set! v0-0 (citizen-spawn arg0 crimson-guard arg1))
       )
      (((traffic-type crimson-guard-0))
       (set! v0-0 (citizen-spawn arg0 crimson-guard arg1))
       )
      )
    v0-0
    )
  )

(defun type-from-vehicle-type ((arg0 vehicle-type))
  (case arg0
    (((vehicle-type bikea))
     bikea
     )
    (((vehicle-type bikeb))
     bikeb
     )
    (((vehicle-type bikec))
     bikec
     )
    (((vehicle-type cara))
     cara
     )
    (((vehicle-type carb))
     carb
     )
    (((vehicle-type carc))
     carc
     )
    (((vehicle-type guard-bike))
     guard-bike
     )
    (((vehicle-type hellcat))
     hellcat
     )
    (((vehicle-type evan-test-bike))
     evan-test-bike
     )
    (((vehicle-type test-bike))
     test-bike
     )
    (((vehicle-type test-car))
     test-car
     )
    (else
      bikea
      )
    )
  )

(defmethod reset-and-init ((this traffic-manager))
  (set! (-> this traffic-engine) *traffic-engine*)
  (reset-and-init-from-manager (-> this traffic-engine) this)
  (restore-city-speeches)
  0
  (none)
  )

;; WARN: Return type mismatch process vs traffic-manager.
(defmethod relocate ((this traffic-manager) (arg0 int))
  (set! *traffic-manager* this)
  (if *traffic-manager*
      (set! *traffic-manager* (&+ *traffic-manager* arg0))
      )
  (the-as traffic-manager ((method-of-type process relocate) this arg0))
  )

(defmethod deactivate ((this traffic-manager))
  (stop-alarm-sound (-> this traffic-engine))
  (set! *traffic-manager* #f)
  (remove-setting *setting-control* this 'task-mask)
  (apply-settings *setting-control*)
  (speech-control-method-9 *speech-control*)
  ((method-of-type process deactivate) this)
  (none)
  )

(defmethod init-params ((this traffic-manager))
  (let ((traffic-want-counts (new 'stack-no-clear 'array 'int8 21)))
    (set! (-> traffic-want-counts 11) 8)
    (set! (-> traffic-want-counts 12) 8)
    (set! (-> traffic-want-counts 13) 8)
    (set! (-> traffic-want-counts 14) 7)
    (set! (-> traffic-want-counts 15) 7)
    (set! (-> traffic-want-counts 16) 7)
    (set! (-> traffic-want-counts 18) 4)
    (set! (-> traffic-want-counts 19) 3)
    (set! (-> traffic-want-counts 20) 0)
    (set! (-> traffic-want-counts 0) 15)
    (set! (-> traffic-want-counts 1) 15)
    (set! (-> traffic-want-counts 2) 14)
    (set! (-> traffic-want-counts 3) 1)
    (set! (-> traffic-want-counts 4) 1)
    (set! (-> traffic-want-counts 6) 9)
    (set! (-> traffic-want-counts 7) 0)
    (set! (-> traffic-want-counts 8) 14)
    (set! (-> traffic-want-counts 9) 14)
    (set! (-> traffic-want-counts 10) 14)
    (set! (-> this fast-spawn) *traffic-fast-spawn*)
    (reset-and-init this)
    (let ((v1-20 (-> this traffic-engine)))
      (dotimes (a0-2 21)
        (set! (-> v1-20 object-type-info-array a0-2 want-count) (-> traffic-want-counts a0-2))
        )
      )
    )
  (let ((params (-> this spawn-params)))
    (set! (-> params object-type) (traffic-type crimson-guard-1))
    (set! (-> params behavior) (the-as uint 1))
    (set! (-> params id) (the-as uint 0))
    (set! (-> params nav-mesh) #f)
    (set! (-> params nav-branch) #f)
    (set! (-> params proc) #f)
    (set! (-> params handle) (the-as handle #f))
    (set! (-> params user-data) (the-as uint 0))
    (set! (-> params flags) (traffic-spawn-flags trsflags-01))
    (set! (-> params guard-type) (the-as uint 7))
    (vector-reset! (-> params velocity))
    (vector-reset! (-> params position))
    (forward-up-nopitch->quaternion
      (-> params rotation)
      (new 'static 'vector :z 1.0 :w 1.0)
      (new 'static 'vector :y 1.0 :w 1.0)
      )
    (set! (-> params id) (the-as uint 1))
    )
  (set! (-> this dark-guard-ratio) (if (task-node-closed? (game-task-node tomb-boss-resolution))
                                       5
                                       0
                                       )
        )
  (restore-default-settings (-> this traffic-engine))
  (set! *traffic-manager* this)
  0
  (none)
  )

(defbehavior traffic-manager-event-handler traffic-manager ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  (let ((gp-0 (the-as object #t)))
    (case arg2
      (('child-killed)
       (child-killed (-> self traffic-engine) arg0)
       )
      (('increase-alert-level)
       (when *target*
         (let ((a1-4 (-> arg3 param 0)))
           (increase-alert-level (-> self traffic-engine) (the-as int a1-4) *target*)
           )
         )
       )
      (('decrease-alert-level)
       (let ((a1-5 (-> arg3 param 0)))
         (decrease-alert-level (-> self traffic-engine) (the-as int a1-5))
         )
       )
      (('set-alert-level)
       (let ((a1-6 (-> arg3 param 0)))
         (set-alert-level (-> self traffic-engine) (the-as int a1-6))
         )
       )
      (('set-max-alert-level)
       (let ((a1-7 (-> arg3 param 0)))
         (set-max-alert-level (-> self traffic-engine) (the-as int a1-7))
         )
       )
      (('get-alert-level)
       (set! gp-0 (get-alert-level (-> self traffic-engine)))
       )
      (('set-alert-duration)
       (let ((a1-8 (-> arg3 param 0)))
         (set-alert-duration (-> self traffic-engine) (the-as time-frame a1-8))
         )
       )
      (('deactivate-all)
       (deactivate-all (-> self traffic-engine))
       )
      (('set-target-level)
       (let ((f0-0 (the-as float (-> arg3 param 0))))
         (set-target-level (-> self traffic-engine) f0-0)
         )
       )
      (('set-guard-target-level)
       (let ((f0-1 (the-as float (-> arg3 param 0))))
         (set-guard-target-level (-> self traffic-engine) f0-1)
         )
       )
      (('restore-default-settings)
       (restore-default-settings (-> self traffic-engine))
       )
      (('add-danger-sphere)
       (let ((a1-11 (-> arg3 param 0)))
         (add-danger (-> self traffic-engine) (the-as traffic-danger-info a1-11))
         )
       )
      (('spawn-object)
       (let ((s5-0 (the-as traffic-object-spawn-params (-> arg3 param 0))))
         (set! (-> s5-0 proc) (traffic-object-spawn self s5-0))
         )
       )
      (('activate-object)
       (let ((a1-13 (-> arg3 param 0)))
         (activate-object (-> self traffic-engine) (the-as traffic-object-spawn-params a1-13))
         )
       )
      (('get-object-remaining-count)
       (let ((a1-14 (-> arg3 param 0)))
         (set! gp-0 (get-object-remaining-count (-> self traffic-engine) (the-as int a1-14)))
         )
       )
      (('set-object-reserve-count)
       (let ((a1-15 (-> arg3 param 0))
             (a2-2 (-> arg3 param 1))
             )
         (set-object-reserve-count (-> self traffic-engine) (the-as int a1-15) a2-2)
         )
       )
      (('get-object-reserve-count)
       (let ((a1-16 (-> arg3 param 0)))
         (set! gp-0 (get-object-reserve-count (-> self traffic-engine) (the-as int a1-16)))
         )
       )
      (('set-object-target-level)
       (let ((a1-17 (-> arg3 param 0))
             (f0-2 (the-as float (-> arg3 param 1)))
             )
         (set-object-target-level (-> self traffic-engine) (the-as int a1-17) f0-2)
         )
       )
      (('set-object-target-count)
       (let ((a1-18 (-> arg3 param 0))
             (a2-4 (-> arg3 param 1))
             )
         (set-object-target-count (-> self traffic-engine) (the-as int a1-18) (the-as int a2-4))
         )
       )
      (('set-guard-target-count-range)
       (let ((a1-19 (-> arg3 param 0))
             (a2-5 (-> arg3 param 1))
             (a3-1 (-> arg3 param 2))
             )
         (set-guard-target-count-range (-> self traffic-engine) (the-as int a1-19) (the-as int a2-5) (the-as int a3-1))
         )
       )
      (('deactivate-by-type)
       (let ((a1-20 (-> arg3 param 0)))
         (deactivate-by-type (-> self traffic-engine) (the-as traffic-type a1-20))
         )
       )
      (('new-suppression-box)
       (let ((a1-21 (-> arg3 param 0)))
         (new-suppression-box (-> self traffic-engine) (the-as traffic-suppression-params a1-21))
         )
       )
      (('update-suppression-box)
       (let ((a1-22 (-> arg3 param 0)))
         (update-suppression-box (-> self traffic-engine) (the-as traffic-suppression-params a1-22))
         )
       )
      (('kill-traffic-sphere)
       (let ((a1-23 (-> arg3 param 0)))
         (kill-traffic-sphere (-> self traffic-engine) (the-as sphere a1-23))
         )
       )
      (('set-guard-multi-focus)
       (let ((a0-74 (-> arg3 param 0))
             (v1-29 (-> self traffic-engine alert-state))
             )
         (if a0-74
             (logior! (-> v1-29 flags) (traffic-alert-flag guard-multi-focus))
             (logclear! (-> v1-29 flags) (traffic-alert-flag guard-multi-focus))
             )
         )
       )
      (('set-disable-pursuit-control)
       (let ((a0-80 (-> arg3 param 0))
             (v1-31 (-> self traffic-engine alert-state))
             )
         (if a0-80
             (logior! (-> v1-31 flags) (traffic-alert-flag disable-pursuit-control))
             (logclear! (-> v1-31 flags) (traffic-alert-flag disable-pursuit-control))
             )
         )
       )
      (('set-object-auto-activate)
       (let ((a1-26 (-> arg3 param 0))
             (a2-6 (-> arg3 param 1))
             )
         (set-object-auto-activate (-> self traffic-engine) (the-as int a1-26) a2-6)
         )
       )
      (('set-guard-force-visible)
       (let ((a0-89 (-> arg3 param 0))
             (v1-34 (-> self traffic-engine alert-state target-status-array))
             )
         (if a0-89
             (logior! (-> v1-34 0 flags) (traffic-target-flag force-visible))
             (logclear! (-> v1-34 0 flags) (traffic-target-flag force-visible))
             )
         )
       )
      (('end-pursuit-by-type)
       (let ((a1-28 (-> arg3 param 0)))
         (end-pursuit-by-type (-> self traffic-engine) (the-as traffic-type a1-28))
         )
       )
      (('level-loaded)
       (let ((a1-29 (-> arg3 param 0)))
         (level-link (-> self traffic-engine) (the-as level a1-29))
         )
       )
      (('level-killed)
       (let ((s5-1 (the-as object (-> arg3 param 0))))
         (level-unlink (-> self traffic-engine) (the-as level s5-1))
         (format #t "traffic-manager : level killed ~S~%" (-> (the-as level s5-1) nickname))
         )
       )
      (('add-object)
       (let ((a1-32 (-> arg3 param 0))
             (a2-8 (-> arg3 param 1))
             )
         (add-object (-> self traffic-engine) (the-as traffic-type a1-32) (the-as process a2-8))
         )
       )
      (('kill-all)
       (format #t "traffic-manager::kill-all~%")
       (deactivate-all (-> self traffic-engine))
       (kill-all-inactive self)
       )
      (('spawn-all)
       (format #t "traffic-manager::spawn-all~%")
       (set! (-> self fast-spawn) #t)
       (spawn-all self)
       )
      (('set-density-factor)
       (let ((f0-3 (the-as float (-> arg3 param 0))))
         (set! (-> self traffic-engine inv-density-factor) (/ 5.0 f0-3))
         )
       )
      (('rider-off)
       (let ((s5-2 (-> self child)))
         (while s5-2
           (send-event (ppointer->process s5-2) 'rider-off)
           (set! s5-2 (-> s5-2 0 brother))
           )
         )
       )
      (('rider-on)
       (let ((s5-3 (-> self child)))
         (while s5-3
           (send-event (ppointer->process s5-3) 'rider-on)
           (set! s5-3 (-> s5-3 0 brother))
           )
         )
       )
      (else
        (set! gp-0 #f)
        )
      )
    gp-0
    )
  )

;; WARN: Return type mismatch object vs none.
(defbehavior traffic-manager-init-by-other traffic-manager ()
  (stack-size-set! (-> self main-thread) 128)
  (ctywide-entity-hack)
  (init-params self)
  (add-setting! 'task-mask 'clear 0.0 (task-mask ctywide))
  (set! (-> self event-hook) traffic-manager-event-handler)
  (rigid-body-queue-manager-spawn *traffic-rigid-body-queue* self)
  (go-virtual idle)
  (none)
  )

(defun traffic-start ()
  (kill-by-type traffic-manager *active-pool*)
  (process-spawn traffic-manager :from *city-dead-pool* :to *entity-pool*)
  0
  (none)
  )

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

(defstate idle (traffic-manager)
  :virtual #t
  :event traffic-manager-event-handler
  :enter (behavior ()
    (spawn-all self)
    )
  :code (behavior ()
    (suspend)
    (suspend)
    (go-virtual active)
    )
  )

(defstate active (traffic-manager)
  :virtual #t
  :event traffic-manager-event-handler
  :code sleep-code
  :post (behavior ()
    (update self)
    )
  )

;; WARN: Return type mismatch object vs none.
(defun riders-on ()
  (send-event *traffic-manager* 'rider-on)
  (none)
  )

;; WARN: Return type mismatch object vs none.
(defun riders-off ()
  (send-event *traffic-manager* 'rider-off)
  (none)
  )

(defun ctywide-login ()
  (format 0 "citywide-login~%")
  (set! *traffic-engine* (new 'loading-level 'traffic-engine))
  (init *city-dead-pool* 'loading-level #x8000)
  0
  (none)
  )

(defun ctywide-activate ((arg0 level) (arg1 symbol))
  (when (zero? (-> arg0 entity length))
    (format 0 "ERROR: ctywide-activate: level ~s has no entities!!" (-> arg0 name))
    (break!)
    0
    )
  (set! *ctywide-entity* (-> arg0 entity data 0 entity))
  (set! *traffic-fast-spawn* (or (= arg1 'life) (= arg1 'debug)))
  (if (and (= arg1 'debug) (not *spawn-actors*))
      (traffic-kill)
      (traffic-start)
      )
  0
  (none)
  )

(define *traffic-alert-level-force* #f)

(defun lwide-activate ((arg0 level) (arg1 symbol))
  (format #t "lwide-activate~%")
  (set! *lwide-entity* (-> arg0 entity data 0 entity))
  (let ((gp-0 *traffic-engine*))
    (when gp-0
      (case (-> arg0 name)
        (('lwidea)
         (set! (-> gp-0 object-type-info-array 0 level) 'lwidea)
         (set! (-> gp-0 object-type-info-array 1 level) 'lwidea)
         (set! (-> gp-0 object-type-info-array 2 level) 'lwidea)
         (set! (-> gp-0 object-type-info-array 3 level) 'lwidea)
         (set! (-> gp-0 object-type-info-array 4 level) 'lwidea)
         (set! (-> gp-0 object-type-info-array 5 level) #f)
         (set! (-> gp-0 object-type-info-array 6 level) 'lwidea)
         (set! (-> gp-0 object-type-info-array 7 level) #f)
         (set! (-> gp-0 object-type-info-array 8 level) #f)
         (set! (-> gp-0 object-type-info-array 9 level) #f)
         (set! (-> gp-0 object-type-info-array 10 level) #f)
         (set! (-> gp-0 object-type-info-array 11 level) 'lwidea)
         (set! (-> gp-0 object-type-info-array 12 level) 'lwidea)
         (set! (-> gp-0 object-type-info-array 13 level) 'lwidea)
         (set! (-> gp-0 object-type-info-array 14 level) 'lwidea)
         (set! (-> gp-0 object-type-info-array 15 level) 'lwidea)
         (set! (-> gp-0 object-type-info-array 16 level) 'lwidea)
         (set! (-> gp-0 object-type-info-array 17 level) #f)
         (set! (-> gp-0 object-type-info-array 18 level) 'lwidea)
         (set! (-> gp-0 object-type-info-array 19 level) 'lwidea)
         (logior! (-> gp-0 alert-state flags) (traffic-alert-flag target-jak))
         (set! *traffic-alert-level-force* #f)
         )
        (('lwideb)
         (set! (-> gp-0 object-type-info-array 0 level) 'lwideb)
         (set! (-> gp-0 object-type-info-array 1 level) #f)
         (set! (-> gp-0 object-type-info-array 2 level) #f)
         (set! (-> gp-0 object-type-info-array 3 level) 'lwideb)
         (set! (-> gp-0 object-type-info-array 4 level) 'lwideb)
         (set! (-> gp-0 object-type-info-array 5 level) #f)
         (set! (-> gp-0 object-type-info-array 6 level) 'lwideb)
         (set! (-> gp-0 object-type-info-array 7 level) #f)
         (set! (-> gp-0 object-type-info-array 8 level) 'lwideb)
         (set! (-> gp-0 object-type-info-array 9 level) 'lwideb)
         (set! (-> gp-0 object-type-info-array 10 level) 'lwideb)
         (set! (-> gp-0 object-type-info-array 11 level) 'lwideb)
         (set! (-> gp-0 object-type-info-array 12 level) #f)
         (set! (-> gp-0 object-type-info-array 13 level) #f)
         (set! (-> gp-0 object-type-info-array 14 level) 'lwideb)
         (set! (-> gp-0 object-type-info-array 15 level) #f)
         (set! (-> gp-0 object-type-info-array 16 level) #f)
         (set! (-> gp-0 object-type-info-array 17 level) #f)
         (set! (-> gp-0 object-type-info-array 18 level) 'lwideb)
         (set! (-> gp-0 object-type-info-array 19 level) #f)
         (logclear! (-> gp-0 alert-state flags) (traffic-alert-flag target-jak))
         (set-alert-level gp-0 3)
         (logior! (-> gp-0 alert-state flags) (traffic-alert-flag guard-multi-focus))
         (set-alert-duration gp-0 (seconds 6048000))
         (set! *traffic-alert-level-force* #t)
         )
        )
      )
    )
  0
  (none)
  )

(defun lwide-deactivate ()
  (set! *lwide-entity* #f)
  (send-event *traffic-manager* 'kill-all)
  0
  (none)
  )

(defun ctywide-deactivate ()
  (set! *ctywide-entity* #f)
  (set! *traffic-engine* #f)
  (set! *trail-graph* #f)
  (init *city-dead-pool* 'loading-level 0)
  0
  (none)
  )

;; og:preserve-this required to suppress rogue entity errors
(defun lwide-kill ()
  (format #t "lwide-kill~%")
  (send-event *traffic-manager* 'kill-all)
  (none)
  )

(defun ctywide-entity-hack ()
  (with-pp
    (cond
      ((and (-> pp entity) (= pp (-> pp entity extra process)))
       (let ((v1-6 (level-get *level* 'ctywide)))
         (if v1-6
             (set! (-> pp level) v1-6)
             )
         )
       )
      (else
        (process-entity-set! pp *ctywide-entity*)
        )
      )
    0
    (none)
    )
  )

(defun lwide-entity-hack ()
  (with-pp
    (process-entity-set! pp *lwide-entity*)
    0
    (none)
    )
  )
