Commits

Steve Losh committed 716b6b7

Kill things!

Comments (0)

Files changed (4)

src/caves/entities/aspects/attacker.clj

+(ns caves.entities.aspects.attacker)
+
+
+(defprotocol Attacker
+  (attack [this world target]
+          "Attack the target."))
+

src/caves/entities/aspects/destructible.clj

+(ns caves.entities.aspects.destructible)
+
+
+(defprotocol Destructible
+  (take-damage [this world damage]
+               "Take the given amount of damage and update the world appropriately."))

src/caves/entities/lichen.clj

 (ns caves.entities.lichen
   (:use [caves.entities.core :only [Entity get-id]]
+        [caves.entities.aspects.destructible :only [Destructible take-damage]]
         [caves.world :only [find-empty-neighbor]]))
 
 
-(defrecord Lichen [id glyph color location])
+(defrecord Lichen [id glyph color location hp])
 
 (defn make-lichen [location]
-  (->Lichen (get-id) "F" :green location))
+  (->Lichen (get-id) "F" :green location 1))
 
 (defn should-grow []
   (< (rand) 0.01))
       (assoc-in world [:entities (:id new-lichen)] new-lichen))
     world))
 
+
 (extend-type Lichen Entity
   (tick [this world]
     (if (should-grow)
       (grow this world)
       world)))
 
-
-
+(extend-type Lichen Destructible
+  (take-damage [{:keys [id] :as this} world damage]
+    (let [damaged-this (update-in this [:hp] - damage)]
+      (if-not (pos? (:hp damaged-this))
+        (update-in world [:entities] dissoc id)
+        (update-in world [:entities id] assoc damaged-this)))))

src/caves/entities/player.clj

   (:use [caves.entities.core :only [Entity]]
         [caves.entities.aspects.mobile :only [Mobile move can-move?]]
         [caves.entities.aspects.digger :only [Digger dig can-dig?]]
+        [caves.entities.aspects.attacker :only [Attacker attack]]
+        [caves.entities.aspects.destructible :only [Destructible take-damage]]
         [caves.coords :only [destination-coords]]
-        [caves.world :only [is-empty? get-tile-kind set-tile-floor]]))
+        [caves.world :only [is-empty? get-tile-kind set-tile-floor
+                            get-entity-at]]))
 
 
 (defrecord Player [id glyph color location])
   (can-dig? [this world dest]
     (check-tile world dest #{:wall})))
 
+(extend-type Player Attacker
+  (attack [this world target]
+    {:pre [(satisfies? Destructible target)]}
+    (let [damage 1]
+      (take-damage target world damage))))
 
 
 (defn make-player [location]
 
 (defn move-player [world dir]
   (let [player (get-in world [:entities :player])
-        target (destination-coords (:location player) dir)]
+        target (destination-coords (:location player) dir)
+        entity-at-target (get-entity-at world target)]
     (cond
+      entity-at-target (attack player world entity-at-target)
       (can-move? player world target) (move player world target)
       (can-dig? player world target) (dig player world target)
       :else world)))