feat: implement Tekton Doors game mode with arena setup, portal management, connection randomization, and game state timers.

This commit is contained in:
2026-02-26 04:25:09 +08:00
parent 551c820d5e
commit ef3d018040
6 changed files with 230 additions and 66 deletions
+35 -15
View File
@@ -34,10 +34,10 @@ func _ready():
# Setup UI
ui_manager.setup_action_buttons(_set_action_state_callback)
ui_manager.setup_playerboard_ui()
ui_manager.setup_timer_labels(self)
ui_manager.setup_playerboard_label(self) # NEW
ui_manager.setup_leaderboard_ui(self)
ui_manager.setup_powerup_bar_ui(self)
ui_manager.setup_timer_labels(self )
ui_manager.setup_playerboard_label(self ) # NEW
ui_manager.setup_leaderboard_ui(self )
ui_manager.setup_powerup_bar_ui(self )
# GlobalMatchTimer is now static in main.tscn - no setup needed
# NetworkPanel is visible during gameplay
@@ -71,7 +71,6 @@ func _ready():
stand_spawner.name = "StandSpawner"
stand_spawner.spawn_path = NodePath("../Stands") # Relative to Spawner, finding sibling
stand_spawner.add_spawnable_scene("res://scenes/static_tekton_stand.tscn")
stand_spawner.add_spawnable_scene("res://scenes/portal_door.tscn")
add_child(stand_spawner)
func _on_goal_count_updated(peer_id: int, count: int):
@@ -84,13 +83,13 @@ func _init_managers():
ui_manager = load("res://scripts/managers/ui_manager.gd").new()
ui_manager.name = "UIManager"
add_child(ui_manager)
ui_manager.initialize(self)
ui_manager.initialize(self )
# Goals cycle manager for 60-second timer and scoring
goals_cycle_manager = load("res://scripts/managers/goals_cycle_manager.gd").new()
goals_cycle_manager.name = "GoalsCycleManager"
add_child(goals_cycle_manager)
goals_cycle_manager.initialize(self)
goals_cycle_manager.initialize(self )
# Stop n Go manager for phase-based gameplay
if LobbyManager.game_mode == "Stop n Go":
@@ -104,7 +103,7 @@ func _init_managers():
portal_mode_manager = load("res://scripts/managers/portal_mode_manager.gd").new()
portal_mode_manager.name = "PortalModeManager"
add_child(portal_mode_manager)
portal_mode_manager.initialize(self, $EnhancedGridMap)
portal_mode_manager.initialize(self , $EnhancedGridMap)
# Screen shake manager for impact feedback
screen_shake_manager = load("res://scripts/managers/screen_shake.gd").new()
@@ -120,7 +119,7 @@ func _init_managers():
touch_controls.name = "TouchControls"
add_child(touch_controls)
touch_controls.initialize(self)
touch_controls.initialize(self )
# NEW: Camera Context Manager for dynamic camera position
camera_context_manager = load("res://scripts/managers/camera_context_manager.gd").new()
@@ -132,7 +131,7 @@ func _init_managers():
obstacle_manager = load("res://scripts/managers/obstacle_manager.gd").new()
obstacle_manager.name = "ObstacleManager"
add_child(obstacle_manager)
obstacle_manager.initialize(self, $EnhancedGridMap)
obstacle_manager.initialize(self , $EnhancedGridMap)
# Connect signals for UI updates
goals_cycle_manager.timer_updated.connect(_on_timer_updated)
@@ -567,7 +566,6 @@ func _setup_client_game():
rpc_id(1, "request_full_grid_sync")
func _auto_start_from_lobby():
"""Called when main.tscn is loaded from lobby - game is already connected."""
# Get match ID from LobbyManager
@@ -1520,7 +1518,7 @@ func randomize_item_at_position(grid_position: Vector2i):
# If current item exists, replace it (scarcity aware)
# If current item exists OR we are forcing a spawn on valid ground
var floor_0_item = enhanced_gridmap.get_cell_item(Vector3i(grid_position.x, 0, grid_position.y))
var is_ground = (floor_0_item != -1) # Simple check, or check specific ground items
var is_ground = (floor_0_item != -1 and floor_0_item != 4) # Skip walls (4) and empty space (-1)
# Prevent stacking on players
if is_ground:
@@ -1553,14 +1551,25 @@ func request_randomize_item(grid_position: Vector2i):
func sync_grid_item(x: int, y: int, z: int, item: int):
var enhanced_gridmap = $EnhancedGridMap
if enhanced_gridmap:
# WALL-SAFETY CHECK: Block tiles (7-20) from being placed on walls (4)
if y == 1 and item >= 7 and item <= 20:
var f0 = enhanced_gridmap.get_cell_item(Vector3i(x, 0, z))
if f0 == 4:
# Log and block illegal placement
print("[Main] Blocked illegal tile (%d) placement on wall at (%d, %d)" % [item, x, z])
return
enhanced_gridmap.set_cell_item(Vector3i(x, y, z), item)
# Force visual update
if enhanced_gridmap.has_method("update_grid_data"):
enhanced_gridmap.update_grid_data()
# Sync grid update (no need to sync whole grid if we do it at start, but if we do it late we might need to sync)
# For simplicity, we trust the grid syncs via normal mechanisms or initial state.
func randomize_game_grid():
if LobbyManager.game_mode == "Stop n Go":
return # Stop n Go manages its own arena setup
if LobbyManager.game_mode == "Stop n Go" or LobbyManager.game_mode == "Tekton Doors":
return # These modes manage their own arena setup and item spawning
var enhanced_gridmap = $EnhancedGridMap
if enhanced_gridmap:
@@ -1595,7 +1604,7 @@ func request_full_grid_sync():
# For all modes, only sync Floor 1 (Items) to prevent MTU packet overflow.
# Floor 0 logic is deterministic and generated locally on level load.
var grid_data = enhanced_gridmap.get_floor_data(1)
var grid_data = enhanced_gridmap.get_floor_data(1)
print("[Main] Server: Prepared grid data. Size: %d. Sending to %d..." % [grid_data.size(), sender_id])
# Delay slightly to ensure socket stability after player syncs
@@ -1604,6 +1613,10 @@ func request_full_grid_sync():
if sender_id in multiplayer.get_peers():
rpc_id(sender_id, "sync_full_grid_data", grid_data)
print("[Main] Server: Sent grid sync rpc_id to %d" % sender_id)
# If Tekton Doors, sync portal connections too
if LobbyManager.game_mode == "Tekton Doors" and portal_mode_manager:
portal_mode_manager.sync_to_client(sender_id)
@rpc("authority", "call_local", "reliable")
func sync_full_grid_data(data: PackedInt32Array):
@@ -1620,6 +1633,13 @@ func sync_full_grid_data(data: PackedInt32Array):
stop_n_go_manager.name = "StopNGoManager"
add_child(stop_n_go_manager)
stop_n_go_manager._apply_arena_setup()
elif LobbyManager.game_mode == "Tekton Doors":
if not portal_mode_manager:
portal_mode_manager = load("res://scripts/managers/portal_mode_manager.gd").new()
portal_mode_manager.name = "PortalModeManager"
add_child(portal_mode_manager)
portal_mode_manager.initialize(self , enhanced_gridmap)
portal_mode_manager.setup_arena_locally()
# Apply the synced data to Floor 1
enhanced_gridmap.set_floor_data(1, data)