Class: LZRTag::Handler::Game
- Defined in:
- lib/lzrtag/handler/game_handler.rb
Overview
Game handler class, managing game registration and game ticks. This class manages the lifecycle of any lasertag game started in it. This includes sending a gameTick, managing phase and game state transitions, sending out but also receiving information on the game state via MQTT, etc.
Instance Attribute Summary collapse
-
#currentGame ⇒ Object
readonly
Returns the instance of the currently active game, or nil if none is present.
-
#gamePhase ⇒ Object
currently active game phase When set it will start a phase change, sending :gamePhaseEnds and :gamePhaseStarts events.
-
#gamePlayers ⇒ Object
List of in-game players.
Attributes inherited from Count
Attributes inherited from Base
Instance Method Summary collapse
- #consume_event(event, data) ⇒ Object
-
#each_participating ⇒ Object
Yield for each currently in-game player.
-
#get_allowed_phases ⇒ Object
Returns an Array<Symbol> of the currently allowed phases of this game.
-
#in_game?(player) ⇒ Boolean
Check if a player is currently in game.
-
#initialize(*data, **argHash) ⇒ Game
constructor
A new instance of Game.
-
#register_game(gameTag, game) ⇒ Object
Register a game by a tag.
-
#set_phase(nextPhase) ⇒ Object
Tries to change the current phase.
-
#start_game(game = @lastGame) ⇒ Object
Starts a given new game (or the last one).
-
#stop_game ⇒ Object
Stops the currently running game.
Methods inherited from HitArb
#_handle_hitArb, #process_raw_hit
Methods inherited from Base
#[], #add_hook, #each, #num_connected, #remove_hook, #send_event
Constructor Details
#initialize(*data, **argHash) ⇒ Game
Returns a new instance of Game.
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 |
# File 'lib/lzrtag/handler/game_handler.rb', line 45 def initialize(*data, **argHash) super(*data, **argHash) @lastTick = Time.now(); @lastGame = nil; @currentGame = nil; @nextGame = nil; @gamePhase = :idle; @gamePlayers = Array.new(); @knownGames = Hash.new(); _start_game_thread(); @mqtt.subscribe_to "Lasertag/Game/Controls/+" do |data, topics| case topics[0] when "SetPhase" phase = data.to_sym; if(get_allowed_phases().include? phase) set_phase(phase); end when "SetGame" if(@knownGames[data]) start_game(@knownGames[data]) elsif(data == "STOP") stop_game(); end end end clean_game_topics(); at_exit { clean_game_topics(); } end |
Instance Attribute Details
#currentGame ⇒ Object (readonly)
Returns the instance of the currently active game, or nil if none is present
28 29 30 |
# File 'lib/lzrtag/handler/game_handler.rb', line 28 def currentGame @currentGame end |
#gamePhase ⇒ Object
currently active game phase When set it will start a phase change, sending :gamePhaseEnds and :gamePhaseStarts events
35 36 37 |
# File 'lib/lzrtag/handler/game_handler.rb', line 35 def gamePhase @gamePhase end |
#gamePlayers ⇒ Object
List of in-game players. This list is mainly to keep track of which players the game is acting upon, but updating it will also send a list of player ID Strings to MQTT (Lasertag/Game/ParticipatingPlayers), and will send :playerEnteredGame and :playerLeftGame events
43 44 45 |
# File 'lib/lzrtag/handler/game_handler.rb', line 43 def gamePlayers @gamePlayers end |
Instance Method Details
#consume_event(event, data) ⇒ Object
135 136 137 138 139 140 |
# File 'lib/lzrtag/handler/game_handler.rb', line 135 def consume_event(event, data) super(event, data) return unless @currentGame @currentGame.consume_event(event, data); end |
#each_participating ⇒ Object
Yield for each currently in-game player
246 247 248 249 250 |
# File 'lib/lzrtag/handler/game_handler.rb', line 246 def each_participating() @gamePlayers.each do |pl| yield(pl) end end |
#get_allowed_phases ⇒ Object
Returns an Array<Symbol> of the currently allowed phases of this game. This list can also be retrieved via MQTT, under Lasertag/Game/CurrentGame
184 185 186 187 188 189 190 191 |
# File 'lib/lzrtag/handler/game_handler.rb', line 184 def get_allowed_phases() allowedPhases = [:idle] if(@currentGame) allowedPhases = [allowedPhases, @currentGame.phases].flatten end return allowedPhases; end |
#in_game?(player) ⇒ Boolean
Check if a player is currently in game
253 254 255 |
# File 'lib/lzrtag/handler/game_handler.rb', line 253 def in_game?(player) return @gamePlayers.include? player end |
#register_game(gameTag, game) ⇒ Object
Register a game by a tag. This function will register a given LZRTag::Game::Base class under a given string tag. This tag can then be used to, via MQTT, start the game, and is also used to give players a cleartext game name. A list of games is published to Lasertag/Game/KnownGames
125 126 127 128 129 130 131 132 |
# File 'lib/lzrtag/handler/game_handler.rb', line 125 def register_game(gameTag, game) raise ArgumentError, "Game Tag must be a string!" unless gameTag.is_a? String raise ArgumentError, "Game must be a LZRTag::Game class" unless game <= LZRTag::Game::Base @knownGames[gameTag] = game; @mqtt.publish_to "Lasertag/Game/KnownGames", @knownGames.keys.to_json, retain: true; end |
#set_phase(nextPhase) ⇒ Object
Tries to change the current phase. This function will set the current phase to nextPhase, if it is an allowed one. However, if nextPhase does not belong to the list of allowed phases, and error is raised. The :gamePhaseEnds and :gamePhaseStarts events are triggered properly. This function can be called from any context, not just inside the game code itself.
200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/lzrtag/handler/game_handler.rb', line 200 def set_phase(nextPhase) allowedPhases = get_allowed_phases(); raise ArgumentError, "Phase must be valid!" unless allowedPhases.include? nextPhase puts "Phase started: #{nextPhase}!".green; oldPhase = @gamePhase send_event(:gamePhaseEnds, oldPhase, nextPhase) @mqtt.publish_to "Lasertag/Game/Phase/Current", @gamePhase.to_s, retain: true @gamePhase = nextPhase; send_event(:gamePhaseStarts, nextPhase, oldPhase); end |
#start_game(game = @lastGame) ⇒ Object
Starts a given new game (or the last one). This function will take either a String (as registered with register_game), or a LZRTag::Game::Base class, instantiate it, and start it. If no fitting game was found, the game is instead stopped.
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/lzrtag/handler/game_handler.rb', line 147 def start_game(game = @lastGame) @lastGame = game; if(game.is_a? String and gClass = @knownGames[game]) game = gClass; elsif(game.is_a? String) stop_game(); return; end if(gKey = @knownGames.key(game)) @mqtt.publish_to "Lasertag/Game/CurrentGame", gKey, retain: true puts "Starting game #{gKey}!".green else @mqtt.publish_to "Lasertag/Game/CurrentGame", "", retain: true end game = game.new(self) if game.is_a? Class and game <= LZRTag::Game::Base; unless(game.is_a? LZRTag::Game::Base) raise ArgumentError, "Game class needs to be specified!" end @nextGame = game; send_event(:gameStarting, @nextGame); @gameTickThread.run(); @mqtt.publish_to "Lasertag/Game/Phase/Valid", get_allowed_phases.to_json(), retain: true end |
#stop_game ⇒ Object
Stops the currently running game.
177 178 179 180 |
# File 'lib/lzrtag/handler/game_handler.rb', line 177 def stop_game() @nextGame = nil; @mqtt.publish_to "Lasertag/Game/CurrentGame", "", retain: true end |