;;-*-Lisp-*-
(in-package goal)
(bundles "ENGINE.CGO" "GAME.CGO")
(require "kernel/gcommon.gc")
(defenum surface-flags
  :bitfield #t
  :type uint32
  (allow-look-around) ;; allows entering first person with triangle
  (dive) ;; set on all diving (dive, dive-bottom) surfaces
  (surf02) ;; unused
  (no-turn-around) ;; prevent "changed direction" animation from happening
  ;; when jak is on a surface with this flag, the case where jak
  ;; is forced to rotate in the direction he's traveling is
  ;; never taken. It's used on ice (though it is not needed, the turn toward transv
  ;; is disabled by not being in target-walk ever) and also used to prevent
  ;; jak from spinning around when he shouldn't (like if he's knocked back)
  (no-rotate-toward-transv)
  ;; if jak should always be forced to rotate in the direction he's travelling.
  ;; used for the slides and also the warp gate jump
  (always-rotate-toward-transv)
  ;; never set, but prevents jak from jumping (both normal and roll)
  (prevent-jump)
  ;; target is launch jumping (from a blue eco pad)
  (prevent-attacks-during-launch-jump)
  (surf08) ;; never set, prevents various attacks from being possible
  (surf09) ;; another attack prevent
  (allow-edge-grab) ;; if set, and jak is falling, turn on the ledge grab search.
  (jump) ;; set on all jumps, used to prevent "on-grounds" in places
  (attacking) ;; set on all attacks, but not actually used anywhere
  (ducking) ;; set on all ducks, but not actually used anywhere
  (moving-ground) ;; unused, but would make sense if jak was on something moving
  )

;; DECOMP BEGINS

;; A "surface" contains parameters for how Jak will behave.
;; It can be used for different in-game surfaces (ice is slippery, grass isn't)
;; but is also used for most other changes to Jak's control
;; For example, when jumping, there's a separate "surface" for jumping that makes
;; Jak less responsive to changing directions.
;; Surfaces have flags and parameters that can be combined with other surfaces

;; The "surface" defines how jak moves on the ground. It includes things like how fast he can go,
;; how slippery it is, and what functions should run when he hits it.
;; Note that "surface" can apply to weird things, like riding the zoomer or swimming as well.

(deftype surface (basic)
  ((name              symbol)
   (turnv             float)
   (turnvv            float)
   (tiltv             float)
   (tiltvv            float)
   (transv-max        float)
   (target-speed      float)
   (seek0             float)
   (seek90            float)
   (seek180           float)
   (fric              float)
   (nonlin-fric-dist  float)
   (slip-factor       float)
   (slide-factor      float)
   (slope-up-factor   float)
   (slope-down-factor float)
   (slope-slip-angle  float)
   (impact-fric       float)
   (bend-factor       float)
   (bend-speed        float)
   (alignv            float)
   (slope-up-traction float)
   (align-speed       float)
   (active-hook       (function none) :offset 128)
   (touch-hook        (function none))
   (impact-hook       function)
   (mult-hook         (function surface surface surface int none))
   (mode              symbol)
   (flags             surface-flags)
   (data              float 30 :overlay-at turnv)
   (hook              function 4 :overlay-at active-hook)
   (dataw             uint32 2 :overlay-at mode)))

;; these calc-terminal functions are unused.
(defun calc-terminal-vel ((arg0 float) (arg1 float) (arg2 float))
  (- (* (/ (- (/ arg0 60) arg1) arg2) (- 1.0 arg2)) arg1))

(defun calc-terminal2-vel ((arg0 float) (arg1 float) (arg2 float) (arg3 float))
  (let ((f0-4 (sqrtf (/ (- (/ arg0 60) arg1) arg2)))) (- f0-4 (+ arg1 (* arg2 (* f0-4 f0-4))))))

(defun calc-terminal4-vel ((arg0 float) (arg1 float) (arg2 float))
  (let ((f0-5 (sqrtf (sqrtf (/ (- (/ arg0 60) arg1) arg2))))) (- f0-5 (+ arg1 (* arg2 (* f0-5 f0-5 f0-5 f0-5))))))

(defmethod print ((this surface))
  ;; seems this format string is wrong.
  (format #t
          "#<surface f0:~m f1:~f tf+:~f tf-:~f sf:~f tvv:~m"
          (-> this turnv)
          (-> this turnvv)
          (-> this tiltv)
          (-> this tiltvv)
          (-> this transv-max))
  (format #t "  tm:~m rv:~R rvv:~R @ #x~X>" (-> this target-speed) (-> this seek0) (-> this seek90) this)
  this)

(defun surface-interp! ((dst surface) (src0 surface) (src1 surface) (amount float))
  "Create a surface between src0 and src1. For things like hooks/mode, src1 wins."
  ;; iterate through surface data
  (dotimes (v1-0 30)
    ;; interpolate between the two
    (set! (-> dst data v1-0) (+ (* (-> src1 data v1-0) amount) (* (-> src0 data v1-0) (- 1.0 amount)))))
  ;; iterate through hooks. Check src1, then src0 for a nonzero and non-nothing hook.
  ;; if there is no good hook, set it to nothing.
  (dotimes (v1-3 4)
    (set! (-> dst hook v1-3)
          (cond
            ((and (nonzero? (-> src1 hook v1-3)) (!= (-> src1 hook v1-3) nothing)) (-> src1 hook v1-3))
            ((and (nonzero? (-> src0 hook v1-3)) (!= (-> src0 hook v1-3) nothing)) (-> src0 hook v1-3))
            (else nothing))))
  ;; just use the dataw's from src1
  (dotimes (v1-6 2)
    (set! (-> dst dataw v1-6) (-> src1 dataw v1-6)))
  dst)

(defun surface-mult! ((dst surface) (src0 surface) (src1 surface))
  "Multiply src0 by src1, and store the result in dst."
  (dotimes (v1-0 30)
    (set! (-> dst data v1-0) (* (-> src1 data v1-0) (-> src0 data v1-0))))
  (dotimes (v1-3 4)
    (set! (-> dst hook v1-3)
          (cond
            ((and (nonzero? (-> src1 hook v1-3)) (!= (-> src1 hook v1-3) nothing)) (-> src1 hook v1-3))
            ((and (nonzero? (-> src0 hook v1-3)) (!= (-> src0 hook v1-3) nothing)) (-> src0 hook v1-3))
            (else nothing))))
  (dotimes (v1-6 2)
    (set! (-> dst dataw v1-6) (-> src1 dataw v1-6)))
  ;; take the or of the flags, I guess
  (set! (-> dst flags) (logior (-> src0 flags) (-> src1 flags)))
  ;; and call the mult-hook
  ((-> dst mult-hook) dst src0 src1 1)
  dst)

(defun surface-clamp-speed ((arg0 surface) (arg1 surface) (arg2 surface) (arg3 int))
  "When arg3 is 1, clamp speed of arg0 to the mins of arg0/arg1"
  (when (= arg3 1)
    (set! (-> arg0 transv-max) (fmin (-> arg0 transv-max) (-> arg1 transv-max)))
    (set! (-> arg0 target-speed) (fmin (-> arg0 target-speed) (-> arg1 target-speed))))
  (none))

;; The common surfaces:

(define *walk-mods*
  (new 'static
       'surface
       :name 'run
       :turnv 131072.0
       :turnvv 524288.0
       :tiltv 65536.0
       :tiltvv 131072.0
       :transv-max 40960.0
       :target-speed 40960.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
       :flags (surface-flags allow-look-around)))

(define *walk-no-turn-mods*
  (new 'static
       'surface
       :name 'run
       :tiltv 65536.0
       :tiltvv 131072.0
       :transv-max 40960.0
       :target-speed 40960.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))

(define *turn-around-mods*
  (new 'static
       'surface
       :name 'run
       :tiltv 65536.0
       :tiltvv 131072.0
       :transv-max 40960.0
       :target-speed 40960.0
       :fric 0.1
       :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))

(let ((a0-3 (new 'static
                 'surface
                 :name 'duck
                 :turnv 131072.0
                 :turnvv 524288.0
                 :tiltv 65536.0
                 :tiltvv 291271.12
                 :transv-max 16384.0
                 :target-speed 16384.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
                 :flags (surface-flags ducking))))
  (set! (-> a0-3 mult-hook) surface-clamp-speed)
  ;; og:preserve-this
  (define *duck-mods* a0-3))

(define *duck-attack-mods*
  (new 'static
       'surface
       :name 'duck
       :tiltv 65536.0
       :tiltvv 291271.12
       :transv-max 16384.0
       :target-speed 16384.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
       :mode 'attack
       :flags (surface-flags attacking ducking)))

(define *jump-mods*
  (new 'static
       'surface
       :name 'jump
       :turnv 131072.0
       :turnvv 18204.445
       :tiltv 32768.0
       :tiltvv 131072.0
       :transv-max 40960.0
       :target-speed 40960.0
       :seek0 0.3
       :seek90 0.3
       :seek180 0.3
       :fric 0.2
       :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 allow-edge-grab jump)))

(define *double-jump-mods*
  (new 'static
       'surface
       :name 'jump-double
       :turnv 131072.0
       :turnvv 18204.445
       :tiltv 32768.0
       :tiltvv 131072.0
       :transv-max 32768.0
       :target-speed 32768.0
       :seek0 0.3
       :seek90 0.3
       :seek180 0.3
       :fric 0.2
       :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 allow-edge-grab jump)))

(define *smack-jump-mods*
  (new 'static
       'surface
       :name 'jump
       :turnv 131072.0
       :turnvv 18204.445
       :tiltv 32768.0
       :tiltvv 131072.0
       :transv-max 40960.0
       :target-speed 40960.0
       :seek0 0.3
       :seek90 0.3
       :seek180 0.3
       :fric 0.05
       :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 allow-edge-grab jump)))

(define *high-jump-mods*
  (new 'static
       'surface
       :name 'high-jump
       :turnv 131072.0
       :turnvv 65536.0
       :tiltv 32768.0
       :tiltvv 131072.0
       :transv-max 26624.0
       :target-speed 26624.0
       :seek0 0.9
       :seek90 0.9
       :seek180 0.9
       :fric 0.3
       :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 allow-edge-grab jump)))

(define *launch-jump-mods*
  (new 'static
       'surface
       :name 'launch-jump
       :turnv 18204.445
       :turnvv 65536.0
       :tiltv 32768.0
       :tiltvv 131072.0
       :transv-max 61440.0
       :target-speed 61440.0
       :seek0 0.9
       :seek90 0.9
       :seek180 0.9
       :fric 0.3
       :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 prevent-attacks-during-launch-jump allow-edge-grab jump)))

(define *forward-high-jump-mods*
  (new 'static
       'surface
       :name 'high-jump
       :turnv 131072.0
       :turnvv 65536.0
       :tiltv 32768.0
       :tiltvv 131072.0
       :transv-max 45056.0
       :target-speed 45056.0
       :seek0 0.9
       :seek90 0.9
       :seek180 0.9
       :fric 0.3
       :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 allow-edge-grab jump)))

(define *flip-jump-mods*
  (new 'static
       'surface
       :name 'high-jump
       :turnv 131072.0
       :turnvv 65536.0
       :tiltv 32768.0
       :tiltvv 131072.0
       :transv-max 80281.6
       :target-speed 51200.0
       :seek0 0.9
       :seek90 0.9
       :seek180 0.9
       :fric 0.3
       :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 allow-edge-grab jump)))

(define *forward-jump-mods*
  (new 'static
       'surface
       :name 'jump
       :turnv 131072.0
       :turnvv 18204.445
       :tiltv 32768.0
       :tiltvv 131072.0
       :transv-max 65536.0
       :target-speed 65536.0
       :seek0 0.3
       :seek90 0.3
       :seek180 0.3
       :fric 0.05
       :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 allow-edge-grab jump)))

(define *forward-pole-jump-mods*
  (new 'static
       'surface
       :name 'jump
       :turnv 131072.0
       :turnvv 18204.445
       :tiltv 32768.0
       :tiltvv 131072.0
       :transv-max 53248.0
       :target-speed 53248.0
       :seek0 0.3
       :seek90 0.3
       :seek180 0.3
       :fric 0.05
       :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 allow-edge-grab jump)))

(define *attack-mods*
  (new 'static
       'surface
       :name 'attack
       :tiltv 65536.0
       :tiltvv 131072.0
       :transv-max 40960.0
       :target-speed 40960.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
       :mode 'attack
       :flags (surface-flags attacking)))

(define *jump-attack-mods*
  (new 'static
       'surface
       :name 'attack
       :turnvv 18204.445
       :tiltv 32768.0
       :tiltvv 131072.0
       :transv-max 24576.0
       :target-speed 24576.0
       :seek0 0.9
       :seek90 0.9
       :seek180 0.9
       :fric 0.2
       :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 allow-edge-grab jump attacking)))

(let ((a0-4 (new 'static
                 'surface
                 :name 'uppercut
                 :turnvv 18204.445
                 :tiltv 32768.0
                 :tiltvv 131072.0
                 :transv-max 32768.0
                 :target-speed 32768.0
                 :seek0 0.3
                 :seek90 0.3
                 :seek180 0.3
                 :fric 0.2
                 :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 allow-edge-grab jump attacking))))
  (set! (-> a0-4 mult-hook) surface-clamp-speed)
  ;; og:preserve-this
  (define *uppercut-jump-mods* a0-4))

(define *run-attack-mods*
  (new 'static
       'surface
       :name 'wheel-flip
       :tiltv 32768.0
       :tiltvv 131072.0
       :transv-max 91750.4
       :target-speed 122880.0
       :seek90 0.5
       :seek180 0.15
       :slip-factor 1.0
       :slide-factor 1.0
       :slope-up-factor 0.25
       :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 'attack
       ;; no-rotate-toward-transv prevents jak from spinning around
       ;; if you punch over bumpy terrain
       :flags (surface-flags no-turn-around no-rotate-toward-transv attacking)))

(define *wheel-mods*
  (new 'static
       'surface
       :name 'wheel
       :turnv 131072.0
       :turnvv 5461.3335
       :tiltv 32768.0
       :tiltvv 131072.0
       :transv-max 91750.4
       :target-speed 11468.8
       :seek0 1.0
       :seek90 1.0
       :seek180 1.0
       :slip-factor 1.0
       :slide-factor 1.0
       :slope-up-factor 0.25
       :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 'attack
       :flags (surface-flags attacking)))

(define *wheel-flip-mods*
  (new 'static
       'surface
       :name 'wheel-flip
       :tiltv 32768.0
       :tiltvv 131072.0
       :transv-max 91750.4
       :target-speed 103219.195
       :seek90 0.5
       :seek180 0.15
       :slip-factor 1.0
       :slide-factor 1.0
       :slope-up-factor 0.25
       :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 'attack
       :flags (surface-flags allow-edge-grab jump attacking)))

(define *flop-mods*
  (new 'static
       'surface
       :name 'flop
       :tiltv 32768.0
       :tiltvv 131072.0
       :transv-max 40960.0
       :target-speed 40960.0
       :seek0 1.0
       :seek90 0.3
       :seek180 1.5
       :slip-factor 1.0
       :slide-factor 1.0
       :slope-up-factor 0.25
       :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 'attack
       :flags (surface-flags jump attacking)))

(let ((a0-5 (new 'static
                 'surface
                 :name 'flop
                 :turnv 9102.223
                 :turnvv 9102.223
                 :tiltv 32768.0
                 :tiltvv 131072.0
                 :transv-max 40960.0
                 :target-speed 40960.0
                 :seek0 0.3
                 :seek90 0.1
                 :seek180 0.15
                 :fric 0.2
                 :nonlin-fric-dist 1.0
                 :slip-factor 1.0
                 :slide-factor 1.0
                 :slope-up-factor 0.25
                 :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))))
  (set! (-> a0-5 mult-hook) surface-clamp-speed)
  ;; og:preserve-this
  (define *flop-land-mods* a0-5))

(define *wade-mods*
  (new 'static
       'surface
       :name 'wade
       :turnv 131072.0
       :turnvv 524288.0
       :tiltv 65536.0
       :tiltvv 131072.0
       :transv-max 40960.0
       :target-speed 40960.0
       :seek0 1.0
       :seek90 0.5
       :seek180 0.5
       :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 'wade
       :flags (surface-flags allow-look-around)))

(define *swim-mods*
  (new 'static
       'surface
       :name 'swim
       :turnv 49152.0
       :turnvv 524288.0
       :tiltv 65536.0
       :tiltvv 131072.0
       :transv-max 28672.0
       :target-speed 28672.0
       :seek0 0.75
       :seek90 0.2
       :seek180 0.2
       :fric 0.05
       :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 'swim))

(define *dive-mods*
  (new 'static
       'surface
       :name 'swim
       :turnv 21845.334
       :turnvv 32768.0
       :tiltv 65536.0
       :tiltvv 131072.0
       :transv-max 20480.0
       :target-speed 20480.0
       :seek0 0.05
       :seek90 0.05
       :seek180 0.05
       :fric 1.0
       :nonlin-fric-dist 1.0
       :impact-fric 1.0
       :bend-factor 1.0
       :bend-speed 1.0
       :alignv 1.0
       :align-speed 1.0
       :mode 'dive
       :flags (surface-flags dive)))

(define *dive-bottom-mods*
  (new 'static
       'surface
       :name 'swim-bottom
       :turnv 21845.334
       :turnvv 32768.0
       :tiltv 65536.0
       :tiltvv 131072.0
       :transv-max 20480.0
       :target-speed 20480.0
       :seek0 0.1
       :seek90 0.05
       :seek180 0.05
       :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 'dive
       :flags (surface-flags dive)))

(let ((a0-7 (copy *walk-mods* 'global)))
  (set! (-> a0-7 name) 'pole)
  (set! (-> a0-7 flags) (surface-flags))
  ;; og:preserve-this
  (define *pole-mods* a0-7))

(let ((a0-9 (copy *walk-mods* 'global)))
  (set! (-> a0-9 name) 'grab)
  (set! (-> a0-9 flags) (surface-flags))
  ;; og:preserve-this
  (define *grab-mods* a0-9))

(let ((a0-11 (copy *walk-mods* 'global)))
  (set! (-> a0-11 name) 'edge-grab)
  (set! (-> a0-11 flags) (surface-flags))
  ;; og:preserve-this
  (define *edge-grab-mods* a0-11))

(define *empty-mods* (new 'static 'surface :name 'empty :seek0 1.0 :seek90 1.0 :seek180 1.0 :fric 1.0))

(define *neutral-mods*
  (new 'static
       'surface
       :name 'walk
       :turnv 131072.0
       :turnvv 524288.0
       :tiltv 65536.0
       :tiltvv 131072.0
       :transv-max 40960.0
       :target-speed 40960.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
       :slope-up-traction 1.0
       :align-speed 1.0))

(let ((v1-41 (new 'static
                  'surface
                  :name '*stone-surface*
                  :turnv 1.0
                  :turnvv 1.0
                  :tiltv 1.0
                  :tiltvv 1.0
                  :transv-max 1.0
                  :target-speed 1.0
                  :seek0 153600.0
                  :seek90 153600.0
                  :seek180 256000.0
                  :fric 153600.0
                  :nonlin-fric-dist 5120.0
                  :slip-factor 1.0
                  :slope-down-factor 10240.0
                  :slope-slip-angle 8192.0
                  :impact-fric 1.0
                  :bend-factor 0.8
                  :bend-speed 4.0
                  :alignv 1.0
                  :slope-up-traction 1.0
                  :align-speed 1.0)))
  ;; og:preserve-this
  (define *stone-surface* v1-41)
  (set! (-> v1-41 mult-hook) (the-as (function surface surface surface int none) nothing))
  (set! (-> v1-41 touch-hook) nothing)
  (set! (-> v1-41 active-hook) nothing))

(let ((v1-42 (new 'static
                  'surface
                  :name '*edge-surface*
                  :turnv 1.0
                  :turnvv 1.0
                  :tiltv 1.0
                  :tiltvv 1.0
                  :transv-max 1.0
                  :target-speed 1.0
                  :seek0 153600.0
                  :seek90 153600.0
                  :seek180 256000.0
                  :fric 30720.0
                  :nonlin-fric-dist 5120.0
                  :slip-factor 1.0
                  :slope-down-factor 18432.0
                  :slope-slip-angle 8192.0
                  :bend-factor 0.8
                  :bend-speed 4.0
                  :alignv 1.0
                  :align-speed 1.0)))
  ;; og:preserve-this
  (define *edge-surface* v1-42)
  (set! (-> v1-42 mult-hook) (the-as (function surface surface surface int none) nothing))
  (set! (-> v1-42 touch-hook) nothing)
  (set! (-> v1-42 active-hook) nothing))

(let ((v1-43 (new 'static
                  'surface
                  :name '*wade-surface*
                  :turnv 1.0
                  :turnvv 1.0
                  :tiltv 1.0
                  :tiltvv 1.0
                  :transv-max 0.7
                  :target-speed 0.7
                  :seek0 153600.0
                  :seek90 153600.0
                  :seek180 256000.0
                  :fric 153600.0
                  :nonlin-fric-dist 5120.0
                  :slip-factor 1.0
                  :slope-down-factor 10240.0
                  :slope-slip-angle 8192.0
                  :impact-fric 1.0
                  :bend-factor 0.8
                  :bend-speed 4.0
                  :alignv 0.6
                  :slope-up-traction 1.0
                  :align-speed 0.6)))
  ;; og:preserve-this
  (define *wade-surface* v1-43)
  (set! (-> v1-43 mult-hook) (the-as (function surface surface surface int none) nothing))
  (set! (-> v1-43 touch-hook) nothing)
  (set! (-> v1-43 active-hook) nothing))

(let ((v1-44 (new 'static
                  'surface
                  :name '*slope-surface*
                  :turnv 1.0
                  :turnvv 1.0
                  :tiltv 1.0
                  :tiltvv 1.0
                  :transv-max 1.0
                  :target-speed 1.0
                  :seek0 122880.0
                  :seek90 245760.0
                  :seek180 409600.0
                  :fric 122880.0
                  :nonlin-fric-dist 4096.0
                  :slip-factor 1.0
                  :slope-up-factor 40960.0
                  :slope-down-factor 8192.0
                  :slope-slip-angle 8192.0
                  :impact-fric 1.0
                  :bend-factor 0.8
                  :bend-speed 4.0
                  :alignv 1.0
                  :align-speed 1.0)))
  ;; og:preserve-this
  (define *slope-surface* v1-44)
  (set! (-> v1-44 mult-hook) (the-as (function surface surface surface int none) nothing))
  (set! (-> v1-44 touch-hook) nothing)
  (set! (-> v1-44 active-hook) nothing))

(let ((v1-45 (new 'static
                  'surface
                  :name '*quicksand-surface*
                  :turnv 0.25
                  :turnvv 1.0
                  :tiltv 1.0
                  :tiltvv 1.0
                  :transv-max 0.5
                  :target-speed 0.5
                  :seek0 81920.0
                  :seek90 83968.0
                  :seek180 165888.0
                  :fric 329728.0
                  :nonlin-fric-dist 5120.0
                  :slip-factor 1.0
                  :slope-down-factor 10240.0
                  :slope-slip-angle 8192.0
                  :impact-fric 1.0
                  :bend-factor 0.8
                  :bend-speed 4.0
                  :alignv 0.5
                  :slope-up-traction 1.0
                  :align-speed 0.5)))
  ;; og:preserve-this
  (define *quicksand-surface* v1-45)
  (set! (-> v1-45 mult-hook) (the-as (function surface surface surface int none) nothing))
  (set! (-> v1-45 touch-hook) nothing)
  (set! (-> v1-45 active-hook) nothing))

(let ((v1-46 (new 'static
                  'surface
                  :name '*tar-surface*
                  :turnv 0.25
                  :turnvv 1.0
                  :tiltv 1.0
                  :tiltvv 1.0
                  :transv-max 0.4
                  :target-speed 0.4
                  :seek0 81920.0
                  :seek90 83968.0
                  :seek180 165888.0
                  :fric 329728.0
                  :nonlin-fric-dist 5120.0
                  :slip-factor 1.0
                  :slope-down-factor 10240.0
                  :slope-slip-angle 8192.0
                  :impact-fric 1.0
                  :bend-factor 0.8
                  :bend-speed 4.0
                  :alignv 0.5
                  :slope-up-traction 1.0
                  :align-speed 0.5)))
  ;; og:preserve-this
  (define *tar-surface* v1-46)
  (set! (-> v1-46 mult-hook) (the-as (function surface surface surface int none) nothing))
  (set! (-> v1-46 touch-hook) nothing)
  (set! (-> v1-46 active-hook) nothing))

(let ((v1-47 (new 'static
                  'surface
                  :name '*grass-surface*
                  :turnv 1.0
                  :turnvv 1.0
                  :tiltv 1.0
                  :tiltvv 1.0
                  :transv-max 1.0
                  :target-speed 1.0
                  :seek0 122880.0
                  :seek90 122880.0
                  :seek180 409600.0
                  :fric 122880.0
                  :nonlin-fric-dist 4096.0
                  :slip-factor 1.0
                  :slope-slip-angle 16384.0
                  :impact-fric 0.5
                  :bend-speed 4.0
                  :alignv 1.0
                  :slope-up-traction 1.0
                  :align-speed 1.0)))
  ;; og:preserve-this
  (define *grass-surface* v1-47)
  (set! (-> v1-47 mult-hook) (the-as (function surface surface surface int none) nothing))
  (set! (-> v1-47 touch-hook) nothing)
  (set! (-> v1-47 active-hook) nothing))

(let ((v1-48 (new 'static
                  'surface
                  :name '*ice-surface*
                  :turnv 0.5
                  :turnvv 1.0
                  :tiltv 1.0
                  :tiltvv 1.0
                  :transv-max 1.5
                  :target-speed 1.5
                  :seek0 24576.0
                  :seek90 24576.0
                  :seek180 24576.0
                  :fric 23756.8
                  :nonlin-fric-dist 4091904.0
                  :slip-factor 0.7
                  :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 no-rotate-toward-transv))))
  ;; og:preserve-this
  (define *ice-surface* v1-48)
  (set! (-> v1-48 mult-hook) (the-as (function surface surface surface int none) nothing))
  (set! (-> v1-48 touch-hook) nothing)
  (set! (-> v1-48 active-hook) nothing))

(let ((v1-49 (new 'static
                  'surface
                  :name '*tread-surface*
                  :turnv 1.0
                  :turnvv 1.0
                  :tiltv 1.0
                  :tiltvv 1.0
                  :transv-max 1.0
                  :target-speed 1.0
                  :seek0 122880.0
                  :seek90 245760.0
                  :seek180 409600.0
                  :fric 122880.0
                  :nonlin-fric-dist 4096.0
                  :slip-factor 1.0
                  :slope-up-factor 8192.0
                  :slope-down-factor 8192.0
                  :impact-fric 1.0
                  :bend-speed 4.0
                  :alignv 1.0
                  :slope-up-traction 1.0
                  :align-speed 1.0)))
  ;; og:preserve-this
  (define *tread-surface* v1-49)
  (set! (-> v1-49 mult-hook) (the-as (function surface surface surface int none) nothing))
  (set! (-> v1-49 touch-hook) nothing)
  (set! (-> v1-49 active-hook) nothing))

(define *standard-ground-surface* *stone-surface*)

(define *swim-surface* *stone-surface*)

;; og:preserve-this
(define-extern *race-track-surface* surface)
