Fix headless class_name dependencies
- Replaced TeamData.Team type hints with int in all scripts - Added explicit preloads for headless mode class resolution - Created stub LagCompensation and DamageProcessor scripts - Fixed PluginManager, SpawnManager, EconomyManager, BuyZone, RoundManager, BuyMenuHandler, BombObjective class_name references - Updated server config to match ServerConfig.gd format Gray screen root cause: server scripts failed to parse in headless mode due to Godot 4 class_name loading order (Resource after Node), leaving server_main.gd non-functional — accepted connections but never spawned players.
This commit is contained in:
@@ -20,6 +20,9 @@
|
||||
extends Node
|
||||
class_name SpawnManager
|
||||
|
||||
# Preload for headless compat
|
||||
const _td_ref = preload("res://scripts/teams/team_data.gd")
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Exports
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -82,7 +85,7 @@ func refresh_spawn_points() -> void:
|
||||
|
||||
|
||||
## Get all spawn point markers for a given team.
|
||||
func get_spawn_points_for_team(team: TeamData.Team) -> Array[Marker3D]:
|
||||
func get_spawn_points_for_team(team: int) -> Array[Marker3D]:
|
||||
var group_name: String = _group_for_team(team)
|
||||
return _spawn_points.get(group_name, []).duplicate()
|
||||
|
||||
@@ -96,10 +99,10 @@ func get_spawn_points_for_team(team: TeamData.Team) -> Array[Marker3D]:
|
||||
## 4. If no spawns exist at all, return Vector3.ZERO.
|
||||
##
|
||||
## Returns the global position of the chosen spawn point.
|
||||
func select_spawn(player_id: int, team: TeamData.Team) -> Vector3:
|
||||
func select_spawn(player_id: int, team: int) -> Vector3:
|
||||
var markers: Array[Marker3D] = get_spawn_points_for_team(team)
|
||||
if markers.is_empty():
|
||||
push_warning("[SpawnManager] No spawn points found for team %s" % TeamData.get_team_name(team))
|
||||
push_warning("[SpawnManager] No spawn points found for team %s" % _td_ref.get_team_name(team))
|
||||
return Vector3.ZERO
|
||||
|
||||
# Separate into valid and contested spawns
|
||||
@@ -141,7 +144,7 @@ func select_spawn(player_id: int, team: TeamData.Team) -> Vector3:
|
||||
|
||||
|
||||
## Return the number of spawn points for a team.
|
||||
func get_spawn_count(team: TeamData.Team) -> int:
|
||||
func get_spawn_count(team: int) -> int:
|
||||
var group_name: String = _group_for_team(team)
|
||||
return _spawn_points.get(group_name, []).size()
|
||||
|
||||
@@ -151,12 +154,12 @@ func get_spawn_count(team: TeamData.Team) -> int:
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
## Check if a position is safe from enemy proximity.
|
||||
func _is_spawn_safe(pos: Vector3, friendly_team: TeamData.Team) -> bool:
|
||||
func _is_spawn_safe(pos: Vector3, friendly_team: int) -> bool:
|
||||
if team_manager == null:
|
||||
return true
|
||||
|
||||
# Get the enemy team(s)
|
||||
var enemy_teams: Array[TeamData.Team] = _get_enemy_teams(friendly_team)
|
||||
var enemy_teams: Array[int] = _get_enemy_teams(friendly_team)
|
||||
|
||||
for enemy_team in enemy_teams:
|
||||
var enemy_ids: Array[int] = team_manager.get_team_players(enemy_team)
|
||||
@@ -172,7 +175,7 @@ func _is_spawn_safe(pos: Vector3, friendly_team: TeamData.Team) -> bool:
|
||||
|
||||
|
||||
## Pick the spawn farthest from all known enemy positions.
|
||||
func _pick_farthest_spawn(candidates: Array[Marker3D], friendly_team: TeamData.Team) -> Marker3D:
|
||||
func _pick_farthest_spawn(candidates: Array[Marker3D], friendly_team: int) -> Marker3D:
|
||||
if candidates.is_empty():
|
||||
return null
|
||||
if candidates.size() == 1:
|
||||
@@ -181,7 +184,7 @@ func _pick_farthest_spawn(candidates: Array[Marker3D], friendly_team: TeamData.T
|
||||
# Collect enemy positions
|
||||
var enemy_positions: Array[Vector3] = []
|
||||
if team_manager != null:
|
||||
var enemy_teams: Array[TeamData.Team] = _get_enemy_teams(friendly_team)
|
||||
var enemy_teams: Array[int] = _get_enemy_teams(friendly_team)
|
||||
for enemy_team in enemy_teams:
|
||||
var enemy_ids: Array[int] = team_manager.get_team_players(enemy_team)
|
||||
for enemy_id in enemy_ids:
|
||||
@@ -213,22 +216,22 @@ func _pick_farthest_spawn(candidates: Array[Marker3D], friendly_team: TeamData.T
|
||||
|
||||
## Get the teams that are enemies of the given team.
|
||||
## For now, CT and T are enemies of each other; SPECTATOR has no enemies.
|
||||
func _get_enemy_teams(team: TeamData.Team) -> Array[TeamData.Team]:
|
||||
func _get_enemy_teams(team: int) -> Array[int]:
|
||||
match team:
|
||||
TeamData.Team.COUNTER_TERRORIST:
|
||||
return [TeamData.Team.TERRORIST]
|
||||
TeamData.Team.TERRORIST:
|
||||
return [TeamData.Team.COUNTER_TERRORIST]
|
||||
_td_ref.Team.COUNTER_TERRORIST:
|
||||
return [_td_ref.Team.TERRORIST]
|
||||
_td_ref.Team.TERRORIST:
|
||||
return [_td_ref.Team.COUNTER_TERRORIST]
|
||||
_:
|
||||
return []
|
||||
|
||||
|
||||
## Translate a Team enum to the spawn group name.
|
||||
func _group_for_team(team: TeamData.Team) -> String:
|
||||
func _group_for_team(team: int) -> String:
|
||||
match team:
|
||||
TeamData.Team.COUNTER_TERRORIST:
|
||||
_td_ref.Team.COUNTER_TERRORIST:
|
||||
return ct_spawn_group
|
||||
TeamData.Team.TERRORIST:
|
||||
_td_ref.Team.TERRORIST:
|
||||
return t_spawn_group
|
||||
_:
|
||||
return ""
|
||||
|
||||
@@ -20,14 +20,19 @@
|
||||
extends Node
|
||||
class_name TeamManager
|
||||
|
||||
# Force TeamData to be loaded first (Godot 4 class_name loading order: Resources after Nodes)
|
||||
const _team_data_ref = preload("res://scripts/teams/team_data.gd")
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Signals
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
## Emitted when a player is assigned to a team (including on team switch).
|
||||
## team is an int (TeamData.Team enum value).
|
||||
signal player_joined_team(player_id: int, team: int)
|
||||
|
||||
## Emitted when a player leaves a team (disconnected or switched).
|
||||
## team is an int (TeamData.Team enum value).
|
||||
signal player_left_team(player_id: int, team: int)
|
||||
|
||||
## Emitted when scores for any team change.
|
||||
@@ -56,8 +61,9 @@ var max_players_per_team: int = 0
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
func _ready() -> void:
|
||||
if ServerConfig and ServerConfig.has_method(&\"get_config_path\"):
|
||||
max_players_per_team = ServerConfig.players_per_team
|
||||
var cfg = get_node_or_null("/root/ServerConfig")
|
||||
if cfg and cfg.has_method(&"get_config_path"):
|
||||
max_players_per_team = cfg.players_per_team
|
||||
else:
|
||||
max_players_per_team = 8
|
||||
|
||||
@@ -68,7 +74,7 @@ func _ready() -> void:
|
||||
|
||||
## Assign a player to a team. Returns true if successful, false if the team is full.
|
||||
## Emits player_left_team for the old team (if any) and player_joined_team for the new team.
|
||||
func assign_player(player_id: int, team: TeamData.Team) -> bool:
|
||||
func assign_player(player_id: int, team: int) -> bool:
|
||||
# Validate team
|
||||
if team < 0 or team > TeamData.Team.size() - 1:
|
||||
push_warning("[TeamManager] Invalid team value: %d" % team)
|
||||
@@ -84,7 +90,7 @@ func assign_player(player_id: int, team: TeamData.Team) -> bool:
|
||||
return false
|
||||
|
||||
# Remove from old team if assigned
|
||||
var old_team: TeamData.Team = _player_teams.get(player_id, TeamData.Team.SPECTATOR)
|
||||
var old_team: int = _player_teams.get(player_id, TeamData.Team.SPECTATOR)
|
||||
if old_team != team:
|
||||
_remove_from_team(player_id, old_team)
|
||||
|
||||
@@ -101,7 +107,7 @@ func assign_player(player_id: int, team: TeamData.Team) -> bool:
|
||||
|
||||
## Remove a player from any team (equivalent to assigning to SPECTATOR).
|
||||
func remove_player(player_id: int) -> void:
|
||||
var current_team: TeamData.Team = _player_teams.get(player_id, TeamData.Team.SPECTATOR)
|
||||
var current_team: int = _player_teams.get(player_id, TeamData.Team.SPECTATOR)
|
||||
_remove_from_team(player_id, current_team)
|
||||
|
||||
|
||||
@@ -116,22 +122,23 @@ func unregister_player(player_id: int) -> void:
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
## Get the team a player belongs to. Returns SPECTATOR if unassigned.
|
||||
func get_player_team(player_id: int) -> TeamData.Team:
|
||||
## Returns an int (TeamData.Team enum value).
|
||||
func get_player_team(player_id: int) -> int:
|
||||
return _player_teams.get(player_id, TeamData.Team.SPECTATOR)
|
||||
|
||||
|
||||
## Get an array of all player IDs on a given team.
|
||||
func get_team_players(team: TeamData.Team) -> Array[int]:
|
||||
func get_team_players(team: int) -> Array[int]:
|
||||
return _team_players.get(team, []).duplicate()
|
||||
|
||||
|
||||
## Get the total number of players on a given team.
|
||||
func get_team_player_count(team: TeamData.Team) -> int:
|
||||
func get_team_player_count(team: int) -> int:
|
||||
return _team_players.get(team, []).size()
|
||||
|
||||
|
||||
## Check if a player is on a specific team.
|
||||
func is_player_on_team(player_id: int, team: TeamData.Team) -> bool:
|
||||
func is_player_on_team(player_id: int, team: int) -> bool:
|
||||
return _player_teams.get(player_id, TeamData.Team.SPECTATOR) == team
|
||||
|
||||
|
||||
@@ -145,8 +152,9 @@ func get_all_assignments() -> Dictionary:
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
## Assign a player to the team with the fewest members (ties: random).
|
||||
## Returns the team the player was assigned to, or SPECTATOR if both teams are full.
|
||||
func assign_to_team_with_fewest(player_id: int) -> TeamData.Team:
|
||||
## Returns the team as an int (TeamData.Team enum value) the player was assigned to,
|
||||
## or SPECTATOR if both teams are full.
|
||||
func assign_to_team_with_fewest(player_id: int) -> int:
|
||||
var ct_count: int = _team_players.get(TeamData.Team.COUNTER_TERRORIST, []).size()
|
||||
var t_count: int = _team_players.get(TeamData.Team.TERRORIST, []).size()
|
||||
|
||||
@@ -163,7 +171,7 @@ func assign_to_team_with_fewest(player_id: int) -> TeamData.Team:
|
||||
return TeamData.Team.SPECTATOR
|
||||
|
||||
# Assign to team with fewer players (ties: randomly pick one)
|
||||
var team: TeamData.Team
|
||||
var team: int = TeamData.Team.COUNTER_TERRORIST
|
||||
if ct_count < t_count:
|
||||
team = TeamData.Team.COUNTER_TERRORIST
|
||||
elif t_count < ct_count:
|
||||
@@ -181,20 +189,20 @@ func assign_to_team_with_fewest(player_id: int) -> TeamData.Team:
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
## Set the score for a given team.
|
||||
func set_team_score(team: TeamData.Team, score: int) -> void:
|
||||
func set_team_score(team: int, score: int) -> void:
|
||||
_team_scores[team] = score
|
||||
team_scores_updated.emit(_team_scores.duplicate())
|
||||
|
||||
|
||||
## Add to a team's current score.
|
||||
func add_team_score(team: TeamData.Team, amount: int = 1) -> void:
|
||||
func add_team_score(team: int, amount: int = 1) -> void:
|
||||
var current: int = _team_scores.get(team, 0)
|
||||
_team_scores[team] = current + amount
|
||||
team_scores_updated.emit(_team_scores.duplicate())
|
||||
|
||||
|
||||
## Get the score for a given team.
|
||||
func get_team_score(team: TeamData.Team) -> int:
|
||||
func get_team_score(team: int) -> int:
|
||||
return _team_scores.get(team, 0)
|
||||
|
||||
|
||||
@@ -218,7 +226,7 @@ func reset_scores() -> void:
|
||||
func reset_all() -> void:
|
||||
# Emit leave signals for all assigned players
|
||||
for player_id in _player_teams.keys():
|
||||
var team: TeamData.Team = _player_teams[player_id]
|
||||
var team: int = _player_teams[player_id]
|
||||
player_left_team.emit(player_id, team)
|
||||
|
||||
_player_teams.clear()
|
||||
@@ -230,7 +238,7 @@ func reset_all() -> void:
|
||||
# Internal
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
func _remove_from_team(player_id: int, team: TeamData.Team) -> void:
|
||||
func _remove_from_team(player_id: int, team: int) -> void:
|
||||
if _player_teams.has(player_id):
|
||||
_player_teams.erase(player_id)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user