diff --git a/addons/enhanced_gridmap/enhanced_gridmap.gd b/addons/enhanced_gridmap/enhanced_gridmap.gd index 85c7da4..c90f1d1 100644 --- a/addons/enhanced_gridmap/enhanced_gridmap.gd +++ b/addons/enhanced_gridmap/enhanced_gridmap.gd @@ -16,7 +16,7 @@ signal grid_updated @export var hover_item: int = 1 @export var start_item: int = -1 @export var end_item: int = -1 -@export var immutable_items: Array[int] = [1, 2, 3, 4] # Items that cannot be randomized/reset (Start, Safe, Finish, Wall) +@export var immutable_items: Array[int] = [1, 2, 3, 4, 16] # Items that cannot be randomized/reset (Start, Safe, Finish, Wall, Safe Zone Wall) var current_mesh_library: MeshLibrary var grid_data: Array = [] # 3D array [floor][row][column] diff --git a/addons/enhanced_gridmap/meshlibrary/default.tres b/addons/enhanced_gridmap/meshlibrary/default.tres index 99b12d0..360534f 100644 --- a/addons/enhanced_gridmap/meshlibrary/default.tres +++ b/addons/enhanced_gridmap/meshlibrary/default.tres @@ -11,6 +11,7 @@ [ext_resource type="ArrayMesh" uid="uid://bfv8cw1vho5p5" path="res://assets/models/meshes/ancient_lightning_stones.res" id="8_cg50n"] [ext_resource type="BoxMesh" uid="uid://fy4bhoeii40c" path="res://addons/enhanced_gridmap/meshlibrary/tile_safe_zone.tres" id="8_uwjsj"] [ext_resource type="BoxMesh" uid="uid://dy5p77cjb3geo" path="res://addons/enhanced_gridmap/meshlibrary/tile_start.tres" id="9_pgnbl"] +[ext_resource type="ArrayMesh" uid="uid://dtr46jmckif0p" path="res://assets/models/meshes/block.res" id="9_uwjsj"] [ext_resource type="Texture2D" uid="uid://dpkx1a780pvwv" path="res://assets/textures/tile_diamond.png" id="10_sx8rm"] [ext_resource type="BoxMesh" uid="uid://b5cc3prem52r6" path="res://addons/enhanced_gridmap/meshlibrary/tile_freeze.tres" id="11_pgnbl"] [ext_resource type="BoxMesh" uid="uid://dcjdwbffgtutt" path="res://addons/enhanced_gridmap/meshlibrary/tile_non_walkable.tres" id="11_uwjsj"] @@ -177,3 +178,10 @@ item/15/mesh_cast_shadow = 1 item/15/shapes = [] item/15/navigation_mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0) item/15/navigation_layers = 1 +item/16/name = "wall" +item/16/mesh = ExtResource("9_uwjsj") +item/16/mesh_transform = Transform3D(2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.5) +item/16/mesh_cast_shadow = 1 +item/16/shapes = [] +item/16/navigation_mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0) +item/16/navigation_layers = 1 diff --git a/assets/models/meshes/ancient_lightning_stones.res b/assets/models/meshes/ancient_lightning_stones.res index a9a9a09..8bf911f 100644 Binary files a/assets/models/meshes/ancient_lightning_stones.res and b/assets/models/meshes/ancient_lightning_stones.res differ diff --git a/assets/models/meshes/block.res b/assets/models/meshes/block.res index 25ec462..353d5a5 100644 Binary files a/assets/models/meshes/block.res and b/assets/models/meshes/block.res differ diff --git a/scenes/main.tscn b/scenes/main.tscn index 96ff0ae..ae6b54a 100644 --- a/scenes/main.tscn +++ b/scenes/main.tscn @@ -9906,7 +9906,7 @@ alignment = 1 [node name="Title" type="Label" parent="PauseMenu/Panel/VBox" unique_id=1740539610] layout_mode = 2 theme_override_font_sizes/font_size = 24 -text = "PAUSED" +text = "Menu" horizontal_alignment = 1 [node name="Spacer" type="Control" parent="PauseMenu/Panel/VBox" unique_id=57341975] diff --git a/scripts/managers/goals_cycle_manager.gd b/scripts/managers/goals_cycle_manager.gd index d6baaa6..3ee1aa3 100644 --- a/scripts/managers/goals_cycle_manager.gd +++ b/scripts/managers/goals_cycle_manager.gd @@ -417,6 +417,10 @@ func _randomize_tiles_around_player(player: Node): # Check if there are tiles nearby or if empty var current_item = enhanced_gridmap.get_cell_item(cell) + # IMMUTABLE CHECK: Do not randomize/delete walls or special items on Floor 1 + if current_item in enhanced_gridmap.immutable_items: + continue + # Decide: delete, spawn, or randomize var action = rng.randi() % 3 diff --git a/scripts/managers/player_movement_manager.gd b/scripts/managers/player_movement_manager.gd index 60f61fa..f5be9d6 100644 --- a/scripts/managers/player_movement_manager.gd +++ b/scripts/managers/player_movement_manager.gd @@ -84,13 +84,20 @@ func simple_move_to(grid_position: Vector2i) -> bool: print("[Move] Failed: Cannot move to finish yet") return false - var cell_item = enhanced_gridmap.get_cell_item(Vector3i(grid_position.x, 0, grid_position.y)) + var cell_floor = enhanced_gridmap.get_cell_item(Vector3i(grid_position.x, 0, grid_position.y)) + var cell_item = enhanced_gridmap.get_cell_item(Vector3i(grid_position.x, 1, grid_position.y)) - # Allow passing through Walls (Item 4) if Invisible - var is_wall_passable = player.get("is_invisible") and cell_item == 4 + # Allow passing through Walls (Item 4 or 16) if Invisible + var is_wall_passable = player.get("is_invisible") and (cell_floor == 4 or cell_item == 16 or cell_item == 4) - if (cell_item == -1 or cell_item in enhanced_gridmap.non_walkable_items) and not is_wall_passable: - print("[Move] Failed: Cell Item %d is non-walkable" % cell_item) + # Check Floor 0 (Basic Walkability/Void) + if (cell_floor == -1 or cell_floor in enhanced_gridmap.non_walkable_items) and not is_wall_passable: + print("[Move] Failed: Floor Item %d is non-walkable" % cell_floor) + return false + + # Check Floor 1 (Obstacles/Walls) + if (cell_item != -1 and cell_item in [4, 13, 16]) and not is_wall_passable: + print("[Move] Failed: Blocked by Item %d on Floor 1" % cell_item) return false # PHYSICS CHECK: Ensure no static obstacles (like Stands) are blocking the path diff --git a/scripts/managers/special_tiles_manager.gd b/scripts/managers/special_tiles_manager.gd index 5442f71..11dfd5c 100644 --- a/scripts/managers/special_tiles_manager.gd +++ b/scripts/managers/special_tiles_manager.gd @@ -391,7 +391,7 @@ func _execute_block_floor(target_pos: Vector2i = Vector2i.ZERO): if "immutable_items" in enhanced_gridmap: if original_item in enhanced_gridmap.immutable_items: is_immutable = true - if original_item in [1, 2, 3, 4] or is_immutable: continue + if original_item in [1, 2, 3, 4, 16] or is_immutable: continue batch_data.append({"x": block_pos.x, "y": 0, "z": block_pos.z, "item": 4}) @@ -441,7 +441,7 @@ func spawn_powerups_around(center: Vector2i, force_powerups: bool = true, only_c # PROTECTED FLOOR CHECK: Don't spawn on existing walls or void var f0 = enhanced_gridmap.get_cell_item(Vector3i(pos.x, 0, pos.y)) var f1 = enhanced_gridmap.get_cell_item(Vector3i(pos.x, 1, pos.y)) - if f0 in [4, -1] or f1 == 4 or f1 == 13: + if f0 in [4, -1] or f1 in [4, 13, 16]: continue var item_id: int diff --git a/scripts/managers/stop_n_go_manager.gd b/scripts/managers/stop_n_go_manager.gd index 1f1e71f..49eefda 100644 --- a/scripts/managers/stop_n_go_manager.gd +++ b/scripts/managers/stop_n_go_manager.gd @@ -470,10 +470,11 @@ func _spawn_safe_zone(): gridmap = get_node_or_null("/root/Main/EnhancedGridMap") if not gridmap: return - # Collect valid center positions (not too close to edges so the zone fits) + # Collect valid center positions (account for wall footprint: radius + 1) + var spawn_buffer = SAFE_ZONE_RADIUS + 1 var valid_positions: Array[Vector2i] = [] - for x in range(SAFE_ZONE_RADIUS, gridmap.columns - SAFE_ZONE_RADIUS): - for z in range(SAFE_ZONE_RADIUS, gridmap.rows - SAFE_ZONE_RADIUS): + for x in range(spawn_buffer, gridmap.columns - spawn_buffer): + for z in range(spawn_buffer, gridmap.rows - spawn_buffer): var tile = gridmap.get_cell_item(Vector3i(x, 0, z)) # Only walkable tiles (not start/finish) if tile == TILE_WALKABLE: @@ -648,16 +649,59 @@ func sync_safe_zone(centers: Array, radius: int): if not gridmap: return # Paint safe zones on Floor 0 (Floor layer) - # This ensures items and walls on Floor 1 are visible ON TOP of the safe zone + # Also paint walls (ID 16) around the zone with 1 door on each side for center in safe_zone_centers: + # 1. Paint the safe floor for dx in range(-radius, radius + 1): for dz in range(-radius, radius + 1): var x = center.x + dx var z = center.y + dz if x >= 0 and x < gridmap.columns and z >= 0 and z < gridmap.rows: - # ONLY replace standard walkable floor (don't overwrite Start/Finish/Walls on Layer 0) if gridmap.get_cell_item(Vector3i(x, 0, z)) == TILE_WALKABLE: gridmap.set_cell_item(Vector3i(x, 0, z), TILE_SAFE) + + # 2. Paint the walls (item ID 16) ON LAYER 1 to block movement + # We scan from -3 to +3 to handle symmetric wall indices around the 5x5 zone + for dx in range(-radius - 1, radius + 2): + for dz in range(-radius - 1, radius + 2): + var x = center.x + dx + var z = center.y + dz + + if x >= 0 and x < gridmap.columns and z >= 0 and z < gridmap.rows: + # big room logic: 5x5 span (Indices -2 to 2) + # North/West use -radius/-radius-1, South/East use radius/radius+1 + var is_north = dz == -radius - 1 and dx >= -radius and dx <= radius + var is_south = dz == radius and dx >= -radius and dx <= radius + var is_west = dx == -radius and dz >= -radius and dz <= radius + var is_east = dx == radius + 1 and dz >= -radius and dz <= radius + + var orientation = 0 + var is_wall = false + + if is_north: + orientation = 0 + is_wall = true + elif is_south: + orientation = 0 + is_wall = true + elif is_west: + orientation = 22 + is_wall = true + elif is_east: + orientation = 22 + is_wall = true + + if is_wall: + # Door logic: Skip center (0) on the respective border line + var is_door = (is_north and dx == 0) or (is_south and dx == 0) or \ + (is_west and dz == 0) or (is_east and dz == 0) + if is_door: + continue + + gridmap.set_cell_item(Vector3i(x, 1, z), 16, orientation) + + # Update pathfinding for bots and movement checks + gridmap.initialize_astar() # Notify local player var my_id = multiplayer.get_unique_id() @@ -683,8 +727,27 @@ func sync_clear_safe_zone(centers_to_clear: Array): var z = center.y + dz if x >= 0 and x < gridmap.columns and z >= 0 and z < gridmap.rows: # Restore Floor 0 back to standard walkable floor - if gridmap.get_cell_item(Vector3i(x, 0, z)) == TILE_SAFE: + var current = gridmap.get_cell_item(Vector3i(x, 0, z)) + if current == TILE_SAFE: gridmap.set_cell_item(Vector3i(x, 0, z), TILE_WALKABLE) + + # Also clean up walls ON LAYER 1 + # Scan -3 to +3 range to ensure all shifted walls are cleared + for dx in range(-SAFE_ZONE_RADIUS - 1, SAFE_ZONE_RADIUS + 2): + for dz in range(-SAFE_ZONE_RADIUS - 1, SAFE_ZONE_RADIUS + 2): + var x = center.x + dx + var z = center.y + dz + if x >= 0 and x < gridmap.columns and z >= 0 and z < gridmap.rows: + # Clear any wall items on Floor 1 + if gridmap.get_cell_item(Vector3i(x, 1, z)) != -1: + gridmap.set_cell_item(Vector3i(x, 1, z), -1) + + # Clear local state + safe_zone_centers = [] + safe_zone_spawned = false + + # Restore navigation + gridmap.initialize_astar() print("[StopNGo] Safe Zones cleared.") # Ensure local state is also updated in case this was just an RPC call