Advertisement
antonsavov

WIP GameManager

Jan 10th, 2018
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.47 KB | None | 0 0
  1. -------------------------------
  2. -- /lib/GameManager -----------
  3. -------------------------------
  4. --
  5. --  A GameManager works by managing 3 entities: buildzones, portals and kews
  6. --  Buildzones are finite locations in the Minecraft world onto which players can play a game.
  7. --  Kews (an easier spelling of 'Queues') are abstract entities that manage players and their achievements in a game and keep track of what got built by who. A kew is either explicitly assigned a buildzone or is dynamically linked to one from a buildzoneList.
  8. --  Portals are finite locations in the Minecraft world where players step into to start or join a game. A portal is either explicitly assigned a kew or is dynamically linked to one from its portal.kews list
  9. --
  10. -- GameManager is a state machine with two states: normal; full
  11. -- Kews are state machines with four states: dormant, inplay, gameover; unavailable
  12. -- Portals are state machines with three states: start, join, closed
  13. --
  14. --  The scenarios that are supported are:
  15. --
  16. --  1. N buildzones, one portal, K kews - IBAGAME style (a subset scenario of scenario 5.)
  17. --      if kews in "inplay" state <= maxgames and at least one kew has less players than maxplayers, portal is in state "start"
  18. --      if player enters the portal they are moved to the currently running game if there is space(controlled with maxplayers) or to a new game on the next available buildzone,
  19. --      if maxgames is reached, portal is "closed",
  20. --      if no more buildzones are available then portal is "closed" until all kews go to "unavailable", then increase city version and make all zones available again.
  21. --
  22. --  2. N buildzones, K portals, K kews
  23. --      the portals are assigned a kew each with portal:setKew(kew)
  24. --      If kew is "dormant" and Buildzones are available portal is in "start",
  25. --      if kew is "inplay" portal is in "join",
  26. --      if kew is "gameover", portal is in "closed".
  27. --      If kew is "dormant" and Buildzones are NOT available portal is "closed",
  28. --      If player enters portal and kew is "dormant" then find the next available buildzone and play there.
  29. --      If no more buildzones are available then all portals
  30. --          (except those with kews in "inplay" state and players < maxplayers ) are "closed"
  31. --          until all kews go to "unavailable", then increase city version and make all zones available again.
  32. --      If player enters portal and kew is playing add player to kew.
  33. --
  34. --  3. K buildzones, K portals, K kews - what we have now in 2.7.0
  35. --      the portals are assigned a kew each with portal:setKew(kew)
  36. --      and the kews are assigned a buildzone each with kew:setBuildzone(buildzone)
  37. --      If kew is "dormant" portal is "start",
  38. --      if kew is "inplay" portal is "join",
  39. --      if kew is "gameover" or ("inplay" and full), portal is "closed".
  40. --      If player enters portal and kew is "dormant" then clean up buildzone and play there.
  41. --      If player enters portal and kew is "inplay" and not full add player to kew.
  42. --
  43. --  4. one buildzone, one portal, one kew - like the debug mode of IBAGAME (a subset of scenario 3.)
  44. --      if player enters portal they are tp-ed to zone if kew is "dormant" or "inplay" with less than maxplayers.
  45. --      if kew is in "inplay" state portal is in "join" state.
  46. --      if max players on the assigned_kew is reached or while kew is in "gameover" state the portal is "closed".
  47. --      if player is first to join, buildzone is cleaned up
  48. --
  49. --  5. K buildzones, L portals, M kews - the general case, probably doesn't make sense to run the game like this but it is supported
  50. --      if kews in "inplay" state <= maxgames and at least one kew has less players than maxplayers, all portals are in state "start"
  51. --      if player enters any portal all kews are checked one after the other if they can take the player: the first kew in "dormant" state or in ("inplay" with less than maxplayers) is chosen
  52. --      if all kews' states are ("inplay" and full) or "gameover" then all portals are "closed" until at least one kew is in "dormant"
  53. --      if at least one kew is in "unavailable" then all portals are "closed" until all kews go to unavailable, then increase city version and make all zones available again.
  54. --
  55. -------------------------------------------------------------------------------------------------------------------
  56. --
  57. --  the GameManager is a state machine with states: normal; full
  58.  
  59. local gm_states_names = {
  60.     normal  = "normal",
  61.     full    = "full"
  62. }
  63.  
  64. ----------------------------------------------------------------------
  65. ------------ "NORMAL" STATE FUNCTIONS --------------------------------
  66.  
  67. local state_normal = {}
  68.  
  69. state_normal.name = gm_states_names.normal
  70.  
  71. --- enterState_normal(self)
  72. function state_normal.enter(self)
  73.     -- large portion of setup is now here
  74.     -- read version and buildzone availability from _buildzones.json file and make the buildzone objects
  75.     -- game:initportals() which creates all portals and sets them to start state
  76.     -- set all queues to dormant
  77. end
  78.  
  79. --- updateState_normal(self)
  80. function state_normal.update(self)
  81.     -- update portals
  82.     -- update queues
  83.     -- check for lost players and tp them to spawnarea
  84.     -- if at least one queue is in "unavailable" state (use table.reduce with queue:isUnavailable() to check that) then
  85.     --      return game:setState(game.states.full)
  86. end
  87.  
  88. --- exitState_normal = nil
  89. state_normal.exit = nil --turn to function if action is needed on exiting normal state
  90.  
  91. --------------------------------------------------------------------
  92. ------------ "FULL" STATE FUNCTIONS --------------------------------
  93.  
  94. local state_full = {}
  95.  
  96. state_full.name = gm_states_names.full
  97.  
  98. --- enterState_full = nil
  99. state_full.enter = nil --turn to function if action is needed on entering the full state
  100.  
  101. ---updateState_full(self)
  102. function state_full.update(self)
  103.     -- update portals
  104.     -- update all queues
  105.     -- check for lost players and tp them to spawnarea
  106.     -- if all queues are "unavailable" then return game:setState(game.states.normal)
  107. end
  108.  
  109. --- exitState_full(self)
  110. function state_full.exit(self)
  111.     -- increase version
  112.     -- reset zone availability by rewriting _buildzones.json file with all zones available
  113. end
  114.  
  115. --------------------------------------------------------------------
  116.  
  117. -------------------------------
  118. --- PRIVATE FUNCTIONS ---------
  119. -------------------------------
  120.  
  121. local gm_states = {state_normal, state_full}
  122.  
  123.  
  124. --- Builds the spawn area space in Minecraft
  125. -- TODO remove the dependencies on "registry."
  126. -- TODO move that to another package
  127. local function drawSpawnZone(settings, _box)
  128.     debug.log("Building spawn area in Minecraft...")
  129.     local spawn_plinth = box( _box.corner_x, _box.corner_y, _box.corner_z, _box.sizeX, -_box.sizeY, _box.sizeZ)
  130.     --fill the trench around the catalogue area with air
  131.     mcset.fillBox( box_offset( box_top_layers(spawn_plinth, settings.trenches.DEPTH), settings.trenches.WIDTH, 0, settings.trenches.WIDTH), registry.BLOCKS.AIR )
  132.     --fill the plinth of the catalogue area with dark grid blocks
  133.     mcset.fillBox( spawn_plinth, registry.BLOCKS.DARK_GRID )
  134.     --place the grid markers with White Grid
  135.     mcset.fillGrid( box_top_layers(spawn_plinth, 1), settings.computer.x, settings.computer.y, settings.computer.z, settings.grid_cell_size, registry.BLOCKS.WHITE_GRID )  
  136.     --fill the glass border
  137.     mcset.fillRing( _box, registry.BLOCKS.SPAWNZONE_FENCE )
  138.     debug.log("Spawn area created in Minecraft!")
  139. end
  140.  
  141. function checkGameSettings( settings )
  142.     debug.log("checking game settings...")
  143.     --local result = true
  144.     local s = settings
  145.     local msg = ""
  146.    
  147.     -- grid_cell_size
  148.     msg = "The grid cell size is set to"..s.grid_cell_size.." but must be an odd number between 3 and 15"
  149.     assert( s.grid_cell_size < 3, msg)
  150.     assert( s.grid_cell_size > 15, msg)
  151.     assert( s.grid_cell_size % 2 == 0, msg)
  152.    
  153.     -- grid_cell_count
  154.     msg = "The grid cell count is set to"..s.grid_cell_count.." but must be between 5 and 20"
  155.     assert( s.grid_cell_count < 5, msg)
  156.     assert( s.grid_cell_count > 20, msg)
  157.    
  158.     -- spawnzone_size
  159.     msg = "The spawn zone size is set to"..s.spawnzone_size.." but must be 39"
  160.     assert( s.spawnzone_size == 39, msg)
  161.    
  162.    
  163.     -- check the PLAY_AREA_OFFSET.z is bigger than the CATALOGUE_SLOT_OFFSET to avoid destrying the computer from the world
  164.     msg = "'play_area_offset.x' and 'play_area_offset.z' must be bigger with at least 1 than the 'catalogue_slot_offset' otherwise the main computer it will be destroyed"
  165.     assert( s.play_area_offset.x - s.catalogue_slot_offset < 1, msg)
  166.     assert( s.play_area_offset.z - s.catalogue_slot_offset < 1, msg)
  167.    
  168.     -- catalofue_slot_size
  169.     msg = "'catalofue_slot_size.x' is set to"..s.catalofue_slot_size.x.." but must be 1 or 3"  
  170.     assert( s.catalofue_slot_size.x == 1 or s.catalofue_slot_size.x == 3, msg)
  171.     msg = "'catalofue_slot_size.z' is set to"..s.catalofue_slot_size.z.." but must be 1 or 3"  
  172.     assert( s.catalofue_slot_size.z == 1 or s.catalofue_slot_size.z == 3, msg)
  173.        
  174.     debug.log("Game settings OK!")
  175. end
  176.  
  177. -------------------------------
  178. --- PUBLIC API ----------------
  179. -------------------------------
  180.  
  181. function newGameManager()
  182.     local game = fsm:new(gm_states)
  183.     game.name = "Game Manager"
  184.     --game.setttings = nil --getSettings()
  185.     --game.elements = {} --moved to a local variable to avoid recursive containment in the "game" table
  186.     --game.builds = {} --moved to a local variable to avoid recursive containment in the "game" table
  187.     game.queues = {}
  188.     --game.waitlist = {}
  189.     --game.spawn = registry.SPAWN
  190.     game.lastClock = os.clock()
  191.     game.nowTime = os.clock()
  192.     game:setState(game.states[gm_states_names.normal])
  193.     return game
  194. end
  195.  
  196. function drawGameWorld(game)
  197.     drawSpawnZone(game.settings, game.spawnzone_box)
  198. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement