From 58142e9d67a9bc4fdfe826f8c587a6bdf30518f0 Mon Sep 17 00:00:00 2001 From: adtpdn Date: Wed, 12 Mar 2025 17:53:19 +0800 Subject: [PATCH] update obstacle to simplify with neighboor --- addons/enhanced_gridmap/enhanced_gridmap.gd | 149 +++++++++++++------- scenes/main.gd | 21 ++- 2 files changed, 109 insertions(+), 61 deletions(-) diff --git a/addons/enhanced_gridmap/enhanced_gridmap.gd b/addons/enhanced_gridmap/enhanced_gridmap.gd index 7215e0b..e0d6ba5 100644 --- a/addons/enhanced_gridmap/enhanced_gridmap.gd +++ b/addons/enhanced_gridmap/enhanced_gridmap.gd @@ -24,8 +24,8 @@ var astar_by_floor = {} # Dictionary of AStar2D instances per floor var path = [] # Update the obstacle items array to use your specified item indices -@export var obstacle_items: Array[int] = [12, 13, 14, 15] # Updated mesh library indices -@export var obstacle_directions: Array[Direction] = [] # Store the directions of placed obstacles +@export var obstacle_items: Array[int] = [12, 13, 14, 15] # Obstacle items in mesh library +@export var obstacle_directions: Dictionary = {} # Store direction for each placed obstacle: {Vector3i position: Direction} # Direction and movement systems @@ -587,47 +587,95 @@ func set_diagonal_movement(enable: bool): #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): - 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_directions.size() > obstacle_idx: - var dir = obstacle_directions[obstacle_idx] - if dir == Direction.BLOCKED_NORTH or dir == Direction.BLOCKED_SOUTH: - return true + # Determine movement direction (without using normalized for Vector2i) + var diff_x = to_pos.x - from_pos.x + var diff_y = to_pos.y - from_pos.y - # 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): - 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_directions.size() > obstacle_idx: - var dir = obstacle_directions[obstacle_idx] - if dir == Direction.BLOCKED_EAST or dir == Direction.BLOCKED_WEST: - return true + # Convert to direction based on sign + var dir_x = 0 + var dir_y = 0 + if diff_x != 0: dir_x = 1 if diff_x > 0 else -1 + if diff_y != 0: dir_y = 1 if diff_y > 0 else -1 - # 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 + # Check for obstacles at both cells + var from_obstacle = get_cell_item(Vector3i(from_pos.x, floor_index, from_pos.y)) + var to_obstacle = get_cell_item(Vector3i(to_pos.x, floor_index, to_pos.y)) + # Check obstacle at starting position + if from_obstacle in obstacle_items: + var from_pos_3d = Vector3i(from_pos.x, floor_index, from_pos.y) + var from_dir = Direction.CENTER + + # Use safe dictionary access + if obstacle_directions.has(from_pos_3d): + from_dir = obstacle_directions[from_pos_3d] + + # Block movement based on obstacle direction + match from_dir: + Direction.NORTH: # Blocks south movement + if dir_y > 0: return true + Direction.EAST: # Blocks west movement + if dir_x < 0: return true + Direction.SOUTH: # Blocks north movement + if dir_y < 0: return true + Direction.WEST: # Blocks east movement + if dir_x > 0: return true + + # Check obstacle at destination position + if to_obstacle in obstacle_items: + var to_pos_3d = Vector3i(to_pos.x, floor_index, to_pos.y) + var to_dir = Direction.CENTER + + # Use safe dictionary access + if obstacle_directions.has(to_pos_3d): + to_dir = obstacle_directions[to_pos_3d] + + # Block movement based on obstacle direction (from opposite side) + match to_dir: + Direction.NORTH: # Blocks south movement (coming from north) + if dir_y < 0: return true + Direction.EAST: # Blocks west movement (coming from east) + if dir_x > 0: return true + Direction.SOUTH: # Blocks north movement (coming from south) + if dir_y > 0: return true + Direction.WEST: # Blocks east movement (coming from west) + if dir_x < 0: return true + + # Check intermediate cell for vertical/horizontal movement + if from_pos.x != to_pos.x and from_pos.y == to_pos.y: # Horizontal movement + var x_step = 1 if to_pos.x > from_pos.x else -1 + var intermediate_x = from_pos.x + x_step + while intermediate_x != to_pos.x: + var inter_obstacle = get_cell_item(Vector3i(intermediate_x, floor_index, from_pos.y)) + if inter_obstacle in obstacle_items: + var inter_pos_3d = Vector3i(intermediate_x, floor_index, from_pos.y) + var inter_dir = Direction.CENTER + + # Use safe dictionary access + if obstacle_directions.has(inter_pos_3d): + inter_dir = obstacle_directions[inter_pos_3d] + + if inter_dir == Direction.NORTH or inter_dir == Direction.SOUTH: + return true + intermediate_x += x_step + elif from_pos.x == to_pos.x and from_pos.y != to_pos.y: # Vertical movement + var y_step = 1 if to_pos.y > from_pos.y else -1 + var intermediate_y = from_pos.y + y_step + while intermediate_y != to_pos.y: + var inter_obstacle = get_cell_item(Vector3i(from_pos.x, floor_index, intermediate_y)) + if inter_obstacle in obstacle_items: + var inter_pos_3d = Vector3i(from_pos.x, floor_index, intermediate_y) + var inter_dir = Direction.CENTER + + # Use safe dictionary access + if obstacle_directions.has(inter_pos_3d): + inter_dir = obstacle_directions[inter_pos_3d] + + if inter_dir == Direction.EAST or inter_dir == Direction.WEST: + return true + intermediate_y += y_step + + # If none of the above conditions triggered, movement is allowed return false func place_obstacle(pos: Vector3i, obstacle_item: int, direction: Direction) -> bool: @@ -639,26 +687,19 @@ func place_obstacle(pos: Vector3i, obstacle_item: int, direction: Direction) -> set_cell_item(pos, obstacle_item) - # Store the direction of the obstacle - var item_index = obstacle_items.find(obstacle_item) - if item_index == -1: - item_index = 0 # Default to first item if not found - - while obstacle_directions.size() <= item_index: - obstacle_directions.append(Direction.CENTER) # Default - - obstacle_directions[item_index] = direction + # Store the direction of the obstacle correctly in the dictionary + obstacle_directions[pos] = direction # Update the cell's orientation based on direction var orientation = 0 match direction: - Direction.BLOCKED_NORTH: + Direction.NORTH: orientation = 0 # Default orientation - Direction.BLOCKED_EAST: - orientation = 1 # 90 degrees clockwise - Direction.BLOCKED_SOUTH: + Direction.EAST: + orientation = 1 # 90 degrees clockwise + Direction.SOUTH: orientation = 2 # 180 degrees - Direction.BLOCKED_WEST: + Direction.WEST: orientation = 3 # 270 degrees clockwise set_cell_item(pos, obstacle_item, orientation) diff --git a/scenes/main.gd b/scenes/main.gd index 68ef3e5..451766a 100644 --- a/scenes/main.gd +++ b/scenes/main.gd @@ -67,8 +67,8 @@ enum ActionState { } # Obstacle -var current_obstacle_direction = ObstacleDirection.VERTICAL -var obstacle_item_index = 12 # Default obstacle item index in mesh library +# Add these properties to track the current obstacle direction +var current_obstacle_direction = EnhancedGridMap.Direction.NORTH # Default to NORTH var current_obstacle_item = 12 # Starting with first obstacle item (12) enum ObstacleDirection { @@ -997,12 +997,11 @@ func setup_obstacle_ui(): obstacle_button.pressed.connect(func(): set_action_state(ActionState.PLACING_OBSTACLE)) $ActionMenu/ActionButtonContainer.add_child(obstacle_button) - # Create the direction toggle button + # Create the direction cycle button var direction_button = Button.new() - direction_button.text = "Direction: Vertical" + direction_button.text = "Direction: North" direction_button.pressed.connect(func(): - current_obstacle_direction = ObstacleDirection.HORIZONTAL if current_obstacle_direction == ObstacleDirection.VERTICAL else ObstacleDirection.VERTICAL - direction_button.text = "Direction: " + ("Horizontal" if current_obstacle_direction == ObstacleDirection.HORIZONTAL else "Vertical") + direction_button.text = cycle_obstacle_direction() ) $ActionMenu/ActionButtonContainer.add_child(direction_button) @@ -1014,7 +1013,6 @@ func setup_obstacle_ui(): ) $ActionMenu/ActionButtonContainer.add_child(type_button) - # Add a function to cycle through obstacle types func cycle_obstacle_type(): var obstacle_types = [12, 13, 14, 15] @@ -1023,6 +1021,15 @@ func cycle_obstacle_type(): current_obstacle_item = obstacle_types[current_index] return "Type: " + str(current_index + 1) +func cycle_obstacle_direction(): + var directions = [EnhancedGridMap.Direction.NORTH, EnhancedGridMap.Direction.EAST, EnhancedGridMap.Direction.SOUTH, EnhancedGridMap.Direction.WEST] + var current_index = directions.find(current_obstacle_direction) + current_index = (current_index + 1) % directions.size() + current_obstacle_direction = directions[current_index] + + var direction_names = ["North", "East", "South", "West"] + return "Direction: " + direction_names[current_index] + func update_board_slot(board_ui: Node, slot_idx: int, value: int): var slot_node = board_ui.get_node_or_null("Slot%d" % (slot_idx + 1)) if slot_node: