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

;; name: glider-ring.gc
;; name in dgo: glider-ring
;; dgos: HGA

(define-extern *curve-glider-ring-linear-up-red* curve2d-piecewise)
(define-extern *trail-color-curve-glider-ring* curve-color-fast)
(define-extern *curve-glider-ring-linear-trail* curve2d-fast)
(define-extern *glider-ring-trail* light-trail-composition)

;; DECOMP BEGINS

(when (or (zero? *curve-glider-ring-linear-up-red*) (!= loading-level global))
  (set! *curve-glider-ring-linear-up-red* (new 'loading-level 'curve2d-piecewise))
  (allocate! *curve-glider-ring-linear-up-red* 2 'loading-level #f)
  )

(set! (-> *curve-glider-ring-linear-up-red* pts data 0 first) 0.0)

(set! (-> *curve-glider-ring-linear-up-red* pts data 0 second) 0.3)

(set! (-> *curve-glider-ring-linear-up-red* pts data 1 first) 1.0)

(set! (-> *curve-glider-ring-linear-up-red* pts data 1 second) 1.0)

(if #t
    (set! *trail-color-curve-glider-ring* (new 'static 'curve-color-fast
                                            :xs (new 'static 'vector :y -0.8 :z -1.0 :w -2.0)
                                            :ys (new 'static 'inline-array vector 4
                                              (new 'static 'vector :z 1.0 :w 128.0)
                                              (new 'static 'vector :y 1.0 :z 1.0 :w 128.0)
                                              (new 'static 'vector :x 1.0 :y 1.0 :w 128.0)
                                              (new 'static 'vector :x 1.0 :y 1.0 :w 128.0)
                                              )
                                            :one-over-x-deltas (new 'static 'vector :x 1.25 :y 5.0000005 :z 1.0 :w 1.0)
                                            )
          )
    )

(if #t
    (set! *curve-glider-ring-linear-trail* (new 'static 'curve2d-fast
                                             :xs (new 'static 'vector :y -1.0 :z -2.0 :w -3.0)
                                             :ys (new 'static 'vector :x 0.3 :y 1.0 :z 2.0 :w 3.0)
                                             :one-over-x-deltas (new 'static 'vector :x 0.7 :y 1.0 :z 1.0 :w 1.0)
                                             )
          )
    )

(if (or (zero? *glider-ring-trail*) (!= loading-level global))
    (set! *glider-ring-trail* (new 'loading-level 'light-trail-composition))
    )

(set! (-> *glider-ring-trail* color-mode) (the-as uint 0))

(set! (-> *glider-ring-trail* color-repeat-dist) 40960.0)

(set! (-> *glider-ring-trail* alpha-1-mode) (the-as uint 0))

(set! (-> *glider-ring-trail* alpha-2-mode) (the-as uint 1))

(set! (-> *glider-ring-trail* base-alpha) 1.0)

(set! (-> *glider-ring-trail* alpha-repeat-dist) 6144.0)

(set! (-> *glider-ring-trail* width-mode) (the-as uint 2))

(set! (-> *glider-ring-trail* base-width) 8192.0)

(set! (-> *glider-ring-trail* width-repeat-dist) 40960.0)

(set! (-> *glider-ring-trail* uv-mode) (the-as uint 0))

(set! (-> *glider-ring-trail* uv-repeat-dist) 16384000.0)

(set! (-> *glider-ring-trail* lie-mode) (lie-mode appearance0))

(set! (-> *glider-ring-trail* max-age) (seconds 1))

(if #f
    (set! (-> *glider-ring-trail* tex-id) (lookup-texture-id-by-name (the-as string #f) (the-as string #f)))
    (set! (-> *glider-ring-trail* tex-id) (new 'static 'texture-id :index #x3 :page #x1))
    )

(set! (-> *glider-ring-trail* width-curve) (the-as curve2d-piecewise *curve-glider-ring-linear-trail*))

(set! (-> *glider-ring-trail* color-curve) (the-as curve-color-piecewise *trail-color-curve-glider-ring*))

(set! (-> *glider-ring-trail* alpha-curve-1) (the-as curve2d-piecewise *curve-linear-down*))

(set! (-> *glider-ring-trail* alpha-curve-2) *curve-glider-ring-linear-up-red*)

(set! (-> *glider-ring-trail* zbuffer?) #f)

(vector-copy! (-> *glider-ring-trail* lie-vector) *up-vector*)

(set! (-> *glider-ring-trail* use-tape-mode?) #f)

(set! (-> *glider-ring-trail* blend-mode) (the-as uint 1))

(set! (-> *glider-ring-trail* frame-stagger) (the-as uint 1))

(deftype light-trail-tracker-glider-ring (light-trail-tracker)
  ()
  )


(defmethod should-track? ((this light-trail-tracker-glider-ring) (arg0 process-focusable))
  #f
  )

(defskelgroup skel-glider-ring des-glider-ring des-glider-ring-lod0-jg des-glider-ring-idle-ja
              ((des-glider-ring-lod0-mg (meters 999999)))
              :bounds (static-spherem 0 0 0 4)
              )

(defpartgroup group-glider-blinking-dot
  :id 660
  :flags (sp0 sp4)
  :bounds (static-bspherem 0 0 0 20)
  :parts ((sp-item 2555 :flags (sp7) :period (seconds 0.167) :length (seconds 0.017)))
  )

(defun sparticle-track-joint-glider ((arg0 sparticle-system) (arg1 sparticle-cpuinfo) (arg2 vector))
  (let* ((v1-1 (-> arg1 key proc))
         (a1-1 (-> arg1 user1-int16))
         (v1-3 (vector<-cspace! (new 'stack-no-clear 'vector) (-> v1-1 node-list data a1-1)))
         )
    (set! (-> arg2 x) (-> v1-3 x))
    (set! (-> arg2 y) (-> v1-3 y))
    (set! (-> arg2 z) (-> v1-3 z))
    )
  0
  (none)
  )

;; WARN: Return type mismatch float vs none.
(defun glider-part-single-birth ((arg0 sparticle-system) (arg1 sparticle-cpuinfo) (arg2 sparticle-launchinfo))
  (set! (-> arg1 user1-int16) (the-as uint (the int (-> arg1 omega))))
  (set! (-> arg1 omega) 8194048.0)
  (none)
  )

(defpart 2555
  :init-specs ((:texture (laser-hit level-default-sprite))
    (:birth-func 'glider-part-single-birth)
    (:num 1.0)
    (:scale-x (meters 10))
    (:rot-z (degrees 0) (degrees 360))
    (:scale-y :copy scale-x)
    (:r 255.0)
    (:g 100.0)
    (:b 0.0)
    (:a 255.0)
    (:omega (degrees 0))
    (:scalevel-x (meters 0.033333335) (meters 0.033333335))
    (:scalevel-y :copy scalevel-x)
    (:fade-a -0.85)
    (:timer (seconds 1))
    (:flags (sp-cpuinfo-flag-3))
    (:func 'sparticle-track-joint-glider)
    )
  )

(defpart 2556
  :init-specs ((:a 64.0) (:next-time (seconds 0.017)) (:next-launcher 2557))
  )

(defpart 2557
  :init-specs ((:a 128.0) (:next-time (seconds 0.017)) (:next-launcher 2556))
  )

(deftype glider-prim (simple-prim)
  ((far?  symbol)
   )
  )


(defmethod strip-setup ((this glider-prim))
  (set! (-> this strip num-verts) (the-as uint 4))
  (set! (-> this strip alpha) *simple-prim-additive*)
  (set! (-> this strip adnops 0 cmds) (gs-reg64 test-1))
  (set! (-> this strip data0)
        (new 'static 'gs-test :ate #x1 :afail #x1 :zte #x1 :ztst (gs-ztest greater-equal))
        )
  (cond
    ((-> this far?)
     (set! (-> this strip bucket) (bucket-id generic-sprite-1))
     (set! (-> this strip sink) (the-as uint 65))
     )
    (else
      (set! (-> this strip bucket) (bucket-id generic-sprite-2))
      (set! (-> this strip sink) (the-as uint 66))
      )
    )
  (none)
  )

(deftype glider-ring (process-drawable)
  ((root          collide-shape :override)
   (touch-time    time-frame)
   (ring-prim     handle)
   (minimap       connection-minimap)
   (player-got    symbol)
   (persistent    symbol)
   (id            int8)
   (boost         float)
   (plane         vector         :inline)
   (save-pos      vector         :inline)
   (up            vector         :inline)
   (right         vector         :inline)
   (part-track    handle)
   (mat           matrix         :inline)
   (xdist         float)
   (ydist         float)
   (toff          time-frame)
   (speedmod      float)
   (shootable     symbol)
   (lastring      symbol)
   (shot          symbol)
   (checkpoint    uint8)
   (distant-part  sparticle-launch-control)
   (blinky-part   sparticle-launch-control)
   (blinky-gone?  symbol)
   (do-trails?    symbol)
   (trails        handle         5)
   (trail-joint   uint8          5)
   (center-joint  uint8)
   )
  (:state-methods
    idle
    die
    )
  (:methods
    (init-collision! (_type_) none)
    (init-fields! (_type_) none)
    (glider-ring-method-24 (_type_) none)
    (set-far (_type_ symbol) none)
    )
  )


(deftype glider-thermal (process-drawable)
  ((id          int8)
   (part-track  handle)
   (mat         matrix  :inline)
   )
  (:state-methods
    idle
    )
  (:methods
    (init-part-and-mat! (_type_) none)
    )
  )


(defbehavior glider-ring-standard-event-handler glider-ring ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  (case arg2
    (('attack)
     (when (and (-> self shootable) (not (-> self shot)))
       (set! (-> self shot) #t)
       (set-time! (-> self state-time))
       (ja :group! des-glider-ring-expand-ja :num! min)
       (sound-play "ring-engage")
       )
     )
    (('touched)
     (let ((gp-2 (as-type (-> (the-as process-drawable arg0) root) collide-shape-moving)))
       (when gp-2
         (let ((s4-1 (new 'stack-no-clear 'inline-array 'vector 2)))
           (vector-copy! (-> s4-1 0) (-> gp-2 trans))
           (vector-copy! (-> s4-1 1) (-> gp-2 trans-old-old))
           (set! (-> s4-1 0 w) 1.0)
           (set! (-> s4-1 1 w) 1.0)
           (let ((f30-0 (vector4-dot (-> self plane) (-> s4-1 0)))
                 (f28-0 (vector4-dot (-> self plane) (-> s4-1 1)))
                 (f0-6 (fmax
                         (vector-vector-distance-squared (-> self root trans) (-> s4-1 0))
                         (vector-vector-distance-squared (-> self root trans) (-> s4-1 1))
                         )
                       )
                 (f1-0 61440.0)
                 )
             (when (and (< f0-6 (* f1-0 f1-0)) (or (not (-> self shootable)) (-> self shot)))
               (when (or (and (< f30-0 0.0) (>= f28-0 0.0)) (and (< f28-0 0.0) (>= f30-0 0.0)))
                 (if (-> self lastring)
                     (sound-play "ring-final")
                     (sound-play "ring-pass")
                     )
                 (if (> (-> self checkpoint) 0)
                     (task-node-close! (game-task-node desert-glide-templetop) 'event)
                     )
                 (send-event arg0 'turbo-ring (-> self boost))
                 (let ((s4-4 (new 'stack-no-clear 'matrix)))
                   (quaternion->matrix s4-4 (-> self root quat))
                   (send-event arg0 'ring-pos (-> self root trans) (-> s4-4 fvec))
                   )
                 (set-time! (-> self touch-time))
                 (if (logtest? (-> group-glider-ring-explode flags) (sp-group-flag sp13))
                     (part-tracker-spawn
                       part-tracker-subsampler
                       :to *entity-pool*
                       :group group-glider-ring-explode
                       :mat-joint (-> self mat)
                       )
                     (part-tracker-spawn part-tracker :to *entity-pool* :group group-glider-ring-explode :mat-joint (-> self mat))
                     )
                 (when (logtest? (-> gp-2 root-prim prim-core collide-as) (collide-spec jak))
                   (set! (-> self player-got) #t)
                   (send-event (ppointer->process (-> self parent)) 'turbo-ring-pickup (-> self id))
                   (if (and (-> self minimap) (not (-> self persistent)))
                       (kill-callback (-> *minimap* engine) (-> self minimap))
                       )
                   )
                 )
               )
             )
           )
         )
       )
     )
    )
  )

(defmethod set-far ((this glider-ring) (arg0 symbol))
  (if (handle->process (-> this ring-prim))
      (set! (-> (the-as glider-prim (-> this ring-prim process 0)) far?) arg0)
      )
  0
  (none)
  )

(define *near-thermal-dist-squared* 0.0)

(defun glider-ring-near-thermal-dist-squared ((arg0 float))
  (set! *near-thermal-dist-squared* arg0)
  0.0
  )

(defstate idle (glider-ring)
  :virtual #t
  :event glider-ring-standard-event-handler
  :code (behavior ()
    (loop
      (suspend)
      )
    )
  :post (behavior ()
    (if (and (-> self player-got)
             (time-elapsed? (-> self touch-time) (seconds 0.5))
             (or (not *target*) (or (< 81920.0 (vector-vector-distance (-> self root trans) (-> *target* control trans)))
                                    (focus-test? *target* teleporting)
                                    )
                 )
             (not (-> self persistent))
             )
        (go-virtual die)
        )
    (if (< (vector-vector-distance-squared (target-pos 0) (-> self root trans)) *near-thermal-dist-squared*)
        (set-far self #f)
        (set-far self #t)
        )
    (vector-copy! (-> self root trans) (-> self save-pos))
    (when (< 0.0 (-> self speedmod))
      (if (!= (-> self xdist) 0.0)
          (vector+*!
            (-> self root trans)
            (-> self root trans)
            (-> self right)
            (* (-> self xdist) (sin (* 75.0 (-> self speedmod) (the float (+ (current-time) (-> self toff))))))
            )
          )
      (if (!= (-> self ydist) 0.0)
          (vector+*!
            (-> self root trans)
            (-> self root trans)
            (-> self up)
            (* (-> self ydist) (cos (* 75.0 (-> self speedmod) (the float (+ (current-time) (-> self toff))))))
            )
          )
      )
    (if (and (-> self shootable) (not (-> self shot)))
        (quaternion-rotate-local-z! (-> self root quat) (-> self root quat) (* 32768.0 (seconds-per-frame)))
        )
    (vector-copy! (-> self mat trans) (-> self root trans))
    (when (and (nonzero? (-> self distant-part)) (not (-> self shootable)))
      )
    (when (logtest? (-> self draw status) (draw-control-status on-screen))
      (cond
        ((-> self shootable)
         (when (-> self shot)
           )
         )
        (else
          )
        )
      )
    (when (-> self shootable)
      (if (-> self shot)
          (ja :group! des-glider-ring-expand-ja :num! (seek! max 10.0))
          )
      (if (not (-> self shot))
          (ja :num! (seek!))
          )
      )
    (when (and (-> self shootable) (-> self shot) (not (-> self blinky-gone?)))
      (kill-particles (-> self blinky-part))
      (set! (-> self blinky-part) (the-as sparticle-launch-control 0))
      (set! (-> self blinky-gone?) #t)
      )
    (when (and (-> self shootable) (not (or (-> self shot) (-> self blinky-gone?))))
      (let ((a1-10 (vector<-cspace! (new 'stack-no-clear 'vector) (-> self node-list data 0))))
        (set! (-> *part-id-table* 2555 init-specs 10 initial-valuef) (the float (-> self center-joint)))
        (spawn (-> self blinky-part) a1-10)
        )
      )
    (when (-> self do-trails?)
      (dotimes (gp-6 5)
        (let ((v1-119 (vector<-cspace! (new 'stack-no-clear 'vector) (-> self node-list data (-> self trail-joint gp-6)))))
          (send-event (handle->process (-> self trails gp-6)) 'notice 'add-crumb-pos v1-119)
          )
        )
      )
    (when (and (-> self shootable) (and (-> self shot)
                                        (time-elapsed? (-> self state-time) (seconds 0.5))
                                        (not (handle->process (-> self ring-prim)))
                                        )
               )
      (let ((gp-7 (get-process *default-dead-pool* glider-prim #x4000 1)))
        (set! (-> self ring-prim)
              (ppointer->handle
                (when gp-7
                  (let ((t9-17 (method-of-type process activate)))
                    (t9-17 gp-7 self "prim" (the-as pointer #x70004000))
                    )
                  (let ((t9-18 run-function-in-process)
                        (a0-41 gp-7)
                        (a1-17 simple-prim-init-by-other)
                        (a2-7 (-> self root trans))
                        (a3-2 (new 'stack-no-clear 'vector))
                        )
                    (set! (-> a3-2 x) 32768.0)
                    (set! (-> a3-2 y) 32768.0)
                    (set! (-> a3-2 z) 32768.0)
                    (set! (-> a3-2 w) 1.0)
                    ((the-as (function object object object object object none) t9-18) a0-41 a1-17 a2-7 a3-2 #x5e700200)
                    )
                  (-> gp-7 ppointer)
                  )
                )
              )
        )
      )
    (let ((v1-149 (handle->process (-> self ring-prim))))
      (when v1-149
        (vector-copy! (-> (the-as glider-prim v1-149) root trans) (-> self root trans))
        (quaternion-copy! (-> (the-as glider-prim v1-149) root quat) (-> self root quat))
        )
      )
    (transform-post)
    )
  )

(defmethod deactivate ((this glider-ring))
  "Make a process dead, clean it up, remove it from the active pool, and return to dead pool."
  (when (nonzero? (-> this distant-part))
    (kill-particles (-> this distant-part))
    (set! (-> this distant-part) (the-as sparticle-launch-control 0))
    0
    )
  (when (and (nonzero? (-> this blinky-part)) (not (-> this blinky-gone?)))
    (kill-particles (-> this blinky-part))
    (set! (-> this blinky-gone?) #t)
    )
  (call-parent-method this)
  (none)
  )

(defstate die (glider-ring)
  :virtual #t
  :code (behavior ()
    (set-time! (-> self state-time))
    (let ((v1-3 (-> self root root-prim)))
      (set! (-> v1-3 prim-core collide-as) (collide-spec))
      (set! (-> v1-3 prim-core collide-with) (collide-spec))
      )
    0
    (until (time-elapsed? (-> self state-time) (seconds 0.1))
      (suspend)
      )
    )
  )

(defmethod init-collision! ((this glider-ring))
  (let ((s5-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player))))
    (set! (-> s5-0 penetrate-using) (the-as penetrate -1))
    (set! (-> s5-0 penetrated-by) (the-as penetrate -1))
    (let ((v1-4 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-4 prim-core collide-as) (collide-spec obstacle))
      (set-vector! (-> v1-4 local-sphere) 0.0 0.0 0.0 65536.0)
      (set! (-> s5-0 total-prims) (the-as uint 1))
      (set! (-> s5-0 root-prim) v1-4)
      )
    (set! (-> s5-0 nav-radius) (* 0.75 (-> s5-0 root-prim local-sphere w)))
    (let ((v1-7 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-7 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-7 prim-core collide-with))
      )
    (set! (-> s5-0 event-self) 'touched)
    (set! (-> this root) s5-0)
    )
  0
  (none)
  )

(defmethod relocate ((this glider-ring) (offset int))
  (when (nonzero? (-> this distant-part))
    (if (nonzero? (-> this distant-part))
        (&+! (-> this distant-part) offset)
        )
    )
  (when (not (-> this blinky-gone?))
    (if (nonzero? (-> this blinky-part))
        (&+! (-> this blinky-part) offset)
        )
    )
  (call-parent-method this offset)
  )

(defmethod init-fields! ((this glider-ring))
  (let ((s5-0 (-> this mat)))
    (let ((s4-0 (new 'stack-no-clear 'quaternion)))
      (quaternion-copy! s4-0 (-> this root quat))
      (quaternion->matrix s5-0 s4-0)
      )
    (vector-cross! (-> this right) *up-vector* (-> s5-0 fvec))
    (vector-normalize! (-> this right) 1.0)
    (vector-cross! (-> this up) (-> this right) (-> s5-0 fvec))
    (vector-normalize! (-> this up) 1.0)
    (vector-copy! (-> s5-0 trans) (-> this root trans))
    (matrix->quaternion (-> this root quat) s5-0)
    (vector-copy! (-> this plane) (-> s5-0 fvec))
    )
  (set! (-> this plane w) (- (vector-dot (-> this plane) (-> this root trans))))
  (update-transforms (-> this root))
  (set! (-> this player-got) #f)
  (set! (-> this part) (create-launch-control group-glider-ring this))
  (set! (-> this distant-part) (create-launch-control group-distant-glider-ring this))
  (set! (-> this blinky-part) (create-launch-control group-glider-blinking-dot this))
  (set! (-> this blinky-gone?) #f)
  (if (not (-> this persistent))
      (set! (-> this minimap) #f)
      )
  (set-time! (-> this touch-time))
  0
  (none)
  )

(defbehavior glider-ring-init-by-other glider-ring ((arg0 glider-ring-info) (arg1 int) (arg2 symbol))
  (init-collision! self)
  (initialize-skeleton
    self
    (the-as skeleton-group (art-group-get-by-name *level* "skel-glider-ring" (the-as (pointer level) #f)))
    (the-as pair 0)
    )
  (set! (-> self entity) #f)
  (cond
    ((-> arg0 shootable)
     (ja :group! des-glider-ring-idle-ja :num! min)
     (set! (-> self ring-prim) (the-as handle #f))
     )
    (else
      (ja :group! des-glider-ring-expand-ja :num! max)
      (let ((s3-3 (get-process *default-dead-pool* glider-prim #x4000 1)))
        (set! (-> self ring-prim)
              (ppointer->handle
                (when s3-3
                  (let ((t9-6 (method-of-type process activate)))
                    (t9-6 s3-3 self "prim" (the-as pointer #x70004000))
                    )
                  (let ((t9-7 run-function-in-process)
                        (a0-8 s3-3)
                        (a1-7 simple-prim-init-by-other)
                        (a2-7 (-> self root trans))
                        (a3-2 (new 'stack-no-clear 'vector))
                        )
                    (set! (-> a3-2 x) 32768.0)
                    (set! (-> a3-2 y) 32768.0)
                    (set! (-> a3-2 z) 32768.0)
                    (set! (-> a3-2 w) 1.0)
                    ((the-as (function object object object object object none) t9-7) a0-8 a1-7 a2-7 a3-2 #x5e700200)
                    )
                  (-> s3-3 ppointer)
                  )
                )
              )
        )
      )
    )
  (vector-copy! (-> self root trans) (-> arg0 pos))
  (quaternion-from-two-vectors! (-> self root quat) *z-vector* (-> arg0 forw))
  (let ((v1-37 (vector-y-quaternion! (new 'stack-no-clear 'vector) (-> self root quat))))
    (vector+*! (-> self root trans) (-> self root trans) v1-37 10240.0)
    )
  (vector-copy! (-> self save-pos) (-> self root trans))
  (set! (-> self boost) (-> arg0 boost))
  (set! (-> self id) arg1)
  (set! (-> self persistent) arg2)
  (set! (-> self xdist) (-> arg0 xdist))
  (set! (-> self ydist) (-> arg0 ydist))
  (set! (-> self toff) (-> arg0 toff))
  (set! (-> self speedmod) (-> arg0 speedmod))
  (set! (-> self checkpoint) (-> arg0 checkpoint))
  (set! (-> self shootable) (-> arg0 shootable))
  (set! (-> self lastring) (-> arg0 lastring))
  (set! (-> self shot) #f)
  (set! (-> self do-trails?) (or (!= (-> self xdist) 0.0) (!= (-> self ydist) 0.0)))
  (set! (-> self center-joint) (the-as uint 2))
  (set! (-> self trail-joint 0) (the-as uint 3))
  (set! (-> self trail-joint 1) (the-as uint 5))
  (set! (-> self trail-joint 2) (the-as uint 7))
  (set! (-> self trail-joint 3) (the-as uint 9))
  (set! (-> self trail-joint 4) (the-as uint 11))
  (when (-> self do-trails?)
    (let ((gp-1 (new 'stack-no-clear 'light-trail-tracker-spawn-params)))
      (set! (-> gp-1 tracked-obj) (process->handle self))
      (set! (-> gp-1 appearance) *glider-ring-trail*)
      (set! (-> gp-1 max-num-crumbs) (the int (* 0.25 (the float (-> gp-1 appearance max-age)))))
      (set! (-> gp-1 track-immediately?) #t)
      (dotimes (s5-1 5)
        (let* ((v1-64
                 (estimate-light-trail-mem-usage
                   (the-as uint (-> gp-1 max-num-crumbs))
                   (the-as uint (= (-> gp-1 appearance lie-mode) (lie-mode use-two-strips)))
                   )
                 )
               (s4-1 (get-process *default-dead-pool* light-trail-tracker-glider-ring (+ v1-64 8192) 1))
               )
          (set! (-> self trails s5-1)
                (ppointer->handle (when s4-1
                                    (let ((t9-12 (method-of-type process activate)))
                                      (t9-12 s4-1 self "light-trail" (the-as pointer #x70004000))
                                      )
                                    (run-now-in-process s4-1 light-trail-tracker-init-by-other gp-1)
                                    (-> s4-1 ppointer)
                                    )
                                  )
                )
          )
        )
      )
    )
  (init-fields! self)
  (go-virtual idle)
  )

;; WARN: Return type mismatch process vs glider-ring.
(defun glider-ring-spawn ((arg0 process) (arg1 glider-ring-info) (arg2 int) (arg3 symbol))
  (local-vars (sv-16 type) (sv-32 int))
  (let ((gp-0 (the-as process #f)))
    (let* ((s1-0 *default-dead-pool*)
           (s0-0 (method-of-object s1-0 get-process))
           )
      (set! sv-16 glider-ring)
      (set! sv-32 5)
      (let* ((a2-1 (+ (* 0 (estimate-light-trail-mem-usage (the-as uint 12) (the-as uint #f))) #x4000))
             (a3-1 1)
             (s1-1 (s0-0 s1-0 sv-16 a2-1 a3-1))
             (v1-4 (when s1-1
                     (let ((t9-2 (method-of-type glider-ring activate)))
                       (t9-2 (the-as glider-ring s1-1) arg0 "glider-ring" (the-as pointer #x70004000))
                       )
                     (run-now-in-process s1-1 glider-ring-init-by-other arg1 arg2 arg3)
                     (-> s1-1 ppointer)
                     )
                   )
             )
        (if v1-4
            (set! gp-0 (-> v1-4 0))
            )
        )
      )
    (the-as glider-ring gp-0)
    )
  )

(defstate idle (glider-thermal)
  :virtual #t
  :code sleep-code
  :post (behavior ()
    (spawn-from-mat (-> self part) (-> self mat))
    0
    )
  )

(defmethod init-part-and-mat! ((this glider-thermal))
  (set! (-> this part) (create-launch-control group-wind-thermal this))
  (matrix-identity! (-> this mat))
  (vector-copy! (-> this mat trans) (-> this root trans))
  0
  (none)
  )

(defbehavior glider-thermal-init-by-other glider-thermal ((arg0 glider-thermal-info) (arg1 int))
  (set! (-> self root) (new 'process 'trsqv))
  (vector-copy! (-> self root trans) (-> arg0 pos))
  (set! (-> self id) arg1)
  (init-part-and-mat! self)
  (go-virtual idle)
  )

;; WARN: Return type mismatch process vs glider-thermal.
(defun glider-thermal-spawn ((arg0 process) (arg1 glider-thermal-info) (arg2 int))
  (let ((gp-0 (the-as process #f)))
    (let ((v1-1 (process-spawn glider-thermal arg1 arg2 :name "glider-thermal" :to arg0)))
      (if v1-1
          (set! gp-0 (-> v1-1 0))
          )
      )
    (the-as glider-thermal gp-0)
    )
  )

(defmethod to-static-macro ((this glider-ring-info) (arg0 object))
  (format arg0 "(static-glider-ring-info")
  (format arg0 " :pos (~8,,2M ~8,,2M ~8,,2M)" (-> this pos x) (-> this pos y) (-> this pos z))
  (format arg0 " :forw (~6,,3f ~6,,3f ~6,,3f)" (-> this forw x) (-> this forw y) (-> this forw z))
  (if (!= (-> this boost) 1.0)
      (format arg0 " :boost ~4,,2f" (-> this boost))
      )
  (if (!= (-> this dist) 819200.0)
      (format arg0 " :dist (meters ~4,,2M)" (-> this dist))
      )
  (if (!= (-> this xdist) 0.0)
      (format arg0 " :xdist ~4,,2M" (-> this xdist))
      )
  (if (nonzero? (-> this toff))
      (format arg0 " :toff ~3,,1f" (* 0.0033333334 (the float (-> this toff))))
      )
  (if (!= (-> this ydist) 0.0)
      (format arg0 " :ydist ~4,,2M" (-> this ydist))
      )
  (if (nonzero? (-> this checkpoint))
      (format arg0 " :checkpoint ~d" (-> this checkpoint))
      )
  (if (-> this shootable)
      (format arg0 " :shootable #t")
      )
  (if (-> this lastring)
      (format arg0 " :lastring #t")
      )
  (if (!= (-> this speedmod) 1.0)
      (format arg0 " :speedmod ~4,,2f" (-> this speedmod))
      )
  (format arg0 " )~%")
  0
  (none)
  )

(defun glider-launch-mist-particle ((arg0 vector) (arg1 process))
  (cond
    ((logtest? (-> group-glider-cloud flags) (sp-group-flag sp13))
     (vector-copy! (-> *launch-matrix* trans) arg0)
     (part-tracker-spawn part-tracker-subsampler :to arg1 :group group-glider-cloud :duration -1)
     )
    (else
      (vector-copy! (-> *launch-matrix* trans) arg0)
      (part-tracker-spawn part-tracker :to arg1 :group group-glider-cloud :duration -1)
      )
    )
  0
  (none)
  )
