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

;; name: intro-obs.gc
;; name in dgo: intro-obs
;; dgos: INTROCST

;; DECOMP BEGINS

(deftype intro-flamer (process-drawable)
  ((up-dir           vector :inline :offset-assert 208)
   (average-dir      vector :inline :offset-assert 224)
   (id               int32          :offset-assert 240)
   (path-u           float          :offset-assert 244)
   (path-du          float          :offset-assert 248)
   (z-rot            float          :offset-assert 252)
   (flit-prev-offset vector :inline :offset-assert 256)
   (flit-next-offset vector :inline :offset-assert 272)
   (flit-factor      float          :offset-assert 288)
   (flit-timer       uint64         :offset-assert 296)
   (flit-interval    uint64         :offset-assert 304)
   )
  :heap-base #xc0
  :method-count-assert 23
  :size-assert         #x138
  :flag-assert         #x1700c00138
  (:methods
    (idle () _type_ :state 20)
    (die () _type_ :state 21)
    (intro-flamer-method-22 (_type_) path-control 22)
    )
  )


(defskelgroup skel-intro-flamer intro-flamer intro-flamer-lod0-jg intro-flamer-fly-straight-ja
              ((intro-flamer-lod0-mg (meters 20)) (intro-flamer-lod1-mg (meters 40)) (intro-flamer-lod2-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 7.5)
              :shadow intro-flamer-shadow-mg
              :origin-joint-index 3
              )

(defstate idle (intro-flamer)
  :virtual #t
  :event (behavior ((proc process) (arg1 int) (event-type symbol) (event event-message-block))
    (case event-type
      (('die)
       (go-virtual die)
       )
      )
    )
  :trans (behavior ()
    (if (= (-> self path-u) 1.0)
        (go-virtual die)
        )
    (when (>= (- (current-time) (the-as int (-> self flit-timer))) (the-as time-frame (-> self flit-interval)))
      (let ((f28-0 (rand-vu-float-range -1.0 1.0))
            (f30-0 (rand-vu-float-range -1.0 1.0))
            (f0-1 (rand-vu-float-range 0.2 0.6))
            )
        (set! (-> self flit-prev-offset quad) (-> self flit-next-offset quad))
        (set-vector! (-> self flit-next-offset) (* 4096.0 f28-0) (* 4096.0 f30-0) 0.0 0.0)
        (set! (-> self flit-factor) 0.0)
        (set! (-> self flit-interval) (the-as uint (the int (* 300.0 f0-1))))
        )
      (set! (-> self flit-timer) (the-as uint (current-time)))
      )
    (none)
    )
  :code (behavior ()
    (ja-channel-set! 1)
    (let ((f30-0 (rand-vu-float-range 0.8 1.2)))
      (until #f
        (ja-no-eval :group! (-> self draw art-group data 5)
                    :num! (seek!
                      (the float (+ (-> (the-as art-joint-anim (-> self draw art-group data 5)) frames num-frames) -1))
                      f30-0
                      )
                    :frame-num 0.0
                    )
        (until (ja-done? 0)
          (suspend)
          (ja :num! (seek! max f30-0))
          )
        )
      )
    #f
    (none)
    )
  :post (behavior ()
    (seek! (-> self path-u) 1.0 (* (-> self path-du) (-> self clock seconds-per-frame)))
    (let ((s3-0 (intro-flamer-method-22 self))
          (s4-0 (new 'stack-no-clear 'vector))
          (s5-0 (new 'stack-no-clear 'quaternion))
          (f30-0 (-> self path-u))
          (gp-0 (new 'stack-no-clear 'vector))
          )
      (get-point-at-percent-along-path! s3-0 gp-0 f30-0 'interp)
      (displacement-between-points-at-percent-normalized! s3-0 s4-0 (fmin 1.0 (+ 0.05 f30-0)))
      (let ((t9-4 vector-normalize!)
            (a0-4 (new 'stack-no-clear 'vector))
            )
        (set! (-> a0-4 x) (-> s4-0 x))
        (set! (-> a0-4 y) 0.0)
        (set! (-> a0-4 z) (-> s4-0 z))
        (set! (-> a0-4 w) 1.0)
        (let ((s3-1 (t9-4 a0-4 1.0))
              (t9-5 vector-normalize!)
              (a0-5 (new 'stack-no-clear 'vector))
              )
          (set! (-> a0-5 x) (-> self average-dir x))
          (set! (-> a0-5 y) 0.0)
          (set! (-> a0-5 z) (-> self average-dir z))
          (set! (-> a0-5 w) 1.0)
          (let* ((v1-10 (t9-5 a0-5 1.0))
                 (f0-15 (vector-dot (vector-cross! (new 'stack-no-clear 'vector) s3-1 v1-10) *up-vector*))
                 (f0-16 (* 49152.0 f0-15))
                 )
            (set! (-> self z-rot) (deg-seek
                                    (-> self z-rot)
                                    (fmax -15473.777 (fmin 15473.777 f0-16))
                                    (* 21845.334 (-> self clock seconds-per-frame))
                                    )
                  )
            )
          )
        )
      (let ((a2-5 (vector-rotate-z! (new 'stack-no-clear 'vector) *up-vector* (-> self z-rot))))
        (forward-up->quaternion s5-0 s4-0 a2-5)
        )
      (quaternion-slerp! (-> self root quat) (-> self root quat) s5-0 (* 8.0 (-> self clock seconds-per-frame)))
      (seek! (-> self flit-factor) 1.0 (* 8.0 (-> self clock seconds-per-frame)))
      (let* ((v1-25 (-> self flit-prev-offset))
             (a1-10 (-> self flit-next-offset))
             (a0-14 (vector-! (new 'stack-no-clear 'vector) a1-10 v1-25))
             (s5-1 (new 'stack-no-clear 'vector))
             )
        (vector+float*! s5-1 v1-25 a0-14 (-> self flit-factor))
        (vector-orient-by-quat! s5-1 s5-1 (-> self root quat))
        (vector+! (-> self root trans) gp-0 s5-1)
        )
      )
    (cond
      ((logtest? (-> self draw status) (draw-control-status on-screen))
       (new 'stack-no-clear 'vector)
       (new 'stack-no-clear 'vector)
       (let ((gp-1 (new 'stack-no-clear 'collide-query)))
         (set! (-> gp-1 start-pos quad) (-> self root trans quad))
         (set-vector! (-> gp-1 move-dist) 0.0 -81920.0 0.0 1.0)
         (let ((v1-37 gp-1))
           (set! (-> v1-37 radius) 2048.0)
           (set! (-> v1-37 collide-with) (collide-spec backgnd))
           (set! (-> v1-37 ignore-process0) self)
           (set! (-> v1-37 ignore-process1) #f)
           (set! (-> v1-37 ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1))
           (set! (-> v1-37 action-mask) (collide-action solid))
           )
         (cond
           ((>= (fill-and-probe-using-line-sphere *collide-cache* gp-1) 0.0)
            (let ((v1-41 (-> self draw shadow-ctrl)))
              (logclear! (-> v1-41 settings flags) (shadow-flags disable-draw))
              )
            0
            (let ((a0-28 (-> gp-1 best-other-tri intersect)))
              (let ((f0-36 (-> self root trans y)))
                (let ((v1-45 (-> self draw shadow-ctrl)))
                  (set! (-> v1-45 settings bot-plane w) (- (+ (- -12288.0 f0-36) (-> a0-28 y))))
                  )
                0
                (let ((v1-48 (-> self draw shadow-ctrl)))
                  (set! (-> v1-48 settings top-plane w) (- (+ (- 12288.0 f0-36) (-> a0-28 y))))
                  )
                )
              0
              (let* ((f2-2 (vector-vector-distance a0-28 (-> self root trans)))
                     (f0-41 (* 0.000030517578 (fmax 0.0 (fmin 32768.0 (+ -57344.0 f2-2)))))
                     )
                (set! (-> self draw shadow-ctrl settings shadow-dir w) (lerp 409600.0 40960.0 f0-41))
                )
              )
            )
           (else
             (let ((v1-58 (-> self draw shadow-ctrl)))
               (logior! (-> v1-58 settings flags) (shadow-flags disable-draw))
               )
             0
             )
           )
         )
       )
      (else
        (let ((v1-61 (-> self draw shadow-ctrl)))
          (logior! (-> v1-61 settings flags) (shadow-flags disable-draw))
          )
        0
        )
      )
    (ja-post)
    (none)
    )
  )

(defstate die (intro-flamer)
  :virtual #t
  :code (behavior ()
    (suspend)
    (cleanup-for-death self)
    (none)
    )
  )

;; WARN: Return type mismatch object vs path-control.
(defmethod intro-flamer-method-22 intro-flamer ((obj intro-flamer))
  (the-as path-control (send-event (ppointer->process (-> obj parent)) 'path (-> obj id)))
  )

;; WARN: Return type mismatch object vs none.
(defmethod init-from-entity! intro-flamer ((obj intro-flamer) (arg0 entity-actor))
  "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that.
This commonly includes things such as:
- stack size
- collision information
- loading the skeleton group / bones
- sounds"
  (set! (-> obj root) (new 'process 'trsqv))
  (process-drawable-from-entity! obj arg0)
  (initialize-skeleton
    obj
    (the-as skeleton-group (art-group-get-by-name *level* "skel-intro-flamer" (the-as (pointer uint32) #f)))
    (the-as pair 0)
    )
  (go (method-of-object obj idle))
  (none)
  )

;; WARN: Return type mismatch object vs none.
(defbehavior intro-flamer-init-by-other intro-flamer ((arg0 int) (arg1 path-control) (arg2 vector))
  (set! (-> self root) (new 'process 'trsqv))
  (initialize-skeleton
    self
    (the-as skeleton-group (art-group-get-by-name *level* "skel-intro-flamer" (the-as (pointer uint32) #f)))
    (the-as pair 0)
    )
  (set! (-> self draw force-lod) 2)
  (set! (-> self id) arg0)
  (set! (-> self path-u) 0.0)
  (set! (-> self path-du) (rand-vu-float-range 0.15 0.32))
  (set! (-> self z-rot) 0.0)
  (set! (-> self flit-timer) (the-as uint (current-time)))
  (set! (-> self flit-interval) (the-as uint 0))
  (vector-reset! (-> self flit-prev-offset))
  (vector-reset! (-> self flit-next-offset))
  (set! (-> self flit-factor) 0.0)
  (get-point-in-path! arg1 (-> self root trans) 0.0 'interp)
  (let ((s4-1 (new 'stack-no-clear 'vector)))
    (displacement-between-points-at-percent-normalized! arg1 s4-1 0.0)
    (forward-up-nopitch->quaternion (-> self root quat) s4-1 *up-vector*)
    )
  (set! (-> self draw shadow-ctrl)
        (new 'process 'shadow-control 0.0 0.0 614400.0 (shadow-flags shdf03) 491520.0)
        )
  (set! (-> self draw light-index) (the-as uint 30))
  (set! (-> self average-dir quad) (-> arg2 quad))
  (go-virtual idle)
  (none)
  )

(deftype metalhead-spawner (process)
  ((path-tbl    path-control 19      :offset-assert 128)
   (init-pos    vector       :inline :offset-assert 208)
   (average-dir vector       :inline :offset-assert 224)
   )
  :heap-base #x70
  :method-count-assert 17
  :size-assert         #xf0
  :flag-assert         #x11007000f0
  (:methods
    (idle () _type_ :state 14)
    (active () _type_ :state 15)
    (die () _type_ :state 16)
    )
  )


(defstate idle (metalhead-spawner)
  :virtual #t
  :event (behavior ((proc process) (arg1 int) (event-type symbol) (event event-message-block))
    (case event-type
      (('trigger)
       (go-virtual active)
       )
      (('path)
       (-> self path-tbl (-> event param 0))
       )
      )
    )
  :code (the-as (function none :behavior metalhead-spawner) sleep-code)
  )

(defstate active (metalhead-spawner)
  :virtual #t
  :event (behavior ((proc process) (arg1 int) (event-type symbol) (event event-message-block))
    (case event-type
      (('untrigger)
       (go-virtual idle)
       )
      (('die)
       (go-virtual die)
       )
      (('path)
       (-> self path-tbl (-> event param 0))
       )
      )
    )
  :code (behavior ()
    (let ((gp-0 0))
      (until #f
        (set! gp-0 (mod (+ gp-0 (rand-vu-int-range 1 6)) 19))
        (let ((s5-0 (get-process *default-dead-pool* intro-flamer #x4000)))
          (when s5-0
            (let ((t9-2 (method-of-type process activate)))
              (t9-2 s5-0 self (symbol->string (-> intro-flamer symbol)) (the-as pointer #x70004000))
              )
            (run-now-in-process s5-0 intro-flamer-init-by-other gp-0 (-> self path-tbl gp-0) (-> self average-dir))
            (-> s5-0 ppointer)
            )
          )
        (let ((s5-1 (the int (* 300.0 (rand-vu-float-range 0.03 0.08))))
              (s4-0 (current-time))
              )
          (until (>= (- (current-time) s4-0) s5-1)
            (suspend)
            )
          )
        )
      )
    #f
    (none)
    )
  :post (behavior ()
    (dotimes (gp-0 19)
      (debug-draw (-> self path-tbl gp-0))
      )
    (none)
    )
  )

(defstate die (metalhead-spawner)
  :virtual #t
  :code (behavior ()
    (let ((gp-0 (-> self child)))
      (while gp-0
        (send-event (ppointer->process gp-0) 'die)
        (set! gp-0 (-> gp-0 0 brother))
        )
      )
    (while (-> self child)
      (suspend)
      )
    (process-entity-status! self (entity-perm-status dead) #t)
    (none)
    )
  )

;; WARN: Return type mismatch process vs metalhead-spawner.
(defmethod relocate metalhead-spawner ((obj metalhead-spawner) (arg0 int))
  (dotimes (v1-0 19)
    (if (nonzero? (-> obj path-tbl v1-0))
        (&+! (-> obj path-tbl v1-0) arg0)
        )
    )
  (the-as
    metalhead-spawner
    ((the-as (function process int process) (find-parent-method metalhead-spawner 7)) obj arg0)
    )
  )

;; WARN: Return type mismatch object vs none.
(defmethod init-from-entity! metalhead-spawner ((obj metalhead-spawner) (arg0 entity-actor))
  "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that.
This commonly includes things such as:
- stack size
- collision information
- loading the skeleton group / bones
- sounds"
  (set! (-> obj init-pos quad) (-> arg0 extra trans quad))
  (vector-reset! (-> obj average-dir))
  (dotimes (s5-0 19)
    (let ((s4-0 (new 'process 'curve-control obj 'path (the float (+ s5-0 1)))))
      (set! (-> obj path-tbl s5-0) s4-0)
      (logior! (-> s4-0 flags) (path-control-flag display draw-line draw-point draw-text))
      (let* ((s3-0 (get-point-at-percent-along-path! s4-0 (new 'stack-no-clear 'vector) 0.0 'interp))
             (v1-10 (get-point-at-percent-along-path! s4-0 (new 'stack-no-clear 'vector) 1.0 'interp))
             (s4-2 (vector-! (new 'stack-no-clear 'vector) v1-10 s3-0))
             )
        (vector-normalize! s4-2 1.0)
        (vector+! (-> obj average-dir) (-> obj average-dir) s4-2)
        )
      )
    )
  (vector-normalize! (-> obj average-dir) 1.0)
  (go (method-of-object obj idle))
  (none)
  )

(deftype vil-windmill-sail (process-drawable)
  ()
  :heap-base #x50
  :method-count-assert 21
  :size-assert         #xc8
  :flag-assert         #x15005000c8
  (:methods
    (idle () _type_ :state 20)
    )
  )


(defskelgroup skel-vil-windmill-sail vil-windmill-sail vil-windmill-sail-lod0-jg vil-windmill-sail-idle-ja
              ((vil-windmill-sail-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 25)
              )

(defstate idle (vil-windmill-sail)
  :virtual #t
  :code (behavior ()
    (until #f
      (ja-no-eval :group! (ja-group)
                  :num! (seek! (the float (+ (-> (ja-group) frames num-frames) -1)))
                  :frame-num 0.0
                  )
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!))
        )
      )
    #f
    (none)
    )
  :post (the-as (function none :behavior vil-windmill-sail) ja-post)
  )

;; WARN: Return type mismatch object vs none.
(defmethod init-from-entity! vil-windmill-sail ((obj vil-windmill-sail) (arg0 entity-actor))
  "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that.
This commonly includes things such as:
- stack size
- collision information
- loading the skeleton group / bones
- sounds"
  (set! (-> obj root) (new 'process 'trsqv))
  (process-drawable-from-entity! obj arg0)
  (initialize-skeleton
    obj
    (the-as skeleton-group (art-group-get-by-name *level* "skel-vil-windmill-sail" (the-as (pointer uint32) #f)))
    (the-as pair 0)
    )
  (go (method-of-object obj idle))
  (none)
  )
