Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Nether PVP Arena
- Master device
- --]]
- game = game or {}
- local GameState = {
- Stopped = 0,
- Starting = 1,
- Started = 2
- }
- local Master = common.newClass(mcnet.device.Server, {
- -- Device
- deviceType = "netherpvp:master",
- -- Server
- registerServantMessage = "netherpvp:registerCell",
- registeredServantMessage = "netherpvp:registeredCell",
- servantType = "netherpvp:cell",
- -- Game
- state = GameState.Stopped,
- scores = nil,
- winScore = 1,
- startTimeout = 0,
- -- Waiting
- waitMessage = nil,
- waitRemaining = nil,
- waitCallback = nil,
- waitContinue = nil
- })
- game.Master = Master
- -- Constructor
- function Master:init()
- mcnet.device.Server.init(self)
- -- Address
- self.address = mcnet.address.new{
- localPart = self.name,
- domainPart = self.domain
- }
- -- Reset
- self:resetGame()
- self:addMessageHandler(game.msg.notifyWin, self.handleNotifyWin)
- end
- function Master:checkServant(deviceType, deviceAddress)
- return deviceType == self.servantType and deviceAddress.domainPart == self.domain
- end
- function Master:getServantName(servantAddress)
- return servantAddress.localPart
- end
- function Master:stop()
- -- Reset game
- self:resetGame()
- -- Stop device
- mcnet.device.Server.stop(self)
- end
- --[[
- Utilities
- --]]
- -- Broadcast message to all cells
- function Master:broadcastToCells(msg)
- -- Sender address
- msg.from = self.address
- -- Broadcast
- for i,cellId in ipairs(self.servants:getAll()) do
- self:send(cellId, msg)
- end
- end
- -- Wait for response from all cells
- function Master:waitForCells(messageType, callbackFunc, continueFunc)
- assert(self.waitMessage == nil, "still waiting for "..tostring(self.waitMessage))
- -- Start waiting
- self.waitMessage = messageType
- self.waitRemaining = common.combine(self.servants:getAll(), true)
- self.waitCallback = callbackFunc
- self.waitContinue = continueFunc
- self:on("mcnet_message", self.handleWait, self)
- end
- function Master:handleWait(senderId, msg)
- if msg.type == self.waitMessage then
- -- Remove from remaining
- self.waitRemaining[senderId] = nil
- -- Callback
- if self.waitCallback ~= nil then
- self.waitCallback(senderId, msg)
- end
- -- Check remaining
- if next(self.waitRemaining) == nil then
- local continue = self.waitContinue
- -- Stop waiting
- self:off("mcnet_message", self.handleWait, self)
- self.waitMessage, self.waitRemaining = nil, nil
- self.waitCallback, self.waitContinue = nil, nil
- -- Callback
- if continue ~= nil then continue() end
- end
- end
- end
- --[[
- Colors
- --]]
- -- Get the current color of all cells and pass it to the callback
- function Master:getCellColors(callbackFunc)
- -- Request color
- self:broadcastToCells(mcnet.message.new{
- type = game.msg.getColor
- })
- -- Wait for all colors
- local cellColors = {}
- self:waitForCells(game.msg.notifyColor,
- function(cellId, msg)
- cellColors[cellId] = tonumber(msg.data)
- end,
- function()
- callbackFunc(cellColors)
- end
- )
- end
- --[[
- Game
- --]]
- function Master:startGame()
- self:trigger("startGame")
- -- Reset game
- self:resetGame()
- -- TODO: Countdown?
- -- Start new round
- self:newRound()
- end
- function Master:stopGame(winnerColor)
- self:trigger("stopGame", winnerColor)
- self:stopRound()
- end
- function Master:resetGame()
- self:trigger("resetGame")
- -- Reset scores
- self.scores = {}
- -- Reset cells
- self:stopRound()
- end
- --[[
- Rounds
- --]]
- function Master:newRound()
- -- Starting
- self.state = GameState.Starting
- self:trigger("newRound")
- self:getCellColors(function(cellColors)
- local cells, colors = common.getKeys(cellColors), common.getValues(cellColors)
- -- Randomly cycle the colors
- local newColors = common.randomCycle(colors)
- -- Initialize new round with new colors
- for i,cellId in ipairs(cells) do
- self:send(cellId, mcnet.message.new{
- type = game.msg.newRound,
- data = newColors[i]
- })
- end
- -- Wait for all cells to get ready
- self:waitForCells(game.msg.notifyReady, nil,
- function()
- self:startRound()
- end
- )
- end)
- end
- function Master:startRound()
- self:beforeStartRound()
- -- Started
- self.state = GameState.Started
- self:trigger("startRound")
- -- Drop lever
- self:dropLever()
- -- Broadcast
- self:broadcastToCells(mcnet.message.new{
- type = game.msg.startRound
- })
- end
- function Master:stopRound()
- -- Stopped
- self.state = GameState.Stopped
- self:trigger("stopRound")
- -- Broadcast
- self:broadcastToCells(mcnet.message.new{
- type = game.msg.stopRound
- })
- end
- function Master:beforeStartRound()
- -- TODO: Countdown on big screen?
- os.sleep(self.startTimeout)
- end
- function Master:dropLever()
- -- TODO
- end
- --[[
- Round winning
- --]]
- function Master:winRound(winnerColor)
- -- Stop round
- self:stopRound()
- -- Add to score
- local score = (self.scores[winnerColor] or 0) + 1
- self.scores[winnerColor] = score
- self:trigger("scoreChanged", winnerColor, score)
- -- New round or game over
- if score == self.winScore then
- self:stopGame()
- else
- self:newRound()
- end
- end
- function Master:handleNotifyWin(senderId, msg)
- if self.state == GameState.Started then
- self:winRound(tonumber(msg.data))
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment