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

;; name: water-anim.gc
;; name in dgo: water-anim
;; dgos: GAME

;; +++wanim-look
(defenum wanim-look
  :type int32
  (nst-lake 0)
  (forb-foresta 1)
  (fora-forestb 2)
  (fora-forestc 3)
  (fora-forestd 4)
  (fora-foreste 5)
  (fora-forestf 6)
  (waspala-thronesec 7)
  (waspala-windowwall 8)
  (waspala-frontthrone 9)
  (waspala-frontwindowwall 10)
  )
;; ---wanim-look


;; DECOMP BEGINS

(deftype water-anim (process-drawable)
  ((water-height         meters)
   (wade-height          meters)
   (swim-height          meters)
   (bottom-height        meters)
   (attack-event         symbol)
   (attack-id            uint32)
   (flow                 flow-control)
   (target               handle)
   (flags                water-flag)
   (look                 wanim-look)
   (play-ambient-sound?  symbol)
   (visible              symbol)
   )
  (:state-methods
    unknown
    idle
    )
  (:methods
    (move-to-point! (_type_ vector) int)
    (get-ripple-height (_type_ vector) float)
    (init-water! (_type_) object)
    (alloc-root! (_type_) none)
    (water-anim-init! (_type_) none)
    (stub (_type_) none)
    (set-offset-and-look! (_type_) none)
    )
  )


(defmethod relocate ((this water-anim) (offset int))
  (if (nonzero? (-> this flow))
      (&+! (-> this flow) offset)
      )
  (call-parent-method this offset)
  )

(defskelgroup skel-water-anim-nst-lake water-anim-nst water-anim-nst-lake-lod0-jg -1
              ((water-anim-nst-lake-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 300)
              )

(defskelgroup skel-water-anim-forb-foresta water-anim-forb 0 -1
              ((1 (meters 999999)))
              :bounds (static-spherem 0 0 0 500)
              )

(defskelgroup skel-water-anim-fora-forestb water-anim-fora 0 -1
              ((1 (meters 999999)))
              :bounds (static-spherem 0 0 0 500)
              )

(defskelgroup skel-water-anim-fora-forestc water-anim-fora 2 -1
              ((3 (meters 999999)))
              :bounds (static-spherem 0 0 0 500)
              )

(defskelgroup skel-water-anim-fora-forestd water-anim-fora 4 -1
              ((5 (meters 999999)))
              :bounds (static-spherem 0 0 0 500)
              )

(defskelgroup skel-water-anim-fora-foreste water-anim-fora 6 -1
              ((7 (meters 999999)))
              :bounds (static-spherem 0 0 0 500)
              )

(defskelgroup skel-water-anim-fora-forestf water-anim-fora 8 -1
              ((9 (meters 999999)))
              :bounds (static-spherem 0 0 0 500)
              )

(defskelgroup skel-water-anim-waspala-thronesec water-anim-waspala water-anim-waspala-thronesec-lod0-jg -1
              ((water-anim-waspala-thronesec-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 500)
              )

(defskelgroup skel-water-anim-waspala-windowwall water-anim-waspala water-anim-waspala-windowwall-lod0-jg -1
              ((water-anim-waspala-windowwall-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 500)
              )

(defskelgroup skel-water-anim-waspala-frontthrone water-anim-waspala water-anim-waspala-frontthrone-lod0-jg -1
              ((water-anim-waspala-frontthrone-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 500)
              )

(defskelgroup skel-water-anim-waspala-frontwindowwall water-anim-waspala water-anim-waspala-frontwindowwall-lod0-jg -1
              ((water-anim-waspala-frontwindowwall-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 500)
              )

(deftype water-anim-look (structure)
  ((skel-group          string)
   (anim                int32)
   (ambient-sound-spec  sound-spec)
   )
  )


(define *water-anim-look*
  (new 'static 'boxed-array :type water-anim-look
    (new 'static 'water-anim-look :skel-group "water-anim-nst-lake" :anim 2 :ambient-sound-spec #f)
    (new 'static 'water-anim-look :skel-group "water-anim-forb-foresta" :anim 2 :ambient-sound-spec #f)
    (new 'static 'water-anim-look :skel-group "water-anim-fora-forestb" :anim 10 :ambient-sound-spec #f)
    (new 'static 'water-anim-look :skel-group "water-anim-fora-forestc" :anim 10 :ambient-sound-spec #f)
    (new 'static 'water-anim-look :skel-group "water-anim-fora-forestd" :anim 10 :ambient-sound-spec #f)
    (new 'static 'water-anim-look :skel-group "water-anim-fora-foreste" :anim 10 :ambient-sound-spec #f)
    (new 'static 'water-anim-look :skel-group "water-anim-fora-forestf" :anim 10 :ambient-sound-spec #f)
    (new 'static 'water-anim-look :skel-group "water-anim-waspala-thronesec" :anim 8 :ambient-sound-spec #f)
    (new 'static 'water-anim-look :skel-group "water-anim-waspala-windowwall" :anim 8 :ambient-sound-spec #f)
    (new 'static 'water-anim-look :skel-group "water-anim-waspala-frontthrone" :anim 8 :ambient-sound-spec #f)
    (new 'static 'water-anim-look :skel-group "water-anim-waspala-frontwindowwall" :anim 8 :ambient-sound-spec #f)
    )
  )

(defbehavior water-anim-event-handler water-anim ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  (local-vars (v0-1 object))
  (case arg2
    (('move-to)
     (move-to-point! self (the-as vector (-> arg3 param 0)))
     (set! v0-1 (logclear (-> self mask) (process-mask sleep-code)))
     (set! (-> self mask) (the-as process-mask v0-1))
     v0-1
     )
    (('move-to-y)
     (let ((a1-2 (new 'stack-no-clear 'vector)))
       (vector-copy! a1-2 (-> self root trans))
       (set! (-> a1-2 y) (the-as float (-> arg3 param 0)))
       (move-to-point! self a1-2)
       )
     (set! v0-1 (logclear (-> self mask) (process-mask sleep-code)))
     (set! (-> self mask) (the-as process-mask v0-1))
     v0-1
     )
    (('water)
     (let ((s5-0 (the-as object (-> arg3 param 0)))
           (gp-0 (as-type (-> arg3 param 1) process-focusable))
           )
       (when (and (logtest? (-> self flags) (water-flag deadly))
                  (logtest? (water-flag touch-water) (-> (the-as water-info s5-0) flags))
                  (the-as uint gp-0)
                  )
         (let ((v1-15 (-> self attack-event)))
           (case v1-15
             ((#f)
              )
             (('heat)
              (send-event (the-as process-tree gp-0) 'heat (* 10.0 (seconds-per-frame)))
              )
             (('drown-death 'lava 'dark-eco-pool)
              (if (and (not (focus-test? (the-as process-focusable gp-0) board))
                       (send-event
                         (the-as process-tree gp-0)
                         'attack-invinc
                         #f
                         (static-attack-info
                           :mask (vehicle-impulse-factor)
                           ((id (-> self attack-id)) (damage 2.0) (vehicle-damage-factor 1.0) (vehicle-impulse-factor 1.0) (mode v1-15))
                           )
                         )
                       )
                  (send-event self 'notify 'attack)
                  )
              )
             (else
               (if (and (not (focus-test? (the-as process-focusable gp-0) board))
                        (send-event
                          (the-as process-tree gp-0)
                          'attack
                          #f
                          (static-attack-info
                            :mask (vehicle-impulse-factor)
                            ((id (-> self attack-id)) (damage 2.0) (vehicle-damage-factor 1.0) (vehicle-impulse-factor 1.0) (mode v1-15))
                            )
                          )
                        )
                   (send-event self 'notify 'attack)
                   )
               )
             )
           )
         )
       (when (and (logtest? (-> self flags) (water-flag flow))
                  (logtest? (water-flag touch-water) (-> (the-as water-info s5-0) flags))
                  )
         (let ((a0-40 (-> self flow)))
           (if (nonzero? a0-40)
               (push-process a0-40 (the-as process-focusable gp-0))
               )
           )
         )
       )
     )
    (('visible)
     (cond
       ((-> arg3 param 0)
        (set! (-> self visible) #t)
        )
       (else
         (set! (-> self visible) #f)
         (logior! (-> self draw status) (draw-control-status no-draw))
         )
       )
     (logclear! (-> self mask) (process-mask sleep-code))
     #t
     )
    )
  )

(defstate idle (water-anim)
  :virtual #t
  :event water-anim-event-handler
  :trans (behavior ()
    (let ((a0-0 (-> self flow)))
      (if (and (nonzero? a0-0) *display-vol-marks*)
          (draw-path a0-0)
          )
      )
    (cond
      ((not (-> self visible))
       )
      ((< (-> (math-camera-pos) y) (+ -8192.0 (-> self root trans y)))
       (logior! (-> self draw status) (draw-control-status no-draw))
       )
      (else
        (logclear! (-> self draw status) (draw-control-status no-draw))
        )
      )
    (if (and (-> self visible) (and (-> self play-ambient-sound?) (nonzero? (-> self sound))))
        (update! (-> self sound))
        )
    )
  :code (behavior ()
    (until #f
      (ja-post)
      (logior! (-> self mask) (process-mask sleep-code))
      (suspend)
      )
    #f
    )
  )

(defmethod move-to-point! ((this water-anim) (arg0 vector))
  (vector-copy! (-> this root trans) arg0)
  (set! (-> this water-height) (-> this root trans y))
  (if (nonzero? (-> this sound))
      (update-trans! (-> this sound) (-> this root trans))
      )
  )

(defmethod get-ripple-height ((this water-anim) (arg0 vector))
  (ripple-find-height this 0 arg0)
  )

;; WARN: Return type mismatch symbol vs none.
(defmethod stub ((this water-anim))
  (none)
  )

;; WARN: Return type mismatch quaternion vs none.
(defmethod set-offset-and-look! ((this water-anim))
  (local-vars (sv-16 res-tag))
  (set! (-> this play-ambient-sound?) #t)
  (set! (-> this visible) #t)
  (set! (-> this look)
        (res-lump-value (-> this entity) 'look wanim-look :default (the-as uint128 -1) :time -1000000000.0)
        )
  (set! sv-16 (new 'static 'res-tag))
  (let ((v1-4 (res-lump-data (-> this entity) 'trans-offset vector :tag-ptr (& sv-16))))
    (when v1-4
      (+! (-> this root trans x) (-> v1-4 x))
      (+! (-> this root trans y) (-> v1-4 y))
      (+! (-> this root trans z) (-> v1-4 z))
      )
    )
  (let ((f0-6 (res-lump-float (-> this entity) 'rotoffset)))
    (if (!= f0-6 0.0)
        (quaternion-rotate-y! (-> this root quat) (-> this root quat) f0-6)
        )
    )
  (none)
  )

;; WARN: Return type mismatch none vs object.
(defmethod init-water! ((this water-anim))
  (let ((s5-0 (-> this look)))
    (if (or (< (the-as int s5-0) 0) (>= (the-as int s5-0) (-> *water-anim-look* length)))
        (go process-drawable-art-error "skel group")
        )
    (let ((s5-1 (-> *water-anim-look* s5-0)))
      (initialize-skeleton-by-name this (-> s5-1 skel-group))
      (ja-channel-set! 1)
      (let ((s4-0 (-> this skel root-channel 0)))
        (joint-control-channel-group-eval!
          s4-0
          (the-as art-joint-anim (-> this draw art-group data (-> s5-1 anim)))
          num-func-identity
          )
        (set! (-> s4-0 frame-num) 0.0)
        )
      (let ((a2-1 (-> s5-1 ambient-sound-spec)))
        (when a2-1
          (let ((a3-0 (new 'stack-no-clear 'vector)))
            (vector+! a3-0 (-> this root trans) (-> this draw bounds))
            (set! (-> this sound) (new 'process 'ambient-sound a2-1 a3-0 0.0))
            )
          )
        )
      )
    )
  (ja-post)
  )

;; WARN: Return type mismatch trsqv vs none.
(defmethod alloc-root! ((this water-anim))
  (set! (-> this root) (new 'process 'trsqv))
  (none)
  )

;; WARN: Return type mismatch water-flag vs none.
(defmethod water-anim-init! ((this water-anim))
  (local-vars (sv-16 res-tag))
  (set! (-> this attack-event) (the-as symbol ((method-of-type res-lump get-property-struct)
                                               (-> this entity)
                                               'attack-event
                                               'interp
                                               -1000000000.0
                                               (the-as structure 'drown)
                                               (the-as (pointer res-tag) #f)
                                               *res-static-buf*
                                               )
                                       )
        )
  (process-drawable-from-entity! this (-> this entity))
  (logclear! (-> this mask) (process-mask actor-pause))
  (set! (-> this vol) (new 'process 'vol-control this))
  (logior! (-> this vol flags) (vol-flags display? vol-flags-1))
  (set! (-> this bottom-height) 32768.0)
  (let* ((v1-8 *game-info*)
         (a0-7 (+ (-> v1-8 attack-id) 1))
         )
    (set! (-> v1-8 attack-id) a0-7)
    (set! (-> this attack-id) a0-7)
    )
  (set! (-> this target) (the-as handle #f))
  (set! sv-16 (new 'static 'res-tag))
  (let ((v1-10 (the-as (pointer float) ((method-of-type res-lump get-property-data)
                                        (-> this entity)
                                        'water-height
                                        'exact
                                        -1000000000.0
                                        (the-as pointer #f)
                                        (& sv-16)
                                        *res-static-buf*
                                        )
                       )
               )
        )
    (when v1-10
      (set! (-> this water-height) (-> v1-10 0))
      (set! (-> this wade-height) (-> v1-10 1))
      (set! (-> this swim-height) (-> v1-10 2))
      (if (>= (-> sv-16 elt-count) (the-as uint 4))
          (set! (-> this flags) (the-as water-flag (the int (-> v1-10 3))))
          )
      (if (>= (-> sv-16 elt-count) (the-as uint 5))
          (set! (-> this bottom-height) (-> v1-10 4))
          )
      )
    )
  (logior! (-> this flags) (water-flag part-water))
  (if (logtest? (-> this flags) (water-flag flow))
      (set! (-> this flow) (new 'process 'flow-control this (the-as res-lump #f)))
      )
  (cond
    ((zero? (-> this flags))
     (if (< 0.0 (-> this wade-height))
         (logior! (-> this flags) (water-flag can-wade))
         )
     (if (< 0.0 (-> this swim-height))
         (logior! (-> this flags) (water-flag can-swim))
         )
     )
    (else
      )
    )
  (none)
  )

(defbehavior water-anim-init-by-other water-anim ((arg0 entity-actor))
  (process-entity-set! self arg0)
  (stub self)
  (alloc-root! self)
  (water-anim-init! self)
  (set-offset-and-look! self)
  (init-water! self)
  (go-virtual idle)
  )

(defmethod init-from-entity! ((this water-anim) (arg0 entity-actor))
  "Set up a newly created process from the entity that created it."
  (stub this)
  (alloc-root! this)
  (water-anim-init! this)
  (set-offset-and-look! this)
  (init-water! this)
  (go (method-of-object this idle))
  )
