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

;; name: fortress-obs.gc
;; name in dgo: fortress-obs
;; dgos: FEB, FDB

;; DECOMP BEGINS

(deftype fort-trap-door (process-drawable)
  ((root          collide-shape-moving :override)
   (notify-actor  entity-actor)
   )
  (:state-methods
    idle
    die
    )
  )


(defskelgroup skel-fort-trap-door fort-trap-door fort-trap-door-lod0-jg fort-trap-door-idle-ja
              ((fort-trap-door-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 5)
              )

(defskelgroup skel-fort-trap-door-explode fort-trap-door fort-trap-door-explode-lod0-jg fort-trap-door-explode-idle-ja
              ((fort-trap-door-explode-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 15)
              )

(define *fort-trap-door-exploder-params*
  (new 'static 'joint-exploder-static-params
    :joints (new 'static 'boxed-array :type joint-exploder-static-joint-params
      (new 'static 'joint-exploder-static-joint-params :joint-index 4 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 5 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 6 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 7 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 8 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 9 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 10 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 11 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 12 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 13 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 14 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 15 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 16 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 17 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 18 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 19 :parent-joint-index -1)
      (new 'static 'joint-exploder-static-joint-params :joint-index 20 :parent-joint-index -1)
      )
    :collide-spec #x1
    )
  )

(defstate idle (fort-trap-door)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('attack)
       (when (logtest? (-> (the-as attack-info (-> block param 1)) penetrate-using) (penetrate flop))
         (go-virtual die)
         #f
         )
       )
      )
    )
  :code sleep-code
  )

(defstate die (fort-trap-door)
  :virtual #t
  :enter (behavior ()
    (let ((root-prim (-> self root root-prim)))
      (set! (-> root-prim prim-core collide-as) (collide-spec))
      (set! (-> root-prim prim-core collide-with) (collide-spec))
      )
    0
    (sound-play "trapdoor")
    (let ((evt (new 'stack-no-clear 'event-message-block)))
      (set! (-> evt from) (process->ppointer self))
      (set! (-> evt num-params) 0)
      (set! (-> evt message) 'trigger)
      (let ((func send-event-function)
            (actor (-> self notify-actor))
            )
        (func
          (if actor
              (-> actor extra process)
              )
          evt
          )
        )
      )
    )
  :code (behavior ()
    ((lambda ()
       (with-pp
         (sound-play "wcrate-break")
         (let ((exploder-tuning (new 'stack 'joint-exploder-tuning (the-as uint 1))))
           (let* ((target *target*)
                  (target-proc (if (type? target process-focusable)
                                   target
                                   )
                               )
                  )
             (when target-proc
               (set! (-> exploder-tuning fountain-rand-transv-lo quad) (-> (get-trans target-proc 0) quad))
               (+! (-> exploder-tuning fountain-rand-transv-lo y) -16384.0)
               )
             )
           (set! (-> exploder-tuning fountain-rand-transv-hi x) 24576.0)
           (set! (-> exploder-tuning fountain-rand-transv-hi y) 81920.0)
           (set! (-> exploder-tuning fountain-rand-transv-hi z) 12288.0)
           (set! (-> exploder-tuning fountain-rand-transv-hi w) 32768.0)
           (process-spawn
             joint-exploder
             (art-group-get-by-name *level* "skel-fort-trap-door-explode" (the-as (pointer uint32) #f))
             5
             exploder-tuning
             *fort-trap-door-exploder-params*
             :to pp
             )
           )
         )
       )
     )
    (suspend)
    (ja-channel-set! 0)
    (suspend-for (seconds 1))
    (send-event self 'death-end)
    (while (-> self child)
      (suspend)
      )
    (cleanup-for-death self)
    )
  :post ja-post
  )

;; WARN: Return type mismatch object vs none.
(defmethod init-from-entity! ((this fort-trap-door) (entity 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"
  (let ((cshape (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player))))
    (let ((prim-mesh (new 'process 'collide-shape-prim-mesh cshape (the-as uint 0) (the-as uint 0))))
      (set! (-> prim-mesh prim-core collide-as) (collide-spec obstacle))
      (set! (-> prim-mesh prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> prim-mesh prim-core action) (collide-action solid))
      (set! (-> prim-mesh transform-index) 0)
      (set-vector! (-> prim-mesh local-sphere) 0.0 0.0 0.0 20480.0)
      (set! (-> cshape total-prims) (the-as uint 1))
      (set! (-> cshape root-prim) prim-mesh)
      )
    (set! (-> cshape nav-radius) (* 0.75 (-> cshape root-prim local-sphere w)))
    (let ((root-prim (-> cshape root-prim)))
      (set! (-> cshape backup-collide-as) (-> root-prim prim-core collide-as))
      (set! (-> cshape backup-collide-with) (-> root-prim prim-core collide-with))
      )
    (set! (-> this root) (the-as collide-shape-moving cshape))
    )
  (set! (-> (the-as collide-shape-moving (-> this root)) penetrated-by) (penetrate flop))
  (process-drawable-from-entity! this entity)
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-fort-trap-door" (the-as (pointer uint32) #f)))
    (the-as pair 0)
    )
  (set! (-> this notify-actor) (entity-actor-lookup entity 'alt-actor 0))
  (let ((channel (-> this skel root-channel 0)))
    (set! (-> channel frame-group) (the-as art-joint-anim (-> this draw art-group data 2)))
    (set! (-> channel frame-num) 0.0)
    (joint-control-channel-group!
      channel
      (the-as art-joint-anim (-> this draw art-group data 2))
      num-func-identity
      )
    )
  (transform-post)
  (go (method-of-object this idle))
  (none)
  )

(deftype water-anim-fortress (water-anim)
  ()
  )


(define ripple-for-water-anim-fortress (new 'static 'ripple-wave-set
                                         :count 3
                                         :converted #f
                                         :normal-scale 1.0
                                         :wave (new 'static 'inline-array ripple-wave 4
                                           (new 'static 'ripple-wave :scale 40.0 :xdiv 1 :speed 1.5)
                                           (new 'static 'ripple-wave :scale 40.0 :xdiv -1 :zdiv 1 :speed 1.5)
                                           (new 'static 'ripple-wave :scale 20.0 :xdiv 5 :zdiv 3 :speed 0.75)
                                           (new 'static 'ripple-wave)
                                           )
                                         )
        )

;; WARN: Return type mismatch ripple-wave-set vs none.
(defmethod init-water! ((this water-anim-fortress))
  "Initialize a [[water-anim]]'s default settings, this may include applying a [[riple-control]]"
  (let ((parent-method (method-of-type water-anim init-water!)))
    (parent-method this)
    )
  (let ((ripple (new 'process 'ripple-control)))
    (set! (-> this draw ripple) ripple)
    (set-vector! (-> this draw color-mult) 0.01 0.45 0.5 0.75)
    (set! (-> ripple global-scale) 3072.0)
    (set! (-> ripple close-fade-dist) 163840.0)
    (set! (-> ripple far-fade-dist) 245760.0)
    (set! (-> ripple waveform) ripple-for-water-anim-fortress)
    )
  (none)
  )
