Early battle system

This commit is contained in:
Dane Johnson 2023-09-13 11:04:44 -05:00
parent 451102e459
commit 8f1d26a0c6
4 changed files with 48 additions and 19 deletions

View File

@ -3,20 +3,36 @@
(:require [minibaldur.ecs :refer :all] (:require [minibaldur.ecs :refer :all]
[minibaldur.engine :refer :all])) [minibaldur.engine :refer :all]))
(defcomponent goblin-ai :void) (defcomponent name)
(defcomponent position)
(defcomponent health)
(defcomponent attack)
(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"))
(goblin-ai))
(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"))
(defn battle-system
[entity]
(let [opponent (if (= (name entity) "Goblin")
(find-by :name "Adventurer")
(find-by :name "Goblin"))]
(health opponent (max 0 (- (health opponent) (first (roll (attack entity))))))))
(defn do-battle
[]
(let [goblin (find-by :name "Goblin")
adventurer (find-by :name "Adventurer")]
(while (every? pos? [(health goblin) (health adventurer)])
(run-e battle-system [:name :health]))))
(defn -main (defn -main
"I don't do a whole lot ... yet." "I don't do a whole lot ... yet."

View File

@ -36,7 +36,7 @@
(doseq [entity (query-e query)] (doseq [entity (query-e query)]
(apply f entity args))) (apply f entity args)))
(defn find-entity-by (defn find-by
[component value] [component value]
(some #(and (= value (val %)) (key %)) (some #(and (= value (val %)) (key %))
(@*components* component))) (@*components* component)))

View File

@ -1,19 +1,18 @@
(ns minibaldur.engine) (ns minibaldur.engine)
(defn diceroll (defn- diceroll
[x] [x]
(re-find #"(\d+)d(\d+)" x)) (if-let [match (re-find #"(\d+)d(\d+)" x)]
(map #(Integer/parseInt %) (next match))))
(defn diceval (defn- diceval
[x] [x]
(if-let [[_ a b] (diceroll x)] (if-let [[a b] (diceroll x)]
(apply + (repeat (Integer/parseInt a) (apply + (repeat a (inc (rand-int b))))
(+ (rand-int (Integer/parseInt b)) 1)))
(Integer/parseInt x))) (Integer/parseInt x)))
(defn roll (defn roll
"Takes a standard ttrpg roll specifier and returns a vector, starting with the sum, and "Takes a standard ttrpg roll specifier and returns a vector, starting with the sum, and then each roll in the order listed in the specifier"
then each roll in the order listed in the specifier"
[specifier] [specifier]
(let [dies-and-ops (clojure.string/split specifier #"\s+") (let [dies-and-ops (clojure.string/split specifier #"\s+")
first-die-val (diceval (first dies-and-ops)) first-die-val (diceval (first dies-and-ops))
@ -28,3 +27,17 @@
"+" (recur (+ sum val) (if roll? (conj rolls val) rolls) (nnext tail)) "+" (recur (+ sum val) (if roll? (conj rolls val) rolls) (nnext tail))
"-" (recur (- sum val) (if roll? (conj rolls val) rolls) (nnext tail)))) "-" (recur (- sum val) (if roll? (conj rolls val) rolls) (nnext tail))))
(into [sum] rolls))))) (into [sum] rolls)))))
(defn roll-advantage
"Rolls 2d20 and returns the highest. Takes an optional specifier for bonuses"
([] (max-key first (roll "1d20") (roll "1d20")))
([bonuses]
(let [spec (str "1d20 + " bonuses)]
(max-key first (roll spec) (roll spec)))))
(defn roll-disadvantage
"Rolls 2d20 and returns the lowest. Takes an optional specifier for bonuses"
([] (min-key first (roll "1d20") (roll "1d20")))
([bonuses]
(let [spec (str "1d20 + " bonuses)]
(min-key first (roll spec) (roll spec)))))

View File

@ -19,7 +19,7 @@
(deftest basic (deftest basic
(run-e age-up :age) (run-e age-up :age)
(is (= 28 (age (find-entity-by :name "Dane"))))) (is (= 28 (age (find-by :name "Dane")))))
(defcomponent alignment) (defcomponent alignment)
(defcomponent health) (defcomponent health)
@ -45,5 +45,5 @@
(deftest full (deftest full
(run-e damage-evil-creatures [:alignment :health] 2) (run-e damage-evil-creatures [:alignment :health] 2)
(is (= 2 (health (find-entity-by :name "Fey")))) (is (= 2 (health (find-by :name "Fey"))))
(is (= 8 (health (find-entity-by :name "Goblin"))))) (is (= 8 (health (find-by :name "Goblin")))))