;;-*-Lisp-*-
(in-package goal)
(bundles "FIN.DGO")
(require "engine/common-obs/plat-eco.gc")
(require "levels/finalboss/robotboss-misc.gc")
(require "levels/finalboss/final-door.gc")
(require "engine/ui/credits.gc")

;; DECOMP BEGINS

(defskelgroup *robotboss-cinematic-sg*
  robotboss-cinematic
  robotboss-cinematic-lod0-jg
  robotboss-cinematic-idle-ja
  ((robotboss-cinematic-lod0-mg (meters 999999)))
  :bounds (static-spherem 0 -10 0 2000))

(defskelgroup *jak-white-sg*
  jak-white
  jak-white-lod0-jg
  jak-white-idle-ja
  ((jak-white-lod0-mg (meters 999999)))
  :bounds (static-spherem 0 0 0 4))

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

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

(deftype plat-eco-finalboss (plat-eco)
  ((force-dest float)
   (targ-dest  float)
   (dest       float)
   (speed      float)
   (touch-time time-frame)))


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

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

(defmethod baseplat-method-26 ((this plat-eco-finalboss))
  (set! (-> this force-dest) -1.0)
  (set! (-> this targ-dest) -1.0)
  (set! (-> this dest) 0.0)
  (set! (-> this speed) 0.1)
  (logclear! (-> this mask) (process-mask actor-pause))
  (process-entity-status! this (entity-perm-status bit-3) #t)
  (none))

(defstate plat-path-active (plat-eco-finalboss)
  :virtual #t
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('target)
         (process-entity-status! self (entity-perm-status complete) #t)
         (set! (-> self force-dest) (the-as float (-> block param 0))))
        (('ridden 'edge-grabbed)
         (if (time-elapsed? (-> self touch-time) (seconds 2))
           (set! (-> self targ-dest)
                 (cond
                   ((= (-> self path-pos) 0.0) (set! (-> self force-dest) -1.0) 0.99)
                   ((= (-> self path-pos) 0.99) 0.0)
                   (else (-> self targ-dest)))))
         (set-time! (-> self touch-time))
         #f)
        (else (plat-event proc argc message block))))
  :enter
    (behavior ((arg0 plat))
      (set-time! (-> self state-time))
      (lods-assign! (-> self draw) (-> self lit-look))
      (process-entity-status! self (entity-perm-status complete) #t)
      (cond
        (arg0)
        (else (dotimes (gp-1 5) (spawn-projectile-blue *target*)))))
  :trans
    (behavior ()
      (let ((s5-0 (eval-path-curve! (-> self path) (new 'stack-no-clear 'vector) 0.0 'interp))
            (gp-0 (eval-path-curve! (-> self path) (new 'stack-no-clear 'vector) 1.0 'interp)))
        (if (time-elapsed? (-> self touch-time) (seconds 3)) (set! (-> self targ-dest) -1.0))
        (set! (-> self dest)
              (cond
                ((>= (-> self force-dest) 0.0) (-> self force-dest))
                ((>= (-> self targ-dest) 0.0) (-> self targ-dest))
                ((< (vector-vector-xz-distance (target-pos 0) s5-0) (vector-vector-xz-distance (target-pos 0) gp-0)) 0.0)
                (else 0.99))))
      (if (= (-> self state-time) (current-time)) (set! (-> self path-pos) (-> self dest)))
      (seek! (-> self path-pos) (-> self dest) (* (-> self speed) (seconds-per-frame)))
      (eval-path-curve! (-> self path) (-> self basetrans) (-> self path-pos) 'interp)
      (if (< (vector-vector-distance (-> self root trans) (ear-trans)) 81920.0)
        (sound-play "eco-plat-hover" :id (-> self sound-id) :position (the-as symbol (-> self root trans))))
      (plat-trans)
      (when (send-event *target* 'query 'powerup (pickup-type eco-yellow))
        (process-entity-status! self (entity-perm-status complete) #t)
        (set! (-> self force-dest) 0.0))))

(deftype sage-finalboss-particle (structure)
  ((part   sparticle-launch-control)
   (active symbol))
  :allow-misaligned)


(deftype sage-finalboss (process-taskable)
  ((redsage           handle)
   (bluesage          handle)
   (yellowsage        handle)
   (assistant         handle)
   (robotplat         handle)
   (robotboss         handle)
   (silodoor          handle)
   (jak-white         handle)
   (left-door         entity-actor)
   (right-door        entity-actor)
   (kick-in-the-door  symbol)
   (kick-the-credits  symbol)
   (credit-fade       float)
   (palette-val       float)
   (particle          sage-finalboss-particle 9 :inline)
   (particle-whiteout sparticle-launch-control)
   (credits-played    symbol))
  (:states
   sage-finalboss-credits))


(defmethod relocate ((this sage-finalboss) (offset int))
  (dotimes (v1-0 9)
    (if (nonzero? (-> this particle v1-0 part)) (&+! (-> this particle v1-0 part) offset)))
  (if (nonzero? (-> this particle-whiteout)) (&+! (-> this particle-whiteout) offset))
  (the-as sage-finalboss ((method-of-type process-taskable relocate) this offset)))

(defmethod deactivate ((this sage-finalboss))
  (dotimes (s5-0 9)
    (let ((a0-1 (-> this particle s5-0 part))) (if (nonzero? a0-1) (kill-and-free-particles a0-1))))
  (if (nonzero? (-> this particle-whiteout)) (kill-and-free-particles (-> this particle-whiteout)))
  ((method-of-type process-taskable deactivate) this)
  (none))

(defskelgroup *sage-finalboss-sg*
  green-sagecage
  green-sagecage-lod0-jg
  green-sagecage-green-sagecage-idle-ja
  ((green-sagecage-lod0-mg (meters 20)) (green-sagecage-lod1-mg (meters 999999)))
  :bounds (static-spherem 0 0 0 2.5)
  :shadow green-sagecage-shadow-mg)

(defmethod play-reminder ((this sage-finalboss))
  (let ((s5-0 (entity-by-name "red-sagecage-1")))
    (when s5-0
      (set! (-> this redsage) (ppointer->handle (manipy-spawn (-> this root trans) s5-0 *redsage-sg* #f :to this)))
      (send-event (handle->process (-> this redsage)) 'anim-mode 'clone-anim)
      (send-event (handle->process (-> this redsage)) 'blend-shape #t)
      (send-event (handle->process (-> this redsage)) 'center-joint 3)
      (send-event (handle->process (-> this redsage)) 'origin-joint-index 3)))
  (let ((s5-1 (entity-by-name "blue-sagecage-1")))
    (when s5-1
      (set! (-> this bluesage) (ppointer->handle (manipy-spawn (-> this root trans) s5-1 *bluesage-sg* #f :to this)))
      (send-event (handle->process (-> this bluesage)) 'anim-mode 'clone-anim)
      (send-event (handle->process (-> this bluesage)) 'blend-shape #t)
      (send-event (handle->process (-> this bluesage)) 'center-joint 3)
      (send-event (handle->process (-> this bluesage)) 'origin-joint-index 3)))
  (let ((s5-2 (entity-by-name "yellow-sagecage-1")))
    (the-as symbol
            (when s5-2
              (set! (-> this yellowsage) (ppointer->handle (manipy-spawn (-> this root trans) s5-2 *yellowsage-sg* #f :to this)))
              (send-event (handle->process (-> this yellowsage)) 'anim-mode 'clone-anim)
              (send-event (handle->process (-> this yellowsage)) 'blend-shape #t)
              (send-event (handle->process (-> this yellowsage)) 'center-joint 3)
              (send-event (handle->process (-> this yellowsage)) 'origin-joint-index 3)))))

(defmethod process-taskable-method-45 ((this sage-finalboss))
  (let ((s5-0 (entity-by-name "assistant-lavatube-end-3")))
    (the-as symbol
            (when s5-0
              (set! (-> this assistant)
                    (ppointer->handle (manipy-spawn (-> this root trans) s5-0 *assistant-lavatube-end-sg* #f :to this)))
              (let ((s5-1 (handle->process (-> this assistant))))
                (if (the-as manipy s5-1)
                  (set! (-> (the-as manipy s5-1) draw level-index) (the-as uint (-> (level-get *level* 'finalboss) index)))))
              (send-event (handle->process (-> this assistant)) 'anim-mode 'clone-anim)
              (send-event (handle->process (-> this assistant)) 'blend-shape #t)
              (send-event (handle->process (-> this assistant)) 'center-joint 3)
              (send-event (handle->process (-> this assistant)) 'origin-joint-index 3)))))

(defmethod play-anim! ((this sage-finalboss) (arg0 symbol))
  (case (current-status (-> this tasks))
    (((task-status unknown))
     (when arg0
       (close-current! (-> this tasks))
       (set-yaw-angle-clear-roll-pitch! (-> this root) 0.0))
     (new 'static
          'spool-anim
          :name "green-sagecage-daxter-sacrifice"
          :index 8
          :parts 6
          :command-list
          '((1 blackout 0) (236 joint "cameraB") (439 joint "camera"))))
    (((task-status need-introduction))
     (when arg0
       (set-yaw-angle-clear-roll-pitch! (-> this root) 0.0)
       (close-current! (-> this tasks))
       (set! (-> this jak-white)
             (ppointer->handle (manipy-spawn (-> this root trans) (-> this entity) *jak-white-sg* #f :to this)))
       (send-event (handle->process (-> this jak-white))
                   'eval
                   (lambda :behavior sage-finalboss ()
                     (set-vector! (-> self draw color-emissive) 0.5 0.5 0.5 0.0)
                     (none)))
       (send-event (handle->process (-> this jak-white)) 'anim-mode 'clone-anim)
       (send-event (handle->process (-> this jak-white)) 'origin-joint-index 3)
       (send-event (handle->process (-> this jak-white)) 'blend-shape #t)
       (set! (-> this robotboss)
             (ppointer->handle (manipy-spawn (-> this root trans) (-> this entity) *robotboss-cinematic-sg* #f :to this)))
       (send-event (handle->process (-> this robotboss)) 'anim-mode 'clone-anim)
       (send-event (handle->process (-> this robotboss)) 'origin-joint-index 3)
       (let ((v1-67 (handle->process (-> this robotboss))))
         (if (the-as manipy v1-67) (set! (-> (the-as manipy v1-67) draw bounds w) 2048000.0)))
       (set! (-> this silodoor)
             (ppointer->handle (manipy-spawn (-> this root trans) (-> this entity) *silodoor-sg* #f :to this)))
       (send-event (handle->process (-> this silodoor)) 'anim-mode 'clone-anim)
       (let ((v1-84 (handle->process (-> this silodoor))))
         (if (the-as manipy v1-84) (set! (-> (the-as silodoor v1-84) draw bounds w) 2048000.0)))
       (send-event (process-by-name "silodoor-5" *active-pool*) 'hide)
       (set-setting! 'music #f 0.0 0)
       (set-setting! 'allow-progress #f 0.0 0))
     (new 'static
          'spool-anim
          :name "green-sagecage-outro-beat-boss-a"
          :index 9
          :parts 8
          :command-list
          '((0 send-event self activate-particle 0)
           (0 send-event self activate-particle 1)
           (0 send-event self activate-particle 7)
           (1 blackout 0)
           (61 joint "cameraB")
           (71 send-event self activate-particle 2)
           (156 joint "camera")
           (216 joint "cameraB")
           (259 send-event self deactivate-particle 2)
           (259 send-event self activate-particle 3)
           (268 send-event self activate-particle 4)
           (270 send-event self deactivate-particle 3)
           (270 send-event self deactivate-particle 0)
           (270 send-event self deactivate-particle 1)
           (271 joint "camera")
           (269 send-event self activate-particle 5)
           (272 send-event self flash)
           (272
            eval
            ,(lambda :behavior sage-finalboss ()
              (let ((a0-1 (get-task-control (game-task finalboss-movies)))) (save-reminder a0-1 (logior (get-reminder a0-1 0) 1) 0))
              (none)))
           (273 send-event self deactivate-particle 5)
           (333 joint "cameraB")
           (395 joint "camera")
           (453 joint "cameraB")
           (478 send-event self deactivate-particle 4)
           (478 send-event self activate-particle 6)
           (482 send-event self deactivate-particle 6)
           (583 joint "camera")
           (640 send-event self deactivate-particle 7))))
    (((task-status need-reminder-a))
     (when arg0
       (set-yaw-angle-clear-roll-pitch! (-> this root) 0.0)
       (close-current! (-> this tasks))
       (play-reminder this)
       (process-taskable-method-45 this)
       (set! (-> this kick-the-credits) #t)
       (set! (-> this robotplat)
             (ppointer->handle (manipy-spawn (-> this root trans) (-> this entity) *plat-eco-finalboss-lit-sg* #f :to this)))
       (send-event (handle->process (-> this robotplat)) 'anim-mode 'clone-anim)
       (send-event (handle->process (-> this robotplat)) 'origin-joint-index 3)
       (set! (-> this old-target-pos trans quad)
             (-> (new 'static 'vector :x 11368946.0 :y 2215900.2 :z -19405602.0 :w 1.0) quad))
       (quaternion-copy! (-> this old-target-pos quat) (new 'static 'quaternion :y -0.8472 :w 0.5312))
       (set-setting! 'music #f 0.0 0)
       (set-setting! 'sfx-volume 'abs 0.0 0)
       (set-setting! 'ambient-volume 'abs 0.0 0)
       (set-setting! 'allow-progress #f 0.0 0))
     (new 'static
          'spool-anim
          :name "green-sagecage-outro-beat-boss-b"
          :index 10
          :parts 27
          :command-list
          '((0 kill "crate-3250")
           (0 kill "crate-3251")
           (0 kill "crate-3252")
           (0 kill "crate-3253")
           (0 kill "crate-3254")
           (0 kill "crate-3255")
           (0 kill "crate-3256")
           (0 kill "crate-3257")
           (0 kill "crate-3258")
           (0 kill "crate-3259")
           (0 kill "plat-eco-finalboss-1")
           (1 blackout 0)
           (61 joint "cameraB")
           (136 joint "camera")
           (510 joint "cameraB")
           (641 joint "camera")
           (751 joint "cameraB")
           (1096 joint "camera")
           (1321 joint "cameraB")
           (1521 joint "camera")
           (1636 joint "cameraB")
           (1751 joint "camera")
           (1916 joint "cameraB")
           (1996 joint "camera")
           (2256 joint "cameraB"))))
    (((task-status need-reminder))
     (when arg0
       (set-yaw-angle-clear-roll-pitch! (-> this root) -13116.667)
       (close-current! (-> this tasks))
       (process-taskable-method-45 this)
       (send-event *camera* 'teleport)
       (set-setting! 'allow-progress #f 0.0 0))
     (cond
       ((target-has-all-the-cells?)
        (new 'static
             'spool-anim
             :name "green-sagecage-outro-beat-boss-enough-cells"
             :index 12
             :parts 6
             :command-list
             '((0 send-event self fade)
              (1 blackout 0)
              (65 joint "cameraB")
              (104 joint "camera")
              (134 joint "cameraB")
              (165 joint "camera")
              (292 joint "cameraB")
              (488 joint "camera")
              (488 auto-save auto-save))))
       (else
        (if arg0 (set-setting! 'allow-progress #f 0.0 0))
        (new 'static
             'spool-anim
             :name "green-sagecage-outro-beat-boss-need-cells"
             :index 11
             :parts 8
             :command-list
             '((0 send-event self fade)
              (1 blackout 0)
              (65 joint "cameraB")
              (104 joint "camera")
              (134 joint "cameraB")
              (165 joint "camera")
              (292 joint "cameraB")
              (488 joint "camera")
              (488 auto-save auto-save))))))
    (((task-status need-reward-speech))
     (when arg0
       (set-yaw-angle-clear-roll-pitch! (-> this root) -13116.667)
       (close-current! (-> this tasks))
       (process-taskable-method-45 this)
       (set! (-> this left-door) (the-as entity-actor (entity-by-name "power-left-2")))
       (set! (-> this right-door) (the-as entity-actor (entity-by-name "power-right-2")))
       (set-setting! 'allow-progress #f 0.0 0))
     (new 'static
          'spool-anim
          :name "green-sagecage-outro-big-finish"
          :index 13
          :parts 7
          :command-list
          '((1 blackout 0)
           (61 joint "cameraB")
           (102 joint "camera")
           (145 joint "cameraB")
           (220 send-event "power-left-2" open)
           (220 send-event "power-right-2" open)
           (235 joint "camera")
           (243 send-event self activate-particle 8)
           (322 joint "cameraB")
           (428 joint "camera")
           (519 joint "cameraB")
           (602 joint "camera"))))
    (else
     (if arg0
       (format 0
               "ERROR: <GMJ>: ~S playing anim for task status ~S~%"
               (-> this name)
               (task-status->string (current-status (-> this tasks)))))
     (-> this draw art-group data 4))))

(defmethod get-art-elem ((this sage-finalboss))
  (-> this draw art-group data 4))

(defbehavior sage-finalboss-credit-particle sage-finalboss ()
  (when (< 0.0 (-> self credit-fade))
    (if (> (-> self part matrix) 0)
      (set-vector! (sprite-get-user-hvdf (-> self part matrix))
                   2048.0
                   2048.0
                   (+ -1024.0 (-> *math-camera* hvdf-off z))
                   (-> *math-camera* hvdf-off w)))
    (set! (-> *part-id-table* 2827 init-specs 8 initial-valuef) (* 128.0 (-> self credit-fade)))
    (cond
      ((< (-> self credit-fade) 1.0)
       (set! (-> *part-id-table* 2825 init-specs 1 initial-valuef) 0.0)
       (set! (-> *part-id-table* 2826 init-specs 1 initial-valuef) 0.0))
      (else
       (set! (-> *part-id-table* 2825 init-specs 1 initial-valuef) 1.0)
       (set! (-> *part-id-table* 2826 init-specs 1 initial-valuef) 0.3)))
    (spawn (-> self part) *zero-vector*)
    (+! (-> self credit-fade) -0.008333334))
  (none))

(defstate play-anim (sage-finalboss)
  :virtual #t
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('fade) (set! (-> self credit-fade) 1.0))
        (('flash) (set! (-> self palette-val) 1.9921875))
        (('activate-particle)
         (let ((v0-0 (the-as object #t))) (set! (-> self particle (-> block param 0) active) (the-as symbol v0-0)) v0-0))
        (('deactivate-particle) (set! (-> self particle (-> block param 0) active) #f) #f)))
  :enter
    (behavior ()
      (set! (-> self credit-fade) 0.0)
      ((-> (method-of-type process-taskable play-anim) enter)))
  :exit
    (behavior ()
      (when (= (current-status (-> self tasks)) (task-status invalid))
        (cond
          ((not (-> self credits-played)) (set! (-> self kick-the-credits) #t))
          (else (set-blackout-frames 0) (initialize! *game-info* 'game (the-as game-save #f) "title-start"))))
      (let ((a0-4 (handle->process (-> self redsage)))) (if a0-4 (deactivate a0-4)))
      (let ((a0-8 (handle->process (-> self bluesage)))) (if a0-8 (deactivate a0-8)))
      (let ((a0-12 (handle->process (-> self yellowsage)))) (if a0-12 (deactivate a0-12)))
      (let ((a0-16 (handle->process (-> self assistant)))) (if a0-16 (deactivate a0-16)))
      (let ((a0-20 (handle->process (-> self robotplat)))) (if a0-20 (deactivate a0-20)))
      (let ((a0-24 (handle->process (-> self robotboss)))) (if a0-24 (deactivate a0-24)))
      (let ((a0-28 (handle->process (-> self jak-white)))) (if a0-28 (deactivate a0-28)))
      (let ((a0-32 (handle->process (-> self silodoor)))) (if a0-32 (deactivate a0-32)))
      (when (-> self left-door)
        (let ((a1-9 (new 'stack-no-clear 'event-message-block)))
          (set! (-> a1-9 from) self)
          (set! (-> a1-9 num-params) 2)
          (set! (-> a1-9 message) 'brightness)
          (set! (-> a1-9 param 0) (the-as uint 1.0))
          (set! (-> a1-9 param 1) (the-as uint 0.0))
          (let ((t9-11 send-event-function)
                (v1-61 (-> self left-door)))
            (t9-11 (if v1-61 (-> v1-61 extra process)) a1-9)))
        (set! (-> self left-door) #f))
      (when (-> self right-door)
        (let ((a1-10 (new 'stack-no-clear 'event-message-block)))
          (set! (-> a1-10 from) self)
          (set! (-> a1-10 num-params) 2)
          (set! (-> a1-10 message) 'brightness)
          (set! (-> a1-10 param 0) (the-as uint 1.0))
          (set! (-> a1-10 param 1) (the-as uint 0.0))
          (let ((t9-12 send-event-function)
                (v1-71 (-> self right-door)))
            (t9-12 (if v1-71 (-> v1-71 extra process)) a1-10)))
        (set! (-> self right-door) #f))
      (cond
        ((= (current-status (-> self tasks)) (task-status need-reward-speech))
         (if (target-has-all-the-cells?)
           (set! (-> self kick-in-the-door) #t)
           (start 'play (get-continue-by-name *game-info* "finalboss-start"))))
        ((= (current-status (-> self tasks)) (task-status invalid)))
        (else (set-blackout-frames (seconds 100))))
      (dotimes (v1-84 9)
        (set! (-> self particle v1-84 active) #f))
      ((-> (method-of-type process-taskable play-anim) exit)))
  :trans
    (behavior ()
      (local-vars (f28-0 float))
      (when (-> self left-door)
        (let ((f30-0 (ja-aframe-num 0)))
          0.0
          (let ((f30-1 (cond
                         ((< f30-0 235.0) (set! f28-0 1.0) 0.0)
                         ((< 320.0 f30-0) (set! f28-0 1.0) 0.0)
                         (else
                          (if (> (-> self particle-whiteout matrix) 0)
                            (set-vector! (sprite-get-user-hvdf (-> self particle-whiteout matrix))
                                         2048.0
                                         2048.0
                                         (+ -1024.0 (-> *math-camera* hvdf-off z))
                                         (-> *math-camera* hvdf-off w)))
                          (set! (-> *part-id-table* 2965 init-specs 8 initial-valuef) (fmax 0.0 (fmin 128.0 (* 0.75 (+ -240.0 f30-0)))))
                          (spawn (-> self particle-whiteout) *zero-vector*)
                          (set! f28-0 (fmin 2.0 (fmax 0.0 (* 0.033333335 (+ -235.0 f30-0)))))
                          f28-0))))
            (let ((a1-1 (new 'stack-no-clear 'event-message-block)))
              (set! (-> a1-1 from) self)
              (set! (-> a1-1 num-params) 2)
              (set! (-> a1-1 message) 'brightness)
              (set! (-> a1-1 param 0) (the-as uint f28-0))
              (set! (-> a1-1 param 1) (the-as uint f30-1))
              (let ((t9-3 send-event-function)
                    (v1-20 (-> self left-door)))
                (t9-3 (if v1-20 (-> v1-20 extra process)) a1-1)))
            (let ((a1-2 (new 'stack-no-clear 'event-message-block)))
              (set! (-> a1-2 from) self)
              (set! (-> a1-2 num-params) 2)
              (set! (-> a1-2 message) 'brightness)
              (set! (-> a1-2 param 0) (the-as uint f28-0))
              (set! (-> a1-2 param 1) (the-as uint f30-1))
              (let ((t9-4 send-event-function)
                    (v1-27 (-> self right-door)))
                (t9-4 (if v1-27 (-> v1-27 extra process)) a1-2))))))
      (when (and *target* (-> self particle 0 active))
        (let ((a1-3 (new 'stack-no-clear 'vector)))
          (set! (-> a1-3 quad) (-> *target* draw origin quad))
          (set! (-> a1-3 y) 1970176.0)
          (spawn (-> self particle 0 part) a1-3)))
      (when (and (handle->process (-> self jak-white)) (-> self particle 1 active))
        (let ((a0-17 (handle->process (-> self jak-white))))
          (spawn (-> self particle 1 part)
                 (process-drawable-random-point! (the-as process-drawable a0-17) (new 'stack-no-clear 'vector)))))
      (when (and (handle->process (-> self jak-white)) (-> self particle 2 active))
        (let* ((v1-52 (handle->process (-> self jak-white)))
               (a1-11 (vector<-cspace! (new 'stack-no-clear 'vector) (-> (the-as process-drawable v1-52) node-list data 52))))
          (spawn (-> self particle 2 part) a1-11)))
      (when (and (handle->process (-> self jak-white)) (-> self particle 3 active))
        (let* ((v1-63 (handle->process (-> self jak-white)))
               (a1-15 (vector<-cspace! (new 'stack-no-clear 'vector) (-> (the-as process-drawable v1-63) node-list data 52))))
          (spawn (-> self particle 3 part) a1-15)))
      (if (and (handle->process (-> self robotboss)) (-> self particle 4 active))
        (spawn (-> self particle 4 part)
               (process-drawable-random-point! (the-as process-drawable (handle->process (-> self robotboss)))
                                               (new 'stack-no-clear 'vector))))
      (if (and (handle->process (-> self robotboss)) (-> self particle 5 active))
        (spawn (-> self particle 5 part)
               (vector<-cspace! (new 'stack-no-clear 'vector)
                                (-> (the-as process-drawable (handle->process (-> self robotboss))) node-list data 15))))
      (if (and (handle->process (-> self robotboss)) (-> self particle 6 active))
        (spawn (-> self particle 6 part)
               (vector<-cspace! (new 'stack-no-clear 'vector)
                                (-> (the-as process-drawable (handle->process (-> self robotboss))) node-list data 6))))
      (when (and (handle->process (-> self robotboss)) (-> self particle 7 active))
        (let ((gp-4 (new 'stack-no-clear 'vector)))
          (vector<-cspace! gp-4 (-> (the-as process-drawable (handle->process (-> self robotboss))) node-list data 7))
          (spawn (-> self particle 7 part) gp-4)))
      (when (-> self particle 8 active)
        (let ((gp-5 (search-process-tree *active-pool* (lambda ((arg0 final-door)) (= (-> arg0 type) power-left))))
              (a0-70 (search-process-tree *active-pool* (lambda ((arg0 final-door)) (= (-> arg0 type) power-left))))
              (a1-43 (new 'stack-no-clear 'vector)))
          (vector+! a1-43 (-> (the-as final-door gp-5) root trans) (-> (the-as final-door a0-70) root trans))
          (vector-float*! a1-43 a1-43 0.5)
          (spawn (-> self particle 8 part) a1-43)))
      (sage-finalboss-credit-particle)
      (let* ((f0-14 (- 0.0 (-> self palette-val)))
             (f0-15 (if (< 0.0 f0-14) (fmin 0.025 f0-14) (fmax -0.025 f0-14))))
        (+! (-> self palette-val) f0-15))
      (set! (-> *palette-fade-controls* control 2 fade) (-> self palette-val))
      (case (current-status (-> self tasks))
        (((task-status need-introduction)) (spool-push *art-control* "green-sagecage-outro-beat-boss-a" 0 self -1.0))
        (((task-status need-reminder-a)) (spool-push *art-control* "green-sagecage-outro-beat-boss-b" 0 self -1.0))
        (((task-status need-reminder))
         (if (target-has-all-the-cells?)
           (spool-push *art-control* "green-sagecage-outro-beat-boss-enough-cells" 0 self -1.0)
           (spool-push *art-control* "green-sagecage-outro-beat-boss-need-cells" 0 self -1.0)))
        (((task-status need-reward-speech)) (spool-push *art-control* "green-sagecage-outro-big-finish" 0 self -1.0)))
      ((-> (method-of-type process-taskable play-anim) trans))))

(defstate sage-finalboss-credits (sage-finalboss)
  :exit
    (behavior ()
      (when (= (current-status (-> self tasks)) (task-status invalid))
        (set-blackout-frames 0)
        (initialize! *game-info* 'game (the-as game-save #f) "title-start")))
  :code
    (behavior ()
      (local-vars (s5-0 symbol))
      (set! (-> self credits-played) #t)
      (set-blackout-frames 0)
      (set-blackout-frames (seconds 0.05))
      (remove-setting! 'sfx-volume)
      (remove-setting! 'ambient-volume)
      (set-setting! 'allow-pause #f 0.0 0)
      (set-setting! 'allow-progress #f 0.0 0)
      (set-setting! 'music 'ogreboss 0.0 0)
      (set! (-> self state-time) (-> *display* game-frame-counter))
      (logior! (-> self draw status) (draw-status hidden))
      (let ((gp-0 (-> self mask)))
        (load-state-want-display-level 'finalboss 'special)
        (logclear! (-> self mask) (process-mask pause progress))
        (add-setting! 'process-mask 'set 0.0 (process-mask pause progress target))
        (apply-settings *setting-control*)
        (let ((f30-0 0.0)
              (f28-0 0.5))
          (until s5-0
            (hide-hud-quick)
            (set! (-> self credit-fade) 1.0)
            (sage-finalboss-credit-particle)
            (set! s5-0 (draw-end-credits (the int f30-0)))
            (if (and *cheat-mode* (cpad-pressed? 0 triangle)) (set! s5-0 #t))
            (cond
              ((paused?))
              ((and (< 1300.0 f30-0) (cpad-hold? 0 circle x))
               (set! f28-0 (seek f28-0 16.0 (* 4.0 (seconds-per-frame))))
               (+! f30-0 (* f28-0 (-> *display* time-adjust-ratio))))
              (else (set! f28-0 (seek f28-0 0.5 (* 16.0 (seconds-per-frame)))) (+! f30-0 (* f28-0 (-> *display* time-adjust-ratio)))))
            (suspend)))
        (set! (-> self mask) gp-0))
      (load-state-want-display-level 'finalboss 'display)
      (remove-setting! 'allow-pause)
      (remove-setting! 'allow-progress)
      (remove-setting! 'process-mask)
      (remove-setting! 'music)
      (apply-settings *setting-control*)
      (set-blackout-frames (seconds 0.05))
      (suspend-for (seconds 0.05))
      (go-virtual hidden)))

(defmethod should-display? ((this sage-finalboss))
  #f)

(defbehavior sage-finalboss-extra-trans sage-finalboss ()
  (case (current-status (-> self tasks))
    (((task-status need-reminder-a) (task-status need-reminder)) (send-event self 'play-anim)))
  (none))

(defbehavior sage-finalboss-extra-enter sage-finalboss ()
  (cond
    ((-> self kick-the-credits) (set! (-> self kick-the-credits) #f) (go sage-finalboss-credits))
    ((-> self kick-in-the-door)
     (set! (-> self kick-in-the-door) #f)
     (entity-birth-no-kill (entity-by-type power-right))
     (entity-birth-no-kill (entity-by-type power-left))
     (send-event *target*
                 'change-mode
                 'final-door
                 (search-process-tree *active-pool* (lambda ((arg0 final-door)) (= (-> arg0 type) power-right)))
                 (search-process-tree *active-pool* (lambda ((arg0 final-door)) (= (-> arg0 type) power-left))))))
  (none))

(defstate hidden (sage-finalboss)
  :virtual #t
  :enter
    (behavior ()
      (sage-finalboss-extra-enter)
      ((-> (method-of-type process-taskable hidden) enter))
      (remove-setting! 'allow-progress))
  :trans
    (behavior ()
      (sage-finalboss-extra-trans)
      ((-> (method-of-type process-taskable hidden) trans))))

(defstate idle (sage-finalboss)
  :virtual #t
  :enter
    (behavior ()
      (sage-finalboss-extra-enter)
      ((-> (method-of-type process-taskable idle) enter)))
  :trans
    (behavior ()
      (sage-finalboss-extra-trans)
      ((-> (method-of-type process-taskable idle) trans))))

(defmethod init-from-entity! ((this sage-finalboss) (arg0 entity-actor))
  (process-taskable-method-40 this arg0 *sage-finalboss-sg* 3 40 (new 'static 'vector :w 4096.0) 5)
  (set! (-> this tasks) (get-task-control (game-task finalboss-movies)))
  (set! (-> this redsage) (the-as handle #f))
  (set! (-> this bluesage) (the-as handle #f))
  (set! (-> this yellowsage) (the-as handle #f))
  (set! (-> this assistant) (the-as handle #f))
  (set! (-> this robotplat) (the-as handle #f))
  (set! (-> this robotboss) (the-as handle #f))
  (set! (-> this jak-white) (the-as handle #f))
  (set! (-> this silodoor) (the-as handle #f))
  (set! (-> this left-door) #f)
  (set! (-> this right-door) #f)
  (set! (-> this kick-in-the-door) #f)
  (set! (-> this kick-the-credits) #f)
  (set! (-> this credits-played) #f)
  (set! (-> this part) (create-launch-control (-> *part-group-id-table* 682) this))
  (set! (-> this part matrix) (sprite-allocate-user-hvdf))
  (set! (-> this particle-whiteout) (create-launch-control (-> *part-group-id-table* 706) this))
  (set! (-> this particle-whiteout matrix) (sprite-allocate-user-hvdf))
  (set! (-> this particle 0 part) (create-launch-control (-> *part-group-id-table* 699) this))
  (set! (-> this particle 1 part) (create-launch-control (-> *part-group-id-table* 700) this))
  (set! (-> this particle 2 part) (create-launch-control (-> *part-group-id-table* 701) this))
  (set! (-> this particle 3 part) (create-launch-control (-> *part-group-id-table* 702) this))
  (set! (-> this particle 7 part) (create-launch-control (-> *part-group-id-table* 645) this))
  (set! (-> this particle 4 part) (create-launch-control (-> *part-group-id-table* 703) this))
  (set! (-> this particle 5 part) (create-launch-control (-> *part-group-id-table* 696) this))
  (set! (-> this particle 6 part) (create-launch-control (-> *part-group-id-table* 704) this))
  (set! (-> this particle 8 part) (create-launch-control (-> *part-group-id-table* 698) this))
  (dotimes (v1-37 9)
    (set! (-> this particle v1-37 active) #f))
  (set! (-> this palette-val) 0.0)
  (+! (-> this root trans y) 2048.0)
  (if (not (should-display? this)) (go (method-of-object this hidden)) (go (method-of-object this idle)))
  (none))
