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

;; definition for symbol *tube-mods*, type surface
(define *tube-mods* (new 'static 'surface
                      :name 'tube
                      :turnv 21845.334
                      :turnvv 524288.0
                      :tiltv 5461.3335
                      :tiltvv 131072.0
                      :transv-max 1.0
                      :target-speed 32768.0
                      :seek0 1.0
                      :seek90 1.0
                      :seek180 1.0
                      :fric 1.0
                      :nonlin-fric-dist 1.0
                      :slip-factor 1.0
                      :slide-factor 1.0
                      :slope-up-factor 1.0
                      :slope-down-factor 1.0
                      :slope-slip-angle 1.0
                      :impact-fric 1.0
                      :bend-factor 1.0
                      :bend-speed 1.0
                      :alignv 1.0
                      :slope-up-traction 1.0
                      :align-speed 1.0
                      )
        )

;; definition for symbol *tube-jump-mods*, type surface
(define *tube-jump-mods* (new 'static 'surface
                           :name 'tube
                           :turnv 21845.334
                           :turnvv 262144.0
                           :tiltv 5461.3335
                           :tiltvv 131072.0
                           :transv-max 1.0
                           :seek0 0.8
                           :seek90 0.7
                           :seek180 0.8
                           :fric 1.0
                           :nonlin-fric-dist 1.0
                           :slip-factor 1.0
                           :slide-factor 1.0
                           :slope-up-factor 1.0
                           :slope-down-factor 1.0
                           :slope-slip-angle 1.0
                           :impact-fric 1.0
                           :bend-factor 1.0
                           :bend-speed 1.0
                           :alignv 1.0
                           :slope-up-traction 1.0
                           :align-speed 1.0
                           :mode 'air
                           :flags (surface-flags jump)
                           )
        )

;; definition for symbol *tube-hit-mods*, type surface
(define *tube-hit-mods* (new 'static 'surface
                          :name 'tube
                          :turnv 21845.334
                          :turnvv 262144.0
                          :tiltv 32768.0
                          :tiltvv 131072.0
                          :transv-max 1.0
                          :target-speed 40960.0
                          :fric 1.0
                          :nonlin-fric-dist 1.0
                          :slip-factor 1.0
                          :slide-factor 1.0
                          :slope-up-factor 1.0
                          :slope-down-factor 1.0
                          :slope-slip-angle 1.0
                          :impact-fric 1.0
                          :bend-factor 1.0
                          :bend-speed 1.0
                          :alignv 1.0
                          :slope-up-traction 1.0
                          :align-speed 1.0
                          :mode 'air
                          )
        )

;; failed to figure out what this is:
(let ((v1-3 (new 'static 'surface
              :name '*tube-surface*
              :turnv 1.0
              :turnvv 1.0
              :tiltv 1.0
              :tiltvv 1.0
              :transv-max 94208.0
              :target-speed 1.0
              :seek0 32768.0
              :seek90 94208.0
              :seek180 8192.0
              :fric 0.98
              :nonlin-fric-dist 4091904.0
              :slip-factor 0.7
              :slope-down-factor 81920.0
              :slope-slip-angle 16384.0
              :bend-speed 4.0
              :alignv 1.0
              :slope-up-traction 1.0
              :align-speed 1.0
              :flags (surface-flags no-turn-around always-rotate-toward-transv)
              )
            )
      )
  (set! *tube-surface* v1-3)
  (set! (-> v1-3 mult-hook) (the-as (function surface surface surface int none) nothing))
  (set! (-> v1-3 touch-hook) nothing)
  (set! (-> v1-3 active-hook) nothing)
  )

;; definition of type tube-info
(deftype tube-info (basic)
  ((entity          basic              :offset-assert   4)
   (tube            handle             :offset-assert   8)
   (downhill        vector     :inline :offset-assert  16)
   (centertube      vector     :inline :offset-assert  32)
   (downtube        vector     :inline :offset-assert  48)
   (sidetube        vector     :inline :offset-assert  64)
   (foretube        vector     :inline :offset-assert  80)
   (old-transv      vector     :inline :offset-assert  96)
   (mod-x           float              :offset-assert 112)
   (mod-y           float              :offset-assert 116)
   (start-time      time-frame         :offset-assert 120)
   (turn-anim-targ  float              :offset-assert 128)
   (turn-anim-frame float              :offset-assert 132)
   (turn-anim-vel   float              :offset-assert 136)
   (tube-sound-id   sound-id           :offset-assert 140)
   (tube-sound-vol  float              :offset-assert 144)
   )
  :method-count-assert 9
  :size-assert         #x94
  :flag-assert         #x900000094
  )

;; definition for method 3 of type tube-info
(defmethod inspect tube-info ((obj tube-info))
  (format #t "[~8x] ~A~%" obj (-> obj type))
  (format #t "~Tentity: ~A~%" (-> obj entity))
  (format #t "~Ttube: ~D~%" (-> obj tube))
  (format #t "~Tdownhill: ~`vector`P~%" (-> obj downhill))
  (format #t "~Tcentertube: ~`vector`P~%" (-> obj centertube))
  (format #t "~Tdowntube: ~`vector`P~%" (-> obj downtube))
  (format #t "~Tsidetube: ~`vector`P~%" (-> obj sidetube))
  (format #t "~Tforetube: ~`vector`P~%" (-> obj foretube))
  (format #t "~Told-transv: ~`vector`P~%" (-> obj old-transv))
  (format #t "~Tmod-x: ~f~%" (-> obj mod-x))
  (format #t "~Tmod-y: ~f~%" (-> obj mod-y))
  (format #t "~Tstart-time: ~D~%" (-> obj start-time))
  (format #t "~Tturn-anim-targ: ~f~%" (-> obj turn-anim-targ))
  (format #t "~Tturn-anim-frame: ~f~%" (-> obj turn-anim-frame))
  (format #t "~Tturn-anim-vel: ~f~%" (-> obj turn-anim-vel))
  (format #t "~Ttube-sound-id: ~D~%" (-> obj tube-sound-id))
  (format #t "~Ttube-sound-vol: ~f~%" (-> obj tube-sound-vol))
  obj
  )

;; definition of type tube-bank
(deftype tube-bank (basic)
  ()
  :method-count-assert 9
  :size-assert         #x4
  :flag-assert         #x900000004
  )

;; definition for method 3 of type tube-bank
(defmethod inspect tube-bank ((obj tube-bank))
  (format #t "[~8x] ~A~%" obj (-> obj type))
  obj
  )

;; definition for symbol *TUBE-bank*, type tube-bank
(define *TUBE-bank* (new 'static 'tube-bank))

;; definition for function tube-sounds
(defbehavior tube-sounds target ()
  (seek!
    (-> self tube tube-sound-vol)
    (if (logtest? (-> self control status) (cshape-moving-flags onsurf))
        100.0
        0.0
        )
    (* 200.0 (-> *display* seconds-per-frame))
    )
  (let ((f30-0 (-> self tube tube-sound-vol))
        (f0-5 (lerp-scale -0.3 0.3 (-> self control unknown-float01) 0.0 122880.0))
        )
    (sound-play
      "slide-loop"
      :id (-> self tube tube-sound-id)
      :vol f30-0
      :pitch f0-5
      :position (the-as symbol (-> self control trans))
      )
    )
  )

;; definition for function tube-thrust
;; INFO: Return type mismatch int vs none.
;; Used lq/sq
(defbehavior tube-thrust target ((arg0 float) (arg1 float))
  (let ((s4-1 (vector-! (new 'stack-no-clear 'vector) (-> self tube foretube) (-> self control trans))))
    (vector-flatten! s4-1 s4-1 (-> self tube downtube))
    (vector-flatten! s4-1 s4-1 (-> self control local-normal))
    (add-debug-vector
      *display-target-marks*
      (bucket-id debug-no-zbuf)
      (-> self control trans)
      s4-1
      (meters 0.00024414062)
      (new 'static 'rgba :g #xff :a #x80)
      )
    (vector-matrix*! s4-1 s4-1 (-> self control unknown-matrix00))
    (vector-float*! s4-1 s4-1 2.0)
    (if (< (-> self control unknown-surface01 target-speed) (vector-length s4-1))
        (vector-normalize! s4-1 (-> self control unknown-surface01 target-speed))
        )
    (vector-v++! (-> self control unknown-vector00) s4-1)
    (when (logtest? (-> self control status) (cshape-moving-flags twall))
      (let ((s3-0 (-> self tube old-transv)))
        (-> self control unknown-vector00 y)
        (vector-reflect! s4-1 s3-0 (-> self control unknown-vector71))
        (let ((f30-1 (vector-dot (-> self tube sidetube) (-> self tube old-transv)))
              (s2-0 (new-stack-vector0))
              (f28-0 (vector-dot (-> self tube sidetube) s4-1))
              )
          0.0
          (vector-! s2-0 s4-1 (vector-float*! s2-0 (-> self tube sidetube) f28-0))
          (let* ((f0-8 (vector-length s2-0))
                 (f1-0 f0-8)
                 )
            (cond
              ((< 0.0 f30-1)
               (if (< f28-0 (- f30-1))
                   (set! f28-0 (- f30-1))
                   )
               )
              ((< f30-1 0.0)
               (if (< (- f30-1) f28-0)
                   (set! f28-0 (- f30-1))
                   )
               )
              )
            (vector+! s4-1 (vector-float*! s4-1 (-> self tube sidetube) f28-0) (vector-float*! s2-0 s2-0 (/ f0-8 f1-0)))
            )
          )
        (vector-flatten! s4-1 s4-1 (-> self control local-normal))
        (let ((s2-1 (new-stack-vector0)))
          (let ((f0-11 (vector-dot (-> self tube downtube) s4-1)))
            0.0
            (vector-! s2-1 s4-1 (vector-float*! s2-1 (-> self tube downtube) f0-11))
            )
          (let* ((f0-12 (vector-length s2-1))
                 (f1-2 f0-12)
                 (f2-5 (fmax (-> self control unknown-float01) (vector-dot s3-0 (-> self tube downtube))))
                 )
            (vector+! s4-1 (vector-float*! s4-1 (-> self tube downtube) f2-5) (vector-float*! s2-1 s2-1 (/ f0-12 f1-2)))
            )
          )
        )
      (vector-matrix*! s4-1 s4-1 (-> self control unknown-matrix00))
      (let ((f0-14 (-> self control unknown-vector00 y)))
        (set! (-> self control unknown-vector00 quad) (-> s4-1 quad))
        (set! (-> self control unknown-vector00 y) f0-14)
        )
      )
    )
  (let ((s4-2 (new 'stack-no-clear 'vector)))
    (set! (-> s4-2 quad) (-> self tube downtube quad))
    (let ((s3-1 (new 'stack-no-clear 'vector)))
      (set! (-> s3-1 quad) (-> self tube sidetube quad))
      (vector-flatten! s3-1 s3-1 (-> self control local-normal))
      (add-debug-vector
        *display-target-marks*
        (bucket-id debug-no-zbuf)
        (-> self control trans)
        s3-1
        (meters 2.0)
        (new 'static 'rgba :r #xff :g #xff :a #x80)
        )
      (vector-matrix*! s3-1 s3-1 (-> self control unknown-matrix00))
      (vector-normalize! s3-1 (* arg0 (-> self control unknown-surface01 seek90)))
      (vector-v++! (-> self control unknown-vector00) s3-1)
      )
    (vector-flatten! s4-2 s4-2 (-> self control local-normal))
    (add-debug-vector
      *display-target-marks*
      (bucket-id debug-no-zbuf)
      (-> self control trans)
      s4-2
      (meters 2.0)
      (new 'static 'rgba :r #xff :g #x80 :b #x40 :a #x80)
      )
    (vector-matrix*! s4-2 s4-2 (-> self control unknown-matrix00))
    (vector-normalize!
      s4-2
      (* (-> self control unknown-surface01 slope-down-factor) (fmax 0.2 (-> self control surface-angle)))
      )
    (vector-v++! (-> self control unknown-vector00) s4-2)
    )
  (let* ((f1-6 (-> self control unknown-surface01 fric))
         (f1-9 (- 1.0 (* 60.0 (-> *display* seconds-per-frame) (- 1.0 f1-6))))
         (f0-21 (* 0.5 (+ 1.0 f1-9)))
         )
    (set! (-> self control unknown-vector00 x) (* (-> self control unknown-vector00 x) f0-21))
    (set! (-> self control unknown-vector00 z) (* (-> self control unknown-vector00 z) f0-21))
    )
  (let ((f30-2
          (- (-> self control unknown-surface01 transv-max) (if (< arg1 0.0)
                                                                (* arg1 (-> self control unknown-surface01 seek0))
                                                                (* arg1 (-> self control unknown-surface01 seek180))
                                                                )
             )
          )
        )
    (if (>= (vector-xz-length (-> self control unknown-vector00)) f30-2)
        (vector-xz-normalize! (-> self control unknown-vector00) f30-2)
        )
    )
  (let ((gp-1 (new-stack-vector0)))
    (vector-matrix*! gp-1 (-> self control unknown-vector00) (-> self control unknown-matrix01))
    (vector-float*! gp-1 gp-1 0.5)
    (add-debug-vector
      *display-target-marks*
      (bucket-id debug-no-zbuf)
      (-> self control trans)
      gp-1
      (meters 0.00024414062)
      (new 'static 'rgba :g #xff :b #xff :a #x80)
      )
    (vector+! gp-1 gp-1 (-> self control trans))
    (add-debug-text-sphere
      *display-target-marks*
      (bucket-id debug-no-zbuf)
      gp-1
      819.2
      "ltransv"
      (new 'static 'rgba :g #xff :b #xff :a #x80)
      )
    (vector-matrix*! gp-1 (new 'static 'vector :z 40960.0 :w 1.0) (-> self control unknown-matrix01))
    (vector-float*! gp-1 gp-1 0.5)
    (vector+! gp-1 gp-1 (-> self control trans))
    (add-debug-text-sphere
      *display-target-marks*
      (bucket-id debug-no-zbuf)
      gp-1
      819.2
      "nose"
      (new 'static 'rgba :r #xff :g #xff :a #x80)
      )
    )
  (tube-sounds)
  0
  (none)
  )

;; definition for function target-tube-post
;; Used lq/sq
(defbehavior target-tube-post target ()
  (let ((gp-0 (the int (-> *display* time-ratio))))
    (set-time-ratios *display* 1.0)
    (countdown (s5-0 gp-0)
      (set! (-> self control unknown-int40) s5-0)
      (set! (-> self tube old-transv quad) (-> self control transv quad))
      (flag-setup)
      (build-conversions (-> self control transv))
      (if (logtest? (-> self state-flags) (state-flags timed-invulnerable))
          (set! (-> self control unknown-surface01 turnv) (* 3.0 (-> self control unknown-surface01 turnv)))
          )
      (forward-up-nopitch->quaternion
        (-> self control dir-targ)
        (vector-z-quaternion! (new 'stack-no-clear 'vector) (-> self control dir-targ))
        (-> self control local-normal)
        )
      (do-rotations1)
      (send-event
        (handle->process (-> self tube tube))
        'update
        (-> self tube centertube)
        (-> self tube downtube)
        (-> self tube sidetube)
        (-> self tube foretube)
        )
      (vector-flatten!
        (-> self tube downhill)
        (vector-negate! (new-stack-vector0) (-> self control dynam gravity-normal))
        (-> self control local-normal)
        )
      (vector-normalize! (-> self tube downhill) 1.0)
      (set! (-> self control unknown-float12) 1.0)
      (let ((f30-0 (analog-input (the-as int (-> self control unknown-cpad-info00 leftx)) 128.0 32.0 110.0 1.0)))
        (set! (-> self tube mod-x) f30-0)
        (let ((f0-5 (analog-input (the-as int (-> self control unknown-cpad-info00 lefty)) 128.0 32.0 110.0 1.0)))
          (set! (-> self tube mod-y) f0-5)
          (tube-thrust f30-0 f0-5)
          )
        )
      (add-gravity)
      (do-rotations2)
      (reverse-conversions (-> self control transv))
      (if *debug-segment*
          (add-frame
            (-> *display* frames (-> *display* on-screen) frame profile-bar 0)
            'draw
            (new 'static 'rgba :r #x40 :b #x40 :a #x80)
            )
          )
      (set! (-> self control reaction) target-collision-reaction)
      (fill-cache-integrate-and-collide!
        (-> self control)
        (-> self control transv)
        (-> self control root-prim collide-with)
        )
      (if (logtest? (-> self control root-prim prim-core action) (collide-action ca-6))
          (find-edge-grabs! *target* *collide-cache*)
          )
      (if *debug-segment*
          (add-frame
            (-> *display* frames (-> *display* on-screen) frame profile-bar 0)
            'draw
            (new 'static 'rgba :r #x80 :g #x60 :b #x40 :a #x80)
            )
          )
      (bend-gravity)
      (post-flag-setup)
      (set! (-> self control surf) *tube-surface*)
      )
    (set-time-ratios *display* (the float gp-0))
    )
  (if *debug-segment*
      (add-frame
        (-> *display* frames (-> *display* on-screen) frame profile-bar 0)
        'draw
        (new 'static 'rgba :r #x40 :b #x40 :a #x80)
        )
      )
  (ja-post)
  (if *debug-segment*
      (add-frame
        (-> *display* frames (-> *display* on-screen) frame profile-bar 0)
        'draw
        (new 'static 'rgba :r #x80 :a #x80)
        )
      )
  (joint-points)
  (do-target-shadow)
  (target-powerup-process)
  (none)
  )

;; failed to figure out what this is:
(defstate target-tube-start (target)
  :event (behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
    (cond
      ((and (= arg2 'query) (= (-> arg3 param 0) 'mode))
       'tube
       )
      (else
        (case arg2
          (('end-mode)
           (go
             target-jump
             (-> *TARGET-bank* tube-jump-height-min)
             (-> *TARGET-bank* tube-jump-height-max)
             (the-as surface #f)
             )
           )
          (('touched)
           (send-event arg0 'attack (-> arg3 param 0) 'tube 0 0)
           #f
           )
          (('attack 'attack-or-shove 'attack-invinc)
           (target-attacked
             'attack-or-shove
             (the-as attack-info (-> arg3 param 1))
             arg0
             (the-as process (-> arg3 param 0))
             target-tube-hit
             )
           )
          (else
            (target-generic-event-handler arg0 arg1 arg2 arg3)
            )
          )
        )
      )
    )
  :exit (behavior ()
    (when (not (or (= (-> self next-state name) 'target-tube)
                   (= (-> self next-state name) 'target-tube-jump)
                   (= (-> self next-state name) 'target-tube-hit)
                   )
               )
      (let ((v1-7 (-> self manipy)))
        (when v1-7
          (deactivate (-> v1-7 0))
          (set! (-> self manipy) (the-as (pointer manipy) #f))
          )
        )
      (logclear! (-> self control root-prim prim-core action) (collide-action ca-13))
      (set! (-> self control unknown-surface00) *walk-mods*)
      (set! (-> self control dynam gravity-max) (-> self control unknown-dynamics00 gravity-max))
      (set! (-> self control dynam gravity-length) (-> self control unknown-dynamics00 gravity-length))
      (target-collide-set! 'normal 0.0)
      (set! (-> self control reaction) target-collision-reaction)
      (send-event *camera* 'clear-slave-option #x6000)
      (sound-stop (-> self tube tube-sound-id))
      (set! (-> self tube tube-sound-id) (new 'static 'sound-id))
      (send-event (handle->process (-> self tube tube)) 'end-mode)
      (target-exit)
      )
    (none)
    )
  :code (behavior ((arg0 handle))
    (send-event *camera* 'set-slave-option #x6000)
    (target-exit)
    (set! *display-profile* #f)
    (set! *display-entity-errors* #f)
    (set! (-> self control surf) *tube-surface*)
    (if (zero? (-> self tube))
        (set! (-> self tube) (new 'process 'tube-info))
        )
    (set! (-> self tube tube) arg0)
    (set! (-> self tube entity) #f)
    (let ((a0-4 (handle->process arg0)))
      (if a0-4
          (set! (-> self tube entity) (-> a0-4 entity))
          )
      )
    (set! (-> self tube start-time) (-> *display* base-frame-counter))
    (set! (-> self tube tube-sound-id) (new-sound-id))
    (set! (-> self tube tube-sound-vol) 0.0)
    (target-collide-set! 'tube 0.0)
    (set! (-> self control transv quad) (the-as uint128 0))
    (set! (-> self control unknown-float01) 0.0)
    (logior! (-> self control root-prim prim-core action) (collide-action ca-13))
    (remove-exit)
    (cond
      ((< (the-as
            float
            (send-event
              (handle->process (-> self tube tube))
              'update
              (-> self tube centertube)
              (-> self tube downtube)
              (-> self tube sidetube)
              (-> self tube foretube)
              )
            )
          0.5
          )
       (vector-normalize-copy! (-> self control transv) (-> self tube downtube) 40960.0)
       (forward-up-nopitch->quaternion
         (-> self control dir-targ)
         (vector-normalize-copy! (new 'stack-no-clear 'vector) (-> self control transv) 1.0)
         (-> self control dynam gravity-normal)
         )
       (go target-tube-jump (-> *TARGET-bank* tube-jump-height-min) (-> *TARGET-bank* tube-jump-height-max))
       )
      (else
        (go target-tube)
        )
      )
    (none)
    )
  :post target-post
  )

;; definition for function target-tube-turn-anim
;; INFO: Return type mismatch int vs none.
(defbehavior target-tube-turn-anim target ()
  (let ((gp-0 (the int (-> *display* time-ratio))))
    (set-time-ratios *display* 1.0)
    (countdown (s5-0 gp-0)
      (set! (-> self control unknown-int40) s5-0)
      (set! (-> self tube turn-anim-targ) (fmax -20.0 (fmin 20.0 (-> self tube turn-anim-targ))))
      (or (not (>= (* (-> self tube turn-anim-targ) (-> self tube turn-anim-frame)) 0.0))
          (< (fabs (-> self tube turn-anim-frame)) (fabs (-> self tube turn-anim-targ)))
          )
      (+! (-> self tube turn-anim-vel)
          (* (- (-> self tube turn-anim-targ) (-> self tube turn-anim-frame))
             (lerp-scale
               20.0
               (if (< (fabs (-> self tube turn-anim-frame)) (fabs (-> self tube turn-anim-targ)))
                   30.0
                   60.0
                   )
               (-> self control unknown-float01)
               0.0
               36864.0
               )
             (-> *display* seconds-per-frame)
             )
          )
      (set! (-> self tube turn-anim-vel)
            (fmax
              -100.0
              (fmin
                100.0
                (* (-> self tube turn-anim-vel) (lerp-scale 0.96 0.9 (-> self control unknown-float01) 0.0 36864.0))
                )
              )
            )
      (+! (-> self tube turn-anim-frame) (* (-> self tube turn-anim-vel) (-> *display* seconds-per-frame)))
      (set! (-> self tube turn-anim-frame) (fmax -20.0 (fmin 20.0 (-> self tube turn-anim-frame))))
      (cond
        ((and (>= (-> self tube turn-anim-frame) 20.0) (>= (-> self tube turn-anim-vel) 0.0))
         (set! (-> self tube turn-anim-vel) 0.0)
         )
        ((and (>= -20.0 (-> self tube turn-anim-frame)) (>= 0.0 (-> self tube turn-anim-vel)))
         (set! (-> self tube turn-anim-vel) 0.0)
         )
        )
      )
    (set-time-ratios *display* (the float gp-0))
    )
  (ja :group! (-> self draw art-group data 105) :num! (identity (ja-aframe (-> self tube turn-anim-frame) 0)))
  0
  (none)
  )

;; failed to figure out what this is:
(defstate target-tube (target)
  :event (-> target-tube-start event)
  :enter (behavior ()
    (set! (-> self control unknown-surface00) *tube-mods*)
    (set! (-> self control surf) *tube-surface*)
    (none)
    )
  :exit (-> target-tube-start exit)
  :trans (behavior ()
    (if (and (logtest? (logior (logior (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) button0-rel 0)
                                       (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) button0-rel 1)
                                       )
                               (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) button0-rel 2)
                               )
                       (pad-buttons x)
                       )
             (can-jump? #f)
             )
        (go target-tube-jump (-> *TARGET-bank* tube-jump-height-min) (-> *TARGET-bank* tube-jump-height-max))
        )
    (none)
    )
  :code (behavior ()
    (case (ja-group)
      (((-> self draw art-group data 41) (-> self draw art-group data 38))
       (ja-channel-push! 1 (seconds 0.04))
       (ja-no-eval :group! (-> self draw art-group data 106) :num! (seek!) :frame-num 0.0)
       (until (ja-done? 0)
         (suspend)
         (ja :num! (seek!))
         )
       (set! (-> self tube turn-anim-frame) 0.0)
       )
      (else
        (ja-channel-push! 1 (seconds 0.04))
        )
      )
    (loop
      (set! (-> self tube turn-anim-targ) (* 20.0 (-> self tube mod-x)))
      (target-tube-turn-anim)
      (suspend)
      )
    (none)
    )
  :post (behavior ()
    (target-tube-post)
    (none)
    )
  )

;; failed to figure out what this is:
(defstate target-tube-jump (target)
  :event (-> target-tube-start event)
  :enter (behavior ((arg0 float) (arg1 float))
    (set! (-> self state-time) (-> *display* base-frame-counter))
    (init-var-jump arg0 arg1 (the-as vector #t) (the-as vector #f) (-> self control transv))
    (logclear! (-> self control status) (cshape-moving-flags onsurf onground tsurf))
    (set! (-> self control unknown-surface00) *tube-jump-mods*)
    (none)
    )
  :exit (-> target-tube-start exit)
  :trans (behavior ()
    (if (logtest? (-> self control status) (cshape-moving-flags onsurf))
        (go target-tube)
        )
    (mod-var-jump #t #t (cpad-hold? (-> self control unknown-cpad-info00 number) x) (-> self control transv))
    (seek!
      (-> self control unknown-float122)
      (fmax 0.0 (fmin 1.0 (* 0.00012207031 (+ -2048.0 (-> self control unknown-float01)))))
      (-> *display* seconds-per-frame)
      )
    (none)
    )
  :code (behavior ((arg0 float) (arg1 float))
    (ja-channel-push! 1 (seconds 0.05))
    (ja :group! (-> self draw art-group data 41) :num! (identity (ja-aframe 16.0 0)))
    (let ((f30-0 35.0)
          (f28-0 1.0)
          )
      (until (ja-done? 0)
        (let* ((f24-0 (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))
               (f26-0 (- f30-0 (ja-aframe-num 0)))
               (f0-8 (fmin (fmin 3.0 f26-0) (/ (* 5.0 f26-0) (the float (time-to-apex f24-0 -245760.0)))))
               (a0-7 (-> self skel root-channel 0))
               )
          (set! (-> a0-7 param 0) (the float (+ (-> a0-7 frame-group data 0 length) -1)))
          (let ((v1-17 (and (< 0.0 f24-0) (< 0.0 f26-0))))
            (set! (-> a0-7 param 1) (if v1-17
                                        f0-8
                                        f28-0
                                        )
                  )
            )
          (joint-control-channel-group-eval! a0-7 (the-as art-joint-anim #f) num-func-seek!)
          )
        (suspend)
        )
      )
    (ja-no-eval :group! (-> self draw art-group data 38) :num! (loop!) :frame-num 0.0)
    (loop
      (suspend)
      (ja :group! (-> self draw art-group data 38) :num! (loop!))
      )
    (none)
    )
  :post (-> target-tube post)
  )

;; failed to figure out what this is:
(defstate target-tube-hit (target)
  :event (-> target-tube-start event)
  :enter (behavior ((arg0 symbol) (arg1 attack-info))
    (send-event
      (handle->process (-> self tube tube))
      'update
      (-> self tube centertube)
      (-> self tube downtube)
      (-> self tube sidetube)
      (-> self tube foretube)
      )
    (none)
    )
  :exit (behavior ()
    (if (!= (-> self next-state name) 'target-tube-death)
        (logclear! (-> self state-flags) (state-flags being-attacked dying))
        )
    (logclear! (-> self state-flags) (state-flags sf02 do-not-notice grabbed first-person-mode))
    ((-> target-tube-start exit))
    (none)
    )
  :code (behavior ((arg0 symbol) (arg1 attack-info))
    (let ((gp-0 (-> self attack-info)))
      (set! (-> self state-time) (-> *display* base-frame-counter))
      (logior! (-> self state-flags) (state-flags being-attacked))
      (set! (-> self game hit-time) (-> *display* base-frame-counter))
      (when (zero? (logand (-> arg1 mask) (attack-mask vector)))
        (vector-!
          (-> arg1 vector)
          (vector+float*! (new 'stack-no-clear 'vector) (-> self tube foretube) (-> self tube downtube) 20480.0)
          (-> self control trans)
          )
        (let ((s3-2 (new-stack-vector0))
              (f30-0 (vector-dot (-> self control unknown-vector71) (-> arg1 vector)))
              )
          0.0
          (vector-! s3-2 (-> arg1 vector) (vector-float*! s3-2 (-> self control unknown-vector71) f30-0))
          (let* ((f0-3 (vector-length s3-2))
                 (f1-0 f0-3)
                 )
            (if (< f30-0 0.0)
                (set! f30-0 (* 0.5 f30-0))
                )
            (vector+!
              (-> arg1 vector)
              (vector-float*! (-> arg1 vector) (-> self control unknown-vector71) f30-0)
              (vector-float*! s3-2 s3-2 (/ f0-3 f1-0))
              )
            )
          )
        (logior! (-> arg1 mask) (attack-mask vector))
        )
      (when (and (logtest? (-> arg1 mask) (attack-mask mode))
                 (= (-> arg1 mode) 'darkeco)
                 (zero? (logand (-> arg1 mask) (attack-mask shove-up)))
                 )
        (set! (-> arg1 shove-up) 12288.0)
        (logior! (-> arg1 mask) (attack-mask shove-up))
        )
      (let ((v1-30 gp-0))
        (set! (-> v1-30 attacker) (the-as handle #f))
        (set! (-> v1-30 mode) 'generic)
        (set! (-> v1-30 shove-back) 6144.0)
        (set! (-> v1-30 shove-up) 12288.0)
        (set! (-> v1-30 angle) #f)
        (set! (-> v1-30 trans quad) (-> self control trans quad))
        (set! (-> v1-30 control) 0.0)
        (set! (-> v1-30 invinc-time) (-> *TARGET-bank* hit-invulnerable-timeout))
        )
      (combine! gp-0 arg1)
      (when (= arg0 'attack)
        (pickup-collectable!
          (-> self fact-info-target)
          (pickup-type eco-green)
          (- (-> *FACT-bank* health-single-inc))
          (the-as handle #f)
          )
        (target-hit-effect gp-0)
        )
      (set! (-> self control unknown-surface00) *smack-mods*)
      (target-hit-setup-anim gp-0)
      (target-hit-move gp-0 (target-hit-orient gp-0 (-> gp-0 vector)) target-falling-anim-trans 1.0)
      (let ((s5-2 (new-stack-vector0))
            (f30-1 (vector-dot (-> self tube downtube) (-> self control transv)))
            )
        0.0
        (vector-! s5-2 (-> self control transv) (vector-float*! s5-2 (-> self tube downtube) f30-1))
        (let ((f0-14 (vector-length s5-2))
              (f2-2 (fmax 40960.0 f30-1))
              (f1-2 0.0)
              )
          (vector+!
            (-> self control transv)
            (vector-float*! (-> self control transv) (-> self tube downtube) f2-2)
            (vector-float*! s5-2 s5-2 (/ f1-2 f0-14))
            )
          )
        )
      (let ((s5-3 forward-up-nopitch->quaternion)
            (s4-2 (-> self control dir-targ))
            (t9-9 vector-normalize!)
            (a0-35 (new-stack-vector0))
            )
        (set! (-> a0-35 quad) (-> self control transv quad))
        (s5-3 s4-2 (t9-9 a0-35 1.0) (vector-y-quaternion! (new-stack-vector0) (-> self control dir-targ)))
        )
      (if (and (= (-> self game mode) 'play) (>= 0.0 (-> self fact-info-target health)))
          (go target-tube-death (-> gp-0 mode))
          )
      )
    (go target-tube)
    (none)
    )
  :post target-post
  )

;; failed to figure out what this is:
(defstate target-tube-death (target)
  :event (-> target-death event)
  :exit (behavior ()
    (logclear! (-> self state-flags) (state-flags being-attacked dying))
    (target-exit)
    (remove-setting! 'process-mask)
    (apply-settings *setting-control*)
    ((-> target-tube-start exit))
    (none)
    )
  :code (behavior ((arg0 symbol))
    (local-vars (v1-40 symbol))
    (set! (-> self neck flex-blend) 0.0)
    (target-timed-invulnerable-off self)
    (add-setting! 'process-mask 'set 0.0 (process-mask enemy platform projectile death))
    (apply-settings *setting-control*)
    (set! (-> self control transv quad) (the-as uint128 0))
    (set! (-> self control unknown-surface00) *neutral-mods*)
    (ja-channel-push! 1 (seconds 0.1))
    (ja-no-eval :group! (-> self draw art-group data 76) :num! (seek! (ja-aframe 134.0 0)) :frame-num 0.0)
    (until (ja-done? 0)
      (compute-alignment! (-> self align))
      (let ((gp-2 (new 'stack-no-clear 'vector)))
        (when (zero? (logand (-> self align flags) (align-flags disabled)))
          (vector-matrix*! gp-2 (the-as vector (-> self align delta)) (-> self control unknown-matrix01))
          (vector-float*! (-> self control transv) gp-2 (-> *display* frames-per-second))
          )
        )
      (suspend)
      (ja :num! (seek! (ja-aframe 134.0 0)))
      )
    (set! (-> self control transv quad) (the-as uint128 0))
    (initialize! (-> self game) 'dead (the-as game-save #f) (the-as string #f))
    (set! (-> self state-time) (-> *display* base-frame-counter))
    (until v1-40
      (suspend)
      (set! v1-40 (and (>= (- (-> *display* base-frame-counter) (-> self state-time)) (seconds 1)) (not (movie?))))
      )
    (go target-tube)
    (none)
    )
  :post target-no-stick-post
  )

;; definition of type slide-control
(deftype slide-control (process-drawable)
  ((target handle         :offset-assert 176)
   (pos    float          :offset-assert 184)
   (trans  vector :inline :offset-assert 192)
   (rot    vector :inline :offset-assert 208)
   (side   vector :inline :offset-assert 224)
   )
  :heap-base #x80
  :method-count-assert 22
  :size-assert         #xf0
  :flag-assert         #x16008000f0
  (:methods
    (slide-control-watch () _type_ :state 20)
    (slide-control-ride () _type_ :state 21)
    )
  )

;; definition for method 3 of type slide-control
(defmethod inspect slide-control ((obj slide-control))
  (let ((t9-0 (method-of-type process-drawable inspect)))
    (t9-0 obj)
    )
  (format #t "~T~Ttarget: ~D~%" (-> obj target))
  (format #t "~T~Tpos: ~f~%" (-> obj pos))
  (format #t "~T~Ttrans: ~`vector`P~%" (-> obj trans))
  (format #t "~T~Trot: ~`vector`P~%" (-> obj rot))
  (format #t "~T~Tside: ~`vector`P~%" (-> obj side))
  obj
  )

;; definition for function distance-from-tangent
(defun distance-from-tangent ((arg0 path-control) (arg1 float) (arg2 vector) (arg3 vector) (arg4 vector) (arg5 vector))
  (eval-path-curve-div! arg0 arg2 arg1 'interp)
  (TODO-RENAME-12 arg0 arg3 arg1)
  (set! (-> arg2 y) (-> arg5 y))
  (set! (-> arg3 y) 0.0)
  (let ((s2-1 (new 'stack-no-clear 'vector)))
    (vector-rotate-y! arg4 arg3 -16384.0)
    (set! (-> arg4 y) 0.0)
    (let* ((a2-5 (vector+! (new 'stack-no-clear 'vector) arg2 arg4))
           (f0-3 (vector-line-distance-point! arg5 arg2 a2-5 s2-1))
           )
      (if (< 0.0 (vector-dot arg3 (vector-! (new 'stack-no-clear 'vector) arg5 s2-1)))
          (set! f0-3 (- f0-3))
          )
      f0-3
      )
    )
  )

;; definition for function find-target-point
;; Used lq/sq
(defbehavior find-target-point slide-control ((arg0 vector))
  (local-vars (f0-2 float))
  (let* ((s4-0 (new 'stack-no-clear 'vector))
         (s5-0 (new 'stack-no-clear 'vector))
         (gp-0 (new 'stack-no-clear 'vector))
         (f28-0 (+ -0.1 (-> self pos)))
         (f26-0 (distance-from-tangent (-> self path) f28-0 s4-0 s5-0 gp-0 arg0))
         )
    0.0
    (let ((f30-0 f28-0))
      (until (or (and (< f26-0 f0-2) (>= f0-2 0.0)) (< (the float (+ (-> self path curve num-cverts) -1)) f28-0))
        (set! f0-2 (distance-from-tangent (-> self path) f28-0 s4-0 s5-0 gp-0 arg0))
        (when (or (>= f26-0 f0-2) (< f26-0 0.0))
          (set! f26-0 f0-2)
          (set! f30-0 f28-0)
          )
        (set! f28-0 (+ 0.01 f28-0))
        )
      (distance-from-tangent (-> self path) f30-0 s4-0 s5-0 gp-0 arg0)
      (set! (-> self trans quad) (-> s4-0 quad))
      (set! (-> self rot quad) (-> s5-0 quad))
      (set! (-> self side quad) (-> gp-0 quad))
      (set! (-> self pos) f30-0)
      )
    )
  (-> self pos)
  )

;; failed to figure out what this is:
(defstate slide-control-watch (slide-control)
  :virtual #t
  :enter (behavior ()
    (eval-path-curve-div! (-> self path) (-> self trans) 0.2 'interp)
    (eval-path-curve-div! (-> self path) (-> self root trans) 0.2 'interp)
    (TODO-RENAME-12 (-> self path) (-> self rot) 0.2)
    (set! (-> self pos) 0.2)
    (none)
    )
  :trans (behavior ()
    (if (and (and *target* (>= 81920.0 (vector-vector-distance (-> self root trans) (-> *target* control trans))))
             (and (< 0.0 (vector-dot
                           (vector-! (new 'stack-no-clear 'vector) (-> *target* control trans) (-> self trans))
                           (-> self rot)
                           )
                     )
                  (send-event *target* 'change-mode 'tube self)
                  )
             )
        (go-virtual slide-control-ride)
        )
    (none)
    )
  :code (the-as (function none :behavior slide-control) anim-loop)
  )

;; failed to figure out what this is:
(defstate slide-control-ride (slide-control)
  :virtual #t
  :event (behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
    (case arg2
      (('end-mode)
       (go-virtual slide-control-watch)
       )
      (('update)
       (let* ((s4-0 arg0)
              (gp-0 (if (and (nonzero? s4-0) (type-type? (-> s4-0 type) process-drawable))
                        s4-0
                        )
                    )
              )
         (if gp-0
             (find-target-point (-> (the-as process-drawable gp-0) root trans))
             )
         (set! (-> (the-as vector (-> arg3 param 0)) quad) (-> self trans quad))
         (set! (-> (the-as vector (-> arg3 param 1)) quad) (-> self rot quad))
         (set! (-> (the-as vector (-> arg3 param 2)) quad) (-> self side quad))
         (eval-path-curve-div! (-> self path) (the-as vector (-> arg3 param 3)) (+ 0.2 (-> self pos)) 'interp)
         (if (>= (-> self pos) (+ -0.2 (the float (+ (-> self path curve num-cverts) -1))))
             (send-event gp-0 'end-mode)
             )
         )
       (-> self pos)
       )
      )
    )
  :enter (behavior ()
    (set! (-> self pos) 0.0)
    (set! (-> self target) (process->handle *target*))
    (process-entity-status! self (entity-perm-status bit-3) #t)
    (none)
    )
  :exit (behavior ()
    (set! (-> self target) (the-as handle #f))
    (process-entity-status! self (entity-perm-status bit-3) #f)
    (none)
    )
  :trans (behavior ()
    (let ((gp-0 (handle->process (-> self target))))
      (cond
        ((if (and (nonzero? gp-0) (type-type? (-> gp-0 type) process-drawable))
             gp-0
             )
         )
        (else
          (go-virtual slide-control-watch)
          )
        )
      )
    (none)
    )
  :code (the-as (function none :behavior slide-control) anim-loop)
  )

;; definition for method 11 of type slide-control
;; INFO: Return type mismatch object vs none.
(defmethod init-from-entity! slide-control ((obj slide-control) (arg0 entity-actor))
  (set! (-> obj root) (new 'process 'trsqv))
  (process-drawable-from-entity! obj arg0)
  (logclear! (-> obj mask) (process-mask actor-pause))
  (set! (-> obj path) (new 'process 'curve-control obj 'path -1000000000.0))
  (logior! (-> obj path flags) (path-control-flag display draw-line draw-point draw-text))
  (set! (-> obj target) (the-as handle #f))
  (go (method-of-object obj slide-control-watch))
  (none)
  )
