update obstacles
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -249,6 +249,9 @@ func place_obstacle(grid_position: Vector2i):
|
||||
# Don't exit the obstacle placement mode to allow multiple placements
|
||||
local_player_character.highlight_valid_obstacle_cells()
|
||||
|
||||
# Exit obstacle placement mode and return to default state
|
||||
set_action_state(ActionState.NONE)
|
||||
|
||||
# Sync the obstacle with other clients
|
||||
if is_multiplayer_authority():
|
||||
rpc("sync_place_obstacle", grid_position.x, grid_position.y, floor_index, current_obstacle_item, direction)
|
||||
|
||||
+70
-23
@@ -297,6 +297,45 @@ func is_within_movement_range(target_position: Vector2i) -> bool:
|
||||
distance = abs(target_position.x - current_position.x) + abs(target_position.y - current_position.y)
|
||||
return distance <= movement_range
|
||||
|
||||
#func move_player_to_clicked_position(grid_position: Vector2i):
|
||||
#if not is_multiplayer_authority() or is_player_moving or action_points <= 0:
|
||||
#return
|
||||
#
|
||||
#var main = get_tree().get_root().get_node_or_null("Main")
|
||||
#if not main or main.current_action_state != main.ActionState.MOVING or not grid_position in highlighted_cells:
|
||||
#return
|
||||
#
|
||||
#if not is_within_movement_range(grid_position):
|
||||
#return
|
||||
#
|
||||
#var cell_item = enhanced_gridmap.get_cell_item(Vector3i(grid_position.x, 0, grid_position.y))
|
||||
#if cell_item in enhanced_gridmap.non_walkable_items or is_position_occupied(grid_position):
|
||||
#return
|
||||
#
|
||||
#rotate_towards_target(grid_position)
|
||||
#
|
||||
#var path = enhanced_gridmap.find_path(Vector2(current_position), Vector2(grid_position))
|
||||
#if path.size() <= 1:
|
||||
#return
|
||||
#
|
||||
#var valid_path = true
|
||||
#for point in path.slice(1):
|
||||
#if is_position_occupied(Vector2i(point.x, point.y)):
|
||||
#valid_path = false
|
||||
#break
|
||||
#
|
||||
#if valid_path:
|
||||
#path.pop_front()
|
||||
## Pass clear_visual=false for bots to preserve player highlights
|
||||
#rpc("start_movement_along_path", path, not (is_bot or is_in_group("Bots")))
|
||||
#action_points -= 1
|
||||
#
|
||||
## Only clear highlights if not a bot
|
||||
#if not (is_bot or is_in_group("Bots")):
|
||||
#clear_highlights()
|
||||
#else:
|
||||
#print("Path is blocked by other players")
|
||||
|
||||
func move_player_to_clicked_position(grid_position: Vector2i):
|
||||
if not is_multiplayer_authority() or is_player_moving or action_points <= 0:
|
||||
return
|
||||
@@ -312,29 +351,25 @@ func move_player_to_clicked_position(grid_position: Vector2i):
|
||||
if cell_item in enhanced_gridmap.non_walkable_items or is_position_occupied(grid_position):
|
||||
return
|
||||
|
||||
# Check if direct movement is blocked by an obstacle
|
||||
if enhanced_gridmap.is_blocked_by_obstacle(current_position, grid_position, 3):
|
||||
# Do not allow movement if blocked (this should not happen if highlight logic is correct)
|
||||
print("Movement blocked by obstacle")
|
||||
return
|
||||
|
||||
rotate_towards_target(grid_position)
|
||||
|
||||
var path = enhanced_gridmap.find_path(Vector2(current_position), Vector2(grid_position))
|
||||
if path.size() <= 1:
|
||||
return
|
||||
|
||||
var valid_path = true
|
||||
for point in path.slice(1):
|
||||
if is_position_occupied(Vector2i(point.x, point.y)):
|
||||
valid_path = false
|
||||
break
|
||||
|
||||
if valid_path:
|
||||
path.pop_front()
|
||||
# Pass clear_visual=false for bots to preserve player highlights
|
||||
rpc("start_movement_along_path", path, not (is_bot or is_in_group("Bots")))
|
||||
action_points -= 1
|
||||
|
||||
# Only clear highlights if not a bot
|
||||
if not (is_bot or is_in_group("Bots")):
|
||||
clear_highlights()
|
||||
else:
|
||||
print("Path is blocked by other players")
|
||||
# Create a direct path rather than using A* for obstacle avoidance
|
||||
# This ensures the player can only move to directly accessible positions
|
||||
var path = [Vector2(current_position.x, current_position.y), Vector2(grid_position.x, grid_position.y)]
|
||||
path.pop_front()
|
||||
|
||||
rpc("start_movement_along_path", path, not (is_bot or is_in_group("Bots")))
|
||||
action_points -= 1
|
||||
|
||||
# Clear highlights after moving
|
||||
if not (is_bot or is_in_group("Bots")):
|
||||
clear_highlights()
|
||||
|
||||
@rpc("any_peer", "call_local")
|
||||
func start_movement_along_path(path: Array, clear_visual: bool = true):
|
||||
@@ -815,13 +850,25 @@ func highlight_movement_range():
|
||||
return
|
||||
|
||||
var cells_to_highlight = []
|
||||
|
||||
# Only highlight cells within movement range that aren't blocked by obstacles
|
||||
for x in range(enhanced_gridmap.columns):
|
||||
for z in range(enhanced_gridmap.rows):
|
||||
var test_pos = Vector2i(x, z)
|
||||
|
||||
# Skip the current position
|
||||
if test_pos == current_position:
|
||||
continue
|
||||
|
||||
# Check if within movement range
|
||||
if is_within_movement_range(test_pos):
|
||||
var cell_item = enhanced_gridmap.get_cell_item(Vector3i(x, 0, z))
|
||||
|
||||
# Check if cell is walkable and not occupied
|
||||
if cell_item != -1 and not (cell_item in enhanced_gridmap.non_walkable_items) and not is_position_occupied(test_pos):
|
||||
cells_to_highlight.append(test_pos)
|
||||
# Most importantly, check if movement is blocked by obstacles
|
||||
if not enhanced_gridmap.is_blocked_by_obstacle(current_position, test_pos, 3):
|
||||
cells_to_highlight.append(test_pos)
|
||||
|
||||
highlight_cells_if_authorized(cells_to_highlight)
|
||||
|
||||
@@ -976,7 +1023,7 @@ func clear_highlights():
|
||||
child.hide()
|
||||
|
||||
# Restore highlights based on current action state
|
||||
if main and current_state == main.ActionState.MOVING and is_my_turn:
|
||||
if main and current_state == main.ActionState.MOVING and is_my_turn and current_state != main.ActionState.PLACING_OBSTACLE:
|
||||
highlight_movement_range()
|
||||
|
||||
func clear_playerboard_highlights():
|
||||
|
||||
Reference in New Issue
Block a user