;;-*-Lisp-*-
(in-package goal)
(bundles "SUN.DGO")
(require "engine/common-obs/generic-obs.gc")

;; DECOMP BEGINS

(deftype sun-iris-door (process-drawable)
  ((root                   collide-shape :override)
   (timeout                float)
   (proximity?             symbol)
   (directional-proximity? symbol)
   (move-to?               symbol)
   (locked-by-task?        symbol)
   (close-dist             float)
   (open-dist              float)
   (move-to-pos            vector :inline)
   (outward-vec            vector :inline)
   (move-to-quat           quaternion :inline))
  (:methods
   (should-close? (_type_) symbol)
   (should-open? (_type_) symbol))
  (:states
   sun-iris-door-closed
   sun-iris-door-closing
   sun-iris-door-open
   sun-iris-door-opening))

(defskelgroup *sun-iris-door-sg*
  sun-iris-door
  sun-iris-door-lod0-jg
  sun-iris-door-idle-ja
  ((sun-iris-door-lod0-mg (meters 999999)))
  :bounds (static-spherem 0 0 0 4.5))

(defmethod should-open? ((this sun-iris-door))
  (let ((f30-0 1228800.0))
    0.0
    (let ((f0-7 (cond
                  ((-> this directional-proximity?)
                   (let ((s5-0 (new 'stack-no-clear 'vector)))
                     (when *target*
                       (vector-! s5-0 (target-pos 0) (-> this root trans))
                       (set! (-> s5-0 y) 0.0)
                       (set! f30-0 (fabs (vector-dot s5-0 (-> this outward-vec)))))
                     (vector-! s5-0 (camera-pos) (-> this root trans))
                     (set! (-> s5-0 y) 0.0)
                     (fabs (vector-dot s5-0 (-> this outward-vec)))))
                  (else
                   (if *target* (set! f30-0 (vector-vector-xz-distance (-> this root trans) (target-pos 0))))
                   (vector-vector-xz-distance (-> this root trans) (camera-pos))))))
      (when (or (>= (-> this open-dist) f30-0) (>= (-> this open-dist) f0-7))
        (if (or (not (-> this locked-by-task?)) (task-complete? *game-info* (-> this entity extra perm task))) (return #t)))))
  #f)

(defstate sun-iris-door-closed (sun-iris-door)
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('trigger) (go sun-iris-door-opening))
        (('move-to)
         (set! (-> self move-to?) #t)
         (set! (-> self move-to-pos quad) (-> (the-as vector (-> block param 0)) quad))
         (quaternion-copy! (-> self move-to-quat) (the-as quaternion (-> block param 1))))))
  :trans
    (behavior ()
      (when (-> self proximity?)
        (if (should-open? self) (go sun-iris-door-opening))))
  :code
    (behavior ()
      (loop
        (logior! (-> self mask) (process-mask sleep-code))
        (suspend)))
  :post
    (behavior ()
      (when (-> self move-to?)
        (set! (-> self move-to?) #f)
        (move-to-point! (-> self root) (-> self move-to-pos))
        (quaternion-copy! (-> self root quat) (-> self move-to-quat))
        (ja-post))))

(defstate sun-iris-door-opening (sun-iris-door)
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('untrigger) (go sun-iris-door-closing))
        (('move-to)
         (set! (-> self move-to?) #t)
         (set! (-> self move-to-pos quad) (-> (the-as vector (-> block param 0)) quad))
         (quaternion-copy! (-> self move-to-quat) (the-as quaternion (-> block param 1))))))
  :code
    (behavior ()
      (sound-play "irisdoor2")
      (ja-no-eval :num! (seek!))
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!)))
      (ja-post)
      (go sun-iris-door-open))
  :post
    (behavior ()
      (cond
        ((-> self move-to?)
         (set! (-> self move-to?) #f)
         (move-to-point! (-> self root) (-> self move-to-pos))
         (quaternion-copy! (-> self root quat) (-> self move-to-quat))
         (ja-post))
        (else (transform-post)))))

(defmethod should-close? ((this sun-iris-door))
  (let ((f30-0 1228800.0))
    0.0
    (let ((f0-7 (cond
                  ((-> this directional-proximity?)
                   (let ((s5-0 (new 'stack-no-clear 'vector)))
                     (when *target*
                       (vector-! s5-0 (target-pos 0) (-> this root trans))
                       (set! (-> s5-0 y) 0.0)
                       (set! f30-0 (fabs (vector-dot s5-0 (-> this outward-vec)))))
                     (vector-! s5-0 (camera-pos) (-> this root trans))
                     (set! (-> s5-0 y) 0.0)
                     (fabs (vector-dot s5-0 (-> this outward-vec)))))
                  (else
                   (if *target* (set! f30-0 (vector-vector-xz-distance (-> this root trans) (target-pos 0))))
                   (vector-vector-xz-distance (-> this root trans) (camera-pos))))))
      (when (and (>= f30-0 (-> this close-dist)) (>= f0-7 (-> this close-dist)))
        (cond
          ((and *target* (-> this directional-proximity?))
           (let ((s4-6 (new 'stack-no-clear 'vector))
                 (s5-3 (new 'stack-no-clear 'vector)))
             (vector-! s4-6 (target-pos 0) (-> this root trans))
             (set! (-> s4-6 y) 0.0)
             (vector-! s5-3 (camera-pos) (-> this root trans))
             (set! (-> s5-3 y) 0.0)
             (case (>= (vector-dot (-> this outward-vec) s4-6) 0.0)
               (((>= (vector-dot (-> this outward-vec) s5-3) 0.0)) (return #t)))))
          (else (return #t))))))
  #f)

(defstate sun-iris-door-open (sun-iris-door)
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('trigger) (let ((v0-0 (the-as object (current-time)))) (set! (-> self state-time) (the-as time-frame v0-0)) v0-0))
        (('untrigger) (go sun-iris-door-closing))
        (('move-to)
         (set! (-> self move-to?) #t)
         (set! (-> self move-to-pos quad) (-> (the-as vector (-> block param 0)) quad))
         (quaternion-copy! (-> self move-to-quat) (the-as quaternion (-> block param 1))))))
  :enter
    (behavior ()
      (set-time! (-> self state-time))
      (clear-collide-with-as (-> self root))
      (logior! (-> self draw status) (draw-status hidden)))
  :exit
    (behavior ()
      (restore-collide-with-as (-> self root))
      (logclear! (-> self draw status) (draw-status hidden)))
  :trans
    (behavior ()
      (when (-> self proximity?)
        (if (should-close? self) (go sun-iris-door-closing)))
      (if (and (!= (-> self timeout) 0.0) (time-elapsed? (-> self state-time) (the int (* 300.0 (-> self timeout)))))
        (go sun-iris-door-closing)))
  :code
    (behavior ()
      (loop
        (logior! (-> self mask) (process-mask sleep-code))
        (suspend)))
  :post
    (behavior ()
      (when (-> self move-to?)
        (set! (-> self move-to?) #f)
        (move-to-point! (-> self root) (-> self move-to-pos))
        (quaternion-copy! (-> self root quat) (-> self move-to-quat))
        (ja-post))))

(defstate sun-iris-door-closing (sun-iris-door)
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('trigger) (go sun-iris-door-opening))
        (('move-to)
         (set! (-> self move-to?) #t)
         (set! (-> self move-to-pos quad) (-> (the-as vector (-> block param 0)) quad))
         (quaternion-copy! (-> self move-to-quat) (the-as quaternion (-> block param 1))))))
  :code
    (behavior ()
      (sound-play "irisdoor2")
      (ja-no-eval :num! (seek! 0.0))
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek! 0.0)))
      (ja-post)
      (go sun-iris-door-closed))
  :post
    (behavior ()
      (cond
        ((-> self move-to?)
         (set! (-> self move-to?) #f)
         (move-to-point! (-> self root) (-> self move-to-pos))
         (quaternion-copy! (-> self root quat) (-> self move-to-quat))
         (ja-post))
        (else (transform-post)))))

(defmethod init-from-entity! ((this sun-iris-door) (arg0 entity-actor))
  (local-vars (sv-16 res-tag))
  (set! (-> this move-to?) #f)
  (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-others))))
    (let ((s3-0 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0))))
      (set! (-> s3-0 prim-core collide-as) (collide-kind wall-object))
      (set! (-> s3-0 collide-with) (collide-kind target))
      (set! (-> s3-0 prim-core action) (collide-action solid))
      (set! (-> s3-0 prim-core offense) (collide-offense indestructible))
      (set! (-> s3-0 transform-index) 0)
      (set-vector! (-> s3-0 local-sphere) 0.0 0.0 0.0 24576.0)
      (set-root-prim! s4-0 s3-0))
    (set! (-> s4-0 nav-radius) (* 0.75 (-> s4-0 root-prim local-sphere w)))
    (backup-collide-with-as s4-0)
    (set! (-> this root) s4-0))
  (process-drawable-from-entity! this arg0)
  (initialize-skeleton this *sun-iris-door-sg* '())
  (set! (-> this close-dist) 49152.0)
  (set! (-> this open-dist) 40960.0)
  (set! (-> this timeout) (res-lump-float arg0 'timeout))
  (set! (-> this proximity?) (nonzero? (res-lump-value arg0 'proximity uint128)))
  (set! (-> this directional-proximity?) #f)
  (when (name= (-> this name) "sun-iris-door-6")
    (set! (-> this close-dist) 16384.0)
    (set! (-> this open-dist) 8192.0)
    (set! (-> this directional-proximity?) #t))
  (set! (-> this locked-by-task?) (nonzero? (-> this entity extra perm task)))
  (let ((f0-11 (res-lump-float arg0 'scale-factor :default 1.0)))
    (set-vector! (-> this root scale) f0-11 f0-11 f0-11 1.0)
    (set! (-> this draw bounds w) (* 18432.0 f0-11))
    (let ((v1-25 (-> this root root-prim))) (set! (-> v1-25 local-sphere w) (* 24576.0 f0-11 f0-11))))
  (set! sv-16 (new 'static 'res-tag))
  (let ((v1-28 (res-lump-data (-> this entity) 'trans-offset (pointer float) :tag-ptr (& sv-16))))
    (when v1-28
      (+! (-> this root trans x) (-> v1-28 0))
      (+! (-> this root trans y) (-> v1-28 1))
      (+! (-> this root trans z) (-> v1-28 2))))
  (let ((f30-0 (quaternion-y-angle (-> this root quat))))
    (set-vector! (-> this outward-vec) (sin f30-0) 0.0 (cos f30-0) 1.0))
  (ja-channel-set! 1)
  (let ((s5-2 (-> this skel root-channel 0)))
    (joint-control-channel-group-eval! s5-2 (the-as art-joint-anim (-> this draw art-group data 3)) num-func-identity)
    (set! (-> s5-2 frame-num) 0.0))
  (update-transforms! (-> this root))
  (ja-post)
  (go sun-iris-door-closed)
  (none))

(defbehavior sun-iris-door-init-by-other sun-iris-door ((arg0 vector) (arg1 quaternion) (arg2 symbol))
  (set! (-> self move-to?) #f)
  (let ((s3-0 (new 'process 'collide-shape self (collide-list-enum hit-by-others))))
    (let ((s2-0 (new 'process 'collide-shape-prim-mesh s3-0 (the-as uint 0) (the-as uint 0))))
      (set! (-> s2-0 prim-core collide-as) (collide-kind wall-object))
      (set! (-> s2-0 collide-with) (collide-kind target))
      (set! (-> s2-0 prim-core action) (collide-action solid))
      (set! (-> s2-0 prim-core offense) (collide-offense indestructible))
      (set! (-> s2-0 transform-index) 0)
      (set-vector! (-> s2-0 local-sphere) 0.0 0.0 0.0 24576.0)
      (set-root-prim! s3-0 s2-0))
    (set! (-> s3-0 nav-radius) (* 0.75 (-> s3-0 root-prim local-sphere w)))
    (backup-collide-with-as s3-0)
    (set! (-> self root) s3-0))
  (set! (-> self root trans quad) (-> arg0 quad))
  (quaternion-copy! (-> self root quat) arg1)
  (initialize-skeleton self *sun-iris-door-sg* '())
  (set! (-> self close-dist) 49152.0)
  (set! (-> self open-dist) 40960.0)
  (set! (-> self timeout) 0.0)
  (set! (-> self proximity?) #f)
  (set! (-> self directional-proximity?) #f)
  (ja-channel-set! 1)
  (if arg2 (ja :group! sun-iris-door-idle-ja :num! max) (ja :group! sun-iris-door-idle-ja :num! min))
  (transform-post)
  (if arg2 (go sun-iris-door-open) (go sun-iris-door-closed))
  (none))
