feat: Initialize core game scene, managers, UI, multiplayer spawning, message bar, and pre-game countdown.
This commit is contained in:
+49
-17
@@ -246,6 +246,47 @@ func add_message_to_bar(player_name: String, message: String, type: int = Messag
|
||||
func broadcast_message(player_name: String, message: String):
|
||||
add_message_to_bar(player_name, message)
|
||||
|
||||
func _start_pre_game_countdown():
|
||||
"""Show a 3-second countdown on all clients before starting."""
|
||||
for i in range(3, 0, -1):
|
||||
if can_rpc():
|
||||
rpc("sync_countdown", str(i))
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
|
||||
if can_rpc():
|
||||
rpc("sync_countdown", "GO!")
|
||||
await get_tree().create_timer(0.5).timeout
|
||||
|
||||
if can_rpc():
|
||||
rpc("sync_countdown", "")
|
||||
|
||||
@rpc("call_local", "reliable")
|
||||
func sync_countdown(text: String):
|
||||
var label = get_node_or_null("CountdownLabel")
|
||||
if not label and text != "":
|
||||
label = Label.new()
|
||||
label.name = "CountdownLabel"
|
||||
add_child(label)
|
||||
|
||||
# Center and Style
|
||||
label.anchors_preset = Control.PRESET_CENTER
|
||||
label.set_anchors_and_offsets_preset(Control.PRESET_CENTER)
|
||||
label.grow_horizontal = Control.GROW_DIRECTION_BOTH
|
||||
label.grow_vertical = Control.GROW_DIRECTION_BOTH
|
||||
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
|
||||
label.add_theme_font_size_override("font_size", 120)
|
||||
label.add_theme_color_override("font_outline_color", Color.BLACK)
|
||||
label.add_theme_constant_override("outline_size", 12)
|
||||
label.add_theme_color_override("font_color", Color.YELLOW)
|
||||
|
||||
if label:
|
||||
label.text = text
|
||||
if text == "":
|
||||
label.queue_free()
|
||||
elif text == "GO!":
|
||||
label.add_theme_color_override("font_color", Color.GREEN)
|
||||
|
||||
func _setup_global_match_timer_ui():
|
||||
"""Create the global match timer display at the top of the screen."""
|
||||
@@ -549,6 +590,9 @@ func _start_game():
|
||||
# This safely sends RPCs over the completed socket connection
|
||||
_assign_random_spawn_positions()
|
||||
|
||||
# PRE-GAME COUNTDOWN (3s)
|
||||
await _start_pre_game_countdown()
|
||||
|
||||
GameStateManager.start_game()
|
||||
if can_rpc():
|
||||
rpc("sync_game_start", GameStateManager.players, TurnManager.turn_based_mode)
|
||||
@@ -695,26 +739,14 @@ func _assign_random_spawn_positions():
|
||||
|
||||
func _assign_stop_n_go_spawn_positions(all_players: Array):
|
||||
"""Assigns spawns to the far left columns (Start Line) for Stop N Go mode."""
|
||||
var enhanced_gridmap = $EnhancedGridMap
|
||||
var valid_spawns = []
|
||||
|
||||
# Find all walkable tiles in the ONLY first column (x = 0)
|
||||
for x in range(1):
|
||||
for z in range(enhanced_gridmap.rows):
|
||||
var ground = enhanced_gridmap.get_cell_item(Vector3i(x, 0, z))
|
||||
if ground == 0 or ground == 2 or ground == 6: # Walkable, Start Line, or Safe Zone
|
||||
valid_spawns.append(Vector2i(x, z))
|
||||
|
||||
valid_spawns.shuffle()
|
||||
|
||||
# Sort players for deterministic assignment
|
||||
# Sort players for deterministic assignment based on ID
|
||||
all_players.sort_custom(func(a, b): return a.name.to_int() < b.name.to_int())
|
||||
|
||||
var spawn_index = 0
|
||||
for player in all_players:
|
||||
var assigned_pos = Vector2i(0, 0) # Fallback
|
||||
if spawn_index < valid_spawns.size():
|
||||
assigned_pos = valid_spawns[spawn_index]
|
||||
# Use deterministic assignment from (0, 1) to (0, 8) to keep players separate
|
||||
# Start Line is Column 0. We use rows 1 to 8.
|
||||
var assigned_pos = Vector2i(0, spawn_index + 1)
|
||||
|
||||
# Ensure immediate sync
|
||||
player.position = player.grid_to_world(assigned_pos)
|
||||
@@ -725,7 +757,7 @@ func _assign_stop_n_go_spawn_positions(all_players: Array):
|
||||
player.rpc("set_spawn_position", assigned_pos)
|
||||
|
||||
spawn_index += 1
|
||||
print("[StopNGo] Assigned starting block %s to player %s" % [assigned_pos, player.name])
|
||||
print("[StopNGo] Assigned fixed starting block %s to player %s" % [assigned_pos, player.name])
|
||||
|
||||
# =============================================================================
|
||||
# Tekton NPC Management
|
||||
|
||||
@@ -83,6 +83,10 @@ func _physics_process(delta):
|
||||
if not multiplayer.is_server():
|
||||
return
|
||||
|
||||
# Only run if game has started
|
||||
if not GameStateManager.is_game_started():
|
||||
return
|
||||
|
||||
# STUCK PREVENTION
|
||||
if actor.is_player_moving:
|
||||
_stuck_timer += delta
|
||||
|
||||
@@ -5,7 +5,7 @@ extends Node
|
||||
signal game_started()
|
||||
signal game_state_changed()
|
||||
|
||||
@export var enable_bots: bool = false
|
||||
@export var enable_bots: bool = true
|
||||
@export var max_players: int = 8
|
||||
|
||||
var players: Array = []
|
||||
|
||||
Reference in New Issue
Block a user