peer-kit / src / ardegazu / peer / games / host / neon_grid_host.cljs
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
;; ported-from: src/games/host/neon-grid-host.ts @ v1.3.0
;;   (itself: game1/client/src/game/game.ts hi/in routing, live-beats-idle
;;   split-brain rule, match flow @ 4c5def7) — the sim lives in
;;   neon-grid-sim.cljs; roster/timers/auto-start in the driver base.
;; divergences: same as seance-host (no roster-grace, no election backstop);
;;   the tick interval is a chained timeout (clients timestamp on receipt, so
;;   cadence drift is cosmetic).
(ns ardegazu.peer.games.host.neon-grid-host
  (:require [ardegazu.peer.games.host.driver :as driver]
            [ardegazu.peer.games.host.neon-grid-sim :as ng]
            [shadow.cljs.modern :refer (defclass)]))

(declare start-round)

(defclass NeonGridHost
  (extends driver/HostDriver)
  (constructor [this room opts]
    (super room (if ^boolean (js* "~{} == null" opts) (js-obj) opts))
    ;; playing/countdown/roundover — true from "st" until "ma" or "lo"
    (unchecked-set this "_live" false)
    (unchecked-set
     this "sim"
     (ng/NeonGridSim.
      (js-obj "roster" (fn [] (driver/roster-entries this))
              "addScore" (fn [id]
                           (let [p (.get ^js (unchecked-get this "roster") id)]
                             (when ^boolean (js* "!!(~{})" p)
                               (unchecked-set p "score" (inc (unchecked-get p "score")))))
                           js/undefined)
              "resetScores" (fn []
                              (.forEach ^js (unchecked-get this "roster")
                                        (fn [p _k] (unchecked-set p "score" 0)))
                              js/undefined))))))

(defn- start-round [self]
  (let [roster (unchecked-get self "roster")
        riders (.map ^js (driver/connected-seated self)
                     (fn [id] (js-obj "id" id
                                      "color" (unchecked-get (.get ^js roster id) "badge"))))]
    (if (zero? (.-length riders))
      (do (unchecked-set self "_live" false)
          (driver/on-lobby self))
      (do (unchecked-set self "_live" true)
          (driver/run-emit self (ng/start-round (unchecked-get self "sim") riders)))))
  js/undefined)

(let [proto (.-prototype NeonGridHost)]
  ;; live round beats idle claim, ties to lowest id (both sides of the split).
  (unchecked-set
   proto "concedeRule"
   (fn [from m]
     (this-as self
       (let [my-live (unchecked-get self "_live")
             their-live (identical? 1 (unchecked-get m "live"))
             i-win (if-not (identical? my-live their-live)
                     my-live
                     (< (unchecked-get (unchecked-get self "room") "myId") from))]
         (not i-win)))))

  (unchecked-set proto "startMatch"
                 (fn [_ids]
                   (this-as self
                     (ng/new-match (unchecked-get self "sim"))
                     (driver/broadcast-roster self)
                     (start-round self)
                     js/undefined)))

  (unchecked-set
   proto "onGameFrame"
   (fn [from m]
     (this-as self
       (let [t (unchecked-get m "t")]
         (cond
           (identical? t "hi") (driver/on-hi self from m)
           (identical? t "in") (ng/input (unchecked-get self "sim") from
                                         (bit-or (unchecked-get m "d") 0))
           :else nil))
       js/undefined)))

  (unchecked-set
   proto "execStep"
   (fn [step]
     (this-as self
       (if (identical? step "round")
         (start-round self)
         (do
           (when (or (identical? step "match") (identical? step "lobby"))
             (unchecked-set self "_live" false))
           (driver/run-emit self (ng/step (unchecked-get self "sim") step))))
       js/undefined)))

  (unchecked-set proto "simPeerGone"
                 (fn [id] (this-as self (ng/peer-gone (unchecked-get self "sim") id))))
  (unchecked-set proto "sendSnap"
                 (fn [to] (this-as self
                            (driver/run-emit self (ng/snapshot (unchecked-get self "sim") to))
                            js/undefined)))
  (unchecked-set proto "roundLive" (fn [] (this-as self (unchecked-get self "_live"))))
  (unchecked-set proto "simRunning"
                 (fn [] (this-as self (unchecked-get (unchecked-get self "sim") "_running"))))
  (unchecked-set proto "abortSim"
                 (fn [] (this-as self
                          (unchecked-set self "_live" false)
                          (ng/abort (unchecked-get self "sim"))))))

static mirror of HEAD · about · clone: git clone https://git.ardegazu.ro/peer-kit.git