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:
2026-07-02 10:09:28 -04:00
parent ad48f38ca5
commit 4a5264c5b0
14 changed files with 202 additions and 284 deletions
+19 -16
View File
@@ -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 ""