logic.clj

Branches > main > 70c1f87 > 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/id fact)))

(defmethod handle-fact ::fact/server-list-requested [_]
  (dosync
    [{::effect/id ::effect/send-server-list
      :server-list-response {:version {:name "26.2"
                                       :protocol 776}
                             :players {:online (count @server/players)
                                       :max server/max-player-count}
                             :description {:text "Bowmap!"}
                             :enforcesSecureChat false}}]))

; Want this to be pure, which means you need a way to encode that state change as data?
(defmethod handle-fact ::fact/player-joined [{::player/keys! [player]}]
  (dosync
    (let [{::player/keys! [uuid]} player]
      (if (@server/players uuid)
        (throw (Exception. "Player tried to join with an existing UUID"))
        (commute server/players assoc uuid (ref player)))
      [])))

(defmethod handle-fact ::fact/player-left [{:keys! [::player/uuid]}]
  (dosync
    (commute server/players dissoc uuid)
    []))

(defmethod handle-fact ::fact/updated-player-movement [{:keys! [::player/uuid ::position/position]}]
  (dosync
    (alter (@server/players uuid) update ::position/position merge position)
    []))

; Called when the player actually moves, not just when a position is sent
(defmethod handle-fact ::fact/player-moved [_ _])