mirror of
https://codeberg.org/sunder/sunder.git
synced 2026-03-08 03:10:26 +00:00
141 lines
4.4 KiB
GDScript
141 lines
4.4 KiB
GDScript
# 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 <https://www.gnu.org/licenses/>.
|
|
## 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
|