logic.clj
Branches > facts > 9a69ad5 > files / src / net / bowmap / server / logic.clj
(ns net.bowmap.server.logic
(:require
[net.bowmap.server.player :as player]
[net.bowmap.server.position :as position]
[net.bowmap.server.server :as server]
[net.bowmap.stormbow.effect :as effect]
[net.bowmap.stormbow.fact :as fact]))
; TODO should also be able to return new facts :)
(defmulti handle-fact
"Returns a sequence of effects from a fact."
(fn [fact]
(::fact/attribute fact)))
(defmethod handle-fact :default [_])
(defmethod handle-fact ::fact/server-list-requested [_]
(dosync
[{::effect/id ::effect/send-server-list
:server-list-response {:version {:name "26.2"
:protocol 776}
; Gets the number of players playing, which is what you want
; And there are no side-effects!
#_(count (fact ::fact/playing))
:players {:online (count (fact/fact ::fact/playing))
:max server/max-player-count}
:description {:text "Bowmap!"}
:enforcesSecureChat false}}]))
(defmethod handle-fact ::fact/player-joined [{::fact/keys! [value]}]
(dosync
(let [{::player/keys! [uuid]} value]
(if (contains? (fact/fact ::fact/playing) uuid)
(throw (Exception. "Player tried to join with an existing UUID"))
[{::fact/attribute ::fact/playing
::fact/entity uuid}]))))
; TODO this is never actually used :p
; So the player list and re-joining are broken
(defmethod handle-fact ::fact/player-left [{::fact/keys! [entity]}]
[{::fact/attribute ::fact/playing
::fact/mode ::fact/retract
::fact/entity entity}])
#_(defmethod handle-fact ::fact/updated-player-movement [{:keys! [::player/uuid ::position/position]}]
(dosync
(alter (@server/players uuid) update ::position/position merge position)
[]))
; TODO move this comment to the fact definition itself somewhere
; Called when the player actually moves, not just when a position is sent
(defmethod handle-fact ::fact/player-moved [_ _])
(defn apply-rules
"Applies rules recursively, returns a map containing :facts and :effects.
:facts being the seqs of all facts that were asserted/retracted,
:effects being the seq of all effects that are implied from that fact."
([fact] (apply-rules {:facts [fact] :effects []} fact))
([acc fact]
(let [results (handle-fact fact)]
(reduce (fn [acc result]
(if (::fact/attribute result)
(apply-rules (update acc :facts conj result) result)
(update acc :effects conj result)))
acc results))))