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

;; name: projectile.gc
;; name in dgo: projectile
;; dgos: GAME

;; DECOMP BEGINS

(defun cshape-reaction-projectile ((arg0 control-info) (arg1 collide-query) (arg2 vector) (arg3 vector))
  (let ((s5-0 (cshape-reaction-default arg0 arg1 arg2 arg3)))
    (case (-> arg1 best-other-tri pat material)
      (((pat-material stopproj))
       (send-event (-> arg0 process) 'die)
       )
      )
    s5-0
    )
  )

(defmethod projectile-method-39 ((this projectile))
  0
  (none)
  )

(defmethod proj-event-handler ((this projectile) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  (case arg2
    (('tracked)
     (let ((v0-0 (the-as object (process->handle (the-as process (-> arg3 param 0))))))
       (set! (-> this last-target) (the-as handle v0-0))
       v0-0
       )
     )
    (('touched 'touch)
     (handle-proj-hit! this arg0 arg3)
     )
    (('die)
     (projectile-method-34 this)
     )
    )
  )

;; WARN: Return type mismatch object vs projectile.
(defbehavior projectile-event-handler projectile ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  (the-as projectile (proj-event-handler self arg0 arg1 arg2 arg3))
  )

;; WARN: Return type mismatch object vs symbol.
(defmethod deal-damage! ((this projectile) (arg0 process) (arg1 event-message-block))
  (let ((v1-1 (new 'stack 'attack-info)))
    (let ((a0-2 v1-1))
      (set! (-> a0-2 mode) (-> this attack-mode))
      (set! (-> a0-2 id) (-> this attack-id))
      (set! (-> a0-2 mask) (attack-mask mode id))
      )
    (when (!= (-> this owner-handle) #f)
      (set! (-> v1-1 attacker) (-> this owner-handle))
      (logior! (-> v1-1 mask) (attack-mask attacker))
      )
    (when (logtest? (-> this options) (projectile-options po13))
      (set! (-> v1-1 attacker-velocity quad) (-> this pre-move-transv quad))
      (logior! (-> v1-1 mask) (attack-mask attacker-velocity))
      )
    (set! (-> v1-1 damage) (-> this damage))
    (set! (-> v1-1 vehicle-damage-factor) (-> this vehicle-damage-factor))
    (set! (-> v1-1 vehicle-impulse-factor) (-> this vehicle-impulse-factor))
    (logior! (-> v1-1 mask) (attack-mask damage vehicle-damage-factor vehicle-impulse-factor))
    (when (logtest? (projectile-options po18) (-> this options))
      (set! (-> v1-1 invinc-time) (-> this invinc-time))
      (logior! (-> v1-1 mask) (attack-mask invinc-time))
      )
    (the-as symbol (send-event
                     arg0
                     (if (logtest? (projectile-options po19) (-> this options))
                         'attack-invinc
                         'attack
                         )
                     arg1
                     v1-1
                     )
            )
    )
  )

(defmethod handle-proj-hit! ((this projectile) (arg0 process) (arg1 event-message-block))
  (when (-> this attack-mode)
    (let* ((a2-1 (-> arg1 param 0))
           (s5-0 (deal-damage! this arg0 (the-as event-message-block a2-1)))
           )
      (when s5-0
        (let ((v1-2 (-> this notify-handle)))
          (send-event (handle->process v1-2) 'notify 'attack arg0)
          )
        (+! (-> this hits) 1)
        (when (and (>= (-> this hits) (-> this max-hits))
                   (not (and (-> this next-state) (= (-> this next-state name) 'impact)))
                   )
          (if (= s5-0 'no-impact)
              (logior! (-> this options) (projectile-options po20))
              )
          (go (method-of-object this impact))
          )
        )
      )
    )
  )

;; WARN: Return type mismatch symbol vs none.
(defmethod projectile-method-34 ((this projectile))
  (if (not (and (-> this next-state) (= (-> this next-state name) 'impact)))
      (go (method-of-object this impact))
      )
  #t
  (none)
  )

(defmethod projectile-method-24 ((this projectile))
  0
  (none)
  )

(defmethod projectile-method-25 ((this projectile))
  (if (nonzero? (-> this part))
      (spawn (-> this part) (-> this root trans))
      )
  0
  (none)
  )

(defmethod projectile-method-26 ((this projectile))
  0
  (none)
  )

(defmethod projectile-method-27 ((this projectile))
  0
  (none)
  )

(defmethod play-impact-sound ((this projectile) (arg0 projectile-options))
  0
  (none)
  )

(defmethod projectile-method-29 ((this projectile))
  (when (nonzero? (-> this sound-id))
    (sound-stop (-> this sound-id))
    (set! (-> this sound-id) (new 'static 'sound-id))
    0
    )
  0
  (none)
  )

(defmethod made-impact? ((this projectile))
  (let ((v1-0 (-> this root))
        (t1-0 (new 'stack-no-clear 'collide-query))
        )
    (let ((a1-0 t1-0))
      (set! (-> a1-0 radius) (-> v1-0 root-prim prim-core world-sphere w))
      (set! (-> a1-0 collide-with) (-> v1-0 root-prim prim-core collide-with))
      (set! (-> a1-0 ignore-process0) this)
      (set! (-> a1-0 ignore-process1) (handle->process (-> this ignore-handle)))
      (set! (-> a1-0 ignore-pat) (-> v1-0 pat-ignore-mask))
      (set! (-> a1-0 action-mask) (collide-action solid))
      )
    (fill-and-try-snap-to-surface v1-0 (-> v1-0 transv) -6144.0 0.0 -2048.0 t1-0)
    )
  )

(defun projectile-move-fill-all-dirs ((arg0 projectile))
  (let ((v1-0 (-> arg0 root))
        (a2-0 (new 'stack-no-clear 'collide-query))
        )
    (set! (-> a2-0 collide-with) (-> v1-0 root-prim prim-core collide-with))
    (set! (-> a2-0 ignore-process0) arg0)
    (set! (-> a2-0 ignore-process1) (handle->process (-> arg0 ignore-handle)))
    (set! (-> a2-0 ignore-pat) (-> v1-0 pat-ignore-mask))
    (set! (-> a2-0 action-mask) (collide-action solid))
    (fill-cache-integrate-and-collide v1-0 (-> v1-0 transv) a2-0 (meters 0))
    )
  0
  (none)
  )

(defun projectile-move-fill-line-sphere ((arg0 projectile))
  (local-vars (at-0 int))
  (rlet ((vf0 :class vf)
         (vf1 :class vf)
         (vf2 :class vf)
         )
    (init-vf0-vector)
    (let ((gp-0 (-> arg0 root)))
      (let ((a1-0 (new 'stack-no-clear 'collide-query)))
        (let ((a2-0 (-> gp-0 root-prim)))
          (vector-copy! (-> a1-0 start-pos) (-> gp-0 trans))
          (let ((v1-1 (-> a1-0 move-dist)))
            (.lvf vf1 (&-> (-> gp-0 transv) quad))
            (let ((f0-0 (seconds-per-frame)))
              (.mov at-0 f0-0)
              )
            (.mov vf2 at-0)
            (.mov.vf.w vf1 vf0)
            (.mul.x.vf.xyz vf1 vf1 vf2)
            (.svf (&-> v1-1 quad) vf1)
            )
          (let ((v1-2 a1-0))
            (set! (-> v1-2 radius) (-> a2-0 prim-core world-sphere w))
            (set! (-> v1-2 collide-with) (-> a2-0 prim-core collide-with))
            (set! (-> v1-2 ignore-process0) arg0)
            (set! (-> v1-2 ignore-process1) (handle->process (-> arg0 ignore-handle)))
            (set! (-> v1-2 ignore-pat) (-> gp-0 pat-ignore-mask))
            (set! (-> v1-2 action-mask) (collide-action solid))
            )
          )
        (fill-using-line-sphere *collide-cache* a1-0)
        )
      (integrate-and-collide! gp-0 (-> gp-0 transv))
      )
    0
    (none)
    )
  )

(defun projectile-update-velocity-add-gravity ((arg0 projectile))
  (vector-v++! (-> arg0 root transv) (compute-acc-due-to-gravity (-> arg0 root) (new-stack-vector0) 1.0))
  0
  (none)
  )

(defun projectile-update-velocity-space-wars ((arg0 projectile))
  (let ((s5-1 (vector-! (new 'stack-no-clear 'vector) (-> arg0 target-pos) (-> arg0 root trans))))
    (let ((s4-0 (new 'stack-no-clear 'vector))
          (s3-0 (vector-normalize-copy! (new 'stack-no-clear 'vector) (-> arg0 root transv) 1.0))
          (f30-0 (vector-length (-> arg0 root transv)))
          )
      (if (logtest? (-> arg0 root status) (collide-status touch-surface))
          (vector-flatten! s5-1 s5-1 (-> arg0 root local-normal))
          )
      (vector-normalize-copy! s4-0 s5-1 1.0)
      (if (and (or (not (handle->process (-> arg0 last-target)))
                   (zero? (-> (the-as collide-shape (-> (the-as process-drawable (handle->process (-> arg0 last-target))) root))
                              root-prim
                              prim-core
                              collide-as
                              )
                          )
                   )
               (< (vector-dot s4-0 s3-0) 0.0)
               )
          (go (method-of-object arg0 dissipate))
          )
      (vector-deg-slerp (-> arg0 root transv) s3-0 s4-0 (-> arg0 tween))
      (vector-normalize! (-> arg0 root transv) f30-0)
      )
    (vector+! (-> arg0 root transv) (-> arg0 root transv) s5-1)
    )
  (vector-v++! (-> arg0 root transv) (compute-acc-due-to-gravity (-> arg0 root) (new-stack-vector0) 0.0))
  (if (< (-> arg0 max-speed) (vector-length (-> arg0 root transv)))
      (vector-normalize! (-> arg0 root transv) (-> arg0 max-speed))
      )
  (if (logtest? (-> arg0 options) (projectile-options po0))
      (set! (-> arg0 root transv y) -40960.0)
      )
  0
  (none)
  )

(defstate moving (projectile)
  :virtual #t
  :event projectile-event-handler
  :exit (behavior ()
    (projectile-method-29 self)
    )
  :trans (behavior ()
    (if (time-elapsed? (-> self spawn-time) (-> self timeout))
        (go-virtual dissipate)
        )
    (let ((t9-1 (-> self pick-target)))
      (if t9-1
          (t9-1 self)
          )
      )
    (let ((t9-2 (-> self update-velocity)))
      (if t9-2
          (t9-2 self)
          )
      )
    (when (logtest? (-> self options) (projectile-options po1))
      (seek! (-> self tween) 1.0 (* 0.5 (seconds-per-frame)))
      (let ((f0-4 (vector-vector-distance (-> self root trans) (-> self target-pos))))
        (cond
          ((< f0-4 20480.0)
           (seek! (-> self tween) 1.0 (* 3.0 (seconds-per-frame)))
           )
          ((< f0-4 40960.0)
           (seek! (-> self tween) 1.0 (seconds-per-frame))
           )
          )
        )
      )
    (let ((gp-0 (-> self root)))
      (vector-copy! (-> self pre-move-transv) (-> gp-0 transv))
      (let ((s5-0 (new 'stack-no-clear 'vector)))
        (vector-copy! s5-0 (-> gp-0 trans))
        ((-> self move) self)
        (projectile-method-39 self)
        (set! (-> self old-dist (-> self old-dist-count)) (* 0.0625 (vector-vector-distance s5-0 (-> gp-0 trans))))
        )
      )
    (set! (-> self old-dist-count) (logand (+ (-> self old-dist-count) 1) 15))
    (let ((f0-14 0.0))
      (countdown (v1-38 16)
        (+! f0-14 (-> self old-dist v1-38))
        )
      (if (or (and (logtest? (-> self options) (projectile-options po4))
                   (and (logtest? (-> self root status) (collide-status touch-wall)) (< f0-14 2048.0))
                   )
              (< f0-14 (-> self stop-speed))
              )
          (go-impact! self)
          )
      )
    )
  :code (behavior ()
    (until #f
      (projectile-method-25 self)
      (play-impact-sound self (projectile-options po0 po1))
      (suspend)
      )
    #f
    )
  )

(defstate impact (projectile)
  :virtual #t
  :event projectile-event-handler
  :enter (behavior ()
    (projectile-method-26 self)
    (play-impact-sound self (projectile-options po0))
    )
  :code (behavior ()
    (suspend)
    (go-virtual die)
    )
  )

(defstate dissipate (projectile)
  :virtual #t
  :event projectile-event-handler
  :enter (behavior ()
    (projectile-method-27 self)
    (play-impact-sound self (projectile-options po1))
    )
  :code (behavior ()
    (suspend)
    (go-virtual die)
    )
  )

(defstate die (projectile)
  :virtual #t
  :code (behavior ()
    (let ((v1-0 (-> self notify-handle)))
      (send-event (handle->process v1-0) 'notify 'die)
      )
    (cleanup-for-death self)
    )
  )

(defmethod init-proj-settings! ((this projectile))
  0
  (none)
  )

(defmethod setup-collision! ((this projectile))
  (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum hit-by-player))))
    (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s5-0 reaction) cshape-reaction-projectile)
    (set! (-> s5-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (let ((v1-6 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-6 prim-core collide-as) (collide-spec projectile))
      (set! (-> v1-6 prim-core collide-with)
            (collide-spec backgnd crate civilian enemy obstacle vehicle-sphere hit-by-others-list pusher)
            )
      (set! (-> v1-6 prim-core action) (collide-action solid))
      (set-vector! (-> v1-6 local-sphere) 0.0 5324.8 0.0 5324.8)
      (set! (-> s5-0 total-prims) (the-as uint 1))
      (set! (-> s5-0 root-prim) v1-6)
      )
    (set! (-> s5-0 nav-radius) (* 0.75 (-> s5-0 root-prim local-sphere w)))
    (let ((v1-9 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-9 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-9 prim-core collide-with))
      )
    (set! (-> s5-0 max-iteration-count) (the-as uint 2))
    (set! (-> s5-0 event-self) 'touched)
    (set! (-> this root) s5-0)
    )
  (set! (-> this root pat-ignore-mask)
        (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noproj #x1 :noendlessfall #x1 :board #x1)
        )
  0
  (none)
  )

(defmethod projectile-method-32 ((this projectile))
  (go (method-of-object this moving))
  0
  (none)
  )

;; WARN: Return type mismatch object vs none.
(defmethod go-impact! ((this projectile))
  (if (not (and (-> this next-state) (= (-> this next-state name) 'impact)))
      (go (method-of-object this impact))
      )
  (none)
  )

(defmethod deactivate ((this projectile))
  "Make a process dead, clean it up, remove it from the active pool, and return to dead pool."
  (projectile-method-29 this)
  ((method-of-type process-drawable deactivate) this)
  (none)
  )

(defmethod projectile-method-40 ((this projectile))
  32
  )

;; WARN: Return type mismatch int vs object.
(defbehavior projectile-init-by-other projectile ((arg0 projectile-init-by-other-params))
  (let ((a1-0 (projectile-method-40 self)))
    (stack-size-set! (-> self main-thread) a1-0)
    )
  (logclear! (-> self mask) (process-mask actor-pause))
  (process-entity-set! self (-> arg0 ent))
  (set! (-> self charge-level) (-> arg0 charge))
  (set! (-> self options) (-> arg0 options))
  (set! (-> self notify-handle) (-> arg0 notify-handle))
  (set! (-> self owner-handle) (-> arg0 owner-handle))
  (set! (-> self ignore-handle) (-> arg0 ignore-handle))
  (set! (-> self attack-id) (-> arg0 attack-id))
  (set! (-> self damage) (if (logtest? (-> arg0 options) (projectile-options po14))
                             (-> arg0 damage)
                             2.0
                             )
        )
  (set! (-> self vehicle-damage-factor) (if (logtest? (-> arg0 options) (projectile-options po15))
                                            (-> arg0 vehicle-damage-factor)
                                            1.0
                                            )
        )
  (set! (-> self vehicle-impulse-factor) (if (logtest? (projectile-options po16) (-> arg0 options))
                                             (-> arg0 vehicle-impulse-factor)
                                             1.0
                                             )
        )
  (set! (-> self attack-mode) #f)
  (set! (-> self max-speed) 40960.0)
  (set! (-> self tween) 1.0)
  (set! (-> self last-target) (the-as handle #f))
  (set! (-> self timeout) (-> arg0 timeout))
  (set! (-> self max-hits) 1)
  (set-time! (-> self spawn-time))
  (set! (-> self update-velocity) #f)
  (set! (-> self move) projectile-move-fill-line-sphere)
  (set! (-> self pick-target) #f)
  (set! (-> self stop-speed) 204.8)
  (set! (-> self desired-target) (-> arg0 target-handle))
  (vector-copy! (-> self desired-target-pos) (-> arg0 target-pos))
  (countdown (v1-29 16)
    (set! (-> self old-dist v1-29) 4095996000.0)
    )
  (logior! (-> self options) (projectile-options po4))
  (setup-collision! self)
  (let ((s5-0 (-> self root))
        (parent (-> self parent 0)))
    (when (type? s5-0 collide-shape-moving)
      (set! (-> self root dynam gravity y) 1228800.0)
      (set! (-> self root dynam gravity-length) 1228800.0)
      (set! (-> self root dynam gravity-max) 1228800.0)
      )
    (logior! (-> self mask) (process-mask projectile))
    (logclear! (-> self mask) (process-mask enemy))
    (set! (-> s5-0 trans quad) (-> arg0 pos quad))
    (set! (-> self starting-pos quad) (-> arg0 pos quad))
    ;; og:preserve-this
    ;; some projectiles have their parent set as *rigid-body-queue-manager*,
    ;; which is not a process-drawable, so we use its own parent
    ;; (usually the vehicle firing the projectile) to set the quat instead.
    ;; on original hardware, this would not crash because misaligned qw loads silently mask the lower bits
    ;; of the address, loading a junk value instead.
    (quaternion-copy! (-> s5-0 quat) (the quaternion (logand (the int (-> self parent 0 root quat)) #xffffffff0)))
    (vector-identity! (-> s5-0 scale))
    (vector-copy! (-> s5-0 transv) (-> arg0 vel))
    (vector-copy! (-> self pre-move-transv) (-> arg0 vel))
    (vector-normalize-copy! (-> self starting-dir) (-> arg0 vel) 1.0)
    (vector+float*! (-> self base-target-pos) (-> s5-0 trans) (-> self starting-dir) 2048000.0)
    )
  (vector-copy! (-> self target-pos) (-> self base-target-pos))
  (set! (-> self event-hook) projectile-event-handler)
  (init-proj-settings! self)
  (update-transforms (-> self root))
  (projectile-method-24 self)
  (play-impact-sound self (projectile-options))
  (when (logtest? (projectile-options po17) (-> self options))
    (if (made-impact? self)
        (go-virtual impact)
        )
    )
  (projectile-method-32 self)
  0
  )

(defbehavior projectile-bounce-update-velocity projectile ((arg0 projectile-bounce))
  (set! (-> arg0 root transv y) (- (-> arg0 root transv y) (* (-> arg0 gravity) (seconds-per-frame))))
  0
  (none)
  )

(defmethod projectile-bounce-method-43 ((this projectile-bounce))
  0
  (none)
  )

(defmethod projectile-method-40 ((this projectile-bounce))
  256
  )

(defbehavior projectile-bounce-falling-post projectile-bounce ()
  (let ((gp-0 (-> self root))
        (s4-0 (new 'stack-no-clear 'collide-query))
        (s5-0 (new 'stack-no-clear 'vector))
        )
    (projectile-bounce-update-velocity self)
    (vector-copy! s5-0 (-> gp-0 trans))
    (vector-v++! s5-0 (-> gp-0 transv))
    (when (find-ground
            gp-0
            s4-0
            (collide-spec backgnd crate obstacle hit-by-others-list pusher)
            4096.0
            81920.0
            1024.0
            (the-as process #f)
            )
      (let ((f30-0 (+ (-> gp-0 gspot-pos y) (-> self root root-prim local-sphere w))))
        (when (>= f30-0 (-> s5-0 y))
          (projectile-bounce-method-43 self)
          (set! (-> s5-0 y) f30-0)
          (vector-reset! (-> gp-0 transv))
          )
        )
      )
    (move-to-point! gp-0 s5-0)
    )
  (transform-post)
  0
  (none)
  )

(defstate sitting (projectile-bounce)
  :virtual #t
  :event projectile-event-handler
  :trans (behavior ()
    (projectile-bounce-method-42 self)
    (if (time-elapsed? (-> self spawn-time) (-> self timeout))
        (go-virtual impact)
        )
    )
  :code sleep-code
  :post projectile-bounce-falling-post
  )

(defmethod projectile-bounce-method-42 ((this projectile-bounce))
  0
  (none)
  )

(defstate dissipate (projectile-bounce)
  :virtual #t
  :enter (behavior ()
    (go-virtual impact)
    )
  )

;; WARN: Return type mismatch object vs none.
(defmethod go-impact! ((this projectile-bounce))
  (go (method-of-object this sitting))
  (none)
  )

(defmethod projectile-method-25 ((this projectile-bounce))
  (ja-post)
  0
  (none)
  )

(defun projectile-bounce-move ((arg0 projectile-bounce))
  (seek-toward-heading-vec! (-> arg0 root) (-> arg0 root transv) 131072.0 (seconds 0.1))
  (quaternion*! (-> arg0 root quat) (-> arg0 root quat) (-> arg0 tumble-quat))
  (projectile-move-fill-all-dirs arg0)
  (none)
  )

(defun projectile-bounce-reaction ((arg0 control-info) (arg1 collide-query) (arg2 vector) (arg3 vector))
  (cshape-reaction-update-state arg0 arg1 arg3)
  (let ((f30-0 (vector-dot arg3 (-> arg0 surface-normal)))
        (s2-0 (new 'stack-no-clear 'vector))
        )
    (vector-float*! s2-0 (-> arg0 surface-normal) (* f30-0 (rand-vu-float-range 1.6 2.2)))
    (vector-! arg2 arg3 s2-0)
    )
  (-> arg0 status)
  )

;; WARN: Return type mismatch sound-id vs none.
(defmethod projectile-method-39 ((this projectile-bounce))
  (let* ((a2-0 (-> this root))
         (v1-0 (-> a2-0 status))
         )
    (if (logtest? v1-0 (collide-status touch-surface))
        (vector-float*! (-> a2-0 transv) (-> a2-0 transv) 0.6)
        )
    (when (and (logtest? v1-0 (collide-status impact-surface))
               (time-elapsed? (-> this played-bounce-time) (seconds 0.3))
               )
      (set-time! (-> this played-bounce-time))
      (sound-play "dark-shot-bounc")
      )
    )
  (none)
  )

(defmethod setup-collision! ((this projectile-bounce))
  (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum hit-by-player))))
    (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s5-0 reaction) projectile-bounce-reaction)
    (set! (-> s5-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (set! (-> s5-0 penetrate-using) (penetrate jak-dark-shot))
    (let ((v1-7 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> v1-7 prim-core action) (collide-action solid))
      (set-vector! (-> v1-7 local-sphere) 0.0 0.0 0.0 819.2)
      (set! (-> s5-0 total-prims) (the-as uint 1))
      (set! (-> s5-0 root-prim) v1-7)
      )
    (set! (-> s5-0 nav-radius) (* 0.75 (-> s5-0 root-prim local-sphere w)))
    (let ((v1-10 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-10 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-10 prim-core collide-with))
      )
    (set! (-> s5-0 max-iteration-count) (the-as uint 2))
    (set! (-> s5-0 event-self) 'touched)
    (set! (-> this root) s5-0)
    )
  (set-collide-with!
    (-> this root)
    (collide-spec backgnd bot crate civilian enemy obstacle vehicle-sphere hit-by-others-list player-list pusher)
    )
  (set-collide-as! (-> this root) (collide-spec projectile))
  (set! (-> this root pat-ignore-mask)
        (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noproj #x1 :noendlessfall #x1 :board #x1)
        )
  (none)
  )

(defmethod init-proj-settings! ((this projectile-bounce))
  (set! (-> this max-speed) 450560.0)
  (set! (-> this timeout) (seconds 1.6))
  (set! (-> this update-velocity) projectile-bounce-update-velocity)
  (set! (-> this move) projectile-bounce-move)
  (set! (-> this gravity) 184320.0)
  (set! (-> this root dynam gravity y) 184320.0)
  (set! (-> this root dynam gravity-length) 184320.0)
  (set! (-> this root dynam gravity-max) 184320.0)
  (let ((f0-5 1092.2667))
    (quaternion-axis-angle! (-> this tumble-quat) 1.0 0.0 0.0 f0-5)
    )
  0
  (none)
  )
