------------------------------- -- /lib/Kew ------------------- ------------------------------- --- A Kew (short for Queue) is a state machine with states: dormant, inplay, gameover; unavailable local kew_states_names = { dormant = "dormant", inplay = "inplay", gameover = "gameover", unavailable = "unavailable" } ----------------------------------------------------------------------- ------------ "DORMANT" STATE DEFINITION ------------------------------- --- enterState_dormant(self) local state_dormant = {} state_dormant.name = kew_states_names.dormant --- dormant_state.enter(self) function state_dormant.enter(self) -- self.buildzone = self.assigned_buildzone or self:getNextBuildzone() -- if self.buildzone == nil then return self:setState(unavailable) end end --- updateState_dormant(self) function state_dormant.update(self) -- if self:hasPlayers() then return self:setState(inplay) end end --- exitState_dormant state_dormant.exit = nil --make this a function if action is needed on exiting dormant state --------------------------------------------------------------------- ------------ "INPLAY" STATE DEFINITION ------------------------------- local state_inplay = {} state_inplay.name = kew_states_names.inplay --- enterState_inplay(self) function state_inplay.enter(self) -- scatterPlayerIntoArea(queue.playerlist {has playerlist.isPlayerList}, queue.buildzone.box) -- setStateDuration = playphaselength -- queue:cleanBuildzone() -- queue:buildInitialCondition() (former prepareBuildzone()) end --- state_inplay.update(self) function state_inplay.update(self) -- updatetime() -- TODO updateVillagers(box,self.villager_code) --this function can be in another package, either players/NPCs or mcset -- if time is up then return queue:setState(gameover) -- if active players are found outside the buildzone they are tp-ed back with a message (TODO use tp Armorstand to playername to avoid glitches) -- queue:addLocationToDetectionList(getPlayersOnDetectionBlock(box)) -- do particle effects for all locations in detection list -- pop the first player in queue.detectionlist and do: -- check for match in catalogue -- if match then clone element; give reward items; update scores; do particle effect; announce in chat; saveToFile; end -- else do fail particle effect; annoucne in chat; end -- if queue:goalachieved() then return queue:setState(gameover) -- queue:dealwithhomecomers(): -- - queue:addHomecomingList(getHomecomers(only for players whose name is in .playerlist)) -- - pop the first player in queue.homecominglist and do: -- - remove from active playlist by setstate(player) to left with homecomer -- - givehomecomer -- - tp to spawn -- if playerlist only inactive players then return queue:setState(dormant) end --- state_inplay.exit(self) function state_inplay.exit(self) -- saveToFile -- saveOnline end ----------------------------------------------------------------------- ------------ "GAMEOVER" STATE DEFINITION ------------------------------ local state_gameover = {} state_gameover.name = kew_states_names.gameover --- state_gameover.enter(self) function state_gameover.enter(self) -- announce game end to all active players and that they can leave with homecomers -- cover floor with pavement end --- state_gameover.update(self) function state_gameover.update(self) -- queue:dealwithhomecomers() end --- state_gameover.exit state_gameover.exit = nil --make this a function if action is needed on exiting gameover state ----------------------------------------------------------------------- ------------ "UNAVAILABLE" STATE DEFINITION --------------------------- local state_unavailable = {} state_unavailable.name = kew_states_names.unavailable --- state_unavailable.enter state_unavailable.enter = nil --make this a function if action is needed on entering unavailable state --- state_unavailable.update state_unavailable.update = nil --make this a function if action is needed on updating unavailable state --- state_unavailable.exit state_unavailable.exit = nil --make this a function if action is needed on exiting unavailable state ----------------------------------------------------------------------- --local kew = {} --GameQueue = kew --[[ --------------------------- --- STATE FUNCTIONS --- the functions for onEnter, update and onExit for each of the 3 states --- DORMANT STATE FUNCTIONS --- local function enterState_dormant(kew) debug.log("Entering the dormant state for queue "..kew.id) kew.phase = registry.QUEUE_PHASE.DORMANT --displayTime(kew.buildzone.selector,0,0) kew.timer = kew.phases[kew.phase].length portal.drawPortal(kew.portal, kew.phase) debug.log("Dormant state for queue "..kew.id.. " - entered!") end --- local function updateState_dormant(kew) debug.log("Updating the dormant state for queue "..kew.id) --checkportal(kew.portal) -- if playerlist is not empty then kew:setstate(playing) debug.log("Dormant state for queue "..kew.id.. " - updated!") end --- local function exitState_dormant(kew) debug.log("exiting the dormant state for queue "..kew.id) -- TODO if it doesnt have an assigned buildzone it picks the next one available from game.buildzones debug.log("dormant state for queue "..kew.id.. " - exited!") end --- PLAYING STATE FUNCTIONS --- local function enterState_playing(kew) debug.log("Entering the playing state for queue "..kew.id) --displayTime(kew.buildzone.selector,0,0) kew.phase = registry.QUEUE_PHASE.PLAYING cleanBuildzone(kew.buildzone) prepareBuildzone(kew.buildzone)--prepare build zone --giveItems(kew.playerlist,registry.STARTING_ITEMS) --Starting items are given as players join now, not all at once displayTitleToPlayers(kew.playerlist,"BUILD!","Place your resources and stand on a detector block.") kew.victory = false kew.timer = kew.phases[kew.phase].length portal.drawPortal(kew.portal,kew.phase) debug.log("Playing state for queue "..kew.id.. " - entered!") end --- local function updateState_playing(kew) debug.log("Updating the playing state for queue "..kew.id) --checkportal(kew.portal) debug.log("Playing state for queue "..kew.id.. " - updated!") end --- local function exitState_playing(kew) debug.log("exiting the playing state for queue "..kew.id) processHighscores(kew) exportKewData(kew,true) -- saves the final state of the game and writes it to the online database cleanAfterGameOver(kew) debug.log("playing state for queue "..kew.id.. " - exited!") end --- GAMEOVER STATE FUNCTIONS --- local function enterState_gameover(kew) debug.log("Entering the gameover state for queue "..kew.id) kew.phase = registry.QUEUE_PHASE.GAMEOVER --displayTime(kew.buildzone.selector,0,0) kew.timer = kew.phases[kew.phase].length displayTitleToPlayers(kew.playerlist,"Times Up!","Use HOMECOMER to return to spawn") portal.drawPortal(kew.portal,kew.phase) debug.log("Gameover state for queue "..kew.id.. " - entered!") end --- local function updateState_gameover(kew) debug.log("Updating the gameover state for queue "..kew.id) debug.log("gameover state for queue "..kew.id.. " - updated!") end --- local function exitState_gameover(kew) debug.log("exiting the gameover state for queue "..kew.id) removePlayersFromKew(kew) -- debug.log("gameover state for queue "..kew.id.. " - exited!") end --]] --------------------------------------- local kew_states = {state_dormant, state_inplay, state_gameover, state_unavailable } --- Kew constructor. Enforces some data structure -- Kews are used for timekeeping and to record which players are -- interacting where. Each queue can only have 1 buildzone, but may have -- many players. Buildzones may move location, but Kews do not. -- @param buildzone The buildzone object to associate with this Kew -- @param maxplayers How many players are allowed to play in the buildzone -- @param portal A portal object created with newPortal() -- @return The constructed Kew Object local function newKew(settings, id, buildzones) -- {TODO assigned buildzone is passed with queue:new(buildzone) (we can check for object being a buildzone with bz.isBuildzone)} --debug.log("creating a new game queue for buildzone #"..buildzone.locid) debug.log("creating a new game queue") local _kew = fsm:new(kew_states)-- _kew's prototype is a state machine --modify _kew to make it a true kew _kew.name = "Kew" --assign kew object functions _kew.addPlayer = _addPlayer _kew.getNextBuildzone = _getNextBuildzone _kew.setBuildzone = _setBuildzone -- _kew.id = id _kew.assigned_buildzone = nil _kew.buildzones = buildzones --[[ handle these with setstate() q.timer = 1 q.phase = registry.QUEUE_PHASE.DORMANT q.victory = false q.phases = { { name = "Selecting Players", length = registry.PHASE_LENGTH_WAIT --displaylength = 15 --this field is not used }, { name = "Game In Progress", length = registry.PHASE_LENGTH_GAME --displaylength = 70 --this field is not used }, { name = "Round Complete", length = registry.PHASE_LENGTH_OVER --displaylength = 5 --this field is not used } } --]] --TODO reset the playerlist in onEnter_playing() _kew.playerlist = {} --needs a metatable to know how to convert to string setmetatable(_kew.playerlist, {__tostring = playerListToString}) -- TODO put this as playerlist:new() in the player package _kew.maxplayers = settings.maxplayers --_kew.portal = portal_box --TODO this needs to be set and reset in onEnter_playing() local timestamp = math.floor(os.clock()) _kew.filename = timestamp.."at".._kew.buildzone.x.."_".._kew.buildzone.z _kew:setState(_kew.states[kew_states_names.dormant]) return q end local function _getNextBuildzone(self) -- if not assigned_buildzone and queue.buildzone == nil then queue.buildzone = queue:getNextBuildzone() {checks in self.buildzones which is pointer to game.buildzones assigned in queue:new(game.buildzones) (we can check for object being a buildzonelist with bz.isBuildzoneList) } -- if queue.buildzone == nil then queue:setState(unavailable) end local function _addPlayer(self, player) -- {adds player to playlerlist; -- if portal.queue:getState() == inplay then -- scatterPlayerIntoArea(player {has player.isPlayer}, portal.queue.buildzone.box)} end --- Sets an assigned kew for a portal local function _setBuildzone(self, _buildzone) self.assigned_buildzone = _buildzone end ------------------------------------------------------------------------------------ --- PUBLIC API --------------------------------------------------------------------- ------------------------------------------------------------------------------------ ---------------------------- --- GAME QUEUE FUNCTIONS --------------------------- --- function initKews(settings) end