From 145a1a53dc415d0ec34f1026c83c12c27c3f6f47 Mon Sep 17 00:00:00 2001 From: Yogi Wiguna Date: Thu, 26 Feb 2026 17:42:47 +0800 Subject: [PATCH] feat: Add PortalModeManager and integrate it for the Tekton Doors game mode. --- scenes/main.gd | 4 +- scripts/managers/portal_mode_manager.gd | 57 +++++++++++++++++-------- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/scenes/main.gd b/scenes/main.gd index 9517f44..0499dec 100644 --- a/scenes/main.gd +++ b/scenes/main.gd @@ -259,8 +259,8 @@ func add_message_to_bar(player_name: String, message: String, type: int = Messag message_bar.visible = false @rpc("any_peer", "call_local") -func broadcast_message(player_name: String, message: String): - add_message_to_bar(player_name, message) +func broadcast_message(player_name: String, message: String, type: int = MessageType.NORMAL): + add_message_to_bar(player_name, message, type) func _start_pre_game_countdown(): """Show a 3-second countdown on all clients before starting.""" diff --git a/scripts/managers/portal_mode_manager.gd b/scripts/managers/portal_mode_manager.gd index 789e010..38757c9 100644 --- a/scripts/managers/portal_mode_manager.gd +++ b/scripts/managers/portal_mode_manager.gd @@ -50,7 +50,14 @@ func initialize(p_main: Node, p_gridmap: Node): # Connect to mission tracking var gcm = main.get_node_or_null("GoalsCycleManager") if gcm: - gcm.goal_count_updated.connect(_on_goal_count_updated) + gcm.global_timer_updated.connect(_on_global_timer_updated) + +func _on_global_timer_updated(time_remaining: float): + if not multiplayer.is_server(): return + + # Last 30 seconds: Reveal Finish Room + if time_remaining <= 30.0 and not finish_spawned: + _spawn_finish_room() func start_game_mode(): if not multiplayer.is_server(): return @@ -81,6 +88,11 @@ func setup_arena_locally(): _setup_arena_size() _setup_room_partitions() _spawn_portal_doors() + + # PRE-FILL TILES: Ensure all floor tiles have items before the countdown starts + if multiplayer.is_server(): + _refresh_tiles() + arena_setup_done = true func _setup_arena_size(): @@ -291,29 +303,38 @@ func sync_portal_data(data: Array): print("[PortalModeManager] Warning: Door index %d or %d out of range during sync" % [a_id, b_id]) -func _on_goal_count_updated(_peer_id: int, count: int): - if not multiplayer.is_server(): return - - if count >= missions_required and not finish_spawned: - _spawn_finish_room() +func _on_global_goal_count_updated(_peer_id: int, _count: int): + # Mission requirement removed in favor of time-based finish reveal + pass func _spawn_finish_room(): - print("[PortalModeManager] Missions complete! Spawning Finish Room...") + print("[PortalModeManager] Time is running out! Revealing Finish Room...") finish_spawned = true - # Choose a random center room tile (X=3, Z=10 or similar in any room) + # Choose a random center room spawn point to place the finish tile var room_centers = get_spawn_points() var center = room_centers[randi() % room_centers.size()] # Place finish tile (ID 3) on Floor 1 (Y=1) - # Check if this center is actually clear (not a wall accidentally) - if gridmap.get_cell_item(Vector3i(center.x, 0, center.y)) == 4: - # Fallback to any non-wall center if needed, but spawn points are usually safe - pass + # We use current_position as spawn point centers are guaranteed to be walkable + # IMPORTANT: Change the floor tile (Floor 0) to item ID 3 (Goal/Finish) + main.rpc("sync_grid_item", center.x, 0, center.y, 3) + + # Clear any item on Floor 1 above the finish tile + main.rpc("sync_grid_item", center.x, 1, center.y, -1) + + # Visual update for server + if gridmap.has_method("update_grid_data"): + gridmap.update_grid_data() - main.rpc("sync_grid_item", center.x, 1, center.y, 3) - main.get_node("EnhancedGridMap").update_grid_data() - main.rpc("display_message", "FINISH ROOM REVEALED!") + main.rpc("display_message", "[ALARM] THE FINISH ROOM HAS APPEARED!") + main.rpc("broadcast_message", "SYSTEM", "The Finish Tile is in Room %d!" % _get_room_index(center), 4) # 4 = MessageType.WARNING + +func _get_room_index(pos: Vector2i) -> int: + if pos.x < 7 and pos.y < 7: return 0 + if pos.x >= 7 and pos.y < 7: return 1 + if pos.x < 7 and pos.y >= 7: return 2 + return 3 func _on_swap_timer_timeout(): _randomize_connections() @@ -336,11 +357,11 @@ func _refresh_tiles(): if gridmap.get_cell_item(Vector3i(x, 1, z)) != -1: continue - # 3. Low chance to spawn a tile - if randf() < 0.1: + # 3. Spawn a tile (60% chance per valid floor cell) + if randf() < 0.6: var weights = ScarcityModel.get_tile_weights() var tile_id = _pick_weighted_tile(weights) - # Update GridMap Floor 1 via RPC for sync (call_local handles host) + # Update GridMap Floor 1 via RPC for sync main.rpc("sync_grid_item", x, 1, z, tile_id) func _pick_weighted_tile(weights: Dictionary) -> int: