init commit

This commit is contained in:
2023-09-12 23:26:36 -05:00
commit 451102e459
11 changed files with 522 additions and 0 deletions

24
src/minibaldur/core.clj Normal file
View File

@@ -0,0 +1,24 @@
(ns minibaldur.core
(:gen-class)
(:require [minibaldur.ecs :refer :all]
[minibaldur.engine :refer :all]))
(defcomponent goblin-ai :void)
(defentity
(name "Goblin")
(position {:x 0 :y 0 :z 0})
(health 10)
(attack "1d4 + 2")
(goblin-ai))
(defentity
(:name "Adventurer")
(:position {:x 0 :y 0 :z 0})
(:health 20)
(:attack "1d6 + 3"))
(defn -main
"I don't do a whole lot ... yet."
[& args]
(println "Hello, World!"))

42
src/minibaldur/ecs.clj Normal file
View File

@@ -0,0 +1,42 @@
(ns minibaldur.ecs
(:require [clojure.string :as str]))
(defonce next-entity (atom 1))
(defonce ^:dynamic *components* (atom {}))
(defmacro defcomponent
[comp-name]
`(do
(swap! *components* assoc ~(keyword comp-name) {})
(defn ~comp-name
([entity#] (get-in @*components* [~(keyword comp-name) entity#]))
([entity# value#] (swap! *components* assoc-in [~(keyword comp-name) entity#] value#)))))
(defmacro defentity
[& components]
(let [entity (gensym)]
`(let [~entity (first (swap-vals! next-entity inc))]
~@(for [[comp-name comp-value] components]
`(~comp-name ~entity ~comp-value)))))
(defn query-e
"Return known entitys matching a query"
[query]
(if (keyword? query)
(some-> (query @*components*) keys)
(loop [ents (query-e (first query))
fils (next query)]
(if (nil? fils)
ents
(recur (filter (set ents) (query-e (first fils))) (next fils))))))
(defn run-e
"Run system on all entities matching query"
[f query & args]
(doseq [entity (query-e query)]
(apply f entity args)))
(defn find-entity-by
[component value]
(some #(and (= value (val %)) (key %))
(@*components* component)))

30
src/minibaldur/engine.clj Normal file
View File

@@ -0,0 +1,30 @@
(ns minibaldur.engine)
(defn diceroll
[x]
(re-find #"(\d+)d(\d+)" x))
(defn diceval
[x]
(if-let [[_ a b] (diceroll x)]
(apply + (repeat (Integer/parseInt a)
(+ (rand-int (Integer/parseInt b)) 1)))
(Integer/parseInt x)))
(defn roll
"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"
[specifier]
(let [dies-and-ops (clojure.string/split specifier #"\s+")
first-die-val (diceval (first dies-and-ops))
first-die-roll? (diceroll (first dies-and-ops))]
(loop [sum first-die-val
rolls (if first-die-roll? [first-die-val] [])
tail (next dies-and-ops)]
(if-let [[op die] tail]
(let [roll? (diceroll die)
val (diceval die)]
(case op
"+" (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)))))