Simple combat
This commit is contained in:
parent
8f1d26a0c6
commit
a5d49832d9
@ -7,34 +7,69 @@
|
|||||||
(defcomponent position)
|
(defcomponent position)
|
||||||
(defcomponent health)
|
(defcomponent health)
|
||||||
(defcomponent attack)
|
(defcomponent attack)
|
||||||
|
(defcomponent player-character)
|
||||||
|
(defcomponent goblin-ai)
|
||||||
|
(defcomponent armor-class)
|
||||||
|
|
||||||
|
(def combat-log println)
|
||||||
|
|
||||||
(defentity
|
(defentity
|
||||||
(name "Goblin")
|
(name "Goblin")
|
||||||
(position {:x 0 :y 0 :z 0})
|
(position {:x 0 :y 0 :z 0})
|
||||||
(health 10)
|
(health 10)
|
||||||
(attack "1d4 + 2"))
|
(attack "1d4 + 2")
|
||||||
|
(armor-class 13)
|
||||||
|
(goblin-ai nil))
|
||||||
|
|
||||||
(defentity
|
(defentity
|
||||||
(name "Adventurer")
|
(name "Adventurer")
|
||||||
(position {:x 0 :y 0 :z 0})
|
(position {:x 0 :y 0 :z 0})
|
||||||
(health 20)
|
(health 20)
|
||||||
(attack "1d6 + 3"))
|
(attack "1d6 + 3")
|
||||||
|
(armor-class 15)
|
||||||
|
(player-character nil))
|
||||||
|
|
||||||
(defn battle-system
|
(def alive? (comp pos? health))
|
||||||
[entity]
|
|
||||||
(let [opponent (if (= (name entity) "Goblin")
|
(defn do-attack
|
||||||
(find-by :name "Adventurer")
|
[entity target]
|
||||||
(find-by :name "Goblin"))]
|
(let [[to-hit] (roll "1d20")]
|
||||||
(health opponent (max 0 (- (health opponent) (first (roll (attack entity))))))))
|
(if (>= to-hit (armor-class target))
|
||||||
|
(let [[dmg] (roll (attack entity))]
|
||||||
|
(combat-log (str (name entity) " hit " (name target) " for " dmg " damage"))
|
||||||
|
(health target (max (- (health target) dmg) 0)))
|
||||||
|
(combat-log (str (name entity) " missed " (name target))))))
|
||||||
|
|
||||||
|
(defn goblin-attack
|
||||||
|
[goblin]
|
||||||
|
(when-let [adventurer (first (filter alive? (query-e [:player-character
|
||||||
|
:health
|
||||||
|
:armor-class])))]
|
||||||
|
(do-attack goblin adventurer)))
|
||||||
|
|
||||||
|
(defn adventurer-attack
|
||||||
|
[adventurer]
|
||||||
|
(let [targets (vec (filter alive? (query-e [:health :armor-class])))]
|
||||||
|
(println "Choose a target:")
|
||||||
|
(doseq [[i target] (map-indexed vector targets)]
|
||||||
|
(println (str "\t" (inc i) ". " (name target))))
|
||||||
|
(let [target-i (dec (Integer/parseInt (read-line)))
|
||||||
|
target (get targets target-i)]
|
||||||
|
(do-attack adventurer target))))
|
||||||
|
|
||||||
(defn do-battle
|
(defn do-battle
|
||||||
[]
|
[]
|
||||||
(let [goblin (find-by :name "Goblin")
|
(let [goblin (find-by :name "Goblin")
|
||||||
adventurer (find-by :name "Adventurer")]
|
adventurer (find-by :name "Adventurer")]
|
||||||
(while (every? pos? [(health goblin) (health adventurer)])
|
(loop [turn adventurer]
|
||||||
(run-e battle-system [:name :health]))))
|
(when (every? alive? [goblin adventurer])
|
||||||
|
(if (= turn adventurer)
|
||||||
|
(do (adventurer-attack adventurer)
|
||||||
|
(recur goblin))
|
||||||
|
(do (goblin-attack goblin)
|
||||||
|
(recur adventurer)))))))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
"I don't do a whole lot ... yet."
|
"I don't do a whole lot ... yet."
|
||||||
[& args]
|
[& args]
|
||||||
(println "Hello, World!"))
|
(do-battle))
|
||||||
|
Loading…
Reference in New Issue
Block a user