;;-*-Lisp-*-
(in-package goal)
(bundles "GAME.CGO")
(require "engine/common-obs/plat.gc")
(require "engine/common-obs/baseplat.gc")

;; DECOMP BEGINS

(deftype plat-eco (plat)
  ((notice-dist      float)
   (sync-offset-dest float)
   (sync-offset-faux float)
   (sync-linear-val  float)
   (target           handle)
   (unlit-look       lod-set :inline)
   (lit-look         lod-set :inline))
  (:methods
   (notice-blue (handle) _type_ :state :overlay-at wad)))


(defskelgroup *plat-eco-unlit-sg*
  plat-eco
  plat-eco-lod0-jg
  plat-eco-idle-ja
  ((plat-eco-lod0-mg (meters 20)) (plat-eco-lod1-mg (meters 40)) (plat-eco-lod2-mg (meters 999999)))
  :bounds (static-spherem 0 0 0 3))

(defskelgroup *plat-eco-lit-sg*
  plat-eco
  plat-eco-lod0-jg
  plat-eco-idle-ja
  ((plat-eco-lit-lod0-mg (meters 20)) (plat-eco-lit-lod1-mg (meters 40)) (plat-eco-lit-lod2-mg (meters 999999)))
  :bounds (static-spherem 0 0 0 3))

(defstate plat-idle (plat-eco)
  :virtual #t
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('wake) (go-virtual plat-path-active (the-as plat #f)))
        (('eco-blue) (go-virtual notice-blue (process->handle proc)))
        (('ridden 'edge-grabbed)
         (when (send-event *target* 'query 'powerup (pickup-type eco-blue))
           (send-to-all (-> self link) 'wake)
           (go-virtual plat-path-active (the-as plat #f))))))
  :enter
    (behavior ()
      (lods-assign! (-> self draw) (-> self unlit-look)))
  :trans
    (behavior ()
      (when (and (and *target* (>= (-> self notice-dist) (vector-vector-distance (-> self root trans) (-> *target* control trans))))
                 (send-event *target* 'query 'powerup (pickup-type eco-blue)))
        (send-to-all (-> self link) 'wake)
        (go-virtual plat-path-active (the-as plat #f)))
      (if (and *target* (>= (-> self notice-dist) (vector-vector-distance (-> self root trans) (-> *target* control trans))))
        (level-hint-spawn (text-id misty-eco-plat) "sksp0073" (the-as entity #f) *entity-pool* (game-task none))))
  :code
    (behavior ()
      (ja-post)
      (update-transforms! (-> self root))
      (anim-loop))
  :post ja-post)

(defstate notice-blue (plat-eco)
  :virtual override
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('wake)
         (sound-play "blue-eco-on" :position (the-as symbol (-> self root trans)))
         (go-virtual plat-path-active (the-as plat #f)))
        (('ridden 'edge-grabbed)
         (when (send-event *target* 'query 'powerup (pickup-type eco-blue))
           (send-to-all (-> self link) 'wake)
           (go-virtual plat-path-active (the-as plat #f))))))
  :trans
    (behavior ()
      ((-> (method-of-object self plat-idle) trans))
      (let ((a1-0 (new 'stack-no-clear 'event-message-block)))
        (set! (-> a1-0 from) self)
        (set! (-> a1-0 num-params) 2)
        (set! (-> a1-0 message) 'query)
        (set! (-> a1-0 param 0) (the-as uint 'powerup))
        (set! (-> a1-0 param 1) (the-as uint 3))
        (if (and (not (send-event-function *target* a1-0))
                 (begin
                   (logior! (-> self mask) (process-mask sleep-code))
                   (not (-> self bouncing))))
          (go-virtual plat-idle))))
  :code
    (behavior ((arg0 handle))
      (set! (-> self target) arg0)
      (loop
        (let* ((gp-0 (handle->process (-> self target)))
               (v1-4 (if (and (nonzero? gp-0) (type-type? (-> gp-0 type) process-drawable)) gp-0)))
          (when v1-4
            (let* ((gp-1 (-> (the-as process-drawable v1-4) root))
                   (v1-6 (if (and (nonzero? gp-1) (type-type? (-> gp-1 type) collide-shape)) gp-1)))
              (when v1-6
                (let* ((s5-0 (-> self root root-prim prim-core))
                       (a1-3 (-> (the-as collide-shape v1-6) root-prim prim-core))
                       (f30-0 (vector-vector-distance (the-as vector s5-0) (the-as vector a1-3))))
                  (when (rand-vu-percent? 0.5)
                    (let ((gp-2 (new 'stack-no-clear 'vector)))
                      (set! (-> gp-2 quad) (-> s5-0 world-sphere quad))
                      (dotimes (s5-1 3)
                        (+! (-> gp-2 data s5-1) (rand-vu-float-range -5324.8 5324.8)))
                      (eco-blue-glow gp-2)))
                  (set! (-> self bouncing) #t)
                  (activate! (-> self smush)
                             (lerp-scale (rand-vu-float-range 1.1 1.3)
                                         (rand-vu-float-range 1.0 1.02)
                                         f30-0
                                         (-> *FACT-bank* suck-suck-dist)
                                         (-> *FACT-bank* suck-bounce-dist))
                             60
                             60
                             1.0
                             1.0))))))
        (suspend)))
  :post
    (behavior ()
      (plat-trans)
      (plat-post)))

(defstate plat-path-active (plat-eco)
  :virtual #t
  :enter
    (behavior ((arg0 plat))
      (lods-assign! (-> self draw) (-> self lit-look))
      (sync-now! (-> self sync) (-> self sync-linear-val))
      (set! (-> self sync-offset-faux) (-> self sync offset))
      (let* ((f0-3 (the float (-> self sync period)))
             (f1-1 (/ f0-3 2)))
        (if (< f1-1 (- (-> self sync-offset-dest) (-> self sync-offset-faux))) (+! (-> self sync-offset-faux) f0-3))
        (if (< f1-1 (- (-> self sync-offset-faux) (-> self sync-offset-dest)))
          (set! (-> self sync-offset-faux) (- (-> self sync-offset-faux) f0-3))))
      (cond
        (arg0
         (let ((f0-5 (-> self sync-offset-dest))) (set! (-> self sync offset) f0-5) (set! (-> self sync-offset-faux) f0-5)))
        (else
         (process-entity-status! self (entity-perm-status complete) #t)
         (dotimes (gp-1 5)
           (spawn-projectile-blue *target*)))))
  :trans
    (behavior ()
      (when (!= (-> self sync-offset-faux) (-> self sync-offset-dest))
        (seek! (-> self sync-offset-faux) (-> self sync-offset-dest) (* 12.0 (seconds-per-frame)))
        (let* ((f0-7 (the float (-> self sync period)))
               (f1-3 (+ (-> self sync-offset-faux) f0-7)))
          (set! (-> self sync offset) (- f1-3 (* (the float (the int (/ f1-3 f0-7))) f0-7)))))
      ((-> (method-of-type plat plat-path-active) trans))))

(defmethod baseplat-method-24 ((this plat-eco))
  (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum hit-by-player))))
    (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s5-0 reaction) default-collision-reaction)
    (set! (-> s5-0 no-reaction) (the-as (function collide-shape-moving collide-shape-intersect vector vector none) nothing))
    (alloc-riders s5-0 1)
    (let ((s4-0 (new 'process 'collide-shape-prim-mesh s5-0 (the-as uint 0) (the-as uint 0))))
      (set! (-> s4-0 prim-core collide-as) (collide-kind ground-object blue-eco-suck))
      (set! (-> s4-0 collide-with) (collide-kind target))
      (set! (-> s4-0 prim-core action) (collide-action solid rider-plat-sticky))
      (set! (-> s4-0 prim-core offense) (collide-offense indestructible))
      (set! (-> s4-0 transform-index) 0)
      (set-vector! (-> s4-0 local-sphere) 0.0 -1228.8 0.0 13926.4)
      (set-root-prim! s5-0 s4-0))
    (set! (-> s5-0 nav-radius) (* 0.75 (-> s5-0 root-prim local-sphere w)))
    (backup-collide-with-as s5-0)
    (set! (-> this root) s5-0))
  0
  (none))

(defmethod get-unlit-skel ((this plat-eco))
  *plat-eco-unlit-sg*)

(defmethod get-lit-skel ((this plat-eco))
  *plat-eco-lit-sg*)

(defmethod init-from-entity! ((this plat-eco) (arg0 entity-actor))
  (logior! (-> this mask) (process-mask platform))
  (set! (-> this notice-dist) (res-lump-float arg0 'notice-dist :default -1.0))
  (set! (-> this link) (new 'process 'actor-link-info this))
  (baseplat-method-24 this)
  (process-drawable-from-entity! this arg0)
  (let ((s4-0 (get-unlit-skel this))
        (s5-1 (get-lit-skel this)))
    (initialize-skeleton this s4-0 '())
    (setup-lods! (-> this unlit-look) s4-0 (-> this draw art-group) (-> this entity))
    (setup-lods! (-> this lit-look) s5-1 (-> this draw art-group) (-> this entity)))
  (logclear! (-> this mask) (process-mask actor-pause))
  (update-transforms! (-> this root))
  (set! (-> this part) (create-launch-control (-> *part-group-id-table* 107) this))
  (set! (-> this path) (new 'process 'curve-control this 'path -1000000000.0))
  (logior! (-> this path flags) (path-control-flag display draw-line draw-point draw-text))
  (set! (-> this fact) (new 'process 'fact-info this (pickup-type eco-pill-random) (-> *FACT-bank* default-pill-inc)))
  (load-params! (-> this sync) this (the-as uint 3000) 0.0 0.15 0.15)
  (set! (-> this sync-offset-dest) (-> this sync offset))
  (set! (-> this sync-linear-val) (get-phase-offset (-> this sync)))
  (sync-now! (-> this sync) (-> this sync-linear-val))
  (set! (-> this sync-offset-faux) (-> this sync offset))
  (set! (-> this path-pos) (get-current-phase-with-mirror (-> this sync)))
  (eval-path-curve! (-> this path) (-> this root trans) (-> this path-pos) 'interp)
  (set! (-> this sound-id) (new-sound-id))
  (baseplat-method-26 this)
  (baseplat-method-21 this)
  (if (or (and (-> this entity) (logtest? (-> this entity extra perm status) (entity-perm-status complete)))
          (< (-> this notice-dist) 0.0))
    (go (method-of-object this plat-path-active) (the-as plat #t))
    (go (method-of-object this plat-idle)))
  (none))
