;;-*-Lisp-*-
(in-package goal)
(bundles "VI3.DGO")
(require "engine/gfx/shadow/shadow-cpu.gc")
(require "engine/common-obs/generic-obs.gc")
(require "engine/entity/ambient.gc")
(require "engine/game/task/task-control.gc")
(require "engine/common-obs/water-anim.gc")
(require "engine/target/target-util.gc")

;; DECOMP BEGINS

(defskelgroup *med-res-ogre-sg*
  medres-ogre
  medres-ogre-lod0-jg
  medres-ogre-idle-ja
  ((medres-ogre-lod0-mg (meters 999999)))
  :bounds (static-spherem -200 0 -450 350)
  :longest-edge (meters 0.01))

(defskelgroup *med-res-ogre2-sg*
  medres-ogre2
  medres-ogre2-lod0-jg
  medres-ogre2-idle-ja
  ((medres-ogre2-lod0-mg (meters 999999)))
  :bounds (static-spherem -200 0 -950 320)
  :longest-edge (meters 0.01))

(defskelgroup *med-res-ogre3-sg*
  medres-ogre3
  medres-ogre3-lod0-jg
  medres-ogre3-idle-ja
  ((medres-ogre3-lod0-mg (meters 999999)))
  :bounds (static-spherem -100 0 -1370 300)
  :longest-edge (meters 0.01))

(defskelgroup *med-res-finalboss-sg*
  medres-finalboss
  medres-finalboss-lod0-jg
  medres-finalboss-idle-ja
  ((medres-finalboss-lod0-mg (meters 999999)))
  :bounds (static-spherem 80 120 -150 470)
  :longest-edge (meters 0.01))

(deftype villagec-lava (water-anim) ())

(define ripple-for-villagec-lava
  (new 'static
       'ripple-wave-set
       :count 2
       :converted #f
       :wave
       (new 'static
            'inline-array
            ripple-wave
            4
            (new 'static 'ripple-wave :scale 40.0 :xdiv 2 :speed 1.5)
            (new 'static 'ripple-wave :scale 40.0 :xdiv -2 :zdiv 2 :speed 0.9)
            (new 'static 'ripple-wave)
            (new 'static 'ripple-wave))))

(defmethod water-vol-method-22 ((this villagec-lava))
  (let ((t9-0 (method-of-type water-anim water-vol-method-22))) (t9-0 this))
  (let ((v1-2 (new 'process 'ripple-control)))
    (set! (-> this draw ripple) v1-2)
    (set! (-> v1-2 global-scale) 3072.0)
    (set! (-> v1-2 waveform) ripple-for-villagec-lava))
  (logclear! (-> this flags) (water-flags wt23))
  (logior! (-> this flags) (water-flags wt25))
  (set! (-> this attack-event) 'lava)
  (none))

(deftype gondola (process-drawable)
  ((root           collide-shape-moving :override)
   (anim           spool-anim)
   (old-target-pos transformq :inline))
  (:state-methods (idle symbol)
   ride-up
   ride-down))

(defskelgroup *gondola-sg*
  gondola
  gondola-lod0-jg
  gondola-idle-down-ja
  ((gondola-lod0-mg (meters 999999)))
  :bounds (static-spherem 0 -5.5 0 6.5)
  :shadow gondola-shadow-mg)

(defstate idle (gondola)
  :virtual #t
  :code
    (behavior ((arg0 symbol))
      (set-time! (-> self state-time))
      (ja-channel-set! 1)
      (cond
        (arg0
         (set! (-> self anim)
               (new 'static
                    'spool-anim
                    :name "gondola-ride-down"
                    :index 6
                    :parts 3
                    :command-list
                    '((0 want-levels village3 snow)
                     (0 shadow target #f)
                     (0 shadow sidekick #f)
                     (1 display-level village3 display)
                     (175 display-level snow #f)
                     (300 setting-reset music village3)
                     (618 save)
                     (619 blackout 20)
                     (619 shadow target #t))))
         (ja :group! gondola-idle-up-ja))
        (else
         (set! (-> self anim)
               (new 'static
                    'spool-anim
                    :name "gondola-ride-up"
                    :index 5
                    :parts 3
                    :command-list
                    '((0 want-levels village3 snow)
                     (0 shadow target #f)
                     (400 setting-reset music snow)
                     (400 display-level snow display)
                     (678 save)
                     (679 blackout 20)
                     (679 shadow target #t))))
         (ja :group! gondola-idle-down-ja)))
      (transform-post)
      (loop
        (when (and *target*
                   (and (< (vector-vector-distance (vector<-cspace! (new 'stack-no-clear 'vector) (joint-node gondola-lod0-jg main)) (target-pos 0))
                           81920.0)
                        (not (movie?))
                        (not (level-hint-displayed?))
                        (time-elapsed? (-> self state-time) (seconds 3))
                        ;; og:preserve-this fix gondola spool not loading because it's "too far away" (technically)
                        (#if (not PC_PORT)
                          (file-status *art-control* (-> self anim name) 0)
                          (begin
                            (spool-push *art-control*
                                        (-> self anim name)
                                        0
                                        self
                                        (vector-vector-distance (vector<-cspace! (new 'stack-no-clear 'vector) (-> self node-list data 3)) (target-pos 0)))
                            (file-status *art-control* (-> self anim name) 0)))))
          (let ((s3-0 (get-reminder (get-task-control (game-task village3-button)) 2))
                (s4-1 (and *cheat-mode* (cpad-hold? 0 l3)))
                (s5-1 (vector<-cspace! (new 'stack-no-clear 'vector) (joint-node gondola-lod0-jg main))))
            (cond
              ((not (or s4-1 (task-closed? (game-task village3-button) (task-status need-hint)))))
              ((and (< (the int (-> *game-info* fuel)) (+ s3-0 2)) (< (the int (-> *game-info* fuel)) 71) (not s4-1))
               (level-hint-spawn (text-id gondola-need-cells) "asstvb75" (the-as entity #f) *entity-pool* (game-task none)))
              (else
               (level-hint-spawn (text-id gondola-enough-cells) "asstvb76" (the-as entity #f) *entity-pool* (game-task none))
               (let ((s4-3 (new 'stack-no-clear 'event-message-block)))
                 (set! (-> s4-3 from) self)
                 (set! (-> s4-3 num-params) 0)
                 (set! (-> s4-3 message) 'update)
                 (let ((s3-1 send-event-function)
                       (v1-36 (entity-actor-lookup (-> self entity) 'alt-actor 0)))
                   (s3-1 (if v1-36 (-> v1-36 extra process)) s4-3)))
               (let ((s4-4 (new 'stack-no-clear 'event-message-block)))
                 (set! (-> s4-4 from) self)
                 (set! (-> s4-4 num-params) 0)
                 (set! (-> s4-4 message) 'update)
                 (let ((s3-2 send-event-function)
                       (v1-40 (entity-actor-lookup (-> self entity) 'alt-actor 1)))
                   (s3-2 (if v1-40 (-> v1-40 extra process)) s4-4)))
               (when (and (< (vector-vector-xz-distance s5-1 (-> *target* control trans)) 18432.0)
                          (and (not (and (logtest? (-> *target* control unknown-surface00 flags) (surface-flags jump))
                                         (not (logtest? (-> *target* control status) (cshape-moving-flags onsurf)))))
                               (and (< (+ -40960.0 (-> s5-1 y)) (-> *target* control trans y))
                                    (begin
                                      (hide-hud)
                                      (level-hint-surpress!)
                                      (kill-current-level-hint '() '(sidekick voicebox) 'exit)
                                      (hud-hidden?))
                                    (can-grab-display? self))))
                 (let ((s5-2 (new 'stack 'font-context *font-default-matrix* 32 160 0.0 (font-color default) (font-flags shadow kerning))))
                   (let ((v1-59 s5-2)) (set! (-> v1-59 width) (the float 440)))
                   (let ((v1-60 s5-2)) (set! (-> v1-60 height) (the float 80)))
                   (set! (-> s5-2 flags) (font-flags shadow kerning large))
                   (print-game-text (lookup-text! *common-text* (text-id press-to-use) #f) s5-2 #f 128 22))
                 (when (and (cpad-pressed? 0 circle) (process-grab? *target*))
                   (if arg0 (go-virtual ride-down) (go-virtual ride-up))))))))
        (spool-push *art-control* (-> self anim name) 0 self -99.0)
        (suspend))))

(defstate ride-up (gondola)
  :virtual #t
  :code
    (behavior ()
      (process-entity-status! self (entity-perm-status bit-3) #t)
      (when (send-event *target* 'clone-anim self)
        (send-event (ppointer->process (-> *target* sidekick)) 'matrix 'play-anim)
        (send-event *target* 'blend-shape #t)
        (set-setting! 'sound-flava #f 30.0 (music-flava to-snow))
        (logclear! (-> self mask) (process-mask enemy))
        (process-spawn othercam self 4 #f #t :to self)
        (ja-play-spooled-anim (-> self anim)
                              (the-as art-joint-anim gondola-idle-down-ja)
                              (the-as art-joint-anim gondola-idle-up-ja)
                              (the-as (function process-drawable symbol) false-func))
        (remove-setting! 'sound-flava)
        (send-event *target* 'blend-shape #f)
        (when *target*
          (vector<-cspace! (the-as vector (-> self old-target-pos)) (-> *target* node-list data 3))
          (send-event *target* 'trans 'restore (-> self old-target-pos))
          (send-event *target* 'end-mode)
          (update-transforms! (-> self root))
          (move-to-ground (-> *target* control) 4096.0 40960.0 #t (-> *target* control root-prim collide-with))
          (logior! (-> *target* control status) (cshape-moving-flags onsurf onground tsurf))
          (suspend)
          (send-event *camera* 'teleport-to-other-start-string))
        (load-state-want-vis 'sno)
        (set-continue! *game-info* "snow-start"))
      (process-entity-status! self (entity-perm-status bit-3) #f)
      (go-virtual idle #t))
  :post
    (behavior ()
      (ja-post)
      (update-direction-from-time-of-day (-> self draw shadow-ctrl))))

(defstate ride-down (gondola)
  :virtual #t
  :code
    (behavior ()
      (process-entity-status! self (entity-perm-status bit-3) #t)
      (when (send-event *target* 'clone-anim self)
        (send-event *target* 'trans 'save (-> self old-target-pos))
        (send-event (ppointer->process (-> *target* sidekick)) 'matrix 'play-anim)
        (send-event *target* 'blend-shape #t)
        (set-setting! 'sound-flava #f 30.0 (music-flava to-snow))
        (logclear! (-> self mask) (process-mask enemy))
        (process-spawn othercam self 4 #f #t :to self)
        (ja-play-spooled-anim (-> self anim)
                              (the-as art-joint-anim gondola-idle-up-ja)
                              (the-as art-joint-anim gondola-idle-down-ja)
                              (the-as (function process-drawable symbol) false-func))
        (remove-setting! 'sound-flava)
        (send-event *target* 'blend-shape #f)
        (when *target*
          (vector<-cspace! (the-as vector (-> self old-target-pos)) (-> *target* node-list data 3))
          (send-event *target* 'trans 'restore (-> self old-target-pos))
          (send-event *target* 'end-mode)
          (update-transforms! (-> self root))
          (move-to-ground (-> *target* control) 4096.0 40960.0 #t (-> *target* control root-prim collide-with))
          (logior! (-> *target* control status) (cshape-moving-flags onsurf onground tsurf))
          (suspend)
          (send-event *camera* 'teleport-to-other-start-string))
        (load-state-want-vis 'vi3)
        (set-continue! *game-info* "village3-farside"))
      (process-entity-status! self (entity-perm-status bit-3) #f)
      (go-virtual idle #f))
  :post
    (-> (method-of-type gondola ride-up)
        post))

(defmethod init-from-entity! ((this gondola) (arg0 entity-actor))
  (stack-size-set! (-> this main-thread) 512)
  (let ((s4-0 (new 'process 'collide-shape-moving this (collide-list-enum hit-by-player))))
    (set! (-> s4-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s4-0 reaction) default-collision-reaction)
    (set! (-> s4-0 no-reaction) (the-as (function collide-shape-moving collide-shape-intersect vector vector none) nothing))
    (alloc-riders s4-0 1)
    (let ((s3-0 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0))))
      (set! (-> s3-0 prim-core collide-as) (collide-kind ground-object))
      (set! (-> s3-0 collide-with) (collide-kind target))
      (set! (-> s3-0 prim-core action) (collide-action solid rider-plat-sticky))
      (set! (-> s3-0 prim-core offense) (collide-offense indestructible))
      (set! (-> s3-0 transform-index) 3)
      (set-vector! (-> s3-0 local-sphere) 0.0 -24576.0 0.0 26624.0)
      (set-root-prim! s4-0 s3-0))
    (set! (-> s4-0 nav-radius) (* 0.75 (-> s4-0 root-prim local-sphere w)))
    (backup-collide-with-as s4-0)
    (set! (-> this root) s4-0))
  (process-drawable-from-entity! this arg0)
  (quaternion-identity! (-> this root quat))
  (initialize-skeleton this *gondola-sg* '())
  (set! (-> this draw origin-joint-index) (the-as uint 3))
  (logclear! (-> this mask) (process-mask actor-pause))
  (set! (-> this draw shadow-joint-index) (the-as uint 3))
  (set! (-> this draw shadow-ctrl) (copy *target-shadow-control* 'process))
  (let ((a0-16 (-> this draw shadow-ctrl)))
    (when a0-16
      (let ((v1-32 a0-16)) (set! (-> v1-32 settings bot-plane w) (- -122880.0)))
      0
      (let ((v1-34 a0-16)) (set! (-> v1-34 settings top-plane w) (- 4096.0)))
      0
      (update-direction-from-time-of-day a0-16)))
  (cond
    ((< (-> (target-pos 0) y) (+ 204800.0 (-> this root trans y))) (go (method-of-object this idle) #f))
    (else
     (set! (-> this anim) (new 'static 'spool-anim :name "gondola-ride-down" :index 6 :parts 3 :command-list '()))
     (go (method-of-object this idle) #t)))
  (none))

(deftype pistons (process-drawable) ()
  (:state-methods
   idle
   (active handle symbol)))

(defskelgroup *pistons-sg*
  pistons
  pistons-lod0-jg
  pistons-idle-ja
  ((pistons-lod0-mg (meters 999999)))
  :bounds (static-spherem 0 6 0 8))

(defstate idle (pistons)
  :virtual #t
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('update) (go-virtual active (process->handle proc) #f))))
  :code
    (behavior ()
      (ja-post)
      (logior! (-> self mask) (process-mask sleep))
      (suspend)
      0))

(defstate active (pistons)
  :virtual #t
  :code
    (behavior ((arg0 handle) (arg1 symbol))
      (process-entity-status! self (entity-perm-status complete) #t)
      (if (not arg1) (sound-play "gdl-start-up"))
      (let ((f30-0 (if arg1 1.0 0.0)))
        (loop
          (set! f30-0 (seek f30-0 1.0 (* 0.2 (seconds-per-frame))))
          (ja :num! (loop! f30-0))
          (ja-post)
          (update! (-> self sound))
          (suspend)))
      ;; og:preserve-this decompiler never gets here and fails hard
      (go-virtual idle)))

(defmethod init-from-entity! ((this pistons) (arg0 entity-actor))
  (set! (-> this root) (new 'process 'trsqv))
  (process-drawable-from-entity! this arg0)
  (initialize-skeleton this *pistons-sg* '())
  (set! (-> this sound) (new 'process 'ambient-sound (static-sound-spec "gdl-gen-loop" :fo-max 100) (-> this root trans)))
  (if (and (-> this entity) (logtest? (-> this entity extra perm status) (entity-perm-status complete)))
    (go (method-of-object this active) (the-as handle #f) #t)
    (go (method-of-object this idle)))
  (none))

(deftype gondolacables (process-drawable) ()
  (:state-methods
   idle))

(defskelgroup *gondolacables-sg*
  gondolacables
  gondolacables-lod0-jg
  gondolacables-idle-ja
  ((gondolacables-lod0-mg (meters 999999)))
  :bounds (static-spherem 0 0 0 120))

(defstate idle (gondolacables)
  :virtual #t
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('update)
         (process-entity-status! self (entity-perm-status complete) #t)
         (let ((v0-0 1)) (set! (-> self draw mgeo effect 0 effect-bits) (the-as uint v0-0)) v0-0))))
  :code
    (behavior ()
      (loop
        (ja-no-eval :group! (ja-group) :num! (seek!) :frame-num 0.0)
        (until (ja-done? 0)
          (suspend)
          (ja :num! (seek!)))))
  :post ja-post)

(defmethod init-from-entity! ((this gondolacables) (arg0 entity-actor))
  (set! (-> this root) (new 'process 'trsqv))
  (process-drawable-from-entity! this arg0)
  (initialize-skeleton this *gondolacables-sg* '())
  (set! (-> this draw mgeo effect 0 effect-bits)
        (the-as uint
                (if (and (-> this entity) (logtest? (-> this entity extra perm status) (entity-perm-status complete))) 1 0)))
  (go (method-of-object this idle))
  (none))
