diff --git a/scenes/main.gd b/scenes/main.gd index 27086f6..38cd40f 100644 --- a/scenes/main.gd +++ b/scenes/main.gd @@ -13,6 +13,8 @@ var camera_context_manager # Minimal local state var _connection_check_timer: float = 0.0 +var reserved_static_positions: Array[Vector2i] = [] + func _ready(): # Initialize scene managers @@ -356,6 +358,9 @@ func _setup_host_game(): print("Spawning lobby player: ", peer_id) _spawn_lobby_client_sync(peer_id) + # 1. PVT: Pre-calculate Static Tekton positions so we know where NOT to spawn players + _precalculate_static_positions() + # IMMEDIATELY assign random spawn positions before any player _ready() completes # Player _ready() has 0.1s await, so we assign before that completes # IMMEDIATELY assign spawn positions (Fixed or Random) @@ -540,6 +545,18 @@ func _assign_random_spawn_positions(): var ground = enhanced_gridmap.get_cell_item(Vector3i(x, 0, z)) if ground == 0: # Walkable var pos = Vector2i(x, z) + + # SAFETY CHECK: Is this reserved for a Static Tekton Stand? + # Stand covers [center-1, center+1] + var is_safe = true + for reserved in reserved_static_positions: + if abs(x - reserved.x) <= 1 and abs(z - reserved.y) <= 1: + is_safe = false + break + + if not is_safe: + continue + all_spawns.append(pos) if x < mid_x and z < mid_z: @@ -648,6 +665,14 @@ func spawn_tekton_npc(): var item_id = enhanced_gridmap.get_cell_item(Vector3i(x, 1, y)) if item_id == 4: continue # Wall/Stand + # Also check RESERVED positions (if they haven't spawned yet or for safety) + var is_safe = true + for reserved in reserved_static_positions: + if abs(x - reserved.x) <= 1 and abs(y - reserved.y) <= 1: + is_safe = false + break + if not is_safe: continue + valid_pos = Vector2i(x, y) # Generate a consistent ID/Name for sync (add index to ensure uniqueness) @@ -691,6 +716,23 @@ func _create_tekton(pos: Vector2i, tekton_id: int, is_static: bool = false): else: print("[Main] Spawned Tekton at %s (ID: %d)" % [pos, tekton_id]) + + +func _precalculate_static_positions(): + """Calculate and reserve Static Tekton positions early.""" + if not multiplayer.is_server(): return + var enhanced_gridmap = $EnhancedGridMap + if not enhanced_gridmap: return + + if not static_tekton_manager: + static_tekton_manager = StaticTektonManager.new() + + # Calculate 3 spots and STORE them + var points: Array[Vector2i] = [] + points = static_tekton_manager.calculate_spawn_points(3, enhanced_gridmap) + reserved_static_positions = points + print("[Main] Pre-calculated Static Tekton Positions: %s" % str(reserved_static_positions)) + func spawn_static_tektons(): """Spawn fixed static tektons using StaticTektonManager.""" if not multiplayer.is_server(): return @@ -700,11 +742,15 @@ func spawn_static_tektons(): print("[Main] Initializing StaticTektonManager...") if not static_tekton_manager: static_tekton_manager = StaticTektonManager.new() - # Keeping manager instance in memory - # Calculate Spawn Points (Server Logic) - var spawn_points = static_tekton_manager.calculate_spawn_points(3, enhanced_gridmap) - print("[Main] Static Tekton Points: %s" % str(spawn_points)) + # Use pre-calculated points if available, otherwise calculate new ones + var spawn_points = [] + if not reserved_static_positions.is_empty(): + spawn_points = reserved_static_positions + else: + spawn_points = static_tekton_manager.calculate_spawn_points(3, enhanced_gridmap) + + print("[Main] Spawning Static Tektons at: %s" % str(spawn_points)) for i in range(spawn_points.size()): var pos = spawn_points[i] diff --git a/scripts/managers/static_tekton_manager.gd b/scripts/managers/static_tekton_manager.gd index 43b2888..fc16a2d 100644 --- a/scripts/managers/static_tekton_manager.gd +++ b/scripts/managers/static_tekton_manager.gd @@ -13,7 +13,7 @@ const STATIC_CONTROLLER_SCRIPT = "res://scripts/static_tekton_controller.gd" # Mid-Left, Mid-Mid, Mid-Right # Bot-Left, Bot-Mid, Bot-Right -func calculate_spawn_points(count: int, gridmap: Node) -> Array: +func calculate_spawn_points(count: int, gridmap: Node) -> Array[Vector2i]: """ Calculates random spawn positions for static tektons. Returns an Array of Vector2i positions. @@ -39,7 +39,7 @@ func calculate_spawn_points(count: int, gridmap: Node) -> Array: # If count < 5, we prioritize corners then center # If count > 5, we only return 5 because that's the max safe non-adjacent set in 3x3 - var spawn_points = [] + var spawn_points: Array[Vector2i] = [] var iterations = min(count, target_indices.size()) for i in range(iterations): diff --git a/scripts/static_tekton_stand.gd b/scripts/static_tekton_stand.gd index 8d749c4..87293f8 100644 --- a/scripts/static_tekton_stand.gd +++ b/scripts/static_tekton_stand.gd @@ -31,7 +31,6 @@ func _update_mesh_from_index(): var shapes = [ _create_cylinder(), _create_box(), - _create_prism(), _create_sphere() ] @@ -61,11 +60,7 @@ func _create_box() -> BoxMesh: var mesh = BoxMesh.new() mesh.size = Vector3(3.2, 0.6, 3.2) return mesh - -func _create_prism() -> PrismMesh: - var mesh = PrismMesh.new() - mesh.size = Vector3(3.2, 0.6, 3.2) - return mesh + func _create_sphere() -> SphereMesh: # A flattened sphere acting like a dome stand