feat: Add diverse game tiles, 3D wall scenes, and player movement and stop-n-go managers.
This commit is contained in:
@@ -180,7 +180,7 @@ item/15/navigation_mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 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_transform = Transform3D(1.68, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
|
||||
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)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
[gd_scene format=3 uid="uid://b8yqx5v3n8u1p"]
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_wall"]
|
||||
size = Vector3(1, 2, 0.1)
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_wall"]
|
||||
albedo_color = Color(0.8, 0.2, 0.2, 0.8)
|
||||
emission_enabled = true
|
||||
emission = Color(1, 0, 0, 1)
|
||||
emission_energy_multiplier = 0.5
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_wall"]
|
||||
material = SubResource("StandardMaterial3D_wall")
|
||||
size = Vector3(1, 2, 0.1)
|
||||
|
||||
[node name="SafeZoneWall" type="StaticBody3D"]
|
||||
collision_layer = 1
|
||||
collision_mask = 0
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||
mesh = SubResource("BoxMesh_wall")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
shape = SubResource("BoxShape3D_wall")
|
||||
@@ -0,0 +1,18 @@
|
||||
[gd_scene format=3 uid="uid://cggmcgvdj6wxt"]
|
||||
|
||||
[ext_resource type="ArrayMesh" uid="uid://dtr46jmckif0p" path="res://assets/models/meshes/block.res" id="1_block"]
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_wall"]
|
||||
size = Vector3(1, 1.5, 1)
|
||||
|
||||
[node name="Wall3D" type="StaticBody3D" unique_id=992511920]
|
||||
collision_mask = 0
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=1405008923]
|
||||
transform = Transform3D(1.68, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
|
||||
mesh = ExtResource("1_block")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1446599023]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.35764623, 0)
|
||||
shape = SubResource("BoxShape3D_wall")
|
||||
debug_color = Color(0.94447005, 0.20628157, 0.3074098, 0.41960785)
|
||||
@@ -100,9 +100,9 @@ func simple_move_to(grid_position: Vector2i) -> bool:
|
||||
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
|
||||
if _is_position_blocked_by_physics(grid_position):
|
||||
print("[Move] Failed: Blocked by physics raycast at %s" % grid_position)
|
||||
# PHYSICS CHECK: Ensure no static obstacles (like Wall blocks or Stands) are blocking the path
|
||||
if _is_path_blocked_by_physics(player.current_position, grid_position):
|
||||
print("[Move] Failed: Path blocked by physics at %s" % grid_position)
|
||||
return false
|
||||
|
||||
if player.is_position_occupied(grid_position):
|
||||
@@ -512,30 +512,42 @@ func _can_push_to(pos: Vector2i) -> bool:
|
||||
if _is_position_in_static_stand_area(pos):
|
||||
return false
|
||||
|
||||
if _is_position_blocked_by_physics(pos):
|
||||
if _is_path_blocked_by_physics(player.current_position, pos):
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
func _is_position_blocked_by_physics(target_pos: Vector2i) -> bool:
|
||||
func _is_path_blocked_by_physics(from_grid: Vector2i, to_grid: Vector2i) -> bool:
|
||||
if not player.is_inside_tree(): return false
|
||||
|
||||
var space_state = player.get_world_3d().direct_space_state
|
||||
var center_x = target_pos.x + 0.5
|
||||
var center_z = target_pos.y + 0.5
|
||||
var from = Vector3(center_x, 1.0, center_z)
|
||||
var to = Vector3(center_x, 0.1, center_z)
|
||||
|
||||
var query = PhysicsRayQueryParameters3D.create(from, to)
|
||||
query.collide_with_areas = false
|
||||
query.collide_with_bodies = true
|
||||
# 1. Path check: Block movement if a wall exists between the current and target tile
|
||||
var from_v3 = Vector3(from_grid.x + 0.5, 0.5, from_grid.y + 0.5)
|
||||
var to_v3 = Vector3(to_grid.x + 0.5, 0.5, to_grid.y + 0.5)
|
||||
|
||||
var result = space_state.intersect_ray(query)
|
||||
if result:
|
||||
if result.collider != player:
|
||||
# ONLY block if it's a Static Tekton Stand
|
||||
# Ignore GridMap floors/walls, which are handled by get_cell_item rules
|
||||
if result.collider.name.find("StaticTektonStand") != -1 or result.collider.is_in_group("StaticTektonStands") or result.collider.has_method("is_stand"):
|
||||
return true
|
||||
var path_query = PhysicsRayQueryParameters3D.create(from_v3, to_v3)
|
||||
path_query.collide_with_areas = false
|
||||
path_query.collide_with_bodies = true
|
||||
|
||||
var path_result = space_state.intersect_ray(path_query)
|
||||
if path_result:
|
||||
if path_result.collider != player:
|
||||
# This correctly hits thin walls placed on tile boundaries
|
||||
return true
|
||||
|
||||
# 2. Target tile occupancy check: Block if a static object is in the middle of the tile
|
||||
var target_from = Vector3(to_grid.x + 0.5, 1.0, to_grid.y + 0.5)
|
||||
var target_to = Vector3(to_grid.x + 0.5, 0.1, to_grid.y + 0.5)
|
||||
|
||||
var target_query = PhysicsRayQueryParameters3D.create(target_from, target_to)
|
||||
target_query.collide_with_areas = false
|
||||
target_query.collide_with_bodies = true
|
||||
|
||||
var target_result = space_state.intersect_ray(target_query)
|
||||
if target_result:
|
||||
if target_result.collider != player:
|
||||
# This hits objects like Stands that sit in the center of the tile
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
@@ -21,6 +21,8 @@ const POWERUP_SPAWN_COUNT: int = 5 # Number of power-up tiles to spawn
|
||||
var powerups_spawned: bool = false
|
||||
var stop_phase_occurred: bool = false
|
||||
|
||||
var safe_zone_wall_scene = preload("res://scenes/wall_3d.tscn")
|
||||
|
||||
const PERMANENT_POWERUP_LOCATIONS: Array[Vector2i] = [
|
||||
Vector2i(4, 3), # Area 1
|
||||
Vector2i(8, 7), # Area 2
|
||||
@@ -657,45 +659,18 @@ func sync_safe_zone(centers: Array, radius: int):
|
||||
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)
|
||||
# 2. Instantiate North and South walls (Horizontal)
|
||||
for dx in range(-radius, radius + 1):
|
||||
if dx == 0: continue # Opening
|
||||
_instantiate_safe_zone_wall(Vector3(center.x + dx + 0.5, 0.0, center.y - radius), 0)
|
||||
_instantiate_safe_zone_wall(Vector3(center.x + dx + 0.5, 0.0, center.y + radius + 1), 0)
|
||||
|
||||
# 3. Instantiate East and West walls (Vertical - 4 walls each)
|
||||
# From -2 to 2 (radius), with center opening = 4 walls per side
|
||||
for dz in range(-radius, radius + 1):
|
||||
if dz == 0: continue # Opening
|
||||
_instantiate_safe_zone_wall(Vector3(center.x - radius, 0.0, center.y + dz + 0.5), 90)
|
||||
_instantiate_safe_zone_wall(Vector3(center.x + radius + 1, 0.0, center.y + dz + 0.5), 90)
|
||||
|
||||
# Update pathfinding for bots and movement checks
|
||||
gridmap.initialize_astar()
|
||||
@@ -728,16 +703,9 @@ func sync_clear_safe_zone(centers_to_clear: Array):
|
||||
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)
|
||||
# Also clean up walls
|
||||
for wall in get_tree().get_nodes_in_group("SafeZoneWalls"):
|
||||
wall.queue_free()
|
||||
|
||||
# Clear local state
|
||||
safe_zone_centers = []
|
||||
@@ -751,6 +719,15 @@ func sync_clear_safe_zone(centers_to_clear: Array):
|
||||
safe_zone_centers = []
|
||||
safe_zone_spawned = false
|
||||
|
||||
func _instantiate_safe_zone_wall(pos: Vector3, rotation_deg: float):
|
||||
if not safe_zone_wall_scene: return
|
||||
|
||||
var wall = safe_zone_wall_scene.instantiate()
|
||||
add_child(wall)
|
||||
wall.add_to_group("SafeZoneWalls")
|
||||
wall.position = pos
|
||||
wall.rotation_degrees.y = rotation_deg
|
||||
|
||||
# =============================================================================
|
||||
# Power-Up Tile Spawning (Speed & Ghost)
|
||||
# =============================================================================
|
||||
|
||||
Reference in New Issue
Block a user