From cc584c32513235a91698497aaf7f039beb3b825f Mon Sep 17 00:00:00 2001 From: adtpdn Date: Tue, 30 Jun 2026 01:59:59 +0800 Subject: [PATCH] fix: hardcode NPC zone coordinates to strictly prevent tiles spawning underneath candy cannon --- scripts/managers/gauntlet_manager.gd | 93 ++++++++++++++-------------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/scripts/managers/gauntlet_manager.gd b/scripts/managers/gauntlet_manager.gd index e6086bf..2a5614f 100644 --- a/scripts/managers/gauntlet_manager.gd +++ b/scripts/managers/gauntlet_manager.gd @@ -412,22 +412,20 @@ func _apply_arena_setup() -> void: var pos = Vector2i(x, z) # Center 3x3 block: NPC obstacle (Candy Pump) - if _is_npc_zone(pos): - # Make the floor empty (-1) beneath the Candy Pump - # We need to clear all possible layers just in case - gridmap.set_cell_item(Vector3i(x, 0, z), -1) + if x >= 8 and x <= 10 and z >= 8 and z <= 10: + # Hardcode clear all possible layers beneath the Candy Pump + for layer in range(5): + gridmap.set_cell_item(Vector3i(x, layer, z), -1) + continue + + # Boundary walls: perimeter (row 0, row 19, col 0, col 19) + if x == 0 or x == ARENA_COLUMNS - 1 or z == 0 or z == ARENA_ROWS - 1: + # Also make border walls visually walkable floors instead of red blocks + gridmap.set_cell_item(Vector3i(x, 0, z), TILE_WALKABLE) gridmap.set_cell_item(Vector3i(x, 1, z), -1) gridmap.set_cell_item(Vector3i(x, 2, z), -1) continue - # Boundary walls: perimeter (row 0, row 19, col 0, col 19) - if x == 0 or x == ARENA_COLUMNS - 1 or z == 0 or z == ARENA_ROWS - 1: - # Also make border walls visually walkable floors instead of red blocks - gridmap.set_cell_item(Vector3i(x, 0, z), TILE_WALKABLE) - gridmap.set_cell_item(Vector3i(x, 1, z), -1) - gridmap.set_cell_item(Vector3i(x, 2, z), -1) - continue - # Interior: walkable floor gridmap.set_cell_item(Vector3i(x, 0, z), TILE_WALKABLE) gridmap.set_cell_item(Vector3i(x, 1, z), -1) @@ -451,10 +449,7 @@ func _apply_arena_setup() -> void: func _is_npc_zone(pos: Vector2i) -> bool: """Check if a position is within the center 3x3 NPC zone.""" - var half = NPC_SIZE / 2 # integer division = 1 - var min_coord = NPC_CENTER - Vector2i(half, half) # (8, 8) - var max_coord = NPC_CENTER + Vector2i(half, half) # (10, 10) - return pos.x >= min_coord.x and pos.x <= max_coord.x and pos.y >= min_coord.y and pos.y <= max_coord.y + return pos.x >= 8 and pos.x <= 10 and pos.y >= 8 and pos.y <= 10 func get_spawn_points(player_count: int) -> Array[Vector2i]: """Return spawn positions based on player count. Inside boundary walls.""" @@ -509,35 +504,35 @@ func _spawn_mission_tiles() -> void: var goal_items = [7, 8, 9, 10] var tiles_spawned: int = 0 - for x in range(ARENA_COLUMNS): - for z in range(ARENA_ROWS): - var pos = Vector2i(x, z) - - # Skip NPC pump zone (center 3x3) - if _is_npc_zone(pos): - continue - - # Check base floor — don't spawn on void (or walls if they were still obstacles) - var base_tile = gridmap.get_cell_item(Vector3i(x, 0, z)) - if base_tile == -1: - continue - - # Ensure we don't spawn powerups on the perimeter walls even though they look like floors - if x == 0 or x == ARENA_COLUMNS - 1 or z == 0 or z == ARENA_ROWS - 1: - continue - - # Skip if something already exists on Layer 1 - var current_item = gridmap.get_cell_item(Vector3i(x, 1, z)) - if current_item != -1: - continue - - # Spawn tiles with 60% density (40% chance to skip) - if randf() > 0.6: - continue - - var tile_type = goal_items[randi() % goal_items.size()] - gridmap.set_cell_item(Vector3i(x, 1, z), tile_type) - tiles_spawned += 1 + for x in range(ARENA_COLUMNS): + for z in range(ARENA_ROWS): + var pos = Vector2i(x, z) + + # Skip NPC pump zone (center 3x3) + if x >= 8 and x <= 10 and z >= 8 and z <= 10: + continue + + # Check base floor — don't spawn on void (or walls if they were still obstacles) + var base_tile = gridmap.get_cell_item(Vector3i(x, 0, z)) + if base_tile == -1: + continue + + # Ensure we don't spawn powerups on the perimeter walls even though they look like floors + if x == 0 or x == ARENA_COLUMNS - 1 or z == 0 or z == ARENA_ROWS - 1: + continue + + # Skip if something already exists on Layer 1 + var current_item = gridmap.get_cell_item(Vector3i(x, 1, z)) + if current_item != -1: + continue + + # Spawn tiles with 60% density (40% chance to skip) + if randf() > 0.6: + continue + + var tile_type = goal_items[randi() % goal_items.size()] + gridmap.set_cell_item(Vector3i(x, 1, z), tile_type) + tiles_spawned += 1 # Sync to clients var main = get_node("/root/Main") @@ -858,6 +853,8 @@ func sync_growth_telegraph(cells: Array) -> void: for cell in cells: var pos = cell as Vector2i + if pos.x >= 8 and pos.x <= 10 and pos.y >= 8 and pos.y <= 10: continue + # Telegraph overlay tile on Layer 2 (still passable). gridmap.set_cell_item(Vector3i(pos.x, 2, pos.y), TILE_TELEGRAPH) _spawn_telegraph_highlight(pos) @@ -929,6 +926,8 @@ func sync_growth_apply(cells: Array) -> void: if not gridmap: return for cell in cells: var pos = cell as Vector2i + if pos.x >= 8 and pos.x <= 10 and pos.y >= 8 and pos.y <= 10: continue + gridmap.set_cell_item(Vector3i(pos.x, 2, pos.y), TILE_STICKY) sticky_cells[pos] = true @@ -1518,6 +1517,8 @@ func sync_bubble_spawn(center: Vector2i, cells: Array) -> void: # Telegraph-style warning overlay on the footprint (still passable). for c in cells: var pos = c as Vector2i + if pos.x >= 8 and pos.x <= 10 and pos.y >= 8 and pos.y <= 10: continue + gridmap.set_cell_item(Vector3i(pos.x, 2, pos.y), TILE_TELEGRAPH) _spawn_bubble_visual(center) if SfxManager: @@ -1539,6 +1540,8 @@ func sync_bubble_explode(center: Vector2i, cells: Array) -> void: return for c in cells: var pos = c as Vector2i + if pos.x >= 8 and pos.x <= 10 and pos.y >= 8 and pos.y <= 10: continue + gridmap.set_cell_item(Vector3i(pos.x, 2, pos.y), TILE_STICKY) sticky_cells[pos] = true # Medium shake — bubbles hit harder than a normal growth tick.