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

(import "goal_src/jak1/import/farthy-snack-ag.gc")
(import "goal_src/jak1/import/billy-ag.gc")
(import "goal_src/jak1/import/billy-sidekick-ag.gc")

;; definition of type billy
(deftype billy (process-taskable)
  ((child-override    (pointer billy-snack)   :offset         20)
   (farthy            handle                  :offset-assert 384)
   (path-data         path-control          3 :offset-assert 392)
   (path-snacks       path-control            :offset        392)
   (path-starts       path-control            :offset        396)
   (path-waypts       path-control            :offset        400)
   (passed-last-stage symbol                  :offset-assert 404)
   (spawn-rats        symbol                  :offset-assert 408)
   (current-wave      int32                   :offset-assert 412)
   (wave-start-time   time-frame              :offset-assert 416)
   (num-snacks        int32                   :offset-assert 424)
   (num-rats          int32                   :offset-assert 428)
   (max-rats          int32                   :offset-assert 432)
   (rat-speed         float                   :offset-assert 436)
   (offending-rat     handle                  :offset-assert 440)
   )
  :heap-base #x150
  :method-count-assert 53
  :size-assert         #x1c0
  :flag-assert         #x35015001c0
  (:states
    billy-done
    billy-playing
    )
  )

;; definition for method 3 of type billy
(defmethod inspect billy ((obj billy))
  (let ((t9-0 (method-of-type process-taskable inspect)))
    (t9-0 obj)
    )
  (format #t "~T~Tfarthy: ~D~%" (-> obj farthy))
  (format #t "~T~Tpath-data[3] @ #x~X~%" (-> obj path-data))
  (format #t "~T~Tpath-snacks: ~A~%" (-> obj path-snacks))
  (format #t "~T~Tpath-starts: ~A~%" (-> obj path-starts))
  (format #t "~T~Tpath-waypts: ~A~%" (-> obj path-waypts))
  (format #t "~T~Tpassed-last-stage: ~A~%" (-> obj passed-last-stage))
  (format #t "~T~Tspawn-rats: ~A~%" (-> obj spawn-rats))
  (format #t "~T~Tcurrent-wave: ~D~%" (-> obj current-wave))
  (format #t "~T~Twave-start-time: ~D~%" (-> obj wave-start-time))
  (format #t "~T~Tnum-snacks: ~D~%" (-> obj num-snacks))
  (format #t "~T~Tnum-rats: ~D~%" (-> obj num-rats))
  (format #t "~T~Tmax-rats: ~D~%" (-> obj max-rats))
  (format #t "~T~Trat-speed: ~f~%" (-> obj rat-speed))
  (format #t "~T~Toffending-rat: ~D~%" (-> obj offending-rat))
  obj
  )

;; definition for method 7 of type billy
;; INFO: Return type mismatch process-drawable vs billy.
(defmethod relocate billy ((obj billy) (arg0 int))
  (countdown (v1-0 3)
    (if (nonzero? (-> obj path-data v1-0))
        (&+! (-> obj path-data v1-0) arg0)
        )
    )
  (the-as
    billy
    ((the-as (function process-drawable int process-drawable) (find-parent-method billy 7)) obj arg0)
    )
  )

;; definition of type billy-snack
(deftype billy-snack (process-drawable)
  ((num-rats int32  :offset-assert 176)
   )
  :heap-base #x50
  :method-count-assert 20
  :size-assert         #xb4
  :flag-assert         #x14005000b4
  (:states
    billy-snack-eat
    billy-snack-idle
    )
  )

;; definition for method 3 of type billy-snack
(defmethod inspect billy-snack ((obj billy-snack))
  (let ((t9-0 (method-of-type process-drawable inspect)))
    (t9-0 obj)
    )
  (format #t "~T~Tnum-rats: ~D~%" (-> obj num-rats))
  obj
  )

;; failed to figure out what this is:
(defskelgroup *farthy-snack-sg* farthy-snack farthy-snack-lod0-jg farthy-snack-idle-ja
              ((farthy-snack-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 4)
              )

;; failed to figure out what this is:
(defstate billy-snack-eat (billy-snack)
  :code (behavior ()
    (ja :group! farthy-snack-eat-ja)
    (ja-no-eval :group! (ja-group) :num! (seek!) :frame-num 0.0)
    (until (ja-done? 0)
      (suspend)
      (ja :num! (seek!))
      )
    (deactivate self)
    (loop
      (suspend)
      )
    (none)
    )
  :post (the-as (function none :behavior billy-snack) ja-post)
  )

;; failed to figure out what this is:
(defstate billy-snack-idle (billy-snack)
  :event (behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
    (case arg2
      (('eat)
       (go billy-snack-eat)
       )
      )
    )
  :code (behavior ()
    (loop
      (ja-no-eval :group! (ja-group) :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!))
        )
      )
    (none)
    )
  :post (the-as (function none :behavior billy-snack) ja-post)
  )

;; definition for function billy-snack-init-by-other
;; INFO: Used lq/sq
;; INFO: Return type mismatch object vs none.
(defbehavior billy-snack-init-by-other billy-snack ((arg0 vector))
  (set! (-> self root) (new 'process 'trsqv))
  (set! (-> self root trans quad) (-> arg0 quad))
  (initialize-skeleton self *farthy-snack-sg* '())
  (set! (-> self num-rats) 0)
  (go billy-snack-idle)
  (none)
  )

;; definition of type billy-rat
(deftype billy-rat (swamp-rat)
  ((dest-type   uint64                  :offset-assert 496)
   (snack       handle                  :offset-assert 504)
   (destination vector          :inline :offset-assert 512)
   (billy       (pointer billy)         :offset-assert 528)
   )
  :heap-base #x1b0
  :method-count-assert 76
  :size-assert         #x214
  :flag-assert         #x4c01b00214
  (:states
    billy-rat-eat
    billy-rat-salivate
    )
  )

;; definition for method 3 of type billy-rat
(defmethod inspect billy-rat ((obj billy-rat))
  (let ((t9-0 (method-of-type swamp-rat inspect)))
    (t9-0 obj)
    )
  (format #t "~T~Tdest-type: ~D~%" (-> obj dest-type))
  (format #t "~T~Tsnack: ~D~%" (-> obj snack))
  (format #t "~T~Tdestination: #<vector @ #x~X>~%" (-> obj destination))
  (format #t "~T~Tbilly: #x~X~%" (-> obj billy))
  obj
  )

;; definition for function rat-about-to-eat?
;; INFO: Return type mismatch basic vs symbol.
(defun rat-about-to-eat? ((arg0 billy-rat) (arg1 billy))
  (the-as symbol (and (= (-> arg0 dest-type) 2) (> (-> arg1 num-snacks) 0) (handle->process (-> arg0 snack))))
  )

;; failed to figure out what this is:
(defstate nav-enemy-idle (billy-rat)
  :virtual #t
  :enter (behavior ()
    (go-virtual nav-enemy-chase)
    (none)
    )
  :post (the-as (function none :behavior billy-rat) nav-enemy-common-post)
  )

;; failed to figure out what this is:
(defstate nav-enemy-die (billy-rat)
  :virtual #t
  :code (behavior ()
    (nav-enemy-fall-and-play-death-anim
      (the-as art-joint-anim (-> self draw art-group data (-> self nav-info die-anim)))
      1.0
      1.0
      1000000000000000.0
      600
      )
    (send-event (ppointer->process (-> self billy)) 'billy-rat-die)
    (cleanup-for-death self)
    (none)
    )
  )

;; failed to figure out what this is:
(defstate billy-rat-eat (billy-rat)
  :trans (behavior ()
    (seek-to-point-toward-point! (-> self collide-info) (-> self destination) 131072.0 (seconds 0.01))
    (none)
    )
  :code (behavior ()
    (send-event (handle->process (-> self snack)) 'eat)
    (sound-play "rat-gulp")
    (ja-channel-push! 1 (seconds 0.05))
    (ja :group! (-> self draw art-group data 12))
    (ja-no-eval :group! (ja-group) :num! (seek!) :frame-num 0.0)
    (until (ja-done? 0)
      (suspend)
      (ja :num! (seek!))
      )
    (send-event (ppointer->process (-> self billy)) 'billy-rat-needs-destination)
    (logclear! (-> self nav flags) (nav-control-flags navcf19))
    (go-virtual nav-enemy-chase)
    (none)
    )
  :post (the-as (function none :behavior billy-rat) nav-enemy-simple-post)
  )

;; failed to figure out what this is:
(defstate billy-rat-salivate (billy-rat)
  :event (the-as
    (function process int symbol event-message-block object :behavior billy-rat)
    nav-enemy-default-event-handler
    )
  :code (behavior ()
    (ja-channel-push! 1 (seconds 0.075))
    (dotimes (gp-0 1)
      (sound-play "rat-eat")
      (let ((f30-0 (nav-enemy-rnd-float-range 0.8 1.2)))
        (ja-no-eval :group! (-> self draw art-group data (-> self nav-info victory-anim))
                    :num! (seek! max f30-0)
                    :frame-num 0.0
                    )
        (until (ja-done? 0)
          (suspend)
          (ja :num! (seek! max f30-0))
          )
        )
      )
    (send-event (ppointer->process (-> self billy)) 'billy-rat-needs-destination)
    (if (= (-> self dest-type) 3)
        (go billy-rat-eat)
        (go-virtual nav-enemy-chase)
        )
    (none)
    )
  :post (the-as (function none :behavior billy-rat) nav-enemy-simple-post)
  )

;; failed to figure out what this is:
(defstate nav-enemy-victory (billy-rat)
  :virtual #t
  :enter (behavior ()
    (let ((t9-1 (-> (the-as (state nav-enemy) (find-parent-method billy-rat 33)) enter)))
      (if t9-1
          (t9-1)
          )
      )
    (when (logtest? (nav-control-flags navcf19) (-> self nav flags))
      (logclear! (-> self nav flags) (nav-control-flags navcf19))
      (if (rat-about-to-eat? self (-> self billy 0))
          (go billy-rat-salivate)
          (send-event (ppointer->process (-> self billy)) 'billy-rat-needs-destination)
          )
      )
    (none)
    )
  )

;; failed to figure out what this is:
(defstate nav-enemy-stare (billy-rat)
  :virtual #t
  :enter (behavior ()
    (go-virtual nav-enemy-chase)
    (none)
    )
  )

;; failed to figure out what this is:
(defstate nav-enemy-chase (billy-rat)
  :virtual #t
  :trans (behavior ()
    (set! (-> self speed-scale) (-> self billy 0 rat-speed))
    (if (or (logtest? (nav-control-flags navcf19) (-> self nav flags))
            (>= (- (-> *display* base-frame-counter) (-> self state-time)) (-> self chase-rest-time))
            )
        (go-virtual nav-enemy-victory)
        )
    (none)
    )
  :post (behavior ()
    (swamp-rat-update-wiggle-target (-> self destination))
    (nav-enemy-travel-post)
    (none)
    )
  )

;; definition for function billy-rat-init-by-other
;; INFO: Used lq/sq
(defbehavior billy-rat-init-by-other billy-rat ((arg0 billy) (arg1 vector) (arg2 vector))
  (set! (-> self billy) (the-as (pointer billy) (process->ppointer arg0)))
  (set! (-> self destination quad) (-> arg2 quad))
  (set! (-> self dest-type) (the-as uint 1))
  (let ((s4-0 (new 'stack-no-clear 'vector)))
    (vector-! s4-0 arg2 arg1)
    (set! (-> s4-0 y) 0.0)
    (vector-normalize! s4-0 1.0)
    (swamp-rat-init-by-other arg0 arg1 s4-0 (pickup-type none) #t)
    )
  (none)
  )

;; failed to figure out what this is:
(defskelgroup *billy-sg* billy billy-lod0-jg billy-idle-breath-ja
              ((billy-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 2)
              :longest-edge (meters 1)
              :shadow billy-shadow-mg
              )

;; failed to figure out what this is:
(defskelgroup *billy-sidekick-sg* billy-sidekick billy-sidekick-lod0-jg billy-sidekick-idle-ja
              ((billy-sidekick-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 4)
              )

;; definition for function billy-kill-all-but-farthy
(defbehavior billy-kill-all-but-farthy billy ()
  (let* ((gp-0 (the-as (pointer process-tree) (-> self child-override)))
         (s5-0 (-> (the-as (pointer billy-snack) gp-0) 0 brother))
         )
    (while gp-0
      (if (not (or (= gp-0 (-> self farthy process)) (type-type? (-> (ppointer->process gp-0) type) fuel-cell)))
          (deactivate (-> gp-0 0))
          )
      (set! gp-0 s5-0)
      (set! s5-0 (-> gp-0 0 brother))
      )
    )
  #f
  )

;; definition for method 32 of type billy
(defmethod play-anim! billy ((obj billy) (arg0 symbol))
  (case (current-status (-> obj tasks))
    (((task-status need-hint) (task-status need-introduction))
     (when arg0
       (set! (-> obj blend-on-exit) (the-as art-joint-anim #t))
       (close-status! (-> obj tasks) (task-status need-introduction))
       (let ((s5-1 (new 'stack-no-clear 'vector)))
         (dotimes (s4-0 (+ (the int (the float (+ (-> obj path-snacks curve num-cverts) -1))) 1))
           (eval-path-curve-div! (-> obj path-snacks) s5-1 (the float s4-0) 'exact)
           (set! (-> s5-1 x) (+ -40960.0 (-> s5-1 x)))
           (set! (-> s5-1 z) (+ 20480.0 (-> s5-1 z)))
           (manipy-spawn s5-1 (-> obj entity) *farthy-snack-sg* #f :to obj)
           )
         )
       )
     (new 'static 'spool-anim
       :name "billy-introduction"
       :index 5
       :parts 14
       :command-list '((0 kill "swamp-blimp-3")
         (0 kill "swamp-tetherrock-14")
         (0 kill "swamp-tetherrock-15")
         (0 kill "flutflut-3")
         (0 kill "tar-plat-26")
         (0 kill "tar-plat-25")
         (0 kill "babak-380")
         (0 kill "eco-164")
         (0 kill "eco-165")
         (0 kill "eco-140")
         (0 kill "launcher-97")
         (0 kill "swamp-rat-nest-5")
         (0 kill "swamp-rat-nest-4")
         (0 kill "swamp-rat-nest-3")
         (0 kill "swamp-rat-nest-2")
         (0 kill "sharkey-9")
         (0 kill "launcher-46")
         (0 kill "launcher-44")
         (0 kill "launcher-42")
         (0 kill "swamp-spike-43")
         (0 kill "swamp-spike-44")
         (0 kill "swamp-spike-45")
         (346 blackout 10)
         (349 blackout 0)
         (494 blackout 10)
         (497 blackout 0)
         (1145 blackout 10)
         (1148 blackout 0)
         (1518 blackout 10)
         (1521 blackout 0)
         )
       )
     )
    (((task-status need-reminder-a) (task-status need-reminder))
     (set! (-> obj skippable) #t)
     (set! (-> obj blend-on-exit) (the-as art-joint-anim #t))
     (set! (-> obj will-talk) #t)
     (new 'static 'spool-anim
       :name "billy-reminder-1"
       :index 8
       :parts 2
       :command-list '((0 kill "swamp-blimp-3")
         (0 kill "swamp-tetherrock-14")
         (0 kill "swamp-tetherrock-15")
         (0 kill "flutflut-3")
         (0 kill "tar-plat-26")
         (0 kill "tar-plat-25")
         (0 kill "babak-380")
         (0 kill "eco-164")
         (0 kill "eco-165")
         (0 kill "eco-140")
         (0 kill "launcher-97")
         (0 kill "swamp-rat-nest-5")
         (0 kill "swamp-rat-nest-4")
         (0 kill "swamp-rat-nest-3")
         (0 kill "swamp-rat-nest-2")
         (0 kill "sharkey-9")
         (0 kill "launcher-46")
         (0 kill "launcher-44")
         (0 kill "launcher-42")
         (0 kill "swamp-spike-43")
         (0 kill "swamp-spike-44")
         (0 kill "swamp-spike-45")
         )
       )
     )
    (((task-status need-reward-speech))
     (when arg0
       (set! (-> obj cell-for-task) (current-task (-> obj tasks)))
       (close-current! (-> obj tasks))
       )
     (new 'static 'spool-anim
       :name "billy-resolution"
       :index 9
       :parts 2
       :command-list '((0 kill "swamp-blimp-3")
         (0 kill "swamp-tetherrock-14")
         (0 kill "swamp-tetherrock-15")
         (0 kill "flutflut-3")
         (0 kill "tar-plat-26")
         (0 kill "tar-plat-25")
         (0 kill "babak-380")
         (0 kill "eco-164")
         (0 kill "eco-165")
         (0 kill "eco-140")
         (0 kill "launcher-97")
         (0 kill "swamp-rat-nest-5")
         (0 kill "swamp-rat-nest-4")
         (0 kill "swamp-rat-nest-3")
         (0 kill "swamp-rat-nest-2")
         (0 kill "sharkey-9")
         (0 kill "launcher-46")
         (0 kill "launcher-44")
         (0 kill "launcher-42")
         (0 kill "swamp-spike-43")
         (0 kill "swamp-spike-44")
         (0 kill "swamp-spike-45")
         )
       )
     )
    (else
      (if arg0
          (format
            0
            "ERROR: <GMJ>: ~S playing anim for task status ~S~%"
            (-> obj name)
            (task-status->string (current-status (-> obj tasks)))
            )
          )
      (-> obj draw art-group data 3)
      )
    )
  )

;; definition for method 31 of type billy
(defmethod get-art-elem billy ((obj billy))
  (case (current-status (-> obj tasks))
    (((task-status invalid) (task-status need-resolution))
     (-> obj draw art-group data 10)
     )
    (else
      (-> obj draw art-group data 3)
      )
    )
  )

;; definition for method 38 of type billy
(defmethod dummy-38 billy ((obj billy))
  (case (current-status (-> obj tasks))
    (((task-status need-reminder-a) (task-status need-reminder))
     (go (method-of-object obj query))
     )
    (((task-status need-reward-speech))
     (go (method-of-object obj play-anim))
     )
    (else
      ((the-as (function nav-enemy none) (find-parent-method billy 38)) (the-as nav-enemy obj))
      )
    )
  (none)
  )

;; definition for method 34 of type billy
(defmethod get-accept-anim billy ((obj billy) (arg0 symbol))
  (if arg0
      (close-current! (-> obj tasks))
      )
  (new 'static 'spool-anim :name "billy-accept" :index 6 :parts 3 :command-list '())
  )

;; definition for method 36 of type billy
(defmethod get-reject-anim billy ((obj billy) (arg0 symbol))
  (new 'static 'spool-anim :name "billy-reject" :index 7 :parts 3 :command-list '())
  )

;; failed to figure out what this is:
(defstate billy-done (billy)
  :event (behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
    (let ((v1-0 arg2))
      (the-as object (when (= v1-0 'billy-rat-needs-destination)
                       (let* ((gp-0 arg0)
                              (v1-2 (if (and (nonzero? gp-0) (type-type? (-> gp-0 type) billy-rat))
                                        gp-0
                                        )
                                    )
                              )
                         (when v1-2
                           (set! (-> (the-as billy-rat v1-2) dest-type) (the-as uint 1))
                           (get-random-point (-> self path-waypts) (-> (the-as billy-rat v1-2) destination))
                           )
                         )
                       )
              )
      )
    )
  :enter (behavior ()
    (init!
      (-> self query)
      (lookup-text! *common-text* (game-text-id play-again?) #f)
      40
      150
      30
      #f
      (lookup-text! *common-text* (game-text-id quit) #f)
      )
    (ja-channel-set! 1)
    (ja :group! (get-art-elem self))
    (send-event *target* 'end-mode)
    (when (and (handle->process (-> self offending-rat)) (zero? (-> self num-snacks)))
      (send-event *camera* 'change-target (handle->process (-> self offending-rat)))
      (send-event *camera* 'change-state cam-standoff 0)
      (send-event *camera* 'set-standoff-height 0.0)
      (send-event *camera* 'set-standoff-dist 20480.0)
      (send-event *camera* 'set-standoff-height 16384.0)
      (send-event *camera-combiner* 'stop-tracking)
      (send-event *camera-combiner* 'start-tracking (ppointer->process (-> *camera* slave 0)))
      (let ((a0-24 (get-reminder (-> self tasks) 0)))
        (save-reminder (-> self tasks) (seekl a0-24 255 1) 0)
        )
      (let ((f0-2 (rand-float-gen)))
        (cond
          ((< 0.75 f0-2)
           (play-ambient (-> self ambient) "BIL-TA04" #t (the-as vector #f))
           )
          ((< 0.5 f0-2)
           (play-ambient (-> self ambient) "BIL-TA05" #t (the-as vector #f))
           )
          ((< 0.25 f0-2)
           (play-ambient (-> self ambient) "BIL-TA4A" #t (the-as vector #f))
           )
          (else
            (play-ambient (-> self ambient) "BIL-TA5A" #t (the-as vector #f))
            )
          )
        )
      )
    (none)
    )
  :exit (behavior ()
    (billy-kill-all-but-farthy)
    (send-event *camera* 'change-target *target*)
    (send-event *camera* 'change-state *camera-base-mode* 0)
    (none)
    )
  :trans (behavior ()
    (cond
      ((> (-> self num-snacks) 0)
       (when (process-grab? *target*)
         (close-current! (-> self tasks))
         (go-virtual play-anim)
         )
       )
      ((< (-> self num-snacks) 0)
       (go-virtual idle)
       )
      (else
        (process-grab? *target*)
        (when (and *target* (logtest? (-> *target* state-flags) (state-flags grabbed)))
          (let ((gp-0 (get-response (-> self query))))
            (cond
              ((and (= gp-0 'yes) (process-release? *target*))
               (go-virtual enter-playing)
               )
              ((= gp-0 'no)
               (go-virtual play-reject)
               )
              )
            )
          )
        )
      )
    (spool-push *art-control* "billy-reject" 0 self -99.0)
    (none)
    )
  :code (the-as (function none :behavior billy) process-taskable-anim-loop)
  :post (behavior ()
    (ja-post)
    (none)
    )
  )

;; definition for function billy-game-update-wave
;; INFO: Return type mismatch time-frame vs none.
(defbehavior billy-game-update-wave billy ()
  (let* ((a0-2 (/ (the-as uint (+ (get-reminder (-> self tasks) 0) 1)) (the-as uint 5)))
         (v1-4 (min 3 (the-as int a0-2)))
         )
    (cond
      ((zero? v1-4)
       (let ((v1-5 (-> self current-wave)))
         (cond
           ((zero? v1-5)
            (set! (-> self max-rats) 6)
            (set! (-> self rat-speed) 1.0)
            (set! (-> self spawn-rats) #t)
            (set! (-> self passed-last-stage) #f)
            (when (>= (- (-> *display* base-frame-counter) (-> self wave-start-time)) (seconds 15))
              (+! (-> self current-wave) 1)
              (set! (-> self wave-start-time) (-> *display* base-frame-counter))
              )
            )
           ((= v1-5 2)
            (set! (-> self max-rats) 8)
            (set! (-> self rat-speed) 1.2)
            (set! (-> self spawn-rats) #t)
            (when (>= (- (-> *display* base-frame-counter) (-> self wave-start-time)) (seconds 20))
              (+! (-> self current-wave) 1)
              (set! (-> self wave-start-time) (-> *display* base-frame-counter))
              )
            )
           ((= v1-5 4)
            (set! (-> self max-rats) 10)
            (set! (-> self rat-speed) 1.35)
            (set! (-> self spawn-rats) #t)
            (when (>= (- (-> *display* base-frame-counter) (-> self wave-start-time)) (seconds 25))
              (+! (-> self current-wave) 1)
              (set! (-> self wave-start-time) (-> *display* base-frame-counter))
              )
            )
           )
         )
       )
      ((= v1-4 1)
       (let ((v1-30 (-> self current-wave)))
         (cond
           ((zero? v1-30)
            (set! (-> self max-rats) 6)
            (set! (-> self rat-speed) 1.0)
            (set! (-> self spawn-rats) #t)
            (set! (-> self passed-last-stage) #f)
            (when (>= (- (-> *display* base-frame-counter) (-> self wave-start-time)) (seconds 15))
              (+! (-> self current-wave) 1)
              (set! (-> self wave-start-time) (-> *display* base-frame-counter))
              )
            )
           ((= v1-30 2)
            (set! (-> self max-rats) 7)
            (set! (-> self rat-speed) 1.2)
            (set! (-> self spawn-rats) #t)
            (when (>= (- (-> *display* base-frame-counter) (-> self wave-start-time)) (seconds 20))
              (+! (-> self current-wave) 1)
              (set! (-> self wave-start-time) (-> *display* base-frame-counter))
              )
            )
           ((= v1-30 4)
            (set! (-> self max-rats) 10)
            (set! (-> self rat-speed) 1.3)
            (set! (-> self spawn-rats) #t)
            (when (>= (- (-> *display* base-frame-counter) (-> self wave-start-time)) (seconds 22))
              (+! (-> self current-wave) 1)
              (set! (-> self wave-start-time) (-> *display* base-frame-counter))
              )
            )
           )
         )
       )
      ((= v1-4 2)
       (let ((v1-55 (-> self current-wave)))
         (cond
           ((zero? v1-55)
            (set! (-> self max-rats) 6)
            (set! (-> self rat-speed) 1.0)
            (set! (-> self spawn-rats) #t)
            (set! (-> self passed-last-stage) #f)
            (when (>= (- (-> *display* base-frame-counter) (-> self wave-start-time)) (seconds 15))
              (+! (-> self current-wave) 1)
              (set! (-> self wave-start-time) (-> *display* base-frame-counter))
              )
            )
           ((= v1-55 2)
            (set! (-> self max-rats) 7)
            (set! (-> self rat-speed) 1.1)
            (set! (-> self spawn-rats) #t)
            (when (>= (- (-> *display* base-frame-counter) (-> self wave-start-time)) (seconds 18))
              (+! (-> self current-wave) 1)
              (set! (-> self wave-start-time) (-> *display* base-frame-counter))
              )
            )
           ((= v1-55 4)
            (set! (-> self max-rats) 9)
            (set! (-> self rat-speed) 1.25)
            (set! (-> self spawn-rats) #t)
            (when (>= (- (-> *display* base-frame-counter) (-> self wave-start-time)) (seconds 20))
              (+! (-> self current-wave) 1)
              (set! (-> self wave-start-time) (-> *display* base-frame-counter))
              )
            )
           )
         )
       )
      (else
        (let ((v1-80 (-> self current-wave)))
          (cond
            ((zero? v1-80)
             (set! (-> self max-rats) 5)
             (set! (-> self rat-speed) 0.9)
             (set! (-> self spawn-rats) #t)
             (set! (-> self passed-last-stage) #f)
             (when (>= (- (-> *display* base-frame-counter) (-> self wave-start-time)) (seconds 15))
               (+! (-> self current-wave) 1)
               (set! (-> self wave-start-time) (-> *display* base-frame-counter))
               )
             )
            ((= v1-80 2)
             (set! (-> self max-rats) 6)
             (set! (-> self rat-speed) 1.0)
             (set! (-> self spawn-rats) #t)
             (when (>= (- (-> *display* base-frame-counter) (-> self wave-start-time)) (seconds 18))
               (+! (-> self current-wave) 1)
               (set! (-> self wave-start-time) (-> *display* base-frame-counter))
               )
             )
            ((= v1-80 4)
             (set! (-> self max-rats) 8)
             (set! (-> self rat-speed) 1.1)
             (set! (-> self spawn-rats) #t)
             (when (>= (- (-> *display* base-frame-counter) (-> self wave-start-time)) (seconds 20))
               (+! (-> self current-wave) 1)
               (set! (-> self wave-start-time) (-> *display* base-frame-counter))
               )
             )
            )
          )
        )
      )
    )
  (none)
  )

;; definition for function billy-game-update
;; INFO: Return type mismatch int vs none.
(defbehavior billy-game-update billy ()
  (let ((v1-0 (-> self current-wave)))
    (cond
      ((or (zero? v1-0) (= v1-0 2) (= v1-0 4))
       (billy-game-update-wave)
       )
      ((= v1-0 5)
       (set! (-> self spawn-rats) #f)
       (set! (-> self passed-last-stage) #t)
       )
      ((begin (set! (-> self spawn-rats) #f) (zero? (-> self num-rats)))
       (when (>= (- (-> *display* base-frame-counter) (-> self wave-start-time)) (seconds 3))
         (+! (-> self current-wave) 1)
         (set! (-> self wave-start-time) (-> *display* base-frame-counter))
         )
       )
      (else
        (set! (-> self wave-start-time) (-> *display* base-frame-counter))
        )
      )
    )
  (when (and (< (-> self num-rats) (-> self max-rats)) (-> self spawn-rats))
    (let ((gp-0 (new 'stack-no-clear 'vector))
          (s5-0 (new 'stack-no-clear 'vector))
          )
      (get-random-point (-> self path-starts) gp-0)
      (get-random-point (-> self path-waypts) s5-0)
      (if (process-spawn billy-rat self gp-0 s5-0 :to self)
          (+! (-> self num-rats) 1)
          )
      )
    )
  0
  (none)
  )

;; failed to figure out what this is:
(defstate billy-playing (billy)
  :event (behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
    (case arg2
      (('billy-rat-die)
       (+! (-> self num-rats) -1)
       (let* ((f0-2 (rand-float-gen))
              (f0-3 (* 3.0 f0-2))
              )
         (cond
           ((< 1.0 f0-3)
            #f
            )
           ((< 0.8333333 f0-3)
            (play-ambient (-> self ambient) "SKSP009F" #t (the-as vector #f))
            )
           ((< 0.6666667 f0-3)
            (play-ambient (-> self ambient) "BIL-TA02" #t (the-as vector #f))
            )
           ((< 0.5 f0-3)
            (play-ambient (-> self ambient) "BIL-TA08" #t (the-as vector #f))
            )
           ((< 0.33333334 f0-3)
            (play-ambient (-> self ambient) "BIL-TA09" #t (the-as vector #f))
            )
           ((< 0.16666667 f0-3)
            (play-ambient (-> self ambient) "BIL-TA2A" #t (the-as vector #f))
            )
           (else
             (play-ambient (-> self ambient) "BIL-TA4B" #t (the-as vector #f))
             )
           )
         )
       )
      (('billy-rat-needs-destination)
       (let* ((s5-0 arg0)
              (gp-0 (if (and (nonzero? s5-0) (type-type? (-> s5-0 type) billy-rat))
                        (the-as billy-rat s5-0)
                        )
                    )
              )
         (when gp-0
           (let ((f0-6 (rand-float-gen)))
             (cond
               ((< 0.75 f0-6)
                (play-ambient (-> self ambient) "BIL-TA01" #t (the-as vector #f))
                )
               ((< 0.5 f0-6)
                (play-ambient (-> self ambient) "BIL-TA03" #t (the-as vector #f))
                )
               ((< 0.25 f0-6)
                (play-ambient (-> self ambient) "BIL-TA1A" #t (the-as vector #f))
                )
               (else
                 (play-ambient (-> self ambient) "BIL-TA3A" #t (the-as vector #f))
                 )
               )
             )
           (cond
             ((rat-about-to-eat? gp-0 self)
              (set! (-> self num-snacks) 0)
              (set! (-> self offending-rat) (process->handle gp-0))
              (set! (-> gp-0 dest-type) (the-as uint 3))
              (let ((v0-1 (the-as object (-> gp-0 destination))))
                (set! (-> (the-as vector v0-1) quad) (-> (the-as billy-snack (-> gp-0 snack process 0)) root trans quad))
                v0-1
                )
              )
             ((or (= (-> gp-0 dest-type) 2) (= (-> gp-0 dest-type) 3) (<= (-> self num-snacks) 0))
              (set! (-> gp-0 dest-type) (the-as uint 1))
              (get-random-point (-> self path-starts) (-> gp-0 destination))
              )
             (else
               (let ((s3-0 100)
                     (s4-0 0)
                     (s2-0 (the-as (pointer process-tree) (-> self child-override)))
                     (s5-1 (the-as process-tree #f))
                     )
                 (while s2-0
                   (let* ((s1-0 (ppointer->process s2-0))
                          (v1-47 (if (and (nonzero? s1-0) (type-type? (-> s1-0 type) billy-snack))
                                     s1-0
                                     )
                                 )
                          )
                     (cond
                       ((not v1-47)
                        )
                       ((< (-> (the-as billy-snack v1-47) num-rats) s3-0)
                        (set! s5-1 v1-47)
                        (set! s3-0 (-> (the-as billy-snack v1-47) num-rats))
                        (set! s4-0 1)
                        )
                       ((= (-> (the-as billy-snack v1-47) num-rats) s3-0)
                        (+! s4-0 1)
                        )
                       )
                     )
                   (set! s2-0 (-> s2-0 0 brother))
                   )
                 (cond
                   ((zero? s4-0)
                    (set! (-> gp-0 dest-type) (the-as uint 1))
                    (get-random-point (-> self path-waypts) (-> gp-0 destination))
                    )
                   (else
                     (set! (-> gp-0 snack) (process->handle (the-as billy-snack s5-1)))
                     (+! (-> (the-as billy-snack s5-1) num-rats) 1)
                     (set! (-> gp-0 dest-type) (the-as uint 2))
                     (set! (-> gp-0 destination quad) (-> (the-as billy-snack s5-1) root trans quad))
                     (let ((f0-8 (+ 6799.36 (-> gp-0 destination x))))
                       (set! (-> gp-0 destination x) f0-8)
                       f0-8
                       )
                     )
                   )
                 )
               )
             )
           )
         )
       )
      )
    )
  :enter (behavior ()
    (add-setting! 'music 'danger 0.0 0)
    (ja-channel-set! 0)
    (clear-collide-with-as (-> self root-override))
    (init! (-> self query) (the-as string #f) 40 150 25 #t (lookup-text! *common-text* (game-text-id quit) #f))
    (set! (-> self wave-start-time) (-> *display* base-frame-counter))
    (set! (-> self num-snacks) 0)
    (set! (-> self num-rats) 0)
    (set! (-> self current-wave) 0)
    (set! (-> self offending-rat) (the-as handle #f))
    (let ((gp-1 (new 'stack-no-clear 'vector)))
      (dotimes (s5-1 (+ (the int (the float (+ (-> self path-snacks curve num-cverts) -1))) 1))
        (eval-path-curve-div! (-> self path-snacks) gp-1 (the float s5-1) 'exact)
        (if (process-spawn billy-snack gp-1 :to self)
            (+! (-> self num-snacks) 1)
            )
        )
      )
    (backup-load-state-and-set-cmds *load-state* '())
    (let* ((gp-2 '((kill "swamp-blimp-3")
                   (kill "swamp-tetherrock-14")
                   (kill "swamp-tetherrock-15")
                   (kill "flutflut-3")
                   (kill "tar-plat-26")
                   (kill "tar-plat-25")
                   (kill "babak-380")
                   (kill "eco-164")
                   (kill "eco-165")
                   (kill "eco-140")
                   (kill "launcher-97")
                   (kill "swamp-rat-nest-5")
                   (kill "swamp-rat-nest-4")
                   (kill "swamp-rat-nest-3")
                   (kill "swamp-rat-nest-2")
                   (kill "sharkey-9")
                   (kill "launcher-46")
                   (kill "launcher-44")
                   (kill "launcher-42")
                   (kill "swamp-spike-43")
                   (kill "swamp-spike-44")
                   (kill "swamp-spike-45")
                   )
                 )
           (a1-8 (car gp-2))
           )
      (while (not (null? gp-2))
        (execute-command *load-state* (the-as pair a1-8))
        (set! gp-2 (cdr gp-2))
        (set! a1-8 (car gp-2))
        )
      )
    (none)
    )
  :exit (behavior ()
    (restore-collide-with-as (-> self root-override))
    (restore-load-state-and-cleanup *load-state*)
    (set! (-> *ACTOR-bank* birth-max) 1000)
    (remove-setting! 'music)
    (none)
    )
  :trans (behavior ()
    (spool-push *art-control* "billy-resolution" 0 self -99.0)
    (spool-push *art-control* "billy-reject" 0 self -99.0)
    (none)
    )
  :code (behavior ()
    (loop
      (billy-game-update)
      (if (or (zero? (-> self num-snacks))
              (and (zero? (-> self num-rats)) (-> self passed-last-stage))
              (and *cheat-mode* (cpad-pressed? 1 x))
              )
          (go billy-done)
          )
      (suspend)
      )
    (none)
    )
  :post (behavior ()
    (ja-post)
    (none)
    )
  )

;; failed to figure out what this is:
(defstate enter-playing (billy)
  :virtual #t
  :trans (behavior ()
    (when (send-event *target* 'change-mode 'billy)
      (send-event *target* 'trans 'reset)
      (let ((v1-8 (entity-actor-lookup (-> self entity) 'alt-actor 0)))
        (cond
          (v1-8
            (move-to-point! (-> *target* control) (-> v1-8 extra trans))
            (go billy-playing)
            )
          (else
            )
          )
        )
      )
    (none)
    )
  )

;; definition for method 43 of type billy
(defmethod TODO-RENAME-43 billy ((obj billy))
  (when (TODO-RENAME-10 (-> obj ambient) (new 'stack-no-clear 'vector) (seconds 30) 122880.0 obj)
    (let ((f30-0 (rand-float-gen)))
      (cond
        ((< 0.9411765 f30-0)
         (play-ambient (-> obj ambient) "BIL-AM01" #f (-> obj root-override trans))
         )
        ((< 0.88235295 f30-0)
         (play-ambient (-> obj ambient) "BIL-AM02" #f (-> obj root-override trans))
         )
        ((< 0.8235294 f30-0)
         (play-ambient (-> obj ambient) "BIL-AM03" #f (-> obj root-override trans))
         )
        ((< 0.7647059 f30-0)
         (play-ambient (-> obj ambient) "BIL-AM04" #f (-> obj root-override trans))
         )
        ((< 0.7058824 f30-0)
         (play-ambient (-> obj ambient) "BIL-AM05" #f (-> obj root-override trans))
         )
        ((< 0.64705884 f30-0)
         (play-ambient (-> obj ambient) "BIL-AM06" #f (-> obj root-override trans))
         )
        ((< 0.5882353 f30-0)
         (play-ambient (-> obj ambient) "BIL-AM07" #f (-> obj root-override trans))
         )
        ((< 0.5294118 f30-0)
         (play-ambient (-> obj ambient) "BIL-AM08" #f (-> obj root-override trans))
         )
        ((< 0.47058824 f30-0)
         (play-ambient (-> obj ambient) "BIL-AM1A" #f (-> obj root-override trans))
         )
        ((< 0.4117647 f30-0)
         (play-ambient (-> obj ambient) "BIL-AM2A" #f (-> obj root-override trans))
         )
        ((< 0.3529412 f30-0)
         (play-ambient (-> obj ambient) "BIL-AM2B" #f (-> obj root-override trans))
         )
        ((= (current-status (-> obj tasks)) (task-status invalid))
         #f
         )
        ((< 0.29411766 f30-0)
         (play-ambient (-> obj ambient) "BIL-LO01" #f (-> obj root-override trans))
         )
        ((< 0.23529412 f30-0)
         (play-ambient (-> obj ambient) "BIL-LO02" #f (-> obj root-override trans))
         )
        ((< 0.1764706 f30-0)
         (play-ambient (-> obj ambient) "BIL-LO03" #f (-> obj root-override trans))
         )
        ((< 0.11764706 f30-0)
         (play-ambient (-> obj ambient) "BIL-LO1A" #f (-> obj root-override trans))
         )
        ((< 0.05882353 f30-0)
         (play-ambient (-> obj ambient) "BIL-LO2A" #f (-> obj root-override trans))
         )
        (else
          (play-ambient (-> obj ambient) "BIL-LO2B" #f (-> obj root-override trans))
          )
        )
      )
    )
  )

;; failed to figure out what this is:
(defstate play-anim (billy)
  :virtual #t
  :exit (behavior ()
    (billy-kill-all-but-farthy)
    ((-> (method-of-type process-taskable play-anim) exit))
    (none)
    )
  )

;; failed to figure out what this is:
(defstate idle (billy)
  :virtual #t
  :code (behavior ()
    (if (!= (ja-group) (get-art-elem self))
        (ja-channel-push! 1 (seconds 0.2))
        )
    (loop
      (ja :group! (get-art-elem self))
      (let* ((f30-0 5.0)
             (v1-9 (/ (the-as int (rand-uint31-gen *random-generator*)) 256))
             (v1-10 (the-as number (logior #x3f800000 v1-9)))
             )
        (countdown (gp-1 (+ (the int (* f30-0 (+ -1.0 (the-as float v1-10)))) 5))
          (ja-no-eval :group! (ja-group) :num! (seek!) :frame-num 0.0)
          (until (ja-done? 0)
            (TODO-RENAME-43 self)
            (suspend)
            (ja :num! (seek!))
            )
          )
        )
      (when (ja-group? billy-idle-breath-ja)
        (ja-no-eval :group! billy-idle-shoo-ja :num! (seek!) :frame-num 0.0)
        (until (ja-done? 0)
          (suspend)
          (ja :num! (seek!))
          )
        )
      )
    (none)
    )
  )

;; definition for method 47 of type billy
;; INFO: Return type mismatch basic vs symbol.
(defmethod target-above-threshold? billy ((obj billy))
  (the-as
    symbol
    (and *target* (zero? (logand (-> *target* control root-prim prim-core action) (collide-action ca-14))))
    )
  )

;; definition for method 11 of type billy
(defmethod init-from-entity! billy ((obj billy) (arg0 entity-actor))
  (dummy-40 obj arg0 *billy-sg* 3 40 (new 'static 'vector :w 4096.0) 5)
  (set! (-> obj tasks) (get-task-control (game-task swamp-billy)))
  (dotimes (s5-0 3)
    (let ((v1-3 (new 'process 'curve-control obj 'path (the float s5-0))))
      (set! (-> obj path-data s5-0) v1-3)
      (logior! (-> v1-3 flags) (path-control-flag display draw-line draw-point draw-text))
      )
    )
  (set! (-> obj path) (-> obj path-snacks))
  (set! (-> obj farthy)
        (ppointer->handle (manipy-spawn (-> obj root-override trans) (-> obj entity) *billy-sidekick-sg* #f :to obj))
        )
  (send-event (handle->process (-> obj farthy)) 'center-joint 3)
  (send-event (handle->process (-> obj farthy)) 'anim-mode 'clone-anim)
  (dummy-42 obj)
  (none)
  )
