;;-*-Lisp-*-
(in-package goal)
(bundles "BEA.DGO")
(require "levels/beach/air.gc")
(require "engine/geometry/path.gc")
(require "engine/collide/collide-cache.gc")
(require "engine/common-obs/process-drawable.gc")

;; note: modified for high fps

(declare-type seagullflock process)

(defconstant SEAGULLFLOCK_MAX 64)

;; DECOMP BEGINS

(defpartgroup group-seagull-takeoff
  :id 160
  :bounds (static-bspherem 0 -12 0 14)
  :parts ((sp-item 663 :fade-after (meters 20))))

(defpart 665
  :init-specs
  ((:texture (hotdot effects))
   (:num 1.0)
   (:scale-x (meters 1) (meters 1))
   (:scale-y :copy scale-x)
   (:r 128.0)
   (:b 128.0)
   (:a 64.0 64.0)
   (:vel-y (meters 0.4))
   (:accel-y (meters -0.2))
   (:timer (seconds 5))
   (:flags (bit2 bit3))))

(define sound-seagull-squall (static-sound-spec "seagulls-2"))

(deftype seagull (process-drawable)
  ((root              collide-shape-moving :override)
   (index             int32)
   (flock             (pointer seagullflock))
   (heading           float)
   (tilt              float)
   (max-tilt          float)
   (angletan          float)
   (target-dist       float)
   (scared            int32)
   (temp-heading      float)
   (temp-heading-time int32)
   (part-time         time-frame)
   (thrust            float)
   (teleport          symbol))
  (:methods
   (move-vertically! (_type_ symbol) none)
   (adjust-heading-around-point-slow! (_type_ float) none)
   (seagull-method-22 (_type_) none)
   (adjust-heading-around-point! (_type_ float) none)
   (seagull-method-24 (_type_) none)
   (seagull-method-25 (_type_ float) none)
   (seagull-method-26 (_type_) symbol)
   (seagull-method-27 (_type_) none))
  (:states
   seagull-flying
   seagull-idle
   (seagull-landing float)
   seagull-soaring
   seagull-takeoff))


(deftype seagullflock (process)
  ((self-override      seagullflock :overlay-at self)
   (path               path-control)
   (trans              vector :inline)
   (bird               (pointer seagull) SEAGULLFLOCK_MAX)
   (birds              int32)
   (link               actor-link-info)
   (bird-at-waterfall  uint64)
   (birds-at-waterfall int32)
   (target             vector :inline)
   (targetnum          int32)
   (alert-time         time-frame)
   (teleport-frames    int32)
   (cam-tracker        uint64)
   (state-time         time-frame)
   (squall             ambient-sound)
   (max-lift           float))
  (:methods
   (spawn-bird (_type_ vector) (pointer process))
   (play-hint (_type_ int) none)
   (seagullflock-method-16 (_type_ seagull) float))
  (:states
   seagullflock-at-waterfall
   seagullflock-idle))


(defmethod relocate ((this seagullflock) (offset int))
  (if (nonzero? (-> this path)) (&+! (-> this path) offset))
  (if (nonzero? (-> this link)) (&+! (-> this link) offset))
  (if (nonzero? (-> this squall)) (&+! (-> this squall) offset))
  (the-as seagullflock ((method-of-type process relocate) this offset)))

(defmethod deactivate ((this seagullflock))
  (if (nonzero? (-> this squall)) (stop! (-> this squall)))
  ((method-of-type process deactivate) this)
  (none))

(define *seagull-boxes*
  (new 'static
       'inline-array
       air-box
       10
       (new 'static
            'air-box
            :vecs
            (new 'static
                 'inline-array
                 vector
                 2
                 (new 'static 'vector :x -1146880.0 :y 143360.0 :z -1638400.0 :w -0.6427)
                 (new 'static 'vector :x 286720.0 :z 716800.0 :w -0.766)))
       (new 'static
            'air-box
            :vecs
            (new 'static
                 'inline-array
                 vector
                 2
                 (new 'static 'vector :x -1277952.0 :y 14336.0 :z -1306624.0 :w -0.6427)
                 (new 'static 'vector :x 675840.0 :z 114688.0 :w -0.766)))
       (new 'static
            'air-box
            :vecs
            (new 'static
                 'inline-array
                 vector
                 2
                 (new 'static 'vector :x -1474560.0 :y 10240.0 :z -1024000.0 :w -0.6427)
                 (new 'static 'vector :x 1228800.0 :z 339968.0 :w -0.766)))
       (new 'static
            'air-box
            :vecs
            (new 'static
                 'inline-array
                 vector
                 2
                 (new 'static 'vector :x -1822720.0 :y 27033.6 :z -1961984.0 :w -0.6427)
                 (new 'static 'vector :x 143360.0 :z 245760.0 :w -0.766)))
       (new 'static
            'air-box
            :vecs
            (new 'static
                 'inline-array
                 vector
                 2
                 (new 'static 'vector :x -1589248.0 :y 43417.6 :z -1933312.0 :w -0.6427)
                 (new 'static 'vector :x 204800.0 :z 184320.0 :w -0.766)))
       (new 'static
            'air-box
            :vecs
            (new 'static
                 'inline-array
                 vector
                 2
                 (new 'static 'vector :x -1597440.0 :y 24985.6 :z -1757184.0 :w -0.6427)
                 (new 'static 'vector :x 133120.0 :z 491520.0 :w -0.766)))
       (new 'static
            'air-box
            :vecs
            (new 'static
                 'inline-array
                 vector
                 2
                 (new 'static 'vector :x -1323008.0 :y 44236.8 :z -1771520.0 :w -0.6427)
                 (new 'static 'vector :x 360448.0 :z 221184.0 :w -0.766)))
       (new 'static
            'air-box
            :vecs
            (new 'static
                 'inline-array
                 vector
                 2
                 (new 'static 'vector :x -1441792.0 :y 24985.6 :z -1564672.0 :w -0.6427)
                 (new 'static 'vector :x 81920.0 :z 421888.0 :w -0.766)))
       (new 'static
            'air-box
            :vecs
            (new 'static
                 'inline-array
                 vector
                 2
                 (new 'static 'vector :x -1124352.0 :y 27975.68 :z -1581465.6 :w -0.8533)
                 (new 'static 'vector :x 204800.0 :z 221184.0 :w -0.5214)))
       (new 'static
            'air-box
            :vecs
            (new 'static
                 'inline-array
                 vector
                 2
                 (new 'static 'vector :x -737280.0 :y 122880.0 :z -1396736.0 :w -0.8533)
                 (new 'static 'vector :x 475136.0 :z 819200.0 :w -0.5214)))))

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

(defmethod seagull-method-25 ((this seagull) (arg0 float))
  (let ((f1-1 (the float (sar (shl (the int (- arg0 (-> this heading))) 48) 48)))
        (f0-5 (- (-> this tilt))))
    (let ((f2-0 (-> this max-tilt)))
      (set! f0-5
            (cond
              ((< f1-1 -364.0889) (if (< (- f2-0) f0-5) (set! f0-5 (+ -91.022224 f0-5))) f0-5)
              ((< 364.0889 f1-1) (if (< f0-5 f2-0) (set! f0-5 (+ 91.022224 f0-5))) f0-5)
              ((< f0-5 0.0) (+ 91.022224 f0-5))
              (else (+ -91.022224 f0-5)))))
    (set! (-> this tilt) (- f0-5))
    (set! (-> this heading) (the float (sar (shl (the int (+ (-> this heading) (* 0.05 f0-5))) 48) 48))))
  0
  (none))

(defmethod seagull-method-24 ((this seagull))
  (let ((s5-0 (new 'stack-no-clear 'vector)))
    (vector-! s5-0 (-> this flock 0 target) (-> this root trans))
    (when (< (vector-dot s5-0 s5-0) 6710886400.0)
      (let ((v1-5 (ash 1 (-> this index))))
        (when (not (logtest? v1-5 (-> this flock 0 bird-at-waterfall)))
          (logior! (-> this flock 0 bird-at-waterfall) v1-5)
          (+! (-> this flock 0 birds-at-waterfall) 1))))
    (cond
      ((> (-> this temp-heading-time) 0)
       (+! (-> this temp-heading-time) -1)
       (let* ((v1-15 this)
              (f1-2 (the float (sar (shl (the int (- (-> this temp-heading) (-> v1-15 heading))) 48) 48)))
              (f0-7 (- (-> v1-15 tilt))))
         (let ((f2-0 (-> v1-15 max-tilt)))
           (set! f0-7
                 (cond
                   ((< f1-2 -364.0889) (if (< (- f2-0) f0-7) (set! f0-7 (+ -91.022224 f0-7))) f0-7)
                   ((< 364.0889 f1-2) (if (< f0-7 f2-0) (set! f0-7 (+ 91.022224 f0-7))) f0-7)
                   ((< f0-7 0.0) (+ 91.022224 f0-7))
                   (else (+ -91.022224 f0-7)))))
         (set! (-> v1-15 tilt) (- f0-7))
         (set! (-> v1-15 heading) (the float (sar (shl (the int (+ (-> v1-15 heading) (* 0.05 f0-7))) 48) 48))))
       0)
      (else
       (let* ((f0-15 (atan (-> s5-0 x) (-> s5-0 z)))
              (v1-18 this)
              (f1-12 (the float (sar (shl (the int (- f0-15 (-> v1-18 heading))) 48) 48)))
              (f0-20 (- (-> v1-18 tilt))))
         (let ((f2-2 (-> v1-18 max-tilt)))
           (set! f0-20
                 (cond
                   ((< f1-12 -364.0889) (if (< (- f2-2) f0-20) (set! f0-20 (+ -91.022224 f0-20))) f0-20)
                   ((< 364.0889 f1-12) (if (< f0-20 f2-2) (set! f0-20 (+ 91.022224 f0-20))) f0-20)
                   ((< f0-20 0.0) (+ 91.022224 f0-20))
                   (else (+ -91.022224 f0-20)))))
         (set! (-> v1-18 tilt) (- f0-20))
         (set! (-> v1-18 heading) (the float (sar (shl (the int (+ (-> v1-18 heading) (* 0.05 f0-20))) 48) 48))))
       0))
    (let ((f0-28 (+ (* (-> s5-0 x) (-> s5-0 x)) (* (-> s5-0 z) (-> s5-0 z)))))
      (set! (-> this angletan) (/ (- (-> s5-0 y)) (sqrtf f0-28)))
      ;; og:preserve-this changed for high fps
      (set! (-> this target-dist) (* DISPLAY_FPS_RATIO (sqrtf (+ f0-28 (* (-> s5-0 y) (-> s5-0 y))))))))
  0
  (none))

(defbehavior seagull-post seagull ()
  (let ((s5-0 (new 'stack-no-clear 'quaternion))
        (gp-0 (new 'stack-no-clear 'quaternion)))
    (quaternion-axis-angle! s5-0 0.0 0.0 1.0 (-> self tilt))
    (quaternion-axis-angle! gp-0 0.0 1.0 0.0 (-> self heading))
    (quaternion*! (-> self root quat) gp-0 s5-0))
  (transform-post)
  0
  (none))

(defstate seagull-idle (seagull)
  :enter
    (behavior ()
      (let* ((v1-0 (-> self flock))
             (f30-0 (seagullflock-method-16 (if v1-0 (-> v1-0 0 self-override)) self))
             (f28-0 21845.334)
             (f26-0 -0.5))
        (set! (-> self heading) (the float (sar (shl (the int (+ f30-0 (* f28-0 (+ f26-0 (rand-float-gen))))) 48) 48)))))
  :trans
    (behavior ()
      (when (nonzero? (-> self scared))
        (+! (-> self scared) -1)
        (when (zero? (-> self scared))
          (restore-collide-with-as (-> self root))
          (go seagull-takeoff)))
      (when *target*
        (let ((v1-12 (vector-! (new 'stack-no-clear 'vector) (-> *target* control trans) (-> self root trans))))
          (when (< (vector-dot v1-12 v1-12) 1677721600.0)
            (let ((v1-14 (-> self flock))) (play-hint (if v1-14 (-> v1-14 0 self-override)) (-> self index)))))))
  :code
    (behavior ()
      (+! (-> self root trans y) 20480.0)
      (move-to-ground (-> self root) 40960.0 40960.0 #t (collide-kind background))
      (update-transforms! (-> self root))
      (clear-collide-with-as (-> self root))
      (ja :group! seagull-idle-ja :num! (identity (ja-aframe 0.0 0)))
      (loop
        (let* ((f30-0 4.0)
               (v1-14 (/ (the-as int (rand-uint31-gen *random-generator*)) 256))
               (v1-15 (the-as number (logior #x3f800000 v1-14)))
               (gp-1 (the int (* f30-0 (+ -1.0 (the-as float v1-15))))))
          (let* ((f30-1 60.0)
                 (v1-18 (/ (the-as int (rand-uint31-gen *random-generator*)) 256))
                 (v1-19 (the-as number (logior #x3f800000 v1-18)))
                 (s5-0 (the int (* f30-1 (+ -1.0 (the-as float v1-19))))))
            (dotimes (s4-0 s5-0)
              (suspend)))
          (cond
            ((zero? gp-1)
             (ja-no-eval :group! seagull-idle-ja :num! (seek! (ja-aframe 4.0 0)) :frame-num (ja-aframe 0.0 0))
             (until (ja-done? 0)
               (suspend)
               (ja :num! (seek! (ja-aframe 4.0 0))))
             (let* ((f30-2 60.0)
                    (v1-37 (/ (the-as int (rand-uint31-gen *random-generator*)) 256))
                    (v1-38 (the-as number (logior #x3f800000 v1-37)))
                    (gp-4 (the int (* f30-2 (+ -1.0 (the-as float v1-38))))))
               (dotimes (s5-1 gp-4)
                 (suspend)))
             (ja-no-eval :group! seagull-idle-ja :num! (seek! (ja-aframe 10.0 0)) :frame-num (ja-aframe 4.0 0))
             (until (ja-done? 0)
               (suspend)
               (ja :num! (seek! (ja-aframe 10.0 0))))
             (let* ((f30-3 60.0)
                    (v1-55 (/ (the-as int (rand-uint31-gen *random-generator*)) 256))
                    (v1-56 (the-as number (logior #x3f800000 v1-55)))
                    (gp-7 (the int (* f30-3 (+ -1.0 (the-as float v1-56))))))
               (dotimes (s5-2 gp-7)
                 (suspend)))
             (ja-no-eval :group! seagull-idle-ja :num! (seek! (ja-aframe 14.0 0)) :frame-num (ja-aframe 10.0 0))
             (until (ja-done? 0)
               (suspend)
               (ja :num! (seek! (ja-aframe 14.0 0)))))
            ((= gp-1 2)
             (ja-no-eval :group! seagull-peck-ja :num! (seek! (ja-aframe 4.0 0)) :frame-num (ja-aframe 0.0 0))
             (until (ja-done? 0)
               (suspend)
               (ja :num! (seek! (ja-aframe 4.0 0)))))
            ((= gp-1 3)
             (ja-no-eval :group! seagull-peck-ja :num! (seek! (ja-aframe 8.0 0)) :frame-num (ja-aframe 4.0 0))
             (until (ja-done? 0)
               (suspend)
               (ja :num! (seek! (ja-aframe 8.0 0)))))
            ((= gp-1 4)
             (ja-no-eval :group! seagull-peck-ja :num! (seek! (ja-aframe 12.0 0)) :frame-num (ja-aframe 8.0 0))
             (until (ja-done? 0)
               (suspend)
               (ja :num! (seek! (ja-aframe 12.0 0)))))))))
  :post seagull-post)

(defmethod move-vertically! ((this seagull) (arg0 symbol))
  (let ((f0-0 (-> this root transv y)))
    (set! f0-0
          (cond
            (arg0 (if (< f0-0 (-> this flock 0 max-lift)) (set! f0-0 (+ 12288.0 f0-0))) f0-0)
            (else (+ -4096.0 f0-0))))
    ;; og:preserve-this changed for high fps
    (set! (-> this root transv y) (* DISPLAY_FPS_RATIO f0-0)))
  0
  (none))

(defmethod seagull-method-26 ((this seagull))
  (let ((s5-0 (new 'stack-no-clear 'vector)))
    (let ((f30-0 -4096.0)
          (f28-0 8192.0))
      (set! (-> s5-0 x) (+ f30-0 (* f28-0 (rand-float-gen)) (-> this flock 0 target x))))
    (let ((f30-1 -4096.0)
          (f28-1 8192.0))
      (set! (-> s5-0 y) (+ f30-1 (* f28-1 (rand-float-gen)) (-> this flock 0 target y))))
    (let ((f30-2 -4096.0)
          (f28-2 8192.0))
      (set! (-> s5-0 z) (+ f30-2 (* f28-2 (rand-float-gen)) (-> this flock 0 target z))))
    (vector-! s5-0 s5-0 (-> this root trans))
    (vector-float*! s5-0 s5-0 0.9)
    (move-by-vector! (-> this root) s5-0))
  (set! (-> this teleport) #f)
  #f)

(defmethod adjust-heading-around-point-slow! ((this seagull) (arg0 float))
  (let ((f30-1 (* arg0 (sin (-> this heading))))
        (f0-4 (* arg0 (cos (-> this heading)))))
    ;; og:preserve-this changed for high fps
    (set! (-> this root transv x) (* DISPLAY_FPS_RATIO (+ (* 0.8 (-> this root transv x)) (* 0.2 f30-1))))
    (set! (-> this root transv z) (* DISPLAY_FPS_RATIO (+ (* 0.8 (-> this root transv z)) (* 0.2 f0-4)))))
  0
  (none))

(defmethod adjust-heading-around-point! ((this seagull) (arg0 float))
  (let ((f30-1 (* arg0 (sin (-> this heading))))
        (f0-4 (* arg0 (cos (-> this heading)))))
    ;; og:preserve-this changed for high fps
    (set! (-> this root transv x) (* DISPLAY_FPS_RATIO f30-1))
    (set! (-> this root transv z) (* DISPLAY_FPS_RATIO f0-4)))
  0
  (none))

(defmethod seagull-method-22 ((this seagull))
  (set! (-> this root transv y) -8192.0)
  0
  (none))

(defmethod seagull-method-27 ((this seagull))
  (local-vars (at-0 int))
  (rlet ((vf0 :class vf)
         (vf1 :class vf)
         (vf2 :class vf))
    (init-vf0-vector)
    (let ((v1-0 (new 'stack-no-clear 'vector))
          (a0-2 (-> this root trans))
          (s5-0 (-> this root transv))
          (a1-1 (new 'stack-no-clear 'vector)))
      (let ((a2-0 v1-0))
        (.lvf vf1 (&-> s5-0 quad))
        (let ((f0-0 (seconds-per-frame))) (.mov at-0 f0-0))
        (.mov vf2 at-0)
        (.mov.vf.w vf1 vf0)
        (.mul.x.vf.xyz vf1 vf1 vf2)
        (.svf (&-> a2-0 quad) vf1))
      (vector+! a1-1 a0-2 v1-0)
      (if (points-in-air? a0-2 a1-1 *seagull-boxes* 10)
        (integrate-no-collide! (-> this root) (-> this root transv))
        (fill-cache-integrate-and-collide! (-> this root) s5-0 (collide-kind background))))
    (none)))

(defstate seagull-takeoff (seagull)
  :trans
    (behavior ()
      (when (< (+ (current-time) (seconds -2)) (-> self part-time))
        (-> self part)
        (-> self root root-prim prim-core)))
  :code
    (behavior ()
      (set-time! (-> self part-time))
      (ja-no-eval :group! seagull-takeoff-ja :num! (seek! (ja-aframe 4.0 0)) :frame-num (ja-aframe 1.0 0))
      (until (ja-done? 0)
        (when (and (>= (ja-frame-num 0) (ja-aframe 2.0 0)) (>= (ja-aframe 3.0 0) (ja-frame-num 0)))
          (let* ((v1-13 self)
                 (a0-7 #t)
                 (f0-5 (-> v1-13 root transv y)))
            (set! f0-5
                  (cond
                    (a0-7 (if (< f0-5 (-> v1-13 flock 0 max-lift)) (set! f0-5 (+ 12288.0 f0-5))) f0-5)
                    (else (+ -4096.0 f0-5))))
            ;; og:preserve-this changed for high fps
            (set! (-> v1-13 root transv y) (* DISPLAY_FPS_RATIO f0-5)))
          0
          (let* ((gp-1 self)
                 (f28-0 (-> self thrust))
                 (f30-2 (* f28-0 (sin (-> gp-1 heading))))
                 (f0-10 (* f28-0 (cos (-> gp-1 heading)))))
            ;; og:preserve-this changed for high fps
            (set! (-> gp-1 root transv x) (* DISPLAY_FPS_RATIO (+ (* 0.8 (-> gp-1 root transv x)) (* 0.2 f30-2))))
            (set! (-> gp-1 root transv z) (* DISPLAY_FPS_RATIO (+ (* 0.8 (-> gp-1 root transv z)) (* 0.2 f0-10)))))
          0)
        (seagull-method-27 self)
        (suspend)
        (ja :num! (seek! (ja-aframe 4.0 0))))
      (ja-no-eval :num! (seek!))
      (ja-channel-push! 1 (seconds 0.067))
      (go seagull-flying))
  :post seagull-post)

(defstate seagull-flying (seagull)
  :trans
    (behavior ()
      (when (< (+ (current-time) (seconds -2)) (-> self part-time))
        (-> self part)
        (-> self root root-prim prim-core)))
  :code
    (behavior ()
      (set! (-> self max-tilt) 1820.4445)
      (let ((gp-0 0))
        (loop
          (ja-no-eval :group! seagull-fly-ja :num! (seek!) :frame-num 0.0)
          (until (ja-done? 0)
            (ja-blend-eval)
            (when (-> self teleport)
              (seagull-method-26 self)
              (suspend)
              0)
            (let ((s5-0 self)
                  (s4-0 (new 'stack-no-clear 'vector)))
              (vector-! s4-0 (-> s5-0 flock 0 target) (-> s5-0 root trans))
              (when (< (vector-dot s4-0 s4-0) 6710886400.0)
                (let ((v1-24 (ash 1 (-> s5-0 index))))
                  (when (not (logtest? v1-24 (-> s5-0 flock 0 bird-at-waterfall)))
                    (logior! (-> s5-0 flock 0 bird-at-waterfall) v1-24)
                    (+! (-> s5-0 flock 0 birds-at-waterfall) 1))))
              (cond
                ((> (-> s5-0 temp-heading-time) 0)
                 (+! (-> s5-0 temp-heading-time) -1)
                 (let* ((v1-34 s5-0)
                        (f1-2 (the float (sar (shl (the int (- (-> s5-0 temp-heading) (-> v1-34 heading))) 48) 48)))
                        (f0-12 (- (-> v1-34 tilt))))
                   (let ((f2-0 (-> v1-34 max-tilt)))
                     (set! f0-12
                           (cond
                             ((< f1-2 -364.0889) (if (< (- f2-0) f0-12) (set! f0-12 (+ -91.022224 f0-12))) f0-12)
                             ((< 364.0889 f1-2) (if (< f0-12 f2-0) (set! f0-12 (+ 91.022224 f0-12))) f0-12)
                             ((< f0-12 0.0) (+ 91.022224 f0-12))
                             (else (+ -91.022224 f0-12)))))
                   (set! (-> v1-34 tilt) (- f0-12))
                   (set! (-> v1-34 heading) (the float (sar (shl (the int (+ (-> v1-34 heading) (* 0.05 f0-12))) 48) 48))))
                 0)
                (else
                 (let* ((f0-20 (atan (-> s4-0 x) (-> s4-0 z)))
                        (v1-37 s5-0)
                        (f1-12 (the float (sar (shl (the int (- f0-20 (-> v1-37 heading))) 48) 48)))
                        (f0-25 (- (-> v1-37 tilt))))
                   (let ((f2-2 (-> v1-37 max-tilt)))
                     (set! f0-25
                           (cond
                             ((< f1-12 -364.0889) (if (< (- f2-2) f0-25) (set! f0-25 (+ -91.022224 f0-25))) f0-25)
                             ((< 364.0889 f1-12) (if (< f0-25 f2-2) (set! f0-25 (+ 91.022224 f0-25))) f0-25)
                             ((< f0-25 0.0) (+ 91.022224 f0-25))
                             (else (+ -91.022224 f0-25)))))
                   (set! (-> v1-37 tilt) (- f0-25))
                   (set! (-> v1-37 heading) (the float (sar (shl (the int (+ (-> v1-37 heading) (* 0.05 f0-25))) 48) 48))))
                 0))
              (let ((f0-33 (+ (* (-> s4-0 x) (-> s4-0 x)) (* (-> s4-0 z) (-> s4-0 z)))))
                (set! (-> s5-0 angletan) (/ (- (-> s4-0 y)) (sqrtf f0-33)))
                ;; og:preserve-this changed for high fps
                (set! (-> s5-0 target-dist) (* DISPLAY_FPS_RATIO (sqrtf (+ f0-33 (* (-> s4-0 y) (-> s4-0 y))))))))
            0
            (let ((v1-42 (>= (ja-frame-num 0) (ja-aframe 3.0 0))))
              (cond
                ((and v1-42 (>= (ja-aframe 9.0 0) (ja-frame-num 0)))
                 (let* ((v1-44 self)
                        (a0-49 #t)
                        (f0-38 (-> v1-44 root transv y)))
                   (set! f0-38
                         (cond
                           (a0-49 (if (< f0-38 (-> v1-44 flock 0 max-lift)) (set! f0-38 (+ 12288.0 f0-38))) f0-38)
                           (else (+ -4096.0 f0-38))))
                   ;; og:preserve-this changed for high fps
                   (set! (-> v1-44 root transv y) (* DISPLAY_FPS_RATIO f0-38)))
                 0)
                (else
                 (let* ((v1-48 self)
                        (a0-55 #f)
                        (f0-39 (-> v1-48 root transv y)))
                   (set! f0-39
                         (cond
                           (a0-55 (if (< f0-39 (-> v1-48 flock 0 max-lift)) (set! f0-39 (+ 12288.0 f0-39))) f0-39)
                           (else (+ -4096.0 f0-39))))
                   ;; og:preserve-this changed for high fps
                   (set! (-> v1-48 root transv y) (* DISPLAY_FPS_RATIO f0-39)))
                 0)))
            (let* ((s5-1 self)
                   (f28-0 (-> self thrust))
                   (f30-2 (* f28-0 (sin (-> s5-1 heading))))
                   (f0-44 (* f28-0 (cos (-> s5-1 heading)))))
              (set! (-> s5-1 root transv x) (+ (* 0.8 (-> s5-1 root transv x)) (* 0.2 f30-2)))
              (set! (-> s5-1 root transv z) (+ (* 0.8 (-> s5-1 root transv z)) (* 0.2 f0-44))))
            0
            (seagull-method-27 self)
            (suspend)
            (ja :num! (seek!)))
          (+! gp-0 1)
          (when (>= gp-0 0)
            (when (>= (-> self angletan) 0.1)
              (if (< 204800.0 (-> self root trans y)) (go seagull-soaring))
              (when (< 57344.0 (-> self root trans y))
                (let* ((f30-3 0.8)
                       (v1-77 (/ (the-as int (rand-uint31-gen *random-generator*)) 256))
                       (v1-78 (the-as number (logior #x3f800000 v1-77))))
                  (if (< f30-3 (+ -1.0 (the-as float v1-78))) (go seagull-soaring)))))))))
  :post seagull-post)

(defstate seagull-soaring (seagull)
  :trans
    (behavior ()
      (when (< (+ (current-time) (seconds -2)) (-> self part-time))
        (-> self part)
        (-> self root root-prim prim-core)))
  :code
    (behavior ()
      (set-time! (-> self state-time))
      (set! (-> self max-tilt) 4551.1113)
      (loop
        (ja-no-eval :group! seagull-slowfly-ja :num! (seek!) :frame-num 0.0)
        (until (ja-done? 0)
          (ja-blend-eval)
          (when (-> self teleport)
            (seagull-method-26 self)
            (suspend)
            0)
          (let ((gp-0 self)
                (s5-0 (new 'stack-no-clear 'vector)))
            (vector-! s5-0 (-> gp-0 flock 0 target) (-> gp-0 root trans))
            (when (< (vector-dot s5-0 s5-0) 6710886400.0)
              (let ((v1-26 (ash 1 (-> gp-0 index))))
                (when (not (logtest? v1-26 (-> gp-0 flock 0 bird-at-waterfall)))
                  (logior! (-> gp-0 flock 0 bird-at-waterfall) v1-26)
                  (+! (-> gp-0 flock 0 birds-at-waterfall) 1))))
            (cond
              ((> (-> gp-0 temp-heading-time) 0)
               (+! (-> gp-0 temp-heading-time) -1)
               (let* ((v1-36 gp-0)
                      (f1-2 (the float (sar (shl (the int (- (-> gp-0 temp-heading) (-> v1-36 heading))) 48) 48)))
                      (f0-12 (- (-> v1-36 tilt))))
                 (let ((f2-0 (-> v1-36 max-tilt)))
                   (set! f0-12
                         (cond
                           ((< f1-2 -364.0889) (if (< (- f2-0) f0-12) (set! f0-12 (+ -91.022224 f0-12))) f0-12)
                           ((< 364.0889 f1-2) (if (< f0-12 f2-0) (set! f0-12 (+ 91.022224 f0-12))) f0-12)
                           ((< f0-12 0.0) (+ 91.022224 f0-12))
                           (else (+ -91.022224 f0-12)))))
                 (set! (-> v1-36 tilt) (- f0-12))
                 (set! (-> v1-36 heading) (the float (sar (shl (the int (+ (-> v1-36 heading) (* 0.05 f0-12))) 48) 48))))
               0)
              (else
               (let* ((f0-20 (atan (-> s5-0 x) (-> s5-0 z)))
                      (v1-39 gp-0)
                      (f1-12 (the float (sar (shl (the int (- f0-20 (-> v1-39 heading))) 48) 48)))
                      (f0-25 (- (-> v1-39 tilt))))
                 (let ((f2-2 (-> v1-39 max-tilt)))
                   (set! f0-25
                         (cond
                           ((< f1-12 -364.0889) (if (< (- f2-2) f0-25) (set! f0-25 (+ -91.022224 f0-25))) f0-25)
                           ((< 364.0889 f1-12) (if (< f0-25 f2-2) (set! f0-25 (+ 91.022224 f0-25))) f0-25)
                           ((< f0-25 0.0) (+ 91.022224 f0-25))
                           (else (+ -91.022224 f0-25)))))
                 (set! (-> v1-39 tilt) (- f0-25))
                 (set! (-> v1-39 heading) (the float (sar (shl (the int (+ (-> v1-39 heading) (* 0.05 f0-25))) 48) 48))))
               0))
            (let ((f0-33 (+ (* (-> s5-0 x) (-> s5-0 x)) (* (-> s5-0 z) (-> s5-0 z)))))
              (set! (-> gp-0 angletan) (/ (- (-> s5-0 y)) (sqrtf f0-33)))
              ;; og:preserve-this changed for high fps
              (set! (-> gp-0 target-dist) (* DISPLAY_FPS_RATIO (sqrtf (+ f0-33 (* (-> s5-0 y) (-> s5-0 y))))))))
          0
          (let ((v1-44 self)) (set! (-> v1-44 root transv y) -8192.0))
          0
          (let* ((gp-1 self)
                 (f28-0 (-> self thrust))
                 (f30-0 (* f28-0 (sin (-> gp-1 heading))))
                 (f0-41 (* f28-0 (cos (-> gp-1 heading)))))
            ;; og:preserve-this changed for high fps
            (set! (-> gp-1 root transv x) (* DISPLAY_FPS_RATIO (+ (* 0.8 (-> gp-1 root transv x)) (* 0.2 f30-0))))
            (set! (-> gp-1 root transv z) (* DISPLAY_FPS_RATIO (+ (* 0.8 (-> gp-1 root transv z)) (* 0.2 f0-41)))))
          0
          (seagull-method-27 self)
          (when (< (-> self angletan) 0.2)
            (if (< (-> self root trans y) 40960.0) (go seagull-flying))
            (when (< (-> self root trans y) 204800.0)
              (if (and (time-elapsed? (-> self state-time) (seconds 0.5))
                       (let* ((f30-1 0.99)
                              (v1-67 (/ (the-as int (rand-uint31-gen *random-generator*)) 256))
                              (v1-68 (the-as number (logior #x3f800000 v1-67))))
                         (< f30-1 (+ -1.0 (the-as float v1-68)))))
                (go seagull-flying))))
          (when (< (-> self target-dist) 81920.0)
            (when (< 1.0 (-> self angletan))
              (if (< (-> self target-dist) 20480.0) (go seagull-flying)))
            (if (and (< 0.4 (-> self angletan)) (>= 1.0 (-> self angletan))) (go seagull-landing 10.0))
            (if (and (>= (-> self angletan) 0.2) (>= 0.4 (-> self angletan))) (go seagull-landing 5.0)))
          (suspend)
          (ja :num! (seek!)))))
  :post seagull-post)

(defstate seagull-landing (seagull)
  :code
    (behavior ((arg0 float))
      (let ((s5-0 (new 'stack 'collide-tri-result)))
        0.0
        (let ((gp-0 (new 'stack-no-clear 'vector)))
          (set! (-> self root transv y) (* 4096.0 (- arg0)))
          (set! (-> gp-0 quad) (-> self root transv quad))
          (let ((f30-0 (fill-and-probe-using-line-sphere *collide-cache*
                                                         (-> self root trans)
                                                         gp-0
                                                         409.6
                                                         (collide-kind background)
                                                         self
                                                         s5-0
                                                         (new 'static 'pat-surface :noentity #x1))))
            (when (or (< f30-0 0.0) (or (< 1.0 f30-0) (nonzero? (-> s5-0 pat mode))))
              (suspend)
              (go seagull-soaring))
            (vector-float*! gp-0 gp-0 f30-0)
            (vector+! gp-0 gp-0 (-> self root trans))
            (while (< 0.5 f30-0)
              (suspend)
              (set! f30-0 (- f30-0 (seconds-per-frame)))
              (fill-cache-integrate-and-collide! (-> self root) (-> self root transv) (collide-kind background))
              (let* ((v1-21 self)
                     (f1-3 (the float (sar (shl (the int (- (-> self heading) (-> v1-21 heading))) 48) 48)))
                     (f0-12 (- (-> v1-21 tilt))))
                (let ((f2-0 (-> v1-21 max-tilt)))
                  (set! f0-12
                        (cond
                          ((< f1-3 -364.0889) (if (< (- f2-0) f0-12) (set! f0-12 (+ -91.022224 f0-12))) f0-12)
                          ((< 364.0889 f1-3) (if (< f0-12 f2-0) (set! f0-12 (+ 91.022224 f0-12))) f0-12)
                          ((< f0-12 0.0) (+ 91.022224 f0-12))
                          (else (+ -91.022224 f0-12)))))
                (set! (-> v1-21 tilt) (- f0-12))
                (set! (-> v1-21 heading) (the float (sar (shl (the int (+ (-> v1-21 heading) (* 0.05 f0-12))) 48) 48))))
              0)
            (ja-no-eval :num! (seek!))
            (ja-channel-push! 1 (seconds 0.135))
            (ja :group! seagull-land-ja :num! (identity (ja-aframe 0.0 0)))
            (while (< 0.0 f30-0)
              (suspend)
              (ja :num! (seek!))
              (set! f30-0 (- f30-0 (seconds-per-frame)))
              (fill-cache-integrate-and-collide! (-> self root) (-> self root transv) (collide-kind background))
              (let* ((v1-48 self)
                     (f1-13 (the float (sar (shl (the int (- (-> self heading) (-> v1-48 heading))) 48) 48)))
                     (f0-32 (- (-> v1-48 tilt))))
                (let ((f2-2 (-> v1-48 max-tilt)))
                  (set! f0-32
                        (cond
                          ((< f1-13 -364.0889) (if (< (- f2-2) f0-32) (set! f0-32 (+ -91.022224 f0-32))) f0-32)
                          ((< 364.0889 f1-13) (if (< f0-32 f2-2) (set! f0-32 (+ 91.022224 f0-32))) f0-32)
                          ((< f0-32 0.0) (+ 91.022224 f0-32))
                          (else (+ -91.022224 f0-32)))))
                (set! (-> v1-48 tilt) (- f0-32))
                (set! (-> v1-48 heading) (the float (sar (shl (the int (+ (-> v1-48 heading) (* 0.05 f0-32))) 48) 48))))
              0))))
      (while (not (ja-done? 0))
        (suspend)
        (ja :num! (seek!))
        (let* ((v1-59 self)
               (f1-23 (the float (sar (shl (the int (- (-> self heading) (-> v1-59 heading))) 48) 48)))
               (f0-47 (- (-> v1-59 tilt))))
          (let ((f2-4 (-> v1-59 max-tilt)))
            (set! f0-47
                  (cond
                    ((< f1-23 -364.0889) (if (< (- f2-4) f0-47) (set! f0-47 (+ -91.022224 f0-47))) f0-47)
                    ((< 364.0889 f1-23) (if (< f0-47 f2-4) (set! f0-47 (+ 91.022224 f0-47))) f0-47)
                    ((< f0-47 0.0) (+ 91.022224 f0-47))
                    (else (+ -91.022224 f0-47)))))
          (set! (-> v1-59 tilt) (- f0-47))
          (set! (-> v1-59 heading) (the float (sar (shl (the int (+ (-> v1-59 heading) (* 0.05 f0-47))) 48) 48))))
        0)
      (go seagull-idle))
  :post seagull-post)

(defun seagull-reaction ((arg0 collide-shape-moving) (arg1 collide-shape-intersect) (arg2 vector) (arg3 vector))
  (let ((s5-0 0))
    (let ((a1-1 (new 'stack-no-clear 'vector)))
      (vector-float*! a1-1 (-> arg1 move-vec) (-> arg1 best-u))
      (set! (-> a1-1 y) (-> arg1 move-vec y))
      (move-by-vector! arg0 a1-1))
    (let ((f0-3 (vector-dot (-> arg0 transv) (-> arg1 best-tri normal)))
          (v1-6 (new 'stack-no-clear 'vector)))
      (vector-float*! v1-6 (-> arg1 best-tri normal) f0-3)
      (vector-! (-> arg0 transv) (-> arg0 transv) v1-6))
    (let ((v1-7 (-> arg1 best-tri normal))
          (s4-1 (-> arg0 process)))
      (set! (-> (the-as seagull s4-1) temp-heading) (atan (-> v1-7 x) (-> v1-7 z)))
      (set! (-> (the-as seagull s4-1) temp-heading-time) (seconds 1)))
    (let ((v0-2 (logior s5-0 3)))
      (set! (-> arg0 status) (the-as cshape-moving-flags v0-2))
      (the-as cshape-moving-flags v0-2))))

(defbehavior seagull-init-by-other seagull ((arg0 vector) (arg1 int) (arg2 seagullflock))
  (let ((s3-0 (new 'process 'collide-shape-moving self (collide-list-enum hit-by-player))))
    (set! (-> s3-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s3-0 reaction) seagull-reaction)
    (set! (-> s3-0 no-reaction) (the-as (function collide-shape-moving collide-shape-intersect vector vector none) nothing))
    (let ((s2-0 (new 'process 'collide-shape-prim-sphere s3-0 (the-as uint 0))))
      (set! (-> s2-0 prim-core collide-as) (collide-kind))
      (set! (-> s2-0 collide-with) (collide-kind background))
      (set! (-> s2-0 prim-core action) (collide-action solid))
      (set! (-> s2-0 prim-core offense) (collide-offense indestructible))
      (set-vector! (-> s2-0 local-sphere) 0.0 2048.0 0.0 2048.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))
  (initialize-skeleton self *seagull-sg* '())
  (logclear! (-> self mask) (process-mask actor-pause))
  (set! (-> self index) arg1)
  (set! (-> self flock) (the-as (pointer seagullflock) (process->ppointer arg2)))
  (set! (-> self heading) 0.0)
  (set! (-> self tilt) 0.0)
  (let ((f30-0 51200.0)
        (f28-0 20480.0))
    (set! (-> self thrust) (+ f30-0 (* f28-0 (rand-float-gen)))))
  (set! (-> self teleport) #f)
  (go seagull-idle)
  (none))

(defmethod play-hint ((this seagullflock) (arg0 int))
  (when (time-elapsed? (-> this alert-time) (seconds 5))
    (eval-path-curve-div! (-> this path) (-> this target) (the float (-> this targetnum)) 'interp)
    (let ((f0-2 4096.0)
          (v1-6 (-> this targetnum)))
      (set! (-> this max-lift)
            (* f0-2
               (cond
                 ((= v1-6 1) 4.0)
                 ((= v1-6 2) 4.0)
                 ((= v1-6 3) 4.0)
                 (else 10.0)))))
    (case (-> this targetnum)
      ((1) (level-hint-spawn (text-id sidekick-seagulls1) "sksp0020" (the-as entity #f) *entity-pool* (game-task none)))
      ((2) (level-hint-spawn (text-id sidekick-seagulls2) "sksp0022" (the-as entity #f) *entity-pool* (game-task none)))
      ((3) (level-hint-spawn (text-id sidekick-seagulls3) "sksp0023" (the-as entity #f) *entity-pool* (game-task none)))
      ((4) (level-hint-spawn (text-id sidekick-seagulls4) "sksp0024" (the-as entity #f) *entity-pool* (game-task none))))
    (let ((v1-16 (-> this entity extra perm)))
      (logior! (-> v1-16 status) (entity-perm-status user-set-from-cstage))
      (set! (-> v1-16 user-int8 0) (min 2 (-> this targetnum))))
    (+! (-> this targetnum) 1)
    (dotimes (v1-19 (-> this birds))
      (set! (-> this bird v1-19 0 scared) (+ (* v1-19 2) 5)))
    (set! (-> this bird arg0 0 scared) 1)
    (set! (-> this bird-at-waterfall) (the-as uint 0))
    (set! (-> this birds-at-waterfall) 0)
    (if (>= (-> this targetnum) 4) (set! (-> this teleport-frames) 1500))
    (sound-play "seagull-takeoff")
    (set-time! (-> this alert-time)))
  (none))

(defmethod seagullflock-method-16 ((this seagullflock) (arg0 seagull))
  (let ((gp-0 (new 'stack-no-clear 'vector)))
    (eval-path-curve-div! (-> this path) gp-0 (the float (-> this targetnum)) 'interp)
    (vector-! gp-0 gp-0 (-> arg0 root trans))
    (atan (-> gp-0 x) (-> gp-0 z))))

(defstate seagullflock-at-waterfall (seagullflock)
  :code
    (behavior ()
      (local-vars (a0-2 process) (a1-0 event-message-block) (t9-1 (function process-tree event-message-block object)))
      (aybabtu 2)
      (set-time! (-> self state-time))
      (-> self link next)
      (until (t9-1 a0-2 a1-0)
        (suspend)
        (let ((v1-5 (-> self link next)))
          (set! a1-0 (new 'stack-no-clear 'event-message-block))
          (set! (-> a1-0 from) self)
          (set! (-> a1-0 num-params) 0)
          (set! (-> a1-0 message) 'loading)
          (set! t9-1 send-event-function)
          (set! a0-2 (if v1-5 (-> v1-5 extra process)))))
      (until (time-elapsed? (-> self state-time) (-> self teleport-frames))
        (suspend))
      (close-specific-task! (game-task beach-seagull) (task-status need-reminder))
      (dotimes (v1-13 (-> self birds))
        (set! (-> self bird v1-13 0 teleport) #t))
      (let ((gp-0 (-> self link next)))
        (set-blackout-frames (seconds 2))
        (suspend)
        (let ((a1-6 (new 'stack-no-clear 'event-message-block)))
          (set! (-> a1-6 from) self)
          (set! (-> a1-6 num-params) 0)
          (set! (-> a1-6 message) 'trigger)
          (let ((t9-4 send-event-function)
                (v1-18 gp-0))
            (t9-4 (if v1-18 (-> v1-18 extra process)) a1-6)))
        (while (not (logtest? (-> gp-0 extra perm status) (entity-perm-status complete)))
          (suspend)))
      (process-entity-status! self (entity-perm-status dead) #t)))

(defstate seagullflock-idle (seagullflock)
  :code
    (behavior ()
      (loop
        (if (> (-> self teleport-frames) 0) (go seagullflock-at-waterfall))
        (if (and *target* (>= 102400.0 (vector-vector-distance (-> self trans) (-> *target* control trans))))
          (level-hint-spawn (text-id zero) (the-as string #f) (-> self entity) *entity-pool* (game-task none)))
        (suspend))))

(defmethod init-from-entity! ((this seagullflock) (arg0 entity-actor))
  (logclear! (-> this mask) (process-mask actor-pause))
  (set! (-> this path) (new 'process 'path-control this 'path 0.0))
  (logior! (-> this path flags) (path-control-flag display draw-line draw-point draw-text))
  (set! (-> this link) (new 'process 'actor-link-info this))
  (set! (-> this targetnum) (+ (-> arg0 extra perm user-int8 0) 1))
  (eval-path-curve-div! (-> this path) (-> this trans) (the float (+ (-> this targetnum) -1)) 'interp)
  (set! (-> this target quad) (-> this trans quad))
  (set! (-> this max-lift) 20480.0)
  (set! (-> this birds) 0)
  (dotimes (v1-16 SEAGULLFLOCK_MAX)
    (set! (-> this bird v1-16) (the-as (pointer seagull) #f)))
  (spawn-bird this (-> this trans))
  (dotimes (s5-1 20)
    (let ((s4-0 (new 'stack-no-clear 'vector)))
      (let* ((f30-0 (-> this trans x))
             (f28-0 4096.0)
             (f26-0 10.0)
             (v1-22 (/ (the-as int (rand-uint31-gen *random-generator*)) 256))
             (v1-23 (the-as number (logior #x3f800000 v1-22))))
        (set! (-> s4-0 x) (+ f30-0 (* f28-0 (* f26-0 (+ -1.0 (the-as float v1-23)))))))
      (let* ((f30-1 (-> this trans z))
             (f28-1 4096.0)
             (f26-1 10.0)
             (v1-26 (/ (the-as int (rand-uint31-gen *random-generator*)) 256))
             (v1-27 (the-as number (logior #x3f800000 v1-26))))
        (set! (-> s4-0 z) (+ f30-1 (* f28-1 (* f26-1 (+ -1.0 (the-as float v1-27)))))))
      (set! (-> s4-0 y) (-> this trans y))
      (set! (-> s4-0 w) 1.0)
      (spawn-bird this s4-0)))
  (set! (-> this squall) (new 'process 'ambient-sound sound-seagull-squall (-> this trans)))
  (set! (-> this teleport-frames) 0)
  (logior! (-> this mask) (process-mask enemy))
  (go seagullflock-idle)
  (none))

(defmethod spawn-bird ((this seagullflock) (arg0 vector))
  ;; og:preserve-this constant
  (if (= (-> this birds) SEAGULLFLOCK_MAX) (return (the-as (pointer process) #f)))
  (let ((v0-0 (process-spawn seagull arg0 (-> this birds) this :to this)))
    (set! (-> this bird (-> this birds)) (the-as (pointer seagull) v0-0))
    (+! (-> this birds) 1)
    v0-0))

(defun-debug beach-rock-trigger ()
  (set! (-> (the-as seagullflock (search-process-tree *active-pool* (lambda ((arg0 process)) (= (-> arg0 type) seagullflock))))
            teleport-frames)
        600))
