# This file is part of sunder. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . ## This class defines a Teams manager class_name Teams extends Resource ## Emitted when a [Team] is created. signal team_added(team_name : String) ## Emitted when a [Team] is removed. signal team_erased(team_name : String) ## Emitted when a [Player] is added to a [Team]. signal player_added(team_name: String, peer_id: int, username: String) ## Emitted when a [Player] is removed from a [Team]. signal player_erased(team_name: String, peer_id: int) # The synced teams state. @export var _state : Dictionary = {}: get = get_state func get_state() -> Dictionary: for team : Team in _teams.values(): _state[team.name] = team.players return _state # The internal dictionary of teams. var _teams : Dictionary = {} ## Retrieves an [Array] of [int] by [param team_name]. ## [codeblock] ## var teams := Teams.new() ## teams.add_team("Phoenix") ## print(teams["Phoenix"]) # this calls `_get` ## [/codeblock] func _get(team_name : StringName) -> Variant: return _teams.get(team_name) ## Sets a [Team] by [param name] with an optional [param default]. ## [codeblock] ## var teams := Teams.new() ## teams["Phoenix"] = Teams.Team.new("Phoenix") # this calls `_set` ## teams["Phoenix"] = null # refcount for Team is now 0 ## [/codeblock] func _set(key : StringName, team : Variant) -> bool: if team == null: return erase(key) if team is Team: _teams[key] = team team_added.emit(key) return true return false ## This method retrieves the array of managed [Team] names. func keys() -> Array: return _teams.keys() ## This method retrieves the array of managed [Team]. func values() -> Array: return _teams.values() # This is the iterator index cursor. var _iter_cursor : int = 0 # This method is an iterator initializer. func _iter_init(_arg : Variant) -> bool: _iter_cursor = 0 # reset return _iter_cursor < len(_teams) # This method checks if the iterator has a next value. func _iter_next(_arg : Variant) -> bool: _iter_cursor += 1 return _iter_cursor < len(_teams) # This method gets the next iterator value. func _iter_get(_arg : Variant) -> Team: return _teams.values()[_iter_cursor] ## This method adds a new [Team] into the manager. func add_team(key: String) -> bool: if not _teams.has(key): var team : Team = Team.new(key) team.player_added.connect(_on_team_player_added) team.player_erased.connect(_on_team_player_erased) return _set(key, team) return false ## This method adds new [Team] in batch from [param team_names]. func add_teams(team_names: Array[String]) -> Teams: for team_name in team_names: add_team(team_name) return self func get_peer_team(peer_id : int) -> Team: for team : Team in _teams.values(): if peer_id in team.players: return team return null func erase(team_name: String) -> bool: var res: bool = _teams.erase(team_name) if res: team_erased.emit(team_name) return res func erase_player(peer_id: int) -> void: for team : Team in _teams.values(): if team.erase(peer_id): break ## The number of [Team]. func size() -> int: return len(_teams) ## This method eases peer team switching by moving them to the specified [param team_name]. ## It does not do anything if the peer is not already added to a [Team], see [method Team.add]. func switch_team(peer_id: int, team_name: String) -> void: var lhs:Team = get_peer_team(peer_id) var rhs:Team = _get(team_name) if lhs and rhs: rhs.add(peer_id, lhs.pop(peer_id)) # This method runs when a Team emits `player_added` signal func _on_team_player_added(team_name: String, peer_id: int, username: String) -> void: player_added.emit(team_name, peer_id, username) # emit manager signal # This method runs when a Team emits `player_erased` signal func _on_team_player_erased(team_name: String, peer_id: int) -> void: player_erased.emit(team_name, peer_id) # emit manager signal