;;-*-Lisp-*-
(in-package goal)
(bundles "MAI.DGO")
(require "engine/gfx/shadow/shadow.gc")
(require "levels/maincave/cavecrystal-light.gc")
(require "engine/physics/trajectory.gc")
(require "engine/common-obs/process-drawable.gc")
(require "engine/nav/navigate-h.gc")

;; DECOMP BEGINS

(deftype mother-spider-egg (process-drawable)
  ((root               collide-shape-moving :override)
   (parent-override    (pointer mother-spider) :overlay-at parent)
   (anim-speed         float)
   (part2              sparticle-launch-control)
   (falling-start-time time-frame)
   (fall-dest          vector :inline)
   (fall-dest-normal   vector :inline)
   (broken-look        lod-set :inline)
   (traj               trajectory :inline)
   (shadow-pos         vector :inline))
  (:methods
   (mother-spider-egg-method-20 (_type_) none)
   (draw-egg-shadow (_type_ vector symbol) symbol))
  (:states
   mother-spider-egg-die
   mother-spider-egg-die-exit
   mother-spider-egg-die-while-falling
   mother-spider-egg-falling
   mother-spider-egg-hatch
   mother-spider-egg-on-ground))


(defskelgroup *mother-spider-egg-unbroken-sg*
  spider-egg
  spider-egg-unbroken-lod0-jg
  -1
  ((spider-egg-unbroken-lod0-mg (meters 20))
   (spider-egg-unbroken-lod1-mg (meters 40))
   (spider-egg-unbroken-lod2-mg (meters 999999)))
  :bounds (static-spherem 0 1 0 2)
  :shadow spider-egg-unbroken-shadow-mg)

(defskelgroup *mother-spider-egg-broken-sg*
  spider-egg
  spider-egg-broken-lod0-jg
  -1
  ((spider-egg-broken-lod0-mg (meters 20))
   (spider-egg-broken-lod1-mg (meters 40))
   (spider-egg-broken-lod2-mg (meters 999999)))
  :bounds (static-spherem 0 1 0 2))

(defpartgroup group-spider-egg-hatches
  :id 324
  :duration (seconds 0.017)
  :linger-duration (seconds 3)
  :flags (use-local-clock)
  :bounds (static-bspherem 0 0 0 8)
  :parts
  ((sp-item 2018 :fade-after (meters 50) :falloff-to (meters 50))
   (sp-item 2071 :fade-after (meters 50) :falloff-to (meters 50))))

(defpart 2071
  :init-specs
  ((:texture (hotdot effects))
   (:num 16.0)
   (:y (meters 0.5))
   (:scale-x (meters 0.1))
   (:rot-x 4)
   (:rot-z (degrees 0) (degrees 360))
   (:scale-y (meters 0.1))
   (:r 255.0)
   (:g 64.0)
   (:b 255.0)
   (:a 32.0 96.0)
   (:timer (seconds 0.75))
   (:flags (bit2 bit3))
   (:next-time (seconds 0.25))
   (:next-launcher 2072)))

(defpart 2072
  :init-specs ((:scale-x (meters 0.1)) (:scale-y (meters 2)) (:scalevel-y (meters 0.2)) (:fade-a -1.4222223)))

(defpart 2018
  :init-specs
  ((:texture (bigpuff effects))
   (:num 8.0)
   (:y (meters 0.5) (meters 0.5))
   (:scale-x (meters 0.5) (meters 1))
   (:rot-z (degrees 0) (degrees 360))
   (:scale-y :copy scale-x)
   (:r 32.0 32.0)
   (:g 0.0 16.0)
   (:b 32.0 32.0)
   (:a 0.0)
   (:vel-y (meters 0.0033333334) (meters 0.0033333334))
   (:scalevel-x (meters 0.006666667))
   (:rotvel-z (degrees -1.2) (degrees 1.2))
   (:scalevel-y :copy scalevel-x)
   (:fade-a 1.4222223)
   (:accel-y (meters 0.00006666667))
   (:timer (seconds 1.25))
   (:flags (bit2 bit12 bit14))
   (:next-time (seconds 0.15))
   (:next-launcher 2073)
   (:conerot-x (degrees 90))
   (:conerot-y (degrees 0) (degrees 360))
   (:conerot-radius (meters 0) (meters 0.5))))

(defpart 2073
  :init-specs ((:fade-a -0.21333334)))

(defpartgroup group-spider-egg-explodes
  :id 325
  :duration (seconds 0.017)
  :linger-duration (seconds 1.25)
  :flags (use-local-clock)
  :bounds (static-bspherem 0 0 0 8)
  :parts ((sp-item 2074 :fade-after (meters 50) :falloff-to (meters 50))))

(defpart 2074
  :init-specs
  ((:texture (bigpuff effects))
   (:num 8.0)
   (:y (meters 0.5) (meters 0.5))
   (:scale-x (meters 1.5) (meters 2))
   (:rot-z (degrees 0) (degrees 360))
   (:scale-y :copy scale-x)
   (:r 32.0 32.0)
   (:g 0.0 16.0)
   (:b 32.0 32.0)
   (:a 32.0 32.0)
   (:vel-y (meters 0.0033333334) (meters 0.0033333334))
   (:scalevel-x (meters 0.006666667))
   (:rotvel-z (degrees -1.2) (degrees 1.2))
   (:scalevel-y :copy scalevel-x)
   (:fade-a -1.4222223)
   (:accel-y (meters 0.00006666667))
   (:timer (seconds 1.25))
   (:flags (bit2 bit12 bit14))
   (:conerot-x (degrees 90))
   (:conerot-y (degrees 0) (degrees 360))
   (:conerot-radius (meters 0) (meters 0.5))))

(defmethod draw-egg-shadow ((this mother-spider-egg) (arg0 vector) (arg1 symbol))
  (cond
    ((and (-> this draw shadow) (zero? (-> this draw cur-lod)) (logtest? (-> this draw status) (draw-status was-drawn)))
     (let ((s5-0 (new 'stack-no-clear 'collide-tri-result))
           (a1-1 (new 'stack-no-clear 'vector))
           (a2-1 (new 'stack-no-clear 'vector)))
       (set! (-> a1-1 quad) (-> this root trans quad))
       (+! (-> a1-1 y) 1228.8)
       (set-vector! a2-1 0.0 -61440.0 0.0 1.0)
       (cond
         ((>= (fill-and-probe-using-line-sphere *collide-cache*
                                                a1-1
                                                a2-1
                                                7372.8
                                                (collide-kind background)
                                                this
                                                s5-0
                                                (new 'static 'pat-surface :noentity #x1))
              0.0)
          (let ((v1-11 (-> this draw shadow-ctrl))) (logclear! (-> v1-11 settings flags) (shadow-flags disable-draw)))
          0
          (let ((v1-14 (-> this draw shadow-ctrl))) (set! (-> v1-14 settings bot-plane w) (- (+ -4096.0 (-> s5-0 intersect y)))))
          0
          (let ((v1-17 (-> this draw shadow-ctrl))) (set! (-> v1-17 settings top-plane w) (- (+ 6144.0 (-> s5-0 intersect y)))))
          0
          (return #t))
         (else (let ((v1-22 (-> this draw shadow-ctrl))) (logior! (-> v1-22 settings flags) (shadow-flags disable-draw))) 0))))
    (else (let ((v1-25 (-> this draw shadow-ctrl))) (logior! (-> v1-25 settings flags) (shadow-flags disable-draw))) 0))
  #f)

(defstate mother-spider-egg-falling (mother-spider-egg)
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('touch 'attack) (go mother-spider-egg-die-while-falling))))
  :enter
    (behavior ()
      (set-time! (-> self falling-start-time)))
  :trans
    (behavior ()
      (let ((f30-0 (fmin (the float (- (current-time) (-> self falling-start-time))) (-> self traj time))))
        (let ((f28-0 (/ f30-0 (-> self traj time))))
          (eval-position! (-> self traj) f30-0 (-> self root trans))
          (let ((f0-3 (lerp 0.3 0.4 f28-0))) (set-vector! (-> self root scale) f0-3 f0-3 f0-3 1.0)))
        (when (= f30-0 (-> self traj time))
          (sound-play "eggs-lands")
          (go mother-spider-egg-on-ground)))
      (draw-egg-shadow self (-> self shadow-pos) #t))
  :code
    (behavior ()
      (ja-channel-push! 1 0)
      (loop
        (ja-no-eval :group! spider-egg-idle-ja :num! (seek! max (-> self anim-speed)) :frame-num 0.0)
        (until (ja-done? 0)
          (suspend)
          (ja :num! (seek! max (-> self anim-speed))))))
  :post transform-post)

(defstate mother-spider-egg-on-ground (mother-spider-egg)
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('touch) (send-shove-back (-> self root) proc (the-as touching-shapes-entry (-> block param 0)) 0.7 6144.0 16384.0))
        (('attack) (go mother-spider-egg-die))))
  :enter
    (behavior ()
      (set-time! (-> self state-time))
      (if (not (draw-egg-shadow self (-> self shadow-pos) #t)) (set! (-> self shadow-pos quad) (-> self fall-dest quad))))
  :trans
    (behavior ()
      (if (time-elapsed? (-> self state-time) (seconds 2)) (go mother-spider-egg-hatch))
      (draw-egg-shadow self (-> self shadow-pos) #f))
  :code
    (behavior ()
      (ja-channel-push! 1 (seconds 0.1))
      (let ((gp-0 (new 'stack-no-clear 'quaternion))
            (s5-0 (new 'stack-no-clear 'quaternion)))
        (let ((s3-0 (new 'stack-no-clear 'vector))
              (s4-0 (new 'stack-no-clear 'vector)))
          (quaternion-copy! gp-0 (-> self root quat))
          (set-vector! s4-0 0.0 1.0 0.0 1.0)
          (set! (-> s3-0 quad) (-> self fall-dest-normal quad))
          (vector-normalize! s3-0 1.0)
          (quaternion-from-two-vectors! s5-0 s4-0 s3-0))
        (quaternion*! s5-0 s5-0 gp-0)
        (ja-no-eval :group! spider-egg-bounce-ja :num! (seek! max 1.3) :frame-num 0.0)
        (until (ja-done? 0)
          (let* ((f0-8 (ja-frame-num 0))
                 (v1-19 (ja-group))
                 (f0-9 (/ f0-8 (the float (+ (-> v1-19 data 0 length) -1)))))
            (quaternion-slerp! (-> self root quat) gp-0 s5-0 f0-9))
          (suspend)
          (ja :num! (seek! max 1.3))))
      (loop
        (ja-no-eval :group! spider-egg-idle-ja :num! (seek! max (-> self anim-speed)) :frame-num 0.0)
        (until (ja-done? 0)
          (suspend)
          (ja :num! (seek! max (-> self anim-speed))))))
  :post transform-post)

(defstate mother-spider-egg-hatch (mother-spider-egg)
  :trans
    (behavior ()
      (when (and (zero? (-> self draw cur-lod)) (logtest? (-> self draw status) (draw-status was-drawn)))
        (let ((a1-0 (new 'stack-no-clear 'vector)))
          (set! (-> a1-0 quad) (-> self fall-dest quad))
          (compute-and-draw-shadow (-> self root trans)
                                   a1-0
                                   (-> self fall-dest-normal)
                                   (the-as vector 7372.8)
                                   81920.0
                                   (the-as float 0)))))
  :code
    (behavior ()
      (send-event (ppointer->process (-> self parent-override)) 'trigger)
      (clear-collide-with-as (-> self root))
      (process-spawn part-tracker
                     :init
                     part-tracker-init
                     group-spider-egg-hatches
                     -1
                     #f
                     #f
                     #f
                     (-> self root trans)
                     :to
                     *entity-pool*)
      (lods-assign! (-> self draw) (-> self broken-look))
      (ja-channel-push! 1 (seconds 0.2))
      (ja-no-eval :group! spider-egg-crack-ja :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!)))
      (let ((v1-37 (-> self draw shadow-ctrl))) (logior! (-> v1-37 settings flags) (shadow-flags disable-draw)))
      0
      (go mother-spider-egg-die-exit))
  :post transform-post)

(defstate mother-spider-egg-die (mother-spider-egg)
  :code
    (behavior ()
      (logclear! (-> self mask) (process-mask actor-pause))
      (let ((v1-3 (-> self draw shadow-ctrl))) (logior! (-> v1-3 settings flags) (shadow-flags disable-draw)))
      0
      (lods-assign! (-> self draw) (-> self broken-look))
      (ja-channel-push! 1 (seconds 0.1))
      (clear-collide-with-as (-> self root))
      (process-spawn part-tracker
                     :init
                     part-tracker-init
                     group-spider-egg-explodes
                     -1
                     #f
                     #f
                     #f
                     (-> self root trans)
                     :to
                     *entity-pool*)
      (ja-no-eval :group! spider-egg-die-ja :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!)))
      (go mother-spider-egg-die-exit))
  :post ja-post)

(defstate mother-spider-egg-die-while-falling (mother-spider-egg)
  :trans
    (behavior ()
      (let ((f0-2 (fmin (the float (- (current-time) (-> self falling-start-time))) (-> self traj time))))
        (eval-position! (-> self traj) f0-2 (-> self root trans))))
  :code
    (behavior ()
      (logclear! (-> self mask) (process-mask actor-pause))
      (clear-collide-with-as (-> self root))
      (let ((v1-5 (-> self draw shadow-ctrl))) (logior! (-> v1-5 settings flags) (shadow-flags disable-draw)))
      0
      (process-spawn part-tracker
                     :init
                     part-tracker-init
                     group-spider-egg-explodes
                     -1
                     #f
                     #f
                     #f
                     (-> self root trans)
                     :to
                     *entity-pool*)
      (lods-assign! (-> self draw) (-> self broken-look))
      (ja-channel-push! 1 (seconds 0.1))
      (ja-no-eval :group! spider-egg-die-ja :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!)))
      (go mother-spider-egg-die-exit))
  :post ja-post)

(defstate mother-spider-egg-die-exit (mother-spider-egg)
  :code
    (behavior ()
      (send-event (ppointer->process (-> self parent-override)) 'untrigger)
      (logior! (-> self draw status) (draw-status hidden))
      (let ((v1-8 (-> self draw shadow-ctrl))) (logior! (-> v1-8 settings flags) (shadow-flags disable-draw)))
      0
      (logclear! (-> self root nav-flags) (nav-flags navf0))
      (logclear! (-> self root nav-flags) (nav-flags navf1))
      (clear-collide-with-as (-> self root))
      (until (not (-> self child))
        (suspend))))

(defbehavior mother-spider-egg-init-by-other mother-spider-egg ((arg0 entity-actor) (arg1 vector) (arg2 vector) (arg3 vector))
  (set! (-> self entity) arg0)
  (set! (-> self anim-speed) (rand-vu-float-range 0.8 1.2))
  (set-time! (-> self falling-start-time))
  (set! (-> self fall-dest quad) (-> arg2 quad))
  (set! (-> self fall-dest-normal quad) (-> arg3 quad))
  (let ((s4-1 (new 'process 'collide-shape-moving self (collide-list-enum usually-hit-by-player))))
    (set! (-> s4-1 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s4-1 reaction) default-collision-reaction)
    (set! (-> s4-1 no-reaction) (the-as (function collide-shape-moving collide-shape-intersect vector vector none) nothing))
    (let ((s3-0 (new 'process 'collide-shape-prim-sphere s4-1 (the-as uint 0))))
      (set! (-> s3-0 prim-core collide-as) (collide-kind enemy))
      (set! (-> s3-0 collide-with) (collide-kind target))
      (set! (-> s3-0 prim-core action) (collide-action solid))
      (set! (-> s3-0 prim-core offense) (collide-offense touch))
      (set-vector! (-> s3-0 local-sphere) 0.0 2048.0 0.0 3686.4)
      (set-root-prim! s4-1 s3-0))
    (set! (-> s4-1 nav-radius) 4096.0)
    (backup-collide-with-as s4-1)
    (set! (-> self root) s4-1))
  (set! (-> self root trans quad) (-> arg1 quad))
  (set-vector! (-> self root scale) 0.3 0.3 0.3 1.0)
  (quaternion-copy! (-> self root quat) (-> self parent-override 0 root quat))
  (logior! (-> self mask) (process-mask actor-pause))
  (logior! (-> self mask) (process-mask enemy))
  (logior! (-> self mask) (process-mask attackable))
  (initialize-skeleton self *mother-spider-egg-unbroken-sg* '())
  (setup-lods! (-> self broken-look) *mother-spider-egg-broken-sg* (-> self draw art-group) (-> self entity))
  (set! (-> self draw shadow-ctrl) (new 'process 'shadow-control 0.0 0.0 614400.0 (the-as float 60) 245760.0))
  (set! (-> self nav) (new 'process 'nav-control (-> self root) 16 40960.0))
  (logior! (-> self nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7))
  (logclear! (-> self root nav-flags) (nav-flags navf0))
  (logior! (-> self root nav-flags) (nav-flags navf1))
  (set! (-> self nav extra-nav-sphere quad) (-> self fall-dest quad))
  (set! (-> self nav extra-nav-sphere w) 4096.0)
  (setup-from-to-height! (-> self traj) (-> self root trans) arg2 4096.0 -4.551111)
  (create-connection! *cavecrystal-light-control*
                      self
                      (-> self entity)
                      (the-as (function object object object object object) cavecrystal-light-control-default-callback)
                      -1
                      4096.0)
  (go mother-spider-egg-falling)
  (none))
