0 1
01234567890123456789
SETUP : MM:SS.s
- NN⚑: R=0 Y=0
+ NN⚑: R=0 y=0
messagemessagemessag
START IN : MM:SS.s
0 1
01234567890123456789
GAME : MM:SS.s
- NN⚑: R=NN Y=NN
+ NN⚑: R=NN y=NN
messagemessagemessag
JB# n/N : MM:SS.s
0 1
01234567890123456789
GAME : MM:SS.s
- NN⚑: R=NN Y=NN
+ NN⚑: R=NN y=NN
messagemessagemessag
GAME END : MM:SS.s
0 1
01234567890123456789
CMUKGB CTFWS TIMER
- NN⚑: R=NN Y=NN
+ NN⚑: R=NN y=NN
messagemessagemessag
GAME OVER @ MM:SS
end
-- call back `cb` cycling through elements of table `ta` using
--- timer `tm` every linger `ms`.
+-- timer `tm` every `linger` ms.
local function alternator(tm, linger, ta, cb)
local lcd = self.lcd
local n = #ta
local function drawSteadyBotLine(self,rix,maxt,rem)
local lcd = self.lcd
+ local ctfws = self.ctfws
if self.dl_remain == nil then
lcd:put(lcd:locate(3,0), " ")
if rix == 0 then
end
local function drawFlags(self)
+ local ctfws = self.ctfws
if ctfws.flagsN then -- try not to blank a flagsmessage unless we have reason
self.ftmr:unregister()
self.fatmr:unregister()
lcd:put(lcd:locate(1,0)," ")
end
if ctfws.startT then
- local oneline = string.format("%d\000: R=%s Y=%s",
+ local rc, yc = "r", "y"
+ (({ ['r'] = function() rc = 'R' end,
+ ['y'] = function() yc = 'Y' end
+ })[ctfws:myTeam()] or function() end)()
+ local oneline = string.format("%d\000: %s=%s %s=%s",
ctfws.flagsN,
- tostring(ctfws.flagsR), tostring(ctfws.flagsY))
+ rc, tostring(ctfws.flagsR),
+ yc, tostring(ctfws.flagsY))
if #oneline <= 20 then
lcd:put(lcd:locate(1,(20-#oneline)/2),oneline)
else
local maxl = math.max(#fr, #fy)
if maxl + #tostring(ctfws.flagsN) + 5 <= 20 then
alternator(self.fatmr, 2000,
- { string.format("%d\000: R=%s%s", ctfws.flagsN, string.rep(" ", maxl-#fr), fr)
- , string.format("%d\000: Y=%s%s", ctfws.flagsN, string.rep(" ", maxl-#fy), fy)
+ { string.format("%d\000: %s=%s%s", ctfws.flagsN, rc, string.rep(" ", maxl-#fr), fr)
+ , string.format("%d\000: %s=%s%s", ctfws.flagsN, yc, string.rep(" ", maxl-#fy), fy)
},
function(msg) lcd:put(lcd:locate(1,(20-#msg)/2),msg) end)
else
local ctfws = "ctfws", "ctfws_lcd", "ctfws_tmr",
"setupD", "roundD", "rounds", "startT", "endT", "flagsN", "flagsR", "flagsY",
- "times", "config", "deconfig", "setFlags", "setEndTime",
+ "ter", "tercfg",
+ "times", "config", "deconfig", "setFlags", "setEndTime", "myTeam", "setTerritory",
"GAME NOT CONFIGURED!",
"GAME OVER @ %02d:%02d", "GAME OVER",
"START TIME IN FUTURE",
"TIME IS UP",
- "CTFWS"
+ "CTFWS",
+ "r", "y"
local lcdpreload =
"define_char",
"lcd", "mtmr", "ftmr", "fatmr", "dl_elapsed", "dl_elapsed", "dl_remain", "dl_round",
"attnState", "reset", "drawTimes", "drawFlags", "drawMessage", "drawFlagsMessage",
"%02d:%02d.%d", "%02d.%d", "%d", "%-20s",
- "%d\000: R=%s Y=%s", "%d\000: R=%s%s", "%d\000: Y=%s%s",
+ "%d\000: %s=%s %s=%s", "%d\000: %s=%s%s",
" CMUKGB CTFWS TIMER ", " ",
"GAME :",
"SETUP :",
"START IN :",
"GAME END :",
"JB# %d/%d :",
- "JB# %2d/%2d :"
+ "JB# %2d/%2d :",
+ "R", "Y"
local init3load =
"flg_tmr", "lastMsgTime", "mqttUser", "msg_tmr", "fla_tmr",
"ctfws/game/message",
"ctfws/game/message/jail",
"none",
- "^%s*(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+).*$",
+ "^%s*(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%S+).*$",
"^%s*(%d+)%s+(-?%d+)%s+(-?%d+).*$",
"^%s*(%d+)%s*(.*)$",
"^%s*%?.*$",
-- rounds* -- number of rounds of game play
-- startT* -- POSIX seconds of game start
-- endT -- POSIX seconds of game end (if set)
+-- tercfg -- The territory config string
+-- ter -- My territory
--
-- flagsN* -- total flags
-- flagsR* -- flags captured by the red team
-- *'d fields are publicly read; startT ~= nil is used as a proxy for "is
-- game configured"
+local v = {}
+
-- returns round index, this round duration, elapsed time
-- round index: 0 for setup, 1-N for game play, and nil for game over / no game
-- all return times in deciseconds
-local function times(self, nowf)
+function v:times(nowf)
if self.startT == nil then
return nil, "GAME NOT CONFIGURED!"
end
end
end
-local function config(self, st, sd, nr, rd, nf)
+function v:config(st, sd, nr, rd, nf, tc)
self.startT = st
self.setupD = sd * 10
self.rounds = nr
self.roundD = rd * 10
self.flagsN = nf
+ self.tercfg = tc
end
-local function deconfig(self)
+function v:deconfig()
self.startT = nil
self.rounds = nil
-- leave flagsN alone for end-of-game display logic
-- return whether or not a change took place, for duplicate message
-- suppression
-local function setFlags(self, fr, fy)
+function v:setFlags(fr, fy)
if (self.flagsR == fr) and (self.flagsY == fy) then return false end
self.flagsR = fr
self.flagsY = fy
return true
end
-local function setEndTime(self,t)
+function v:setEndTime(t)
self.endT = t
end
-local self = {}
-self.times = times
-self.config = config
-self.deconfig = deconfig
-self.setFlags = setFlags
-self.setEndTime = setEndTime
-return self
+function v:setTerritory(t)
+ self.ter = t
+end
+
+function v:myTeam()
+ if self.ter == nil then return nil end
+ if self.tercfg == nil then return nil end
+ return ({ 'r', 'y' })[self.tercfg:find(self.ter)]
+end
+
+return v
if mqc == nil then
print("CTFWS", "You forgot your MQTT configuration file")
end
+local mqttLocnTopic = string.format("ctfws/devc/%s/location",mqttUser)
local mqttBootTopic = string.format("ctfws/dev/%s/beat",mqttUser)
mqc:lwt(mqttBootTopic,"dead",1,1)
if not m or m == "none"
then ctfws:deconfig()
ctfws_lcd_draw_all()
- else local st, sd, nr, rd, nf = m:match("^%s*(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+).*$")
+ else local st, -- start time
+ sd, -- setup duration
+ nr, -- number of rounds
+ rd, -- round duration
+ nf, -- number of flags
+ gn, -- game number
+ tc -- territory configuration string
+ -- st sd nr rd nf gn tc
+ = m:match("^%s*(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%S+).*$")
if st == nil
then ctfws:deconfig()
else -- the game's afoot!
ctfws:config(tonumber(st), tonumber(sd), tonumber(nr),
- tonumber(rd), tonumber(nf))
+ tonumber(rd), tonumber(nf), tc)
ctfws_start_tmr()
end
ctfws_lcd_draw_all()
-- if m:match("^%s*(%d+)%s+%?.*$") then ... end
-- but for now, let's just take any ill-formed message
if ctfws:setFlags("?","?") then ctfws_lcd:drawFlags() end
+ elseif t == mqttLocnTopic then
+ ctfws:setTerritory(m)
+ ctfws_lcd:drawFlags()
elseif t:match("^ctfws/game/message") then
boot_message_hack = nil
local mt, ms = m:match("^%s*(%d+)%s*(.*)$")
["ctfws/game/config"] = 2,
["ctfws/game/endtime"] = 2,
["ctfws/game/flags"] = 2,
+ [mqttLocnTopic] = 2, -- my location
["ctfws/game/message"] = 2, -- broadcast messages
["ctfws/game/message/jail"] = 2, -- jail-specific messages
})