 ; Actions
 ; ----------------------------------------------------------------------
 
-(defn shoot [{:keys [shots shooting? millis-since-last-shot firing? millis-since-last-missile] :as ship}]
-  (let [millis-since-last-shot (+ turn-millis millis-since-last-shot)
-        millis-since-last-missile (+ turn-millis millis-since-last-missile)
-        shoots? (and shooting? (>= millis-since-last-shot (-> ammunition-types :projectile :cooldown)))
-        shots (if shoots? (conj shots (create-projectile ship)) shots)
-        fires? (and firing? (>= millis-since-last-missile (-> ammunition-types :missile :cooldown)))
-        shots (if fires? (conj shots (create-missile ship)) shots)]
-    (when shoots? (play-sound "projectile-fired"))
-    (when fires? (play-sound "missile-fired"))
-    (assoc ship :millis-since-last-shot (if shoots? 0 millis-since-last-shot)
-                :millis-since-last-missile (if fires? 0 millis-since-last-missile)
-                :shots shots)))
+(defn toggle-shooting [{:keys [weapons] :as ship} weapon-type activate?]
+  (if (contains? weapons weapon-type)
+    (-> ship
+        (assoc-in [:weapons weapon-type :shooting?] activate?)
+        (assoc :collidable? ship-damage))
+    ship))
+
+(defn fire-weapon [{:keys [shots] :as ship}
+                   [weapon-type {:keys [ammunition-type cooldown shooting?] :as weapon}]]
+  (let [cooldown (if (> cooldown turn-millis) (- cooldown turn-millis) 0)
+        shoots? (and shooting? (= cooldown 0))
+        cooldown (if shoots? (-> ammunition-types ammunition-type :cooldown) cooldown)
+        shots (if shoots? (conj shots (create-shot ammunition-type ship)) shots)]
+    (when shoots? (play-sound (str (name ammunition-type) "-fired")))
+    (-> ship
+        (assoc-in [:weapons weapon-type :cooldown] cooldown)
+        (assoc :shots shots))))
+
+(defn shoot [{:keys [weapons] :as ship}]
+  (reduce fire-weapon ship weapons))
 
 (defn basic-move
   ([{:keys [direction rotation-speed speed acceleration position] :as object} wrap?]

              (int \A) {:rotation (- ship-rotation-speed)}
              (int \D) {:rotation ship-rotation-speed}
              (int \W) {:acceleration ship-acceleration}
              (int \J) {:fire-missile true}
              (int \K) {:shoot true}})

; END: constants


    :collidable?    'whatever
    }))

(defn create-shot [ammunition-type {:keys [position size direction speed] :as ship}]
  (let [dir-vec (m/rotate-vec direction [0 1])
        position (m/vec+vec position (m/num*vec size dir-vec))
        speed (m/vec+vec speed (m/num*vec (-> ammunition-types ammunition-type :speed) dir-vec))
        ammunition (get ammunition-types ammunition-type)]
    {:type           ammunition-type

     :size           (:size ammunition)
     :shape          (:shape ammunition)
     :color          (:color ammunition)
     :paint-method   fill-polygon

     :position       position
     :speed          speed
     :acceleration   (:acceleration ammunition)

     :direction      direction
     :rotation-speed 0

     :collidable?    (:damage ammunition)}))

(defn create-asteroid
  ([size pos speed]
