update obstacles

This commit is contained in:
2025-03-11 17:40:54 +08:00
parent 495c9c64a5
commit 161f03d931
3 changed files with 225 additions and 50 deletions
+152 -27
View File
@@ -267,6 +267,56 @@ func randomize_floor_custom(randomize_states: Array, floor_index: int):
set_cell_item(cell_pos, normal_items[0], current_orientation)
# Improved neighbor checking system
#func get_neighbors(current_pos: Vector2i, floor_index: int) -> Array[NeighborInfo]:
#var neighbors: Array[NeighborInfo] = []
#
#var directions = {
#Direction.NORTHWEST: Vector2i(-1, -1),
#Direction.NORTH: Vector2i(0, -1),
#Direction.NORTHEAST: Vector2i(1, -1),
#Direction.WEST: Vector2i(-1, 0),
#Direction.EAST: Vector2i(1, 0),
#Direction.SOUTHWEST: Vector2i(-1, 1),
#Direction.SOUTH: Vector2i(0, 1),
#Direction.SOUTHEAST: Vector2i(1, 1)
#}
#
#for dir in directions:
#var offset = directions[dir]
#var neighbor_pos = current_pos + offset
#
#if is_position_valid(neighbor_pos):
#var is_walkable = is_cell_walkable(neighbor_pos, floor_index)
#
#if is_diagonal_direction(dir):
#var adjacent1: Vector2i
#var adjacent2: Vector2i
#
#match dir:
#Direction.NORTHWEST:
#adjacent1 = current_pos + Vector2i(-1, 0)
#adjacent2 = current_pos + Vector2i(0, -1)
#Direction.NORTHEAST:
#adjacent1 = current_pos + Vector2i(1, 0)
#adjacent2 = current_pos + Vector2i(0, -1)
#Direction.SOUTHWEST:
#adjacent1 = current_pos + Vector2i(-1, 0)
#adjacent2 = current_pos + Vector2i(0, 1)
#Direction.SOUTHEAST:
#adjacent1 = current_pos + Vector2i(1, 0)
#adjacent2 = current_pos + Vector2i(0, 1)
#
#is_walkable = is_walkable and \
#is_position_valid(adjacent1) and is_cell_walkable(adjacent1, floor_index) and \
#is_position_valid(adjacent2) and is_cell_walkable(adjacent2, floor_index) and \
#not is_blocked_by_obstacle(current_pos, adjacent1, floor_index) and \
#not is_blocked_by_obstacle(current_pos, adjacent2, floor_index)
#
#if diagonal_movement or not is_diagonal_direction(dir):
#neighbors.append(NeighborInfo.new(neighbor_pos, dir, is_walkable))
#
#return neighbors
func get_neighbors(current_pos: Vector2i, floor_index: int) -> Array[NeighborInfo]:
var neighbors: Array[NeighborInfo] = []
@@ -288,29 +338,36 @@ func get_neighbors(current_pos: Vector2i, floor_index: int) -> Array[NeighborInf
if is_position_valid(neighbor_pos):
var is_walkable = is_cell_walkable(neighbor_pos, floor_index)
# Check for obstacles - specifically for orthogonal movement
if not is_diagonal_direction(dir) and is_blocked_by_obstacle(current_pos, neighbor_pos, 3):
is_walkable = false
# Special handling for diagonal movement
if is_diagonal_direction(dir):
var adjacent1: Vector2i
var adjacent2: Vector2i
match dir:
Direction.NORTHWEST:
adjacent1 = current_pos + Vector2i(-1, 0)
adjacent2 = current_pos + Vector2i(0, -1)
adjacent1 = current_pos + Vector2i(-1, 0) # West
adjacent2 = current_pos + Vector2i(0, -1) # North
Direction.NORTHEAST:
adjacent1 = current_pos + Vector2i(1, 0)
adjacent2 = current_pos + Vector2i(0, -1)
adjacent1 = current_pos + Vector2i(1, 0) # East
adjacent2 = current_pos + Vector2i(0, -1) # North
Direction.SOUTHWEST:
adjacent1 = current_pos + Vector2i(-1, 0)
adjacent2 = current_pos + Vector2i(0, 1)
adjacent1 = current_pos + Vector2i(-1, 0) # West
adjacent2 = current_pos + Vector2i(0, 1) # South
Direction.SOUTHEAST:
adjacent1 = current_pos + Vector2i(1, 0)
adjacent2 = current_pos + Vector2i(0, 1)
adjacent1 = current_pos + Vector2i(1, 0) # East
adjacent2 = current_pos + Vector2i(0, 1) # South
# For diagonal movement, both adjacent cells must be walkable
# AND the movements to those adjacent cells must not be blocked
is_walkable = is_walkable and \
is_position_valid(adjacent1) and is_cell_walkable(adjacent1, floor_index) and \
is_position_valid(adjacent2) and is_cell_walkable(adjacent2, floor_index) and \
not is_blocked_by_obstacle(current_pos, adjacent1, floor_index) and \
not is_blocked_by_obstacle(current_pos, adjacent2, floor_index)
is_position_valid(adjacent1) and is_cell_walkable(adjacent1, floor_index) and \
is_position_valid(adjacent2) and is_cell_walkable(adjacent2, floor_index) and \
not is_blocked_by_obstacle(current_pos, adjacent1, 3) and \
not is_blocked_by_obstacle(current_pos, adjacent2, 3)
if diagonal_movement or not is_diagonal_direction(dir):
neighbors.append(NeighborInfo.new(neighbor_pos, dir, is_walkable))
@@ -357,8 +414,11 @@ func initialize_astar():
if not astar.are_points_connected(current_point_id, neighbor_id):
var weight = 1.0 if not is_diagonal_direction(neighbor.direction) else 1.4142
astar.connect_points(current_point_id, neighbor_id, true)
astar.set_point_weight_scale(neighbor_id, weight)
# Check if movement is allowed by obstacles
if not is_blocked_by_obstacle(current_pos, neighbor.position, 3):
astar.connect_points(current_point_id, neighbor_id, true)
astar.set_point_weight_scale(neighbor_id, weight)
astar_by_floor[y] = astar
@@ -474,35 +534,100 @@ func set_diagonal_movement(enable: bool):
initialize_astar()
# Add this function to check if a movement is blocked by an obstacle
func is_blocked_by_obstacle(from_pos: Vector2i, to_pos: Vector2i, floor_index: int = 0) -> bool:
# Check if there's a horizontal obstacle
if from_pos.y == to_pos.y: # Moving horizontally
# Check for vertical obstacles that would block horizontal movement
#func is_blocked_by_obstacle(from_pos: Vector2i, to_pos: Vector2i, floor_index: int = 3) -> bool:
## Detect movement direction
#var diff_x = to_pos.x - from_pos.x
#var diff_y = to_pos.y - from_pos.y
#
## Case 1: Moving along X axis (horizontally)
#if diff_y == 0 and diff_x != 0:
## Check if there's a vertical obstacle blocking horizontal movement
#var min_x = min(from_pos.x, to_pos.x)
#var max_x = max(from_pos.x, to_pos.x)
#for x in range(min_x, max_x + 1):
#var cell_pos = Vector3i(x, floor_index, from_pos.y)
#var cell_index = get_cell_item(cell_pos)
#if cell_index in obstacle_items:
#var obstacle_idx = obstacle_items.find(cell_index)
#if obstacle_idx != -1 and obstacle_idx < obstacle_directions.size():
#var dir = obstacle_directions[obstacle_idx]
#if dir == Direction.BLOCKED_NORTH or dir == Direction.BLOCKED_SOUTH:
#return true
#
## Case 2: Moving along Y axis (vertically)
#if diff_x == 0 and diff_y != 0:
## Check if there's a horizontal obstacle blocking vertical movement
#var min_y = min(from_pos.y, to_pos.y)
#var max_y = max(from_pos.y, to_pos.y)
#for y in range(min_y, max_y + 1):
#var cell_pos = Vector3i(from_pos.x, floor_index, y)
#var cell_index = get_cell_item(cell_pos)
#if cell_index in obstacle_items:
#var obstacle_idx = obstacle_items.find(cell_index)
#if obstacle_idx != -1 and obstacle_idx < obstacle_directions.size():
#var dir = obstacle_directions[obstacle_idx]
#if dir == Direction.BLOCKED_EAST or dir == Direction.BLOCKED_WEST:
#return true
#
## Case 3: Diagonal movement - check if both direct paths are blocked
## This will force the player to take the longer route
#if diff_x != 0 and diff_y != 0:
## Check if moving horizontally first then vertically would be blocked
#var horiz_first = is_blocked_by_obstacle(from_pos, Vector2i(to_pos.x, from_pos.y), floor_index)
#var vert_second = is_blocked_by_obstacle(Vector2i(to_pos.x, from_pos.y), to_pos, floor_index)
#
## Check if moving vertically first then horizontally would be blocked
#var vert_first = is_blocked_by_obstacle(from_pos, Vector2i(from_pos.x, to_pos.y), floor_index)
#var horiz_second = is_blocked_by_obstacle(Vector2i(from_pos.x, to_pos.y), to_pos, floor_index)
#
## If both paths are blocked, then the diagonal movement is blocked
#if (horiz_first or vert_second) and (vert_first or horiz_second):
#return true
#
#return false
func is_blocked_by_obstacle(from_pos: Vector2i, to_pos: Vector2i, floor_index: int = 3) -> bool:
# Simple case: Moving horizontally (same Y)
if from_pos.y == to_pos.y:
# Check for vertical obstacles that block horizontal movement
var min_x = min(from_pos.x, to_pos.x)
var max_x = max(from_pos.x, to_pos.x)
for x in range(min_x, max_x + 1):
var cell_index = get_cell_item(Vector3i(x, floor_index, from_pos.y))
for x in range(min_x, max_x):
var cell_pos = Vector3i(x, floor_index, from_pos.y)
var cell_index = get_cell_item(cell_pos)
if cell_index in obstacle_items:
var obstacle_idx = obstacle_items.find(cell_index)
if obstacle_idx != -1 and obstacle_idx < obstacle_directions.size():
if obstacle_idx != -1 and obstacle_directions.size() > obstacle_idx:
var dir = obstacle_directions[obstacle_idx]
if dir == Direction.BLOCKED_NORTH or dir == Direction.BLOCKED_SOUTH:
return true
# Check if there's a vertical obstacle
if from_pos.x == to_pos.x: # Moving vertically
# Check for horizontal obstacles that would block vertical movement
# Simple case: Moving vertically (same X)
if from_pos.x == to_pos.x:
# Check for horizontal obstacles that block vertical movement
var min_y = min(from_pos.y, to_pos.y)
var max_y = max(from_pos.y, to_pos.y)
for y in range(min_y, max_y + 1):
var cell_index = get_cell_item(Vector3i(from_pos.x, floor_index, y))
for y in range(min_y, max_y):
var cell_pos = Vector3i(from_pos.x, floor_index, y)
var cell_index = get_cell_item(cell_pos)
if cell_index in obstacle_items:
var obstacle_idx = obstacle_items.find(cell_index)
if obstacle_idx != -1 and obstacle_idx < obstacle_directions.size():
if obstacle_idx != -1 and obstacle_directions.size() > obstacle_idx:
var dir = obstacle_directions[obstacle_idx]
if dir == Direction.BLOCKED_EAST or dir == Direction.BLOCKED_WEST:
return true
# For diagonal movement, if direct path is blocked, return true
# This ensures diagonal moves across obstacles aren't allowed
if from_pos.x != to_pos.x and from_pos.y != to_pos.y:
# Check if horizontal movement would be blocked
if is_blocked_by_obstacle(from_pos, Vector2i(to_pos.x, from_pos.y), floor_index):
return true
# Check if vertical movement would be blocked
if is_blocked_by_obstacle(Vector2i(from_pos.x, to_pos.y), to_pos, floor_index):
return true
return false
func place_obstacle(pos: Vector3i, obstacle_item: int, direction: Direction) -> bool: