;;-*-Lisp-*-
(in-package goal)
(bundles "OGR.DGO")
(require "engine/geometry/path.gc")
(require "engine/common-obs/generic-obs.gc")
(require "engine/collide/collide-cache.gc")
(require "engine/entity/entity.gc")

;; DECOMP BEGINS

(defskelgroup *ogrecam-sg*
  ogrecam
  ogrecam-lod0-jg
  -1
  ((ogrecam-lod0-mg (meters 999999)))
  :bounds (static-spherem 0 2 0 6))

(deftype plunger-lurker (process-drawable)
  ((alt-actor entity-actor)
   (got-hit   symbol))
  (:states
   plunger-lurker-die
   plunger-lurker-flee
   plunger-lurker-idle
   plunger-lurker-plunge))


(defskelgroup *plunger-lurker-sg*
  plunger-lurker
  plunger-lurker-lod0-jg
  plunger-lurker-idle-ja
  ((plunger-lurker-lod0-mg (meters 20)) (plunger-lurker-lod1-mg (meters 40)) (plunger-lurker-lod2-mg (meters 999999)))
  :bounds (static-spherem 2 4 0 12))

(defstate plunger-lurker-plunge (plunger-lurker)
  :code
    (behavior ()
      (set-setting! 'allow-progress #f 0.0 0)
      (logclear! (-> self mask) (process-mask actor-pause))
      (process-entity-status! self (entity-perm-status bit-3) #t)
      (while (or (not *target*) (logtest? (-> *target* state-flags) (state-flags being-attacked dying)))
        (suspend))
      (while (not (process-grab? *target*))
        (suspend))
      (let ((gp-1 (ppointer->handle (manipy-spawn (-> self entity extra trans) (-> self entity) *ogrecam-sg* #f :to self))))
        (let ((s5-0 (the-as othercam (get-process *default-dead-pool* othercam #x4000))))
          (ppointer->handle (when s5-0
                              (let ((t9-7 (method-of-type othercam activate))) (t9-7 s5-0 (-> gp-1 process 0) 'othercam (the-as pointer #x70004000)))
                              (run-now-in-process s5-0 othercam-init-by-other (-> gp-1 process 0) 4 #f #t)
                              (-> s5-0 ppointer))))
        (send-event (handle->process gp-1)
                    'eval
                    (lambda :behavior manipy ()
                      (let ((v0-0 (logior (-> self draw status) (draw-status skip-bones))))
                        (set! (-> self draw status) v0-0)
                        (the-as uint v0-0))))
        (let ((a1-9 (new 'stack-no-clear 'event-message-block)))
          (set! (-> a1-9 from) self)
          (set! (-> a1-9 num-params) 1)
          (set! (-> a1-9 message) 'clone-and-kill-links)
          (set! (-> a1-9 param 0) (the-as uint (process->handle self)))
          (let ((t9-10 send-event-function)
                (v1-34 (-> self alt-actor)))
            (t9-10 (if v1-34 (-> v1-34 extra process)) a1-9)))
        (send-event (-> gp-1 process 0) 'clone-copy-trans #f)
        (send-event (-> gp-1 process 0) 'anim-mode 'clone-anim)
        (ja-play-spooled-anim (new 'static
                                   'spool-anim
                                   :name "plunger-lurker-blowup"
                                   :index 7
                                   :parts 4
                                   :command-list
                                   '((200 alive "tntbarrel-223")
                                    (200 alive "tntbarrel-222")
                                    (200 alive "tntbarrel-221")
                                    (200 alive "tntbarrel-220")
                                    (200 alive "tntbarrel-224")
                                    (200 alive "tntbarrel-219")
                                    (200 alive "tntbarrel-246")
                                    (200 alive "tntbarrel-249")
                                    (200 alive "tntbarrel-250")
                                    (200 alive "tntbarrel-251")
                                    (200 alive "tntbarrel-225")
                                    (201 joint "cameraB")
                                    (220 send-event "tntbarrel-223" 'die-big)
                                    (230 send-event "tntbarrel-222" 'die-big)
                                    (240 send-event "tntbarrel-221" 'die-big)
                                    (240 send-event "tntbarrel-220" 'die-big)
                                    (245 send-event "tntbarrel-224" 'die-big)
                                    (250 send-event "tntbarrel-219" 'die-big)
                                    (251 joint "cameraA")
                                    (260 send-event "tntbarrel-246" 'die-big)
                                    (325 send-event "tntbarrel-249" 'die-big)
                                    (380 send-event "tntbarrel-250" 'die-big)
                                    (410 send-event "tntbarrel-251" 'die-big)
                                    (420 blackout 30)
                                    (421 joint "cameraB")
                                    (430 send-event "tntbarrel-225" 'die-big)))
                              (the-as art-joint-anim #f)
                              (the-as art-joint-anim plunger-lurker-idle-ja)
                              (the-as (function process-drawable symbol) false-func))
        (if (handle->process gp-1) (deactivate (-> gp-1 process 0))))
      (let ((a1-14 (new 'stack-no-clear 'event-message-block)))
        (set! (-> a1-14 from) self)
        (set! (-> a1-14 num-params) 0)
        (set! (-> a1-14 message) 'reset)
        (let ((t9-15 send-event-function)
              (v1-56 (-> self alt-actor)))
          (t9-15 (if v1-56 (-> v1-56 extra process)) a1-14)))
      (process-release? *target*)
      (suspend)
      0
      (send-event *target* 'attack-invinc #f (static-attack-info ((mode 'instant-death))))
      (cleanup-for-death self)
      (deactivate self)
      (loop
        (suspend)))
  :post ja-post)

(defstate plunger-lurker-flee (plunger-lurker)
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('attack) (let ((v0-0 #t)) (set! (-> self got-hit) v0-0) v0-0))))
  :trans
    (behavior ()
      (when (-> self got-hit)
        (close-specific-task! (game-task plunger-lurker-hit) (task-status need-hint))
        (process-entity-status! self (entity-perm-status complete) #t)
        (level-hint-spawn (text-id ogre-plunger-lurker-resolution) "sksp0321" (the-as entity #f) *entity-pool* (game-task none))
        (process-spawn part-tracker
                       :init
                       part-tracker-init
                       (-> *part-group-id-table* 474)
                       -1
                       #f
                       #f
                       #f
                       (-> self root trans)
                       :to
                       *entity-pool*)
        (cleanup-for-death self)
        (deactivate self)))
  :code
    (behavior ()
      (ja-no-eval :group! plunger-lurker-notice-ja :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!)))
      (ja-no-eval :group! plunger-lurker-death-ja :num! (seek!) :frame-num 0.0)
      (until (ja-done? 0)
        (suspend)
        (ja :num! (seek!)))
      (loop
        (suspend)))
  :post ja-post)

(defstate plunger-lurker-idle (plunger-lurker)
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('plunge) (logclear! (-> self mask) (process-mask actor-pause)) (go plunger-lurker-plunge))))
  :trans
    (behavior ()
      (spool-push *art-control* "plunger-lurker-blowup" 0 self -99.0)
      (when (and *target* (< (vector-vector-distance-squared (-> self root trans) (target-pos 0)) 6710886400.0))
        (logclear! (-> self mask) (process-mask actor-pause))
        (go plunger-lurker-flee)))
  :code
    (behavior ()
      (loop
        (ja-no-eval :group! plunger-lurker-idle-ja :num! (seek!) :frame-num 0.0)
        (until (ja-done? 0)
          (suspend)
          (ja :num! (seek!)))))
  :post ja-post)

(defstate plunger-lurker-die (plunger-lurker)
  :code
    (behavior ()
      (cleanup-for-death self)
      (deactivate self)
      (suspend)
      0))

(defmethod init-from-entity! ((this plunger-lurker) (arg0 entity-actor))
  (stack-size-set! (-> this main-thread) 512)
  (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player))))
    (let ((s3-0 (new 'process 'collide-shape-prim-sphere s4-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 20480.0 -16384.0 40960.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 *plunger-lurker-sg* '())
  (set! (-> this alt-actor) (entity-actor-lookup arg0 'alt-actor 0))
  (set! (-> this got-hit) #f)
  (quaternion-rotate-y! (-> this root quat) (-> this root quat) -16384.0)
  (if (= (get-task-status (game-task plunger-lurker-hit)) (task-status invalid))
    (go plunger-lurker-die)
    (go plunger-lurker-idle))
  (none))

(deftype flying-lurker (process-drawable)
  ((curve-position    float)
   (speed             float)
   (tangent           vector :inline)
   (anim-blend        float)
   (y-offset          float)
   (y-offset-desired  float)
   (y-vel             float)
   (last-look-time    time-frame)
   (time-to-next-look time-frame)
   (take-off          symbol)
   (race-seconds      float)
   (race-start-time   time-frame)
   (rank              int32)
   (alt-actor         entity-actor)
   (alt-trans         vector)
   (shadow-backup     shadow-geo)
   (try-count         uint8)
   (try-counted       symbol)
   (default-bounds    vector :inline))
  (:methods
   (flying-lurker-method-20 (_type_) none))
  (:states (flying-lurker-clone handle string)
   flying-lurker-die
   flying-lurker-fly
   flying-lurker-idle
   flying-lurker-sleep
   flying-lurker-start))


(defskelgroup *flying-lurker-sg*
  flying-lurker
  flying-lurker-lod0-jg
  flying-lurker-fly-ja
  ((flying-lurker-lod0-mg (meters 20)) (flying-lurker-lod1-mg (meters 40)) (flying-lurker-lod2-mg (meters 999999)))
  :bounds (static-spherem 0 2 0 6)
  :longest-edge (meters 2.3)
  :shadow flying-lurker-shadow-mg)

(defmethod flying-lurker-method-20 ((this flying-lurker))
  (with-pp
    (let ((s5-0 (-> this draw shadow-ctrl))
          (s4-0 #f))
      (when (-> this draw shadow)
        (when (or (logtest? (-> this draw status) (draw-status was-drawn))
                  (< (vector-vector-xz-distance-squared (-> this root trans) (camera-pos)) 10485760000.0))
          (let ((s3-1 (new 'stack-no-clear 'collide-tri-result))
                (a1-1 (new 'stack-no-clear 'vector))
                (a2-0 (new 'stack-no-clear 'vector)))
            (set! (-> a1-1 quad) (-> this root trans quad))
            (+! (-> a1-1 y) -8192.0)
            (set-vector! a2-0 0.0 -81920.0 0.0 1.0)
            (when (>= (fill-and-probe-using-line-sphere *collide-cache*
                                                        a1-1
                                                        a2-0
                                                        8192.0
                                                        (collide-kind background)
                                                        pp
                                                        s3-1
                                                        (new 'static 'pat-surface :noentity #x1))
                      0.0)
              (set! (-> s3-1 intersect w) 8192.0)
              (when (and (sphere-in-view-frustum? (the-as sphere (-> s3-1 intersect)))
                         (< 822083600.0 (vector-vector-distance-squared (-> s3-1 intersect) (camera-pos))))
                (set! s4-0 #t)
                (let ((v1-17 s5-0)) (logclear! (-> v1-17 settings flags) (shadow-flags disable-draw)))
                0
                (let ((v1-19 s5-0)) (set! (-> v1-19 settings bot-plane w) (- (+ -8192.0 (-> s3-1 intersect y)))))
                0
                (let ((v1-21 s5-0)) (set! (-> v1-21 settings top-plane w) (- (+ 6144.0 (-> s3-1 intersect y)))))
                0
                (let ((s2-2 (new 'stack-no-clear 'bounding-box)))
                  (let ((s1-1 (new 'stack-no-clear 'vector)))
                    (vector<-cspace! s1-1 (-> this node-list data 4))
                    (vector+float! (-> s2-2 min) s1-1 -18432.0)
                    (vector+float! (-> s2-2 max) s1-1 18432.0))
                  (add-spheres! s2-2 (the-as (inline-array sphere) (-> s3-1 intersect)) 1)
                  (let ((f0-17 (* 0.5 (vector-vector-distance (-> s2-2 min) (-> s2-2 max)))))
                    (set-vector! (-> this draw bounds)
                                 (* 0.5 (+ (-> s2-2 min x) (-> s2-2 max x)))
                                 (* 0.5 (+ (-> s2-2 min y) (-> s2-2 max y)))
                                 (* 0.5 (+ (-> s2-2 min z) (-> s2-2 max z)))
                                 1.0)
                    (vector-! (-> this draw bounds) (-> this draw bounds) (-> this root trans))
                    (set! (-> this draw bounds w) f0-17)))
                (set! (-> this draw origin-joint-index) (the-as uint 0))
                0)))))
      (when (not s4-0)
        (logior! (-> s5-0 settings flags) (shadow-flags disable-draw))
        0
        (set! (-> this draw bounds quad) (-> this default-bounds quad))
        (set! (-> this draw origin-joint-index) (the-as uint 4))))
    (none)))

(defbehavior flying-lurker-inc-try-count flying-lurker ()
  (when (not (-> self try-counted))
    (set! (-> self try-counted) #t)
    (let ((gp-0 (-> self entity extra perm)))
      (logior! (-> gp-0 status) (entity-perm-status user-set-from-cstage))
      (seekl! (-> gp-0 user-int8 0) 255 1)
      (set! (-> self try-count) (the-as uint (-> gp-0 user-int8 0)))))
  0
  (none))

(defun play-movie? ()
  (= (get-task-status (game-task plunger-lurker-hit)) (task-status unknown)))

(defstate flying-lurker-die (flying-lurker)
  :code
    (behavior ()
      (cleanup-for-death self)
      (deactivate self)))

(defstate flying-lurker-sleep (flying-lurker)
  :code
    (behavior ()
      (process-entity-status! self (entity-perm-status bit-3) #f)
      (logior! (-> self draw status) (draw-status hidden))
      (loop
        (suspend))))

(defbehavior first? flying-lurker ()
  (not (-> self link prev)))

(defbehavior flying-lurker-calc-speed flying-lurker ((arg0 meters) (arg1 meters) (arg2 meters) (arg3 meters))
  (let ((s4-1 (vector-! (new 'stack-no-clear 'vector) (target-pos 0) (-> self root trans)))
        (s3-0 (new 'stack-no-clear 'vector)))
    (set! (-> s3-0 quad) (-> self tangent quad))
    0.0
    (let ((f30-0 (vector-length s4-1)))
      (set! (-> s4-1 y) 0.0)
      (set! (-> s3-0 y) 0.0)
      (let ((f28-0 (vector-dot s4-1 s3-0)))
        (let ((f26-0 (* (path-distance (-> self path))
                        (/ (the float (- (-> *display* game-frame-counter) (-> self race-start-time))) (-> self race-seconds))))
              (f0-6 (* (path-distance (-> self path)) (-> self curve-position))))
          0.0
          (let* ((f1-6 (* -81920.0 (the float (-> self rank))))
                 (f0-10 (+ (if (< f26-0 f0-6) (fmax (+ -81920.0 f1-6) (- f26-0 f0-6)) (fmin (+ 245760.0 f1-6) (- f26-0 f0-6))) f28-0))
                 (f1-10 (/ f0-10 (meters 20)))
                 (f0-12 (fmax -0.5 (fmin 0.5 f1-10))))
            (set! (-> self speed) (+ (* (+ 0.5 f0-12) (- arg2 arg3)) arg3))))
        ;; og:preserve-this PAL patch here
        (let ((f0-16 65536.0))
          (if (and (< 0.6332 (-> self curve-position)) (< (-> self curve-position) 0.6928)) (set! f0-16 40960.0))
          (set! (-> self y-offset-desired) (fmin f0-16 (fmax 0.0 (* 1.6 (- 40960.0 (fmin (- f28-0) f30-0))))))))))
  (none))

(defbehavior flying-lurker-move flying-lurker ()
  (+! (-> self curve-position)
      (/ (the float (* (- (current-time) (-> *display* old-base-frame-counter)) (the int (-> self speed))))
         (path-distance (-> self path))))
  (set! (-> self curve-position) (fmin 1.0 (fmax 0.0 (-> self curve-position))))
  (eval-path-curve! (-> self path) (-> self root trans) (-> self curve-position) 'interp)
  (cond
    ((< (-> self y-offset-desired) (-> self y-offset))
     (set! (-> self y-vel) (* 0.25 (- (-> self y-offset-desired) (-> self y-offset))))
     (set! (-> self y-vel) (fmax -436.90668 (-> self y-vel)))
     (+! (-> self y-offset) (-> self y-vel))
     (when (>= (-> self y-offset-desired) (-> self y-offset))
       (set! (-> self y-offset) (-> self y-offset-desired))
       (set! (-> self y-vel) 0.0)))
    ((< (-> self y-offset) (-> self y-offset-desired))
     (set! (-> self y-vel) (* 0.5 (- (-> self y-offset-desired) (-> self y-offset))))
     (set! (-> self y-vel) (fmin 436.90668 (-> self y-vel)))
     (+! (-> self y-offset) (-> self y-vel))
     (when (>= (-> self y-offset) (-> self y-offset-desired))
       (set! (-> self y-offset) (-> self y-offset-desired))
       (set! (-> self y-vel) 0.0))))
  (+! (-> self root trans y) (-> self y-offset))
  (+! (-> self root trans y) 12288.0)
  (none))

(defbehavior flying-lurker-rotate flying-lurker ()
  (let ((gp-0 (new 'stack-no-clear 'matrix)))
    (let ((s5-0 (new 'stack-no-clear 'matrix)))
      (let ((s3-0 (new 'stack-no-clear 'vector))
            (s4-0 (new 'stack-no-clear 'vector)))
        (path-control-method-14 (-> self path) (-> self tangent) (-> self curve-position))
        (eval-path-curve! (-> self path) s3-0 (+ (/ 12288.0 (path-distance (-> self path))) (-> self curve-position)) 'interp)
        (eval-path-curve! (-> self path) s4-0 (+ (/ 4096.0 (path-distance (-> self path))) (-> self curve-position)) 'interp)
        (vector-! s3-0 s3-0 (-> self root trans))
        (vector-! s4-0 s4-0 (-> self root trans))
        (set! (-> s3-0 y) 0.0)
        (set! (-> s4-0 y) 0.0)
        (vector-normalize! s3-0 1.0)
        (vector-normalize! s4-0 1.0)
        (vector-cross! s4-0 s4-0 s3-0)
        (set! (-> self anim-blend) (asin (-> s4-0 y))))
      (set! (-> self anim-blend) (* 0.0010986328 (-> self anim-blend)))
      (set! (-> self anim-blend) (fmax -1.0 (fmin 1.0 (-> self anim-blend))))
      (set! (-> self anim-blend) (sin (* 16384.0 (-> self anim-blend))))
      (forward-down->inv-matrix gp-0 (-> self tangent) (new 'static 'vector :y -1.0))
      (matrix-rotate-z! s5-0 (* -10922.667 (-> self anim-blend)))
      (matrix*! gp-0 s5-0 gp-0))
    (matrix->quaternion (-> self root quat) gp-0)))

(defbehavior flying-lurker-calc-anim-speed flying-lurker ()
  (let* ((f0-1 (fabs (-> self speed)))
         (f0-2 (* 0.07324219 f0-1))
         (f0-3 (+ -15.0 f0-2))
         (f1-3 (* 0.13333334 f0-3)))
    (fmin 1.5 (fmax 0.9 f1-3))))

(defstate flying-lurker-fly (flying-lurker)
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('clone-and-kill-links)
         (let ((a1-1 (new 'stack-no-clear 'event-message-block)))
           (set! (-> a1-1 from) self)
           (set! (-> a1-1 num-params) 0)
           (set! (-> a1-1 message) 'sleep)
           (let ((t9-0 send-event-function)
                 (v1-3 (-> self link next)))
             (t9-0 (if v1-3 (-> v1-3 extra process)) a1-1)))
         (go flying-lurker-clone (the-as handle (-> block param 0)) ""))
        (('die)
         (let ((v1-7 (new 'stack-no-clear 'event-message-block)))
           (set! (-> v1-7 from) proc)
           (set! (-> v1-7 num-params) argc)
           (set! (-> v1-7 message) message)
           (set! (-> v1-7 param 0) (-> block param 0))
           (set! (-> v1-7 param 1) (-> block param 1))
           (set! (-> v1-7 param 2) (-> block param 2))
           (set! (-> v1-7 param 3) (-> block param 3))
           (set! (-> v1-7 param 4) (-> block param 4))
           (set! (-> v1-7 param 5) (-> block param 5))
           (set! (-> v1-7 param 6) (-> block param 6))
           (let ((t9-2 send-event-function)
                 (a1-3 (-> self link next)))
             (t9-2 (if a1-3 (-> a1-3 extra process)) v1-7)))
         (cleanup-for-death self)
         (deactivate self))
        (('sleep)
         (let ((v1-12 (new 'stack-no-clear 'event-message-block)))
           (set! (-> v1-12 from) proc)
           (set! (-> v1-12 num-params) argc)
           (set! (-> v1-12 message) message)
           (set! (-> v1-12 param 0) (-> block param 0))
           (set! (-> v1-12 param 1) (-> block param 1))
           (set! (-> v1-12 param 2) (-> block param 2))
           (set! (-> v1-12 param 3) (-> block param 3))
           (set! (-> v1-12 param 4) (-> block param 4))
           (set! (-> v1-12 param 5) (-> block param 5))
           (set! (-> v1-12 param 6) (-> block param 6))
           (let ((t9-5 send-event-function)
                 (a1-5 (-> self link next)))
             (t9-5 (if a1-5 (-> a1-5 extra process)) v1-12)))
         (go flying-lurker-sleep))
        (('reset)
         (let ((v1-15 (new 'stack-no-clear 'event-message-block)))
           (set! (-> v1-15 from) proc)
           (set! (-> v1-15 num-params) argc)
           (set! (-> v1-15 message) message)
           (set! (-> v1-15 param 0) (-> block param 0))
           (set! (-> v1-15 param 1) (-> block param 1))
           (set! (-> v1-15 param 2) (-> block param 2))
           (set! (-> v1-15 param 3) (-> block param 3))
           (set! (-> v1-15 param 4) (-> block param 4))
           (set! (-> v1-15 param 5) (-> block param 5))
           (set! (-> v1-15 param 6) (-> block param 6))
           (let ((t9-7 send-event-function)
                 (a1-7 (-> self link next)))
             (t9-7 (if a1-7 (-> a1-7 extra process)) v1-15)))
         (deactivate self))))
  :enter
    (behavior ()
      (process-entity-status! self (entity-perm-status bit-3) #t)
      (logclear! (-> self draw status) (draw-status hidden)))
  :trans
    (behavior ()
      (flying-lurker-method-20 self)
      (when (not (movie?))
        (flying-lurker-calc-speed (meters 15) (meters 30) (meters 0.11666667) (meters 0.083333336))
        (flying-lurker-move)
        (flying-lurker-rotate)
        (when (and (-> self alt-actor)
                   (or (< (vector-vector-distance-squared (-> self root trans) (-> self alt-actor extra trans)) 6710886400.0)
                       (and *target* (< 4194304000000.0 (vector-vector-distance-squared (-> self root trans) (target-pos 0))))))
          (set-or-clear-status! (-> self alt-actor) (entity-perm-status dead) #f)
          (entity-birth-no-kill (-> self alt-actor))
          (let ((a1-4 (new 'stack-no-clear 'event-message-block)))
            (set! (-> a1-4 from) self)
            (set! (-> a1-4 num-params) 0)
            (set! (-> a1-4 message) 'plunge)
            (let ((t9-10 send-event-function)
                  (v1-13 (-> self alt-actor)))
              (t9-10 (if v1-13 (-> v1-13 extra process)) a1-4))))))
  :code
    (behavior ()
      (loop
        (when (not (ja-group? flying-lurker-fly-ja))
          (ja-channel-push! 1 (seconds 0.2))
          (ja :group! flying-lurker-fly-ja))
        (ja :num! (loop! (flying-lurker-calc-anim-speed)))
        (suspend)
        (when (time-elapsed? (-> self last-look-time) (-> self time-to-next-look))
          (ja-channel-push! 1 (seconds 0.2))
          (ja-no-eval :group! flying-lurker-look-ja :num! (seek!) :frame-num 0.0)
          (until (ja-done? 0)
            (suspend)
            (ja :num! (seek!)))
          (set-time! (-> self last-look-time))
          (let* ((f30-0 300.0)
                 (f28-0 3.0)
                 (f26-0 5.0)
                 (v1-41 (/ (the-as int (rand-uint31-gen *random-generator*)) 256))
                 (v1-42 (the-as float (logior #x3f800000 v1-41))))
            (set! (-> self time-to-next-look) (the-as time-frame (the int (* f30-0 (+ f28-0 (* f26-0 (+ -1.0 v1-42)))))))))))
  :post ja-post)

(defbehavior flying-lurker-handler flying-lurker ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  (case arg2
    (('fly-away)
     (when (-> self link next)
       (entity-birth-no-kill (-> self link next))
       (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) 'fly-away)
         (set! (-> a1-1 param 0) (the-as uint (/ (the-as int (-> arg3 param 0)) 16)))
         (set! (-> a1-1 param 1) (-> arg3 param 1))
         (let ((t9-1 send-event-function)
               (v1-11 (-> self link next)))
           (t9-1 (if v1-11 (-> v1-11 extra process)) a1-1))))
     (let* ((v1-14 (-> arg3 param 0))
            (a0-4 (-> arg3 param 1))
            (v1-15 (logand v1-14 3)))
       (set! (-> self rank) (the-as int v1-15))
       (cond
         ((< 15 (the-as int a0-4))
          (cond
            ((zero? v1-15) (set! (-> self race-seconds) 33000.0))
            ((= v1-15 1) (set! (-> self race-seconds) 34500.0))
            (else (set! (-> self race-seconds) 36000.0))))
         ((< 10 (the-as int a0-4))
          (cond
            ((zero? v1-15) (set! (-> self race-seconds) 31800.0))
            ((= v1-15 1) (set! (-> self race-seconds) 33300.0))
            (else (set! (-> self race-seconds) 34800.0))))
         ((< 5 (the-as int a0-4))
          (cond
            ((zero? v1-15) (set! (-> self race-seconds) 30600.0))
            ((= v1-15 1) (set! (-> self race-seconds) 32100.0))
            (else (set! (-> self race-seconds) 33600.0))))
         ((zero? v1-15) (set! (-> self race-seconds) 30000.0))
         ((= v1-15 1) (set! (-> self race-seconds) 31500.0))
         (else (set! (-> self race-seconds) 33000.0))))
     (logclear! (-> self mask) (process-mask actor-pause))
     (set! (-> self race-start-time) (-> *display* game-frame-counter))
     (go flying-lurker-fly))))

(defbehavior flying-lurker-play-intro flying-lurker ()
  (logclear! (-> self mask) (process-mask actor-pause))
  (close-specific-task! (game-task plunger-lurker-hit) (task-status unknown))
  (while (and *target*
              (logtest? (-> *target* control unknown-surface00 flags) (surface-flags jump))
              (not (logtest? (-> *target* control status) (cshape-moving-flags onsurf))))
    (suspend))
  (while (not (process-grab? *target*))
    (suspend))
  (kill-current-level-hint '(notice) '() 'exit)
  (while (or (-> *setting-control* current talking)
             (-> *setting-control* current spooling)
             (-> *setting-control* current hint)
             (!= (-> *level* loading-level) (-> *level* level-default)))
    (suspend))
  (suspend)
  (kill-current-level-hint '() '() 'die)
  (suspend)
  (let ((gp-1 (ppointer->handle (manipy-spawn (-> self entity extra trans) (-> self entity) *ogrecam-sg* #f :to self))))
    (let ((s5-0 (the-as othercam (get-process *default-dead-pool* othercam #x4000))))
      (ppointer->handle (when s5-0
                          (let ((t9-8 (method-of-type othercam activate))) (t9-8 s5-0 (-> gp-1 process 0) 'othercam (the-as pointer #x70004000)))
                          (run-now-in-process s5-0 othercam-init-by-other (-> gp-1 process 0) 4 #f #t)
                          (-> s5-0 ppointer))))
    (send-event (handle->process gp-1)
                'eval
                (lambda :behavior manipy ()
                  (let ((v0-0 (logior (-> self draw status) (draw-status skip-bones))))
                    (set! (-> self draw status) v0-0)
                    (the-as uint v0-0))))
    (send-event (-> gp-1 process 0) 'clone-copy-trans #f)
    (send-event (-> gp-1 process 0) 'anim-mode 'clone-anim)
    (let ((a1-12 (new 'stack-no-clear 'event-message-block)))
      (set! (-> a1-12 from) self)
      (set! (-> a1-12 num-params) 2)
      (set! (-> a1-12 message) 'clone)
      (set! (-> a1-12 param 0) (the-as uint (process->handle self)))
      (set! (-> a1-12 param 1) (the-as uint 2))
      (let ((t9-13 send-event-function)
            (v1-58 (-> self link next)))
        (t9-13 (if v1-58 (-> v1-58 extra process)) a1-12)))
    (ja-play-spooled-anim (new 'static 'spool-anim :name "flying-lurker-intro" :index 7 :parts 2 :command-list '())
                          (the-as art-joint-anim #f)
                          (the-as art-joint-anim #f)
                          (the-as (function process-drawable symbol) false-func))
    (if (handle->process gp-1) (deactivate (-> gp-1 process 0))))
  (process-release? *target*)
  (process-spawn-function process
    (lambda :behavior process ()
      (suspend-for (seconds 0.1))
      (level-hint-spawn (text-id ogre-race-hint) "asstvb24" (the-as entity #f) *entity-pool* (game-task none))
      (none))
    :to
    self)
  (none))

(defstate flying-lurker-start (flying-lurker)
  :event flying-lurker-handler
  :exit
    (behavior ()
      (remove-setting! 'allow-progress))
  :code
    (behavior ()
      (when (play-movie?)
        (set-setting! 'allow-progress #f 0.0 0)
        (flying-lurker-play-intro))
      (flying-lurker-inc-try-count)
      (ja-channel-set! 1)
      (ja :group! flying-lurker-fly-ja)
      (let* ((v1-8 (/ (the-as int (rand-uint31-gen *random-generator*)) 256))
             (v1-9 (the-as float (logior #x3f800000 v1-8)))
             (f0-2 (+ -1.0 v1-9)))
        (cond
          ((< 0.8333333 f0-2) (send-event self 'fly-away 18 (-> self try-count)))
          ((< 0.6666667 f0-2) (send-event self 'fly-away 33 (-> self try-count)))
          ((< 0.5 f0-2) (send-event self 'fly-away 258 (-> self try-count)))
          ((< 0.33333334 f0-2) (send-event self 'fly-away 288 (-> self try-count)))
          ((< 0.16666667 f0-2) (send-event self 'fly-away 513 (-> self try-count)))
          (else (send-event self 'fly-away 528 (-> self try-count))))))
  :post ja-post)

(defstate flying-lurker-clone (flying-lurker)
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('die)
         (let ((v1-1 (new 'stack-no-clear 'event-message-block)))
           (set! (-> v1-1 from) proc)
           (set! (-> v1-1 num-params) argc)
           (set! (-> v1-1 message) message)
           (set! (-> v1-1 param 0) (-> block param 0))
           (set! (-> v1-1 param 1) (-> block param 1))
           (set! (-> v1-1 param 2) (-> block param 2))
           (set! (-> v1-1 param 3) (-> block param 3))
           (set! (-> v1-1 param 4) (-> block param 4))
           (set! (-> v1-1 param 5) (-> block param 5))
           (set! (-> v1-1 param 6) (-> block param 6))
           (let ((t9-0 send-event-function)
                 (a1-1 (-> self link next)))
             (t9-0 (if a1-1 (-> a1-1 extra process)) v1-1)))
         (cleanup-for-death self)
         (deactivate self))
        (('sleep)
         (let ((v1-6 (new 'stack-no-clear 'event-message-block)))
           (set! (-> v1-6 from) proc)
           (set! (-> v1-6 num-params) argc)
           (set! (-> v1-6 message) message)
           (set! (-> v1-6 param 0) (-> block param 0))
           (set! (-> v1-6 param 1) (-> block param 1))
           (set! (-> v1-6 param 2) (-> block param 2))
           (set! (-> v1-6 param 3) (-> block param 3))
           (set! (-> v1-6 param 4) (-> block param 4))
           (set! (-> v1-6 param 5) (-> block param 5))
           (set! (-> v1-6 param 6) (-> block param 6))
           (let ((t9-3 send-event-function)
                 (a1-3 (-> self link next)))
             (t9-3 (if a1-3 (-> a1-3 extra process)) v1-6)))
         (go flying-lurker-sleep))
        (('reset)
         (let ((v1-9 (new 'stack-no-clear 'event-message-block)))
           (set! (-> v1-9 from) proc)
           (set! (-> v1-9 num-params) argc)
           (set! (-> v1-9 message) message)
           (set! (-> v1-9 param 0) (-> block param 0))
           (set! (-> v1-9 param 1) (-> block param 1))
           (set! (-> v1-9 param 2) (-> block param 2))
           (set! (-> v1-9 param 3) (-> block param 3))
           (set! (-> v1-9 param 4) (-> block param 4))
           (set! (-> v1-9 param 5) (-> block param 5))
           (set! (-> v1-9 param 6) (-> block param 6))
           (let ((t9-5 send-event-function)
                 (a1-5 (-> self link next)))
             (t9-5 (if a1-5 (-> a1-5 extra process)) v1-9)))
         (deactivate self))
        (else (flying-lurker-handler proc argc message block))))
  :exit
    (behavior ()
      (ja-channel-set! 0))
  :code
    (behavior ((arg0 handle) (arg1 string))
      (clone-anim arg0 3 #t arg1)))

(defstate flying-lurker-idle (flying-lurker)
  :event
    (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
      (case message
        (('saw-player)
         (set! (-> self take-off) #t)
         (when (-> self link prev)
           (entity-birth-no-kill (-> self link prev))
           (let ((a1-1 (new 'stack-no-clear 'event-message-block)))
             (set! (-> a1-1 from) proc)
             (set! (-> a1-1 num-params) argc)
             (set! (-> a1-1 message) message)
             (set! (-> a1-1 param 0) (-> block param 0))
             (set! (-> a1-1 param 1) (-> block param 1))
             (set! (-> a1-1 param 2) (-> block param 2))
             (set! (-> a1-1 param 3) (-> block param 3))
             (set! (-> a1-1 param 4) (-> block param 4))
             (set! (-> a1-1 param 5) (-> block param 5))
             (set! (-> a1-1 param 6) (-> block param 6))
             (let ((t9-1 send-event-function)
                   (v1-13 (-> self link prev)))
               (t9-1 (if v1-13 (-> v1-13 extra process)) a1-1)))))
        (('clone)
         (when (-> self link next)
           (entity-birth-no-kill (-> self link next))
           (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) 'clone)
             (set! (-> a1-2 param 0) (-> block param 0))
             (set! (-> a1-2 param 1) (+ (-> block param 1) -1))
             (let ((t9-3 send-event-function)
                   (v1-25 (-> self link next)))
               (t9-3 (if v1-25 (-> v1-25 extra process)) a1-2))))
         (case (-> block param 1)
           ((2) (go flying-lurker-clone (the-as handle (-> block param 0)) "flying-lurker-b-"))
           ((1) (go flying-lurker-clone (the-as handle (-> block param 0)) "flying-lurker-c-"))))
        (else (flying-lurker-handler proc argc message block))))
  :exit
    (behavior ()
      (logclear! (-> self draw status) (draw-status hidden)))
  :trans
    (behavior ()
      (spool-push *art-control* "flying-lurker-intro" 0 self -99.0)
      (if (and (-> self take-off) (first?)) (go flying-lurker-start)))
  :code
    (behavior ()
      (local-vars (gp-0 int) (f30-0 float))
      1.0
      0
      (cond
        ((not (-> self link next)) (set! f30-0 0.9) (set! gp-0 0))
        ((not (-> self link prev)) (set! f30-0 1.0) (set! gp-0 5))
        (else (set! f30-0 1.2) (set! gp-0 11)))
      (loop
        (cond
          ((play-movie?)
           (ja-channel-set! 0)
           (if (= (get-task-status (game-task plunger-lurker-hit)) (task-status invalid)) (go flying-lurker-die))
           (when (and *target* (>= 172032.0 (vector-vector-xz-distance (-> self root trans) (-> *target* control trans))))
             (process-grab? *target*)
             (suspend-for (seconds 1))
             (process-release? *target*)
             (send-event self 'saw-player))
           (suspend)
           0)
          (else
           (ja :group! flying-lurker-fly-ja)
           (ja-no-eval :group! flying-lurker-fly-ja :num! (seek! max f30-0) :frame-num (the float gp-0))
           (until (ja-done? 0)
             (if (and *target* (>= 172032.0 (vector-vector-xz-distance (-> self root trans) (-> *target* control trans))))
               (send-event self 'saw-player))
             (suspend)
             (ja :num! (seek! max f30-0)))
           (set! gp-0 0)))))
  :post ja-post)

(defmethod init-from-entity! ((this flying-lurker) (arg0 entity-actor))
  (stack-size-set! (-> this main-thread) 512)
  (set! (-> this root) (new 'process 'trsqv))
  (process-drawable-from-entity! this arg0)
  (initialize-skeleton this *flying-lurker-sg* '())
  (set! (-> this link) (new 'process 'actor-link-info this))
  (set! (-> this path) (new 'process 'curve-control this 'path -1000000000.0))
  (logior! (-> this path flags) (path-control-flag display draw-line draw-point draw-text))
  (set! (-> this root pause-adjust-distance) 122880.0)
  (set! (-> this curve-position) 0.0)
  (cond
    ((play-movie?)
     (eval-path-curve! (-> this path) (-> this root trans) (-> this curve-position) 'interp)
     (path-control-method-14 (-> this path) (-> this tangent) (-> this curve-position))
     (quaternion-identity! (-> this root quat)))
    (else (flying-lurker-move) (flying-lurker-rotate)))
  (set! (-> this y-offset) 0.0)
  (set! (-> this y-vel) 0.0)
  (set! (-> this last-look-time) 0)
  (set! (-> this time-to-next-look) 0)
  (set! (-> this draw origin-joint-index) (the-as uint 4))
  (set! (-> this draw shadow-joint-index) (the-as uint 4))
  (set! (-> this take-off) #f)
  (set-vector! (-> this default-bounds) 0.0 8192.0 0.0 24576.0)
  (set! (-> this draw bounds quad) (-> this default-bounds quad))
  (set! (-> this draw shadow-ctrl) (new 'process 'shadow-control 131072.0 151552.0 614400.0 (the-as float 60) 409600.0))
  (let ((v1-27 (-> this draw shadow-ctrl))) (logclear! (-> v1-27 settings flags) (shadow-flags disable-draw)))
  0
  (set! (-> this alt-actor) (entity-actor-lookup arg0 'alt-actor 0))
  (set! (-> this shadow-backup) (-> this draw shadow))
  (set! (-> this try-counted) #f)
  (if (= (get-task-status (game-task plunger-lurker-hit)) (task-status invalid))
    (go flying-lurker-die)
    (go flying-lurker-idle))
  (none))
