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

;; name: temple-obs2.gc
;; name in dgo: temple-obs2
;; dgos: TEMA

(declare-type tpl-watcher process-focusable)

;; DECOMP BEGINS

(deftype tpl-gate (process-drawable)
  ((alt-actor  entity-actor)
   (extra-id   uint32)
   (perm       uint32)
   )
  (:state-methods
    idle
    open
    close
    closed
    opened
    die
    )
  )


(defskelgroup skel-tpl-gate tpl-gate tpl-gate-lod0-jg tpl-gate-idle-ja
              ((tpl-gate-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 15)
              )

(defstate idle (tpl-gate)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('open)
       (go-virtual open)
       )
      (('close)
       (go-virtual close)
       )
      )
    )
  :code (behavior ()
    (until #f
      (ja-no-eval :group! (ja-group) :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!))
        )
      )
    #f
    )
  :post (behavior ()
    (transform-post)
    )
  )

(defstate open (tpl-gate)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('trigger)
       (when (= (-> self extra-id) 1)
         )
       (go-virtual close)
       )
      )
    )
  :code (behavior ()
    (sound-play "gate-lower")
    (ja-no-eval :group! tpl-gate-open-ja :num! (seek!) :frame-num 0.0)
    (until (ja-done? 0)
      (transform-post)
      (suspend)
      (ja :num! (seek!))
      )
    (until #f
      (suspend)
      )
    #f
    )
  )

(defstate close (tpl-gate)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('open)
       (go-virtual open)
       )
      )
    )
  :code (behavior ()
    (process-entity-status! self (entity-perm-status bit-13) #t)
    (when (= (-> self extra-id) 1)
      (until (process-grab? *target* #f)
        (suspend)
        )
      (set-setting! 'entity-name "camera-356" 0.0 0)
      (suspend-for (seconds 1)
        )
      )
    (sound-play "gate-raise")
    (ja-no-eval :group! tpl-gate-close-ja :num! (seek!) :frame-num 0.0)
    (until (ja-done? 0)
      (transform-post)
      (suspend)
      (ja :num! (seek!))
      )
    (suspend-for (seconds 0.1)
      )
    (let ((a1-6 (new 'stack-no-clear 'event-message-block)))
      (set! (-> a1-6 from) (process->ppointer self))
      (set! (-> a1-6 num-params) 0)
      (set! (-> a1-6 message) 'trigger)
      (let ((t9-9 send-event-function)
            (v1-42 (-> self alt-actor))
            )
        (t9-9
          (if v1-42
              (-> v1-42 extra process)
              )
          a1-6
          )
        )
      )
    (when (= (-> self extra-id) 1)
      (suspend-for (seconds 0.5)
        )
      (remove-setting! 'entity-name)
      (suspend-for (seconds 2.5)
        )
      (until (process-release? *target*)
        (suspend)
        )
      (task-close! "temple-oracle-pre-pole-room")
      )
    (until #f
      (suspend)
      )
    #f
    )
  )

(defstate closed (tpl-gate)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('open)
       (go-virtual open)
       )
      (('trigger)
       (when (= (-> self extra-id) 1)
         )
       (go-virtual close)
       )
      )
    )
  :code (behavior ()
    (ja-channel-push! 1 0)
    (ja :group! (get-art-by-name (-> self draw art-group) "close" art-joint-anim) :num! max)
    (transform-post)
    (until #f
      (suspend)
      )
    #f
    )
  )

(defstate opened (tpl-gate)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('trigger)
       (when (= (-> self extra-id) 1)
         )
       (go-virtual close)
       )
      (('close)
       (go-virtual close)
       )
      )
    )
  :code (behavior ()
    (ja-channel-push! 1 0)
    (ja :group! (get-art-by-name (-> self draw art-group) "open" art-joint-anim) :num! max)
    (transform-post)
    (until #f
      (suspend)
      )
    #f
    )
  )

(defstate die (tpl-gate)
  :virtual #t
  :code (behavior ()
    (suspend)
    0
    )
  )

(defmethod init-from-entity! ((this tpl-gate) (arg0 entity-actor))
  "Set up a newly created process from the entity that created it."
  (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player))))
    (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-spec obstacle camera-blocker pusher))
      (set! (-> s3-0 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> s3-0 prim-core action) (collide-action solid rideable))
      (set! (-> s3-0 transform-index) 3)
      (set-vector! (-> s3-0 local-sphere) 0.0 0.0 0.0 61440.0)
      (set! (-> s4-0 total-prims) (the-as uint 1))
      (set! (-> s4-0 root-prim) s3-0)
      )
    (pusher-init s4-0)
    (set! (-> s4-0 nav-radius) (* 0.75 (-> s4-0 root-prim local-sphere w)))
    (let ((v1-12 (-> s4-0 root-prim)))
      (set! (-> s4-0 backup-collide-as) (-> v1-12 prim-core collide-as))
      (set! (-> s4-0 backup-collide-with) (-> v1-12 prim-core collide-with))
      )
    (set! (-> this root) s4-0)
    )
  (set! (-> this entity) arg0)
  (process-drawable-from-entity! this arg0)
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-tpl-gate" (the-as (pointer level) #f)))
    (the-as pair 0)
    )
  (logclear! (-> this mask) (process-mask actor-pause))
  (set! (-> this alt-actor) (entity-actor-lookup arg0 'alt-actor 0))
  (set! (-> this extra-id) (res-lump-value (-> this entity) 'extra-id uint :time -1000000000.0))
  (set! (-> this draw light-index) (the-as uint 6))
  (cond
    ((task-node-closed? (game-task-node temple-oracle-pole-half))
     (process-entity-status! this (entity-perm-status dead) #t)
     (go (method-of-object this die))
     )
    ((and (not (task-node-closed? (game-task-node temple-oracle-pole-half)))
          (-> this entity)
          (logtest? (-> this entity extra perm status) (entity-perm-status bit-13))
          )
     (go (method-of-object this closed))
     )
    (else
      (go (method-of-object this opened))
      )
    )
  )

(deftype tpl-watcher-manager (process)
  ((actor-group          (pointer actor-group))
   (actor-group-count    int32)
   (within-outer-ring    symbol)
   (within-inner-ring    symbol)
   (ouched               symbol)
   (bound-cam            string)
   (trans                vector  :inline)
   (state-time           time-frame)
   (jak-in-hint-region   symbol)
   (watchers-vulnerable  symbol)
   )
  (:state-methods
    idle
    waiting
    until-watchers-dead
    )
  )


(defbehavior shoot-at-jak tpl-watcher-manager ()
  (when (not (-> *setting-control* user-current freeze-screen))
    (let ((gp-0 -1))
      (let ((f30-0 17592186000000.0)
            (s4-0 (the-as object #f))
            )
        (dotimes (s5-0 (length (-> self actor-group 0)))
          (let* ((f28-0 (vector-vector-distance-squared (-> self actor-group 0 data s5-0 actor trans) (target-pos 0)))
                 (v1-10 (-> self actor-group 0 data s5-0 actor))
                 (s3-1 (if v1-10
                           (-> v1-10 extra process)
                           )
                       )
                 )
            (when s3-1
              (set! s4-0 (or s4-0 (send-event s3-1 'is-shooting?)))
              (let ((a1-2 (new 'stack-no-clear 'event-message-block)))
                (set! (-> a1-2 from) (process->ppointer self))
                (set! (-> a1-2 num-params) 0)
                (set! (-> a1-2 message) 'can-shoot?)
                (when (and (send-event-function s3-1 a1-2)
                           (not (focus-test? (the-as process-focusable s3-1) dead))
                           (not (logtest? (-> self actor-group 0 data s5-0 actor extra perm status) (entity-perm-status bit-9 bit-10)))
                           (< f28-0 f30-0)
                           )
                  (set! f30-0 f28-0)
                  (set! gp-0 s5-0)
                  )
                )
              )
            )
          )
        )
      (when (< -1 gp-0)
        (let ((a1-3 (new 'stack-no-clear 'event-message-block)))
          (set! (-> a1-3 from) (process->ppointer self))
          (set! (-> a1-3 num-params) 0)
          (set! (-> a1-3 message) 'fire)
          (let ((t9-5 send-event-function)
                (v1-41 (-> self actor-group 0 data gp-0 actor))
                )
            (t9-5
              (if v1-41
                  (-> v1-41 extra process)
                  )
              a1-3
              )
            )
          )
        )
      )
    )
  )

(defbehavior tpl-watcher-manager-ehandler tpl-watcher-manager ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  (local-vars (v0-1 object))
  (case arg2
    (('trigger-on)
     (task-node-close! (game-task-node temple-oracle-introduction) 'event)
     (set! v0-1 #t)
     (set! (-> self within-outer-ring) (the-as symbol v0-1))
     v0-1
     )
    (('trigger-off)
     (set! (-> self within-outer-ring) #f)
     #f
     )
    (('inside-enter)
     (set! v0-1 #t)
     (set! (-> self within-inner-ring) (the-as symbol v0-1))
     v0-1
     )
    (('inside-exit)
     (set! (-> self within-inner-ring) #f)
     #f
     )
    (('ouch)
     (set! (-> self ouched) #t)
     (shoot-at-jak)
     )
    (('watchers-vulnerable)
     (-> self watchers-vulnerable)
     )
    (('confirm-shot)
     (or (-> self within-outer-ring) (-> self ouched))
     )
    (('seize-camera)
     (when (not (-> self jak-in-hint-region))
       (set! (-> self jak-in-hint-region) #t)
       (let ((v1-8 (-> self entity extra perm)))
         (logior! (-> v1-8 status) (entity-perm-status bit-5))
         (+! (-> v1-8 user-uint64) 1)
         (logior! (-> v1-8 status) (entity-perm-status bit-14))
         )
       )
     (set! (-> self bound-cam) (the-as string (-> arg3 param 0)))
     (set! (-> self ouched) #t)
     (go-virtual until-watchers-dead)
     )
    (('wandered-away)
     (remove-setting! 'entity-name)
     )
    )
  )

;; WARN: Return type mismatch symbol vs none.
(defbehavior watcher-man-trans tpl-watcher-manager ()
  (set! (-> self watchers-vulnerable)
        (< (if *target*
               (vector-vector-distance (-> self trans) (-> *target* control trans))
               4096000.0
               )
           313384.97
           )
        )
  (none)
  )

(defstate idle (tpl-watcher-manager)
  :virtual #t
  :event tpl-watcher-manager-ehandler
  :trans watcher-man-trans
  :code sleep-code
  :post (behavior ()
    (when (and *target*
               (-> self within-outer-ring)
               (not (-> self within-inner-ring))
               (not (logtest? (target-flags invisible) (-> *target* target-flags)))
               )
      (shoot-at-jak)
      (go-virtual waiting)
      )
    )
  )

(defstate waiting (tpl-watcher-manager)
  :virtual #t
  :event tpl-watcher-manager-ehandler
  :trans watcher-man-trans
  :code (behavior ()
    (suspend-for (seconds 1)
      )
    (while (and *target* (focus-test? *target* dead))
      (suspend)
      )
    (go-virtual idle)
    )
  )

(defstate until-watchers-dead (tpl-watcher-manager)
  :virtual #t
  :event tpl-watcher-manager-ehandler
  :enter (behavior ()
    (set-time! (-> self state-time))
    )
  :trans watcher-man-trans
  :code (behavior ()
    (when (not (-> *setting-control* user-current freeze-screen))
      (set-setting! 'entity-name (-> self bound-cam) 0.0 0)
      (suspend)
      (while (not (process-grab? *target* #f))
        (suspend)
        )
      (process-entity-status! self (entity-perm-status no-kill) #t)
      (suspend-for (seconds 2.5)
        )
      (while (not (process-release? *target*))
        (suspend)
        )
      (process-entity-status! self (entity-perm-status no-kill) #f)
      )
    (let ((gp-1 #t))
      (while gp-1
        (suspend)
        (when (and *target* (not (logtest? (-> *target* focus-status) (focus-status dead))))
          (set! gp-1 #f)
          (dotimes (s5-0 (length (-> self actor-group 0)))
            (let* ((v1-20 (-> self actor-group 0 data s5-0 actor))
                   (a0-9 (if v1-20
                             (-> v1-20 extra process)
                             )
                         )
                   )
              (if (and a0-9
                       (not (focus-test? (the-as process-focusable a0-9) dead))
                       (not (logtest? (-> self actor-group 0 data s5-0 actor extra perm status) (entity-perm-status bit-9 bit-10)))
                       )
                  (set! gp-1 #t)
                  )
              )
            )
          )
        )
      )
    (until (time-elapsed? (-> self state-time) (seconds 1))
      (suspend)
      )
    (task-close! "temple-oracle-watchers-complete")
    (remove-setting! 'entity-name)
    )
  :post (behavior ()
    (let ((a0-0 (-> self entity extra perm)))
      (when (< (the-as uint 4) (-> a0-0 user-uint64))
        (let ((gp-0
                (new 'stack 'font-context *font-default-matrix* 90 300 0.0 (font-color default) (font-flags shadow kerning))
                )
              )
          (set-width! gp-0 340)
          (set-height! gp-0 60)
          (set-scale! gp-0 0.6)
          (set! (-> gp-0 flags) (font-flags shadow kerning middle middle-vert large))
          (print-game-text
            (lookup-text!
              *common-text*
              (if (or (not (focus-test? *target* gun)) (!= (-> *game-info* gun-type) 27))
                  (text-id use-the-wave-concussor)
                  (text-id hold-to-charge-and-then-release-to-fire-blast)
                  )
              #f
              )
            gp-0
            #f
            44
            (bucket-id hud-draw-hud-alpha)
            )
          )
        )
      )
    (if (and *target*
             (-> self within-outer-ring)
             (not (-> self within-inner-ring))
             (not (logtest? (target-flags invisible) (-> *target* target-flags)))
             )
        (shoot-at-jak)
        )
    )
  )

(defmethod init-from-entity! ((this tpl-watcher-manager) (arg0 entity-actor))
  "Set up a newly created process from the entity that created it."
  (local-vars (sv-16 res-tag))
  (set! (-> this within-outer-ring) #f)
  (set! (-> this within-inner-ring) #f)
  (set! (-> this ouched) #f)
  (vector-copy! (-> this trans) (-> arg0 trans))
  (logclear! (-> this mask) (process-mask actor-pause))
  (set! sv-16 (new 'static 'res-tag))
  (let ((v1-4 (res-lump-data arg0 'actor-groups pointer :tag-ptr (& sv-16))))
    (cond
      ((and v1-4 (nonzero? (-> sv-16 elt-count)))
       (set! (-> this actor-group-count) (the-as int (-> sv-16 elt-count)))
       (set! (-> this actor-group) (the-as (pointer actor-group) v1-4))
       )
      (else
        (set! (-> this actor-group-count) 0)
        0
        )
      )
    )
  (set! (-> this entity) arg0)
  (set! (-> this jak-in-hint-region) #f)
  (set! (-> this watchers-vulnerable) #t)
  (go (method-of-object this idle))
  )

;; WARN: Return type mismatch object vs symbol.
(defbehavior has-jak-visibility? tpl-watcher ((arg0 object) (arg1 process-drawable))
  (the-as
    symbol
    (and (-> arg1 draw) (not (-> arg1 skel)) (not (logtest? (target-flags invisible) (-> *target* target-flags))))
    )
  )

(deftype tpl-watcher (process-focusable)
  ((manager          tpl-watcher-manager)
   (bob-clock        time-frame)
   (period-a         int32)
   (period-b         int32)
   (laser-sight      sparticle-launch-control)
   (laser-charge-fx  sparticle-launch-control)
   (los              los-control  :inline)
   )
  (:state-methods
    idle
    firing
    die
    standing-down
    )
  (:methods
    (init-collision! (_type_) none)
    )
  )


(defskelgroup skel-tpl-watcher tpl-watcher tpl-watcher-lod0-jg tpl-watcher-idle-ja
              ((tpl-watcher-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 2)
              )

(defskelgroup skel-tpl-watcher-explode tpl-watcher tpl-watcher-explode-lod0-jg tpl-watcher-explode-idle-ja
              ((tpl-watcher-explode-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 35)
              )

(define *tpl-watcher-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 3 :parent-joint-index 3)
      (new 'static 'joint-exploder-static-joint-params :joint-index 4 :parent-joint-index 3)
      (new 'static 'joint-exploder-static-joint-params :joint-index 5 :parent-joint-index 3)
      (new 'static 'joint-exploder-static-joint-params :joint-index 6 :parent-joint-index 3)
      (new 'static 'joint-exploder-static-joint-params :joint-index 7 :parent-joint-index 3)
      (new 'static 'joint-exploder-static-joint-params :joint-index 8 :parent-joint-index 3)
      (new 'static 'joint-exploder-static-joint-params :joint-index 9 :parent-joint-index 3)
      (new 'static 'joint-exploder-static-joint-params :joint-index 10 :parent-joint-index 3)
      (new 'static 'joint-exploder-static-joint-params :joint-index 11 :parent-joint-index 3)
      (new 'static 'joint-exploder-static-joint-params :joint-index 12 :parent-joint-index 3)
      (new 'static 'joint-exploder-static-joint-params :joint-index 13 :parent-joint-index 3)
      (new 'static 'joint-exploder-static-joint-params :joint-index 14 :parent-joint-index 3)
      )
    :collide-spec (collide-spec backgnd)
    )
  )

(defbehavior watcher-bob-trans tpl-watcher ()
  (+! (-> self bob-clock) (- (current-time) (-> self clock old-frame-counter)))
  (let ((gp-0 (new-stack-vector0)))
    (let ((f28-0 65536.0))
      (set! (-> gp-0 y)
            (* 2048.0
               (+ (sin (* (/ (the float (mod (-> self bob-clock) (-> self period-a))) (the float (-> self period-a))) f28-0))
                  (cos (* (/ (the float (mod (-> self bob-clock) (-> self period-b))) (the float (-> self period-b))) f28-0))
                  )
               )
            )
      )
    (vector+! (-> self root trans) (-> self entity trans) gp-0)
    )
  (spawn
    (-> self part)
    (vector+! (new 'stack-no-clear 'vector) (-> self root trans) (new 'static 'vector :y 3276.8 :w 1.0))
    )
  (spawn-from-cspace (-> self laser-sight) (joint-node tpl-watcher-lod0-jg gun))
  (none)
  )

;; WARN: Return type mismatch int vs search-info-flag.
(defmethod get-search-info-flag ((this tpl-watcher))
  "Get search-info-flag for this process."
  (with-pp
    (let ((a1-0 (new 'stack-no-clear 'event-message-block)))
      (set! (-> a1-0 from) (process->ppointer pp))
      (set! (-> a1-0 num-params) 0)
      (set! (-> a1-0 message) 'watchers-vulnerable)
      (let ((t9-0 send-event-function)
            (v1-2 (-> this manager))
            )
        (the-as search-info-flag (if (not (t9-0
                                            (if v1-2
                                                (-> v1-2 child 3)
                                                )
                                            a1-0
                                            )
                                          )
                                     1
                                     (the-as int (call-parent-method this))
                                     )
                )
        )
      )
    )
  )

(defstate idle (tpl-watcher)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('fire)
       (go-virtual firing)
       )
      (('attack)
       (let ((v1-3 (the-as attack-info (-> block param 1))))
         (when (and (or (>= (-> v1-3 damage) 1.0) (>= (penetrate-using->damage (-> v1-3 penetrate-using)) 1.0))
                    (and (not (focus-test? *target* dead)) (let ((a1-1 (new 'stack-no-clear 'event-message-block)))
                                                             (set! (-> a1-1 from) (process->ppointer self))
                                                             (set! (-> a1-1 num-params) 0)
                                                             (set! (-> a1-1 message) 'watchers-vulnerable)
                                                             (let ((t9-2 send-event-function)
                                                                   (v1-12 (-> self manager))
                                                                   )
                                                               (t9-2
                                                                 (if v1-12
                                                                     (-> v1-12 child 3)
                                                                     )
                                                                 a1-1
                                                                 )
                                                               )
                                                             )
                         )
                    )
           (logior! (-> self focus-status) (focus-status dead))
           (go-virtual die)
           )
         )
       )
      (('can-shoot?)
       (should-check-los? (-> self los) 0)
       )
      (('prevent-bounce?)
       #t
       )
      (('is-shooting?)
       #f
       )
      )
    )
  :trans watcher-bob-trans
  :code sleep-code
  :post (behavior ()
    (let ((a1-1 (the-as target (as-type *target* process-focusable))))
      (if a1-1
          (los-control-method-9 (-> self los) a1-1 (the-as vector #f) 819.2 4096.0)
          )
      )
    (transform-post)
    )
  )

(set! (-> *lightning-spec-id-table* 26) (new 'static 'lightning-spec
                                          :name "lightning-blast"
                                          :flags (lightning-spec-flags lsf0)
                                          :start-color (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
                                          :end-color (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
                                          :fade-to-color (new 'static 'rgba :r #xbf :b #x8f :a #x5)
                                          :fade-start-factor 0.2
                                          :fade-time 30.0
                                          :texture (new 'static 'texture-id :index #x3f :page #x4)
                                          :reduction 0.42
                                          :num-points 16
                                          :box-size 16384.0
                                          :merge-factor 0.5
                                          :merge-count 2
                                          :radius 2048.0
                                          :duration 150.0
                                          :sound (static-sound-spec "shock" :group 0)
                                          )
      )

(defstate firing (tpl-watcher)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('attack)
       (let ((v1-1 (the-as attack-info (-> block param 1))))
         (if (or (>= (-> v1-1 damage) 1.0) (>= (penetrate-using->damage (-> v1-1 penetrate-using)) 1.0))
             (go-virtual die)
             )
         )
       )
      (('prevent-bounce?)
       #t
       )
      (('can-shoot?)
       (should-check-los? (-> self los) 0)
       )
      (('is-shooting?)
       #t
       )
      )
    )
  :enter (behavior ()
    (set-time! (-> self state-time))
    )
  :trans (behavior ()
    (spawn
      (-> self part)
      (vector+! (new 'stack-no-clear 'vector) (-> self root trans) (new 'static 'vector :y 3276.8 :w 1.0))
      )
    (spawn-from-mat (-> self laser-charge-fx) (-> self node-list data 4 bone transform))
    )
  :code (behavior ()
    (local-vars (v1-32 time-frame) (a1-12 process-drawable))
    (rlet ((acc :class vf)
           (Q :class vf)
           (vf0 :class vf)
           (vf1 :class vf)
           (vf2 :class vf)
           (vf3 :class vf)
           )
      (init-vf0-vector)
      (let ((s5-0 (-> self root quat))
            (gp-0 (new-sound-id))
            )
        (sound-play "wtcher-turn" :id gp-0)
        (let ((s4-0 (current-time)))
          (until (>= v1-32 (if (-> a1-12 nav)
                               75
                               450
                               )
                     )
            (let* ((s3-0 (get-trans *target* 3))
                   (f0-0 (if *target*
                             (vector-vector-xz-distance (-> self root trans) (-> *target* control trans))
                             4096000.0
                             )
                         )
                   (v1-10 (vector-! (new 'stack-no-clear 'vector) s3-0 (-> self root trans)))
                   (f30-0 (/ f0-0 (meters 10)))
                   (s2-0 vector-xz-normalize!)
                   (a0-7 v1-10)
                   )
              (vector-copy! a0-7 v1-10)
              (set! (-> a0-7 y) 0.0)
              (let* ((a1-7 (s2-0 (vector-normalize! a0-7 1.0) 1.0))
                     (a2-2 (vector-lerp-clamp! (new 'stack-no-clear 'vector) a1-7 *up-vector* f30-0))
                     )
                (let ((f0-2 1.0))
                  (.lvf vf1 (&-> a2-2 quad))
                  (.mul.vf.xyz vf2 vf1 vf1)
                  (let ((v1-13 f0-2))
                    (.mov vf3 v1-13)
                    )
                  )
                (.mul.x.vf.w acc vf0 vf2)
                (.add.mul.y.vf.w acc vf0 vf2 acc)
                (.add.mul.z.vf.w vf2 vf0 vf2 acc)
                (.isqrt.vf Q vf3 vf2 :fsf #b0 :ftf #b11)
                (.wait.vf)
                (.mul.vf.xyz vf1 vf1 Q)
                (.nop.vf)
                (.nop.vf)
                (.nop.vf)
                (.svf (&-> a2-2 quad) vf1)
                (let ((t9-7 quaternion-look-at!)
                      (a0-10 (new 'stack-no-clear 'quaternion))
                      (a1-9 (vector-! (new 'stack-no-clear 'vector) s3-0 (-> self node-list data 4 bone transform trans)))
                      )
                  (let ((f0-3 1.0))
                    (.lvf vf1 (&-> a1-9 quad))
                    (.mul.vf.xyz vf2 vf1 vf1)
                    (let ((v1-18 f0-3))
                      (.mov vf3 v1-18)
                      )
                    )
                  (.mul.x.vf.w acc vf0 vf2)
                  (.add.mul.y.vf.w acc vf0 vf2 acc)
                  (.add.mul.z.vf.w vf2 vf0 vf2 acc)
                  (.isqrt.vf Q vf3 vf2 :fsf #b0 :ftf #b11)
                  (.wait.vf)
                  (.mul.vf.xyz vf1 vf1 Q)
                  (.nop.vf)
                  (.nop.vf)
                  (.nop.vf)
                  (.svf (&-> a1-9 quad) vf1)
                  (let ((a2-3 (t9-7 a0-10 a1-9 a2-2)))
                    (if (not (time-elapsed? (-> self state-time) (seconds 0.25)))
                        (quaternion-slerp!
                          (-> self root quat)
                          s5-0
                          a2-3
                          (* 0.013333334 (the float (- (current-time) (-> self state-time))))
                          )
                        (quaternion-copy! (-> self root quat) a2-3)
                        )
                    )
                  )
                )
              )
            (suspend)
            ;; og:preserve-this fix vf0 clobbering after suspend
            (init-vf0-vector)
            (set! v1-32 (- (current-time) s4-0))
            (let ((a0-14 (-> self manager)))
              (set! a1-12 (if a0-14
                              (the-as process-drawable (-> a0-14 child 3))
                              )
                    )
              )
            )
          )
        (sound-stop gp-0)
        )
      (let ((a1-13 (new 'stack-no-clear 'event-message-block)))
        (set! (-> a1-13 from) (process->ppointer self))
        (set! (-> a1-13 num-params) 0)
        (set! (-> a1-13 message) 'confirm-shot)
        (let ((t9-11 send-event-function)
              (v1-37 (-> self manager))
              )
          (when (t9-11
                  (if v1-37
                      (-> v1-37 child 3)
                      )
                  a1-13
                  )
            ((lambda :behavior tpl-watcher
               ()
               (local-vars (sv-96 symbol) (sv-112 vector))
               (let ((gp-0 (get-process *default-dead-pool* lightning-tracker #x4000 0)))
                 (when gp-0
                   (let ((t9-1 (method-of-type lightning-tracker activate)))
                     (t9-1 (the-as lightning-tracker gp-0) *entity-pool* "lightning-tracker" (the-as pointer #x70004000))
                     )
                   (let ((s5-0 run-function-in-process)
                         (s4-0 gp-0)
                         (s3-0 lightning-tracker-init)
                         (s2-0 (-> *lightning-spec-id-table* 26))
                         (s1-0 150)
                         (s0-0 #f)
                         )
                     (set! sv-96 (the-as symbol #f))
                     (set! sv-112 (-> self node-list data 4 bone transform trans))
                     (let ((t3-0 (get-trans *target* 3)))
                       ((the-as (function object object object object object object object object none) s5-0)
                        s4-0
                        s3-0
                        s2-0
                        s1-0
                        s0-0
                        sv-96
                        sv-112
                        t3-0
                        )
                       )
                     )
                   (-> gp-0 ppointer)
                   )
                 )
               (send-event
                 *target*
                 'attack-invinc
                 #f
                 (static-attack-info
                   :mask (vehicle-impulse-factor)
                   ((id (new-attack-id)) (damage 250.0) (vehicle-damage-factor 1.0) (vehicle-impulse-factor 1.0) (mode 'shock))
                   )
                 )
               )
             )
            (sound-play "wtcher-fire")
            (suspend-for (seconds 1)
              '()
              )
            )
          )
        )
      (go-virtual standing-down)
      )
    )
  :post ja-post
  )

(defstate die (tpl-watcher)
  :virtual #t
  :enter (behavior ()
    (logior! (-> self focus-status) (focus-status dead))
    )
  :code (behavior ()
    (cond
      ((logtest? (-> group-tpl-watcher-explosion flags) (sp-group-flag sp13))
       (vector-copy! (-> *launch-matrix* trans) (-> self root trans))
       (part-tracker-spawn part-tracker-subsampler :to *entity-pool* :group group-tpl-watcher-explosion)
       )
      (else
        (vector-copy! (-> *launch-matrix* trans) (-> self root trans))
        (part-tracker-spawn part-tracker :to *entity-pool* :group group-tpl-watcher-explosion)
        )
      )
    (let ((v1-33 (-> self root root-prim)))
      (set! (-> v1-33 prim-core collide-as) (collide-spec))
      (set! (-> v1-33 prim-core collide-with) (collide-spec))
      )
    0
    (logior! (-> self draw status) (draw-control-status no-draw))
    (set! (-> self root root-prim local-sphere w) 245760.0)
    ((lambda () (with-pp
                  (let ((gp-0 (new 'stack 'joint-exploder-tuning (the-as uint 0))))
                    (set-vector! (-> gp-0 fountain-rand-transv-lo) -24576.0 12288.0 -24576.0 1.0)
                    (set-vector! (-> gp-0 fountain-rand-transv-hi) 24576.0 98304.0 24576.0 1.0)
                    (process-spawn
                      joint-exploder
                      (art-group-get-by-name *level* "skel-tpl-watcher-explode" (the-as (pointer level) #f))
                      6
                      gp-0
                      *tpl-watcher-exploder-params*
                      :name "joint-exploder"
                      :to pp
                      :unk 0
                      )
                    )
                  #f
                  )
             )
     )
    (sound-play "wtcher-xplo")
    (let ((a1-7 (new 'stack-no-clear 'event-message-block)))
      (set! (-> a1-7 from) (process->ppointer self))
      (set! (-> a1-7 num-params) 0)
      (set! (-> a1-7 message) 'ouch)
      (let ((t9-9 send-event-function)
            (v1-45 (-> self manager))
            )
        (t9-9
          (if v1-45
              (-> v1-45 child 3)
              )
          a1-7
          )
        )
      )
    (suspend-for (seconds 4)
      )
    (while (-> self child)
      (suspend)
      )
    (cleanup-for-death self)
    )
  :post ja-post
  )

(defstate standing-down (tpl-watcher)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('fire)
       (go-virtual firing)
       )
      (('attack)
       (let ((v1-3 (the-as attack-info (-> block param 1))))
         (if (or (>= (-> v1-3 damage) 1.0) (>= (penetrate-using->damage (-> v1-3 penetrate-using)) 1.0))
             (go-virtual die)
             )
         )
       )
      (('prevent-bounce?)
       #t
       )
      )
    )
  :enter (behavior ()
    (set-time! (-> self state-time))
    )
  :code (behavior ()
    (let ((gp-0 (-> self root quat))
          (s5-0 (-> self entity quat))
          )
      (suspend-for (seconds 1.5)
        (quaternion-slerp!
          (-> self root quat)
          gp-0
          s5-0
          (* 0.0022222223 (the float (- (current-time) (-> self state-time))))
          )
        )
      )
    (go-virtual idle)
    )
  :post ja-post
  )

;; WARN: Return type mismatch collide-shape-moving vs none.
(defmethod init-collision! ((this tpl-watcher))
  (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player))))
    (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s5-0 reaction) cshape-reaction-default)
    (set! (-> s5-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (set! (-> s5-0 penetrated-by)
          (penetrate dark-punch explode jak-yellow-shot jak-red-shot jak-blue-shot jak-dark-shot)
          )
    (let ((v1-7 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-7 prim-core collide-as) (collide-spec enemy))
      (set! (-> v1-7 prim-core collide-with) (collide-spec jak player-list))
      (set! (-> v1-7 prim-core action) (collide-action solid))
      (set! (-> v1-7 transform-index) 3)
      (set-vector! (-> v1-7 local-sphere) 0.0 0.0 819.2 6553.6)
      (set! (-> s5-0 total-prims) (the-as uint 1))
      (set! (-> s5-0 root-prim) v1-7)
      )
    (set! (-> s5-0 nav-radius) (* 0.75 (-> s5-0 root-prim local-sphere w)))
    (let ((v1-10 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-10 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-10 prim-core collide-with))
      )
    (set! (-> this root) s5-0)
    )
  (none)
  )

;; WARN: Return type mismatch process-drawable vs tpl-watcher.
(defmethod relocate ((this tpl-watcher) (offset int))
  (if (nonzero? (-> this laser-sight))
      (&+! (-> this laser-sight) offset)
      )
  (if (nonzero? (-> this laser-charge-fx))
      (&+! (-> this laser-charge-fx) offset)
      )
  (the-as tpl-watcher ((method-of-type process-drawable relocate) this offset))
  )

(defmethod deactivate ((this tpl-watcher))
  "Make a process dead, clean it up, remove it from the active pool, and return to dead pool."
  (if (nonzero? (-> this laser-sight))
      (kill-particles (-> this laser-sight))
      )
  (if (nonzero? (-> this laser-charge-fx))
      (kill-particles (-> this laser-charge-fx))
      )
  ((method-of-type process-drawable deactivate) this)
  (none)
  )

(defmethod init-from-entity! ((this tpl-watcher) (arg0 entity-actor))
  "Set up a newly created process from the entity that created it."
  (local-vars (sv-16 res-tag))
  (stack-size-set! (-> this main-thread) 384)
  (init-collision! this)
  (process-drawable-from-entity! this arg0)
  (logior! (-> this mask) (process-mask enemy))
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-tpl-watcher" (the-as (pointer level) #f)))
    (the-as pair 0)
    )
  (logclear! (-> this mask) (process-mask actor-pause))
  (set! sv-16 (new 'static 'res-tag))
  (let ((v1-12 (res-lump-data arg0 'actor-groups (pointer actor-group) :tag-ptr (& sv-16))))
    (if (and v1-12 (> (-> sv-16 elt-count) 0))
        (set! (-> this manager) (the-as tpl-watcher-manager (-> v1-12 0 data 0 actor)))
        (set! (-> this manager) #f)
        )
    )
  (set! (-> this draw light-index) (the-as uint 10))
  (set! (-> this bob-clock) (rand-vu-int-range 0 (seconds 19)))
  (set! (-> this period-a) (rand-vu-int-range 1200 3900))
  (set! (-> this period-b) (rand-vu-int-range 2700 5700))
  (set! (-> this part) (create-launch-control group-tpl-watcher-exhaust-distort this))
  (set! (-> this laser-sight) (create-launch-control group-tpl-watcher-laser-glow this))
  (init-los! (-> this los) this (seconds 0.1) 327680.0 (collide-spec backgnd))
  (set! (-> this laser-charge-fx) (create-launch-control group-tpl-watcher-laser-charge this))
  (let* ((s5-1 (-> this laser-charge-fx))
         (s4-1 (method-of-object s5-1 set-local-space-info))
         (s3-1 (add-connection *part-local-space-engine* this local-space-proc-joint 4 0 0))
         )
    (let ((v1-32 (process->handle this)))
      (if (= v1-32 #f)
          (set! v1-32 (process->handle this))
          )
      (set! (-> (the-as particle-local-space-info s3-1) hand) (the-as handle v1-32))
      )
    (matrix-identity! (-> (the-as particle-local-space-info s3-1) mat-new))
    (matrix-identity! (-> (the-as particle-local-space-info s3-1) mat-prev))
    (set! (-> (the-as particle-local-space-info s3-1) flags) (part-local-space-flags))
    (s4-1 s5-1 (the-as particle-local-space-info s3-1))
    )
  (go (method-of-object this idle))
  )

(deftype tpl-door-switch (process-drawable)
  ()
  (:state-methods
    idle
    down
    )
  )


(defskelgroup skel-tpl-door-switch tpl-door-switch tpl-door-switch-lod0-jg tpl-door-switch-idle-ja
              ((tpl-door-switch-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 6)
              )

(defstate idle (tpl-door-switch)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('attack)
       (let ((v1-1 (the-as object (-> block param 1))))
         (when (and (logtest? (penetrate flop dark-bomb) (-> (the-as attack-info v1-1) penetrate-using))
                    (< (if *target*
                           (vector-vector-xz-distance (-> self root trans) (-> *target* control trans))
                           4096000.0
                           )
                       24576.0
                       )
                    )
           (go-virtual down)
           #f
           )
         )
       )
      )
    )
  :enter (behavior ()
    (setup-masks (-> self draw) 3 0)
    )
  :code sleep-code
  :post ja-post
  )

(defstate down (tpl-door-switch)
  :virtual #t
  :enter (behavior ()
    (sound-play "jak-btn-press")
    (setup-masks (-> self draw) 0 2)
    )
  :code (behavior ()
    (local-vars (sv-96 res-tag))
    (sound-play "stone-lower")
    (ja-no-eval :group! tpl-door-switch-press-ja :num! (seek!) :frame-num 0.0)
    (until (ja-done? 0)
      (suspend)
      (ja :num! (seek!))
      )
    (process-entity-status! self (entity-perm-status subtask-complete) #t)
    (send-event *target* 'change-mode 'normal self)
    (set! sv-96 (new 'static 'res-tag))
    (let ((gp-1 (res-lump-data (-> self entity) 'actor-groups (pointer actor-group) :tag-ptr (& sv-96))))
      (cond
        ((and gp-1 (< (the-as uint 1) (-> sv-96 elt-count)))
         (let ((s5-1 (new 'stack-no-clear 'event-message-block)))
           (set! (-> s5-1 from) (process->ppointer self))
           (set! (-> s5-1 num-params) 1)
           (set! (-> s5-1 message) 'seize-camera)
           (set! (-> s5-1 param 0) (res-lump-struct (-> self entity) 'cutaway-camera uint))
           (let ((t9-9 send-event-function)
                 (v1-39 (-> gp-1 1 data 0 actor))
                 )
             (t9-9
               (if v1-39
                   (-> v1-39 extra process)
                   )
               s5-1
               )
             )
           )
         )
        (else
          (format 0 "ERROR: ~s: entity missing actor-group!~%" (-> self name))
          )
        )
      (suspend)
      (while (< (if *target*
                    (vector-vector-xz-distance (-> self root trans) (-> *target* control trans))
                    4096000.0
                    )
                98304.0
                )
        (suspend)
        )
      (let ((a1-10 (new 'stack-no-clear 'event-message-block)))
        (set! (-> a1-10 from) (process->ppointer self))
        (set! (-> a1-10 num-params) 0)
        (set! (-> a1-10 message) 'wandered-away)
        (let ((t9-12 send-event-function)
              (v1-54 (-> gp-1 1 data 0 actor))
              )
          (t9-12
            (if v1-54
                (-> v1-54 extra process)
                )
            a1-10
            )
          )
        )
      )
    (sleep-code)
    )
  :post transform-post
  )

(defstate already-down (tpl-watcher)
  :enter (behavior ()
    (setup-masks (-> self draw) 0 2)
    )
  :code (behavior ()
    (ja :group! tpl-watcher-idle-ja :num! (identity (the float (ja-num-frames 0))))
    (transform-post)
    (sleep-code)
    )
  :post ja-post
  )

(defmethod init-from-entity! ((this tpl-door-switch) (arg0 entity-actor))
  ;; og:preserve-this added
  (stack-size-set! (-> this main-thread) 512)
  (let ((s4-0 (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player))))
    (set! (-> s4-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s4-0 reaction) cshape-reaction-default)
    (set! (-> s4-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 3) 0)))
      (set! (-> s4-0 total-prims) (the-as uint 4))
      (set! (-> s3-0 prim-core collide-as) (collide-spec obstacle))
      (set! (-> s3-0 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> s3-0 prim-core action) (collide-action solid))
      (set! (-> s3-0 transform-index) 3)
      (set-vector! (-> s3-0 local-sphere) 0.0 0.0 0.0 24576.0)
      (set! (-> s4-0 root-prim) s3-0)
      )
    (let ((v1-13 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 2) (the-as uint 0))))
      (set! (-> v1-13 prim-core collide-as) (collide-spec obstacle))
      (set! (-> v1-13 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> v1-13 prim-core action) (collide-action solid))
      (set! (-> v1-13 transform-index) 6)
      (set-vector! (-> v1-13 local-sphere) 0.0 0.0 0.0 24576.0)
      )
    (let ((v1-15 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 1) (the-as uint 0))))
      (set! (-> v1-15 prim-core collide-as) (collide-spec obstacle))
      (set! (-> v1-15 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> v1-15 prim-core action) (collide-action solid))
      (set! (-> v1-15 transform-index) 5)
      (set-vector! (-> v1-15 local-sphere) 0.0 0.0 0.0 16384.0)
      )
    (let ((v1-17 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0))))
      (set! (-> v1-17 prim-core collide-as) (collide-spec obstacle))
      (set! (-> v1-17 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> v1-17 prim-core action) (collide-action solid))
      (set! (-> v1-17 transform-index) 4)
      (set-vector! (-> v1-17 local-sphere) 0.0 0.0 0.0 8192.0)
      )
    (set! (-> s4-0 nav-radius) (* 0.75 (-> s4-0 root-prim local-sphere w)))
    (let ((v1-20 (-> s4-0 root-prim)))
      (set! (-> s4-0 backup-collide-as) (-> v1-20 prim-core collide-as))
      (set! (-> s4-0 backup-collide-with) (-> v1-20 prim-core collide-with))
      )
    (set! (-> this root) s4-0)
    )
  (process-drawable-from-entity! this arg0)
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-tpl-door-switch" (the-as (pointer level) #f)))
    (the-as pair 0)
    )
  (set! (-> this entity) arg0)
  (if (task-closed? "temple-oracle-watchers-complete")
      (go already-down)
      (go (method-of-object this idle))
      )
  )

(defskelgroup skel-tpl-door-a tpl-door-a tpl-door-a-lod0-jg tpl-door-a-idle-ja
              ((tpl-door-a-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 5 0 8)
              )

(deftype tpl-door-a (com-airlock)
  ()
  )


(defmethod init-from-entity! ((this tpl-door-a) (arg0 entity-actor))
  "Set up a newly created process from the entity that created it."
  (let ((a0-2 (res-lump-struct arg0 'task-name structure)))
    (when (and a0-2 (task-closed? (the-as string a0-2)))
      (cleanup-for-death this)
      (deactivate this)
      )
    )
  (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player))))
    (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s5-0 reaction) cshape-reaction-default)
    (set! (-> s5-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (set! (-> s5-0 penetrated-by) (penetrate))
    (let ((s4-0 (new 'process 'collide-shape-prim-group s5-0 (the-as uint 2) 0)))
      (set! (-> s5-0 total-prims) (the-as uint 3))
      (set! (-> s4-0 prim-core collide-as) (collide-spec obstacle))
      (set! (-> s4-0 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> s4-0 prim-core action) (collide-action solid))
      (set-vector! (-> s4-0 local-sphere) 0.0 20480.0 0.0 32768.0)
      (set! (-> s5-0 root-prim) s4-0)
      )
    (let ((v1-19 (new 'process 'collide-shape-prim-mesh s5-0 (the-as uint 0) (the-as uint 0))))
      (set! (-> v1-19 prim-core collide-as) (collide-spec obstacle))
      (set! (-> v1-19 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> v1-19 prim-core action) (collide-action solid))
      (set! (-> v1-19 transform-index) 4)
      (set-vector! (-> v1-19 local-sphere) 0.0 20480.0 0.0 32768.0)
      )
    (let ((v1-21 (new 'process 'collide-shape-prim-mesh s5-0 (the-as uint 1) (the-as uint 0))))
      (set! (-> v1-21 prim-core collide-as) (collide-spec obstacle))
      (set! (-> v1-21 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> v1-21 prim-core action) (collide-action solid))
      (set! (-> v1-21 transform-index) 5)
      (set-vector! (-> v1-21 local-sphere) 0.0 20480.0 0.0 32768.0)
      )
    (set! (-> s5-0 nav-radius) (* 0.75 (-> s5-0 root-prim local-sphere w)))
    (let ((v1-24 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-24 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-24 prim-core collide-with))
      )
    (set! (-> this root) s5-0)
    )
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-tpl-door-a" (the-as (pointer level) #f)))
    (the-as pair 0)
    )
  (init-airlock! this)
  (set! (-> this lock-frame) 0.0)
  (set! (-> this open-frame) 0.0)
  (set! (-> this sound-open-loop) (static-sound-spec "tpl-a-door-open" :group 0))
  (set! (-> this sound-open-stop) (static-sound-spec "tpl-a-door-hit" :group 0))
  (set! (-> this sound-close-loop) (static-sound-spec "tpl-a-door-cls" :group 0))
  (set! (-> this sound-close-stop) (static-sound-spec "tpl-a-cls-hit" :group 0))
  (set! (-> this sound-behind?) #t)
  (set! (-> this close-speed-multiplier) 6.0)
  (go (method-of-object this close) #t)
  )

(defskelgroup skel-tpl-door-b tpl-door-b tpl-door-b-lod0-jg tpl-door-b-idle-ja
              ((tpl-door-b-lod0-mg (meters 20)) (tpl-door-b-lod1-mg (meters 999999)))
              :bounds (static-spherem 0 5 0 8)
              )

(deftype tpl-door-b (com-airlock)
  ()
  )


(defmethod init-from-entity! ((this tpl-door-b) (arg0 entity-actor))
  "Set up a newly created process from the entity that created it."
  (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player))))
    (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s5-0 reaction) cshape-reaction-default)
    (set! (-> s5-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (set! (-> s5-0 penetrated-by) (penetrate))
    (let ((v1-6 (new 'process 'collide-shape-prim-mesh s5-0 (the-as uint 0) (the-as uint 0))))
      (set! (-> v1-6 prim-core collide-as) (collide-spec obstacle))
      (set! (-> v1-6 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> v1-6 prim-core action) (collide-action solid))
      (set! (-> v1-6 transform-index) 3)
      (set-vector! (-> v1-6 local-sphere) 0.0 20480.0 0.0 32768.0)
      (set! (-> s5-0 total-prims) (the-as uint 1))
      (set! (-> s5-0 root-prim) v1-6)
      )
    (set! (-> s5-0 nav-radius) (* 0.75 (-> s5-0 root-prim local-sphere w)))
    (let ((v1-9 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-9 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-9 prim-core collide-with))
      )
    (set! (-> this root) s5-0)
    )
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-tpl-door-b" (the-as (pointer level) #f)))
    (the-as pair 0)
    )
  (init-airlock! this)
  (set! (-> this lock-frame) 0.0)
  (set! (-> this open-frame) 0.0)
  (set! (-> this sound-open-loop) (static-sound-spec "tpl-a-door-open" :group 0))
  (set! (-> this sound-open-stop) (static-sound-spec "tpl-a-door-hit" :group 0))
  (set! (-> this sound-close-loop) (static-sound-spec "tpl-a-door-cls" :group 0))
  (set! (-> this sound-close-stop) (static-sound-spec "tpl-a-cls-hit" :group 0))
  (set! (-> this sound-behind?) #t)
  (set! (-> this close-speed-multiplier) 1.0)
  (go (method-of-object this close) #t)
  )

(deftype tpl-spinning-plat (process-drawable)
  ((root                collide-shape :override)
   (last-ridden         time-frame)
   (basal-trans         vector         :inline)
   (no-collision-timer  time-frame)
   (attack-id           int32)
   (my-sound            sound-id)
   (pitch-mod-hack      float)
   )
  (:state-methods
    desync
    flip
    wait
    underfoot
    )
  (:methods
    (tpl-spinning-plat-method-24 (_type_) none)
    )
  )


(defskelgroup skel-tpl-spinning-plat tpl-spinning-plat tpl-spinning-plat-lod0-jg tpl-spinning-plat-idle-ja
              ((tpl-spinning-plat-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 5)
              )

;; WARN: Return type mismatch collide-shape-moving vs none.
(defmethod tpl-spinning-plat-method-24 ((this tpl-spinning-plat))
  (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player))))
    (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s5-0 reaction) projectile-bounce-reaction)
    (set! (-> s5-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (let ((s4-0 (new 'process 'collide-shape-prim-group s5-0 (the-as uint 2) 0)))
      (set! (-> s5-0 total-prims) (the-as uint 3))
      (set! (-> s4-0 prim-core collide-as) (collide-spec obstacle pusher))
      (set! (-> s4-0 prim-core collide-with) (collide-spec jak player-list))
      (set! (-> s4-0 prim-core action) (collide-action solid rideable))
      (set-vector! (-> s4-0 local-sphere) 0.0 0.0 0.0 20480.0)
      (set! (-> s5-0 root-prim) s4-0)
      )
    (pusher-init s5-0)
    (let ((v1-14 (new 'process 'collide-shape-prim-mesh s5-0 (the-as uint 0) (the-as uint 1))))
      (set! (-> v1-14 prim-core collide-as) (collide-spec obstacle pusher))
      (set! (-> v1-14 prim-core collide-with) (collide-spec jak player-list))
      (set! (-> v1-14 prim-core action) (collide-action solid rideable))
      (set! (-> v1-14 transform-index) 3)
      (set-vector! (-> v1-14 local-sphere) 0.0 0.0 0.0 20480.0)
      )
    (let ((v1-16 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 2))))
      (set! (-> v1-16 prim-core collide-as) (collide-spec obstacle))
      (set! (-> v1-16 prim-core collide-with) (collide-spec jak player-list))
      (set! (-> v1-16 prim-core action) (collide-action solid))
      (set! (-> v1-16 transform-index) 3)
      (set-vector! (-> v1-16 local-sphere) 0.0 0.0 0.0 18432.0)
      )
    (set! (-> s5-0 nav-radius) (* 0.75 (-> s5-0 root-prim local-sphere w)))
    (let ((v1-19 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-19 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-19 prim-core collide-with))
      )
    (set! (-> this root) s5-0)
    )
  (none)
  )

(defstate flip (tpl-spinning-plat)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('touch)
       (let ((gp-0 (as-type proc process-focusable)))
         (when (and gp-0 ((method-of-type touching-shapes-entry prims-touching?)
                          (the-as touching-shapes-entry (-> block param 0))
                          (-> self root)
                          (the-as uint 2)
                          )
                    )
           (when (time-elapsed? (-> self no-collision-timer) (-> *TARGET-bank* hit-invulnerable-timeout))
             (let ((s4-2
                     (vector-! (new 'stack-no-clear 'vector) (-> (the-as process-focusable gp-0) root trans) (-> self root trans))
                     )
                   )
               (set! (-> s4-2 y) 0.0)
               (vector-xz-normalize! s4-2 1.0)
               (when (send-event
                       gp-0
                       'attack
                       (-> block param 0)
                       (static-attack-info
                         :mask (vehicle-impulse-factor)
                         ((id (the-as uint (-> self attack-id)))
                          (damage 0.0)
                          (vehicle-damage-factor 1.0)
                          (vehicle-impulse-factor 1.0)
                          (vector s4-2)
                          (shove-back (meters 10))
                          (shove-up (meters 10))
                          (control (if (focus-test? (the-as process-focusable gp-0) board)
                                       1.0
                                       0.0
                                       )
                                   )
                          )
                         )
                       )
                 (let ((v0-0 (current-time)))
                   (set! (-> self no-collision-timer) v0-0)
                   v0-0
                   )
                 )
               )
             )
           )
         )
       )
      )
    )
  :enter (behavior ()
    (set! (-> self no-collision-timer) 0)
    0
    )
  :trans (behavior ()
    (let ((v1-3 (-> (the-as collide-shape-prim-group (-> self root root-prim)) child 1)))
      (cond
        ((-> *setting-control* user-current freeze-screen)
         (set! (-> v1-3 prim-core collide-as) (collide-spec))
         (set! (-> v1-3 prim-core collide-with) (collide-spec))
         0
         )
        (else
          (set! (-> v1-3 prim-core collide-as) (collide-spec obstacle))
          (set! (-> v1-3 prim-core collide-with) (collide-spec jak player-list))
          )
        )
      )
    (rider-trans)
    (cond
      ((< 0.0 (-> *setting-control* user-current slow-time))
       (when *sound-player-enable*
         (let ((gp-0 (the-as sound-rpc-set-param (get-sound-buffer-entry))))
           (set! (-> gp-0 command) (sound-command set-param))
           (set! (-> gp-0 id) (-> self my-sound))
           (set! (-> gp-0 params pitch-mod)
                 (the int (* 1524.0 (lerp (-> self pitch-mod-hack) -0.6 (-> *setting-control* user-current slow-time))))
                 )
           (set! (-> gp-0 params mask) (the-as uint 2))
           (-> gp-0 id)
           )
         )
       )
      (else
        '()
        )
      )
    )
  :code (behavior ()
    (set! (-> self pitch-mod-hack) (rand-vu-float-range -0.15 0.15))
    (when (not (-> *setting-control* user-current freeze-screen))
      (sound-stop (-> self my-sound))
      (suspend)
      0
      )
    (when *sound-player-enable*
      (let ((v1-6 (the-as sound-rpc-set-param (get-sound-buffer-entry))))
        (set! (-> v1-6 command) (sound-command set-param))
        (set! (-> v1-6 id) (-> self my-sound))
        (set! (-> v1-6 params mask) (the-as uint 0))
        (-> v1-6 id)
        )
      )
    (sound-play-by-name
      (static-sound-name "coin-flip")
      (-> self my-sound)
      1024
      (the int (* 1524.0 (lerp-scale (-> self pitch-mod-hack) -15.25 (-> self clock clock-ratio) 1.0 0.05)))
      0
      (sound-group)
      #t
      )
    (let ((gp-2 (vector-! (new 'stack-no-clear 'vector) (target-pos 0) (-> self root trans)))
          (s5-1 (new 'stack-no-clear 'quaternion))
          )
      (set! (-> gp-2 y) 0.0)
      (vector-normalize! gp-2 -1.0)
      (vector-rotate90-around-y! gp-2 gp-2)
      (vector-orient-by-quat! gp-2 gp-2 (quaternion-inverse! (new 'stack-no-clear 'quaternion) (-> self root quat)))
      (quaternion-set! s5-1 (-> gp-2 x) (-> gp-2 y) (-> gp-2 z) 0.0)
      (quaternion-normalize! (-> self root quat))
      (let ((gp-3 (quaternion-copy! (new 'stack-no-clear 'quaternion) (-> self root quat)))
            (s5-2 (quaternion*! (new 'stack-no-clear 'quaternion) (-> self root quat) s5-1))
            )
        (quaternion-normalize! s5-2)
        (set-time! (-> self state-time))
        (let ((f30-1 (lerp-scale 45.0 9.0 (-> self clock clock-ratio) 1.0 0.05)))
          (suspend-for (the int f30-1)
            (quaternion-slerp!
              (-> self root quat)
              gp-3
              s5-2
              (/ (the float (- (current-time) (-> self state-time))) f30-1)
              )
            (quaternion-normalize! (-> self root quat))
            )
          )
        (quaternion-copy! (-> self root quat) s5-2)
        )
      )
    (if (-> *setting-control* user-current freeze-screen)
        (go-virtual wait)
        (go-virtual flip)
        )
    )
  :post pusher-post
  )

(defstate desync (tpl-spinning-plat)
  :virtual #t
  :trans rider-trans
  :code (behavior ()
    (let ((f30-0 (res-lump-float (-> self entity) 'tpl-platform-predelay)))
      (suspend-for (the int (* 300.0 f30-0))
        '()
        )
      )
    (go-virtual flip)
    )
  :post pusher-post
  )

(defstate wait (tpl-spinning-plat)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('ridden)
       (set! (-> self last-ridden) (-> *display* real-clock frame-counter))
       (go-virtual underfoot)
       )
      )
    )
  :trans rider-trans
  :code (behavior ()
    (local-vars (v1-10 symbol))
    (set-time! (-> self state-time))
    (let ((gp-0 (the int (* 300.0 (res-lump-float (-> self entity) 'tpl-platform-predelay)))))
      (mod (current-time) 84)
      (until v1-10
        (suspend)
        (let ((v1-9 (mod (current-time) 84)))
          (set! v1-10 (and (>= v1-9 gp-0)
                           (< (- (the-as time-frame v1-9) (- (current-time) (-> self clock old-frame-counter))) gp-0)
                           )
                )
          )
        )
      )
    (go-virtual flip)
    )
  :post pusher-post
  )

(defstate underfoot (tpl-spinning-plat)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('ridden)
       (let ((v0-0 (-> *display* real-clock frame-counter)))
         (set! (-> self last-ridden) v0-0)
         v0-0
         )
       )
      )
    )
  :trans rider-trans
  :code (behavior ()
    (set-time! (-> self state-time))
    (set! (-> self state-time) (-> *display* real-clock frame-counter))
    (suspend-for (seconds 0.25)
      '()
      )
    (while (< (+ (-> *display* real-clock frame-counter) (seconds -1)) (-> self last-ridden))
      (suspend)
      )
    (go-virtual flip)
    )
  :post pusher-post
  )

(defmethod init-from-entity! ((this tpl-spinning-plat) (arg0 entity-actor))
  "Set up a newly created process from the entity that created it."
  (tpl-spinning-plat-method-24 this)
  (process-drawable-from-entity! this arg0)
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-tpl-spinning-plat" (the-as (pointer level) #f)))
    (the-as pair 0)
    )
  (logclear! (-> this mask) (process-mask actor-pause))
  (vector-copy! (-> this basal-trans) (-> this root trans))
  (let* ((v1-8 *game-info*)
         (a0-10 (+ (-> v1-8 attack-id) 1))
         )
    (set! (-> v1-8 attack-id) a0-10)
    (set! (-> this attack-id) (the-as int a0-10))
    )
  (set! (-> this my-sound) (new-sound-id))
  (go (method-of-object this desync))
  )

(deftype tpl-oracle-eye (process-drawable)
  ((leye-sparta  sparticle-launch-control)
   (reye-sparta  sparticle-launch-control)
   )
  (:state-methods
    open
    )
  )


(defskelgroup skel-tpl-oracle-eye tpl-oracle-eye tpl-oracle-eye-lod0-jg tpl-oracle-eye-idle-ja
              ((tpl-oracle-eye-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 4)
              )

(defstate open (tpl-oracle-eye)
  :virtual #t
  :trans (behavior ()
    (if (nonzero? (-> self leye-sparta))
        (spawn-from-cspace (-> self leye-sparta) (joint-node tpl-oracle-eye-lod0-jg lefteyeglow))
        )
    (if (nonzero? (-> self reye-sparta))
        (spawn-from-cspace (-> self reye-sparta) (joint-node tpl-oracle-eye-lod0-jg righteyeglow))
        )
    )
  :code (behavior ()
    (until #f
      (ja-no-eval :group! (ja-group) :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!))
        )
      )
    #f
    )
  :post ja-post
  )

(defmethod init-from-entity! ((this tpl-oracle-eye) (arg0 entity-actor))
  "Set up a newly created process from the entity that created it."
  (set! (-> this root) (new 'process 'trsqv))
  (process-drawable-from-entity! this arg0)
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-tpl-oracle-eye" (the-as (pointer level) #f)))
    (the-as pair 0)
    )
  (set! (-> this leye-sparta) (create-launch-control group-temple-oracle-eye-glow this))
  (set! (-> this reye-sparta) (create-launch-control group-temple-oracle-eye-glow this))
  (go (method-of-object this open))
  )

;; WARN: Return type mismatch process-drawable vs tpl-oracle-eye.
(defmethod relocate ((this tpl-oracle-eye) (offset int))
  (if (nonzero? (-> this leye-sparta))
      (&+! (-> this leye-sparta) offset)
      )
  (if (nonzero? (-> this reye-sparta))
      (&+! (-> this reye-sparta) offset)
      )
  (the-as tpl-oracle-eye ((method-of-type process-drawable relocate) this offset))
  )

(defmethod deactivate ((this tpl-oracle-eye))
  "Make a process dead, clean it up, remove it from the active pool, and return to dead pool."
  (let ((a0-1 (-> this leye-sparta)))
    (if (nonzero? a0-1)
        (kill-particles a0-1)
        )
    )
  (let ((a0-2 (-> this reye-sparta)))
    (if (nonzero? a0-2)
        (kill-particles a0-2)
        )
    )
  ((method-of-type process-drawable deactivate) this)
  (none)
  )

(deftype tpl-banner-b (process-drawable)
  ()
  (:state-methods
    idle
    )
  )


(defskelgroup skel-tpl-banner-b tpl-banner-b tpl-banner-b-lod0-jg tpl-banner-b-idle-ja
              ((tpl-banner-b-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 -4 0 6)
              )

(defstate idle (tpl-banner-b)
  :virtual #t
  :code (behavior ()
    (until #f
      (ja-no-eval :group! (ja-group) :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!))
        )
      )
    #f
    )
  :post ja-post
  )

(defmethod init-from-entity! ((this tpl-banner-b) (arg0 entity-actor))
  "Set up a newly created process from the entity that created it."
  (set! (-> this root) (new 'process 'trsqv))
  (process-drawable-from-entity! this arg0)
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-tpl-banner-b" (the-as (pointer level) #f)))
    (the-as pair 0)
    )
  (go (method-of-object this idle))
  )

(deftype tpl-elevator (elevator)
  ()
  )


(defskelgroup skel-tpl-elevator tpl-elevator tpl-elevator-lod0-jg tpl-elevator-idle-ja
              ((tpl-elevator-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 11)
              :origin-joint-index 3
              )

(defstate running (tpl-elevator)
  :virtual #t
  :enter (behavior ()
    (setup-masks (-> self draw) 3 0)
    (call-parent-state-handler enter)
    )
  :exit (behavior ()
    (setup-masks (-> self draw) 1 2)
    (let ((t9-2 (-> (find-parent-state) exit)))
      (if t9-2
          (t9-2)
          )
      )
    )
  )

(defmethod get-art-group ((this tpl-elevator))
  (art-group-get-by-name *level* "skel-tpl-elevator" (the-as (pointer level) #f))
  )

;; WARN: Return type mismatch collide-shape-moving vs none.
(defmethod init-collision! ((this tpl-elevator))
  (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player))))
    (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s5-0 reaction) cshape-reaction-default)
    (set! (-> s5-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (let ((s4-0 (new 'process 'collide-shape-prim-group s5-0 (the-as uint 2) 0)))
      (set! (-> s5-0 total-prims) (the-as uint 3))
      (set! (-> s4-0 prim-core collide-as) (collide-spec pusher))
      (set! (-> s4-0 prim-core collide-with) (collide-spec jak player-list))
      (set! (-> s4-0 prim-core action) (collide-action solid rideable))
      (set! (-> s4-0 transform-index) 3)
      (set-vector! (-> s4-0 local-sphere) 0.0 0.0 0.0 45056.0)
      (set! (-> s5-0 root-prim) s4-0)
      )
    (pusher-init s5-0)
    (let ((v1-15 (new 'process 'collide-shape-prim-mesh s5-0 (the-as uint 0) (the-as uint 0))))
      (set! (-> v1-15 prim-core collide-as) (collide-spec pusher))
      (set! (-> v1-15 prim-core collide-with) (collide-spec jak bot player-list))
      (set! (-> v1-15 prim-core action) (collide-action solid rideable))
      (set! (-> v1-15 transform-index) 3)
      (set-vector! (-> v1-15 local-sphere) 0.0 0.0 0.0 45056.0)
      )
    (let ((v1-18 (new 'process 'collide-shape-prim-mesh s5-0 (the-as uint 1) (the-as uint (shl #xfe00 16)))))
      (set! (-> v1-18 prim-core action) (collide-action solid))
      (set! (-> v1-18 transform-index) 3)
      (set-vector! (-> v1-18 local-sphere) 0.0 0.0 0.0 45056.0)
      )
    (set! (-> s5-0 nav-radius) (* 0.75 (-> s5-0 root-prim local-sphere w)))
    (let ((v1-21 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-21 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-21 prim-core collide-with))
      )
    (set! (-> this root) s5-0)
    )
  (none)
  )

(defmethod base-plat-method-34 ((this tpl-elevator))
  (setup-masks (-> this draw) 1 2)
  (set! (-> this bounce-scale) 0.0)
  (set! (-> this sound-running-loop) (static-sound-spec "tpl-elevator" :group 0))
  (set! (-> this draw light-index) (the-as uint 4))
  (none)
  )

(deftype tpl-banner (process-drawable)
  ((sound-id  sound-id)
   )
  (:state-methods
    idle
    )
  )


(defskelgroup skel-tpl-banner tpl-banner tpl-banner-lod0-jg tpl-banner-idle-ja
              ((tpl-banner-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 -4.5 0 6)
              )

(defstate idle (tpl-banner)
  :virtual #t
  :code (behavior ()
    (until #f
      (if (nonzero? (-> self sound))
          (update! (-> self sound))
          )
      (ja-no-eval :group! (ja-group) :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!))
        )
      )
    #f
    )
  :post ja-post
  )

(defmethod init-from-entity! ((this tpl-banner) (arg0 entity-actor))
  "Set up a newly created process from the entity that created it."
  (set! (-> this root) (new 'process 'trsqv))
  (process-drawable-from-entity! this arg0)
  (initialize-skeleton
    this
    (the-as skeleton-group (art-group-get-by-name *level* "skel-tpl-banner" (the-as (pointer level) #f)))
    (the-as pair 0)
    )
  (set! (-> this sound-id) (new-sound-id))
  (logclear! (-> this mask) (process-mask actor-pause))
  (go (method-of-object this idle))
  )

(defmethod deactivate ((this tpl-banner))
  "Make a process dead, clean it up, remove it from the active pool, and return to dead pool."
  (if (-> this sound-id)
      (sound-stop (-> this sound-id))
      )
  ((method-of-type process-focusable deactivate) (the-as process-focusable this))
  (none)
  )
