diff --git a/systems/grid.gd b/systems/grid.gd index 8a26b15..d713b45 100644 --- a/systems/grid.gd +++ b/systems/grid.gd @@ -120,16 +120,46 @@ func get_empty_stoppable(rule: Callable, unit: Unit, rays: int = 8) -> Array[int func raycast_unit(from: Vector2,direction: Vector2,distance: float = -1) -> Unit: if not direction.is_normalized(): direction = direction.normalized() - var result = null + var result: Unit = null - var to: Vector2 = from + direction * rows * columns - var dv: Vector2 = to.floor() - from.floor() - var step = abs(dv.x) + 1 if abs(dv.x) > abs(dv.y) else abs(dv.y) + 1 - var check_pos = from + # Simple algorithm + var step: float = max(abs(direction.x),abs(direction.y)) + var step_v: Vector2 = Vector2(direction.x/step,direction.y/step) - while is_position_valid(check_pos) and distance != 0: - check_pos += dv/step - distance -= 1 + var check_position: Vector2 = from + step_v * cell_size + while is_position_valid(check_position) and distance != 0: + var index: int = to_index(check_position) + if index == -1: + break + + if grid[index] != null: + result = grid[index] + break + + check_position += step_v * cell_size + + return result + +## Casts a ray along [code]direction[/code] from [code]from[/code] to find all units along the line. If distance is given, restricts lookup to [code]distance[/code] cells. +func raycast_units(from: Vector2,direction: Vector2,distance: float = -1) -> Array[Unit]: + if not direction.is_normalized(): + direction = direction.normalized() + var result: Array[Unit] = [] + + # Simple algorithm + var step: float = max(abs(direction.x),abs(direction.y)) + var step_v: Vector2 = Vector2(direction.x/step,direction.y/step) + + var check_position: Vector2 = from + step_v * cell_size + while is_position_valid(check_position) and distance != 0: + var index: int = to_index(check_position) + if index == -1: + break + + if grid[index] != null: + result.append(grid[index]) + + check_position += step_v * cell_size return result @@ -139,31 +169,19 @@ func raycast_empty(from: Vector2,direction: Vector2,distance: float = -1) -> Arr direction = direction.normalized() var result: Array[int] = [] - var dv: Vector2 = (Vector2.ONE/direction).round() - var steps_y: int = int(abs(dv.y)) - var steps_x: int = int(abs(dv.x)) - var check_pos = from.floor() - var change_y: bool = true if abs(dv.y) > abs(dv.x) else false + # Simple algorithm + var step: float = max(abs(direction.x),abs(direction.y)) + var step_v: Vector2 = Vector2(direction.x/step,direction.y/step) - while is_position_valid(check_pos) and distance != 0: - if steps_x == 0: - steps_x = int(abs(dv.x)) - change_y = true - elif steps_y == 0: - steps_y = int(abs(dv.y)) - change_y = false - - if change_y: - check_pos += Vector2(0,sign(dv.y)) * cell_size - steps_y-=1 - else: - check_pos += Vector2(sign(dv.x),0) * cell_size - steps_x -= 1 - - var index = to_index(check_pos) + var check_position: Vector2 = from + step_v * cell_size + while is_position_valid(check_position) and distance != 0: + var index: int = to_index(check_position) if index == -1: break + if grid[index] == null: result.append(index) + + check_position += step_v * cell_size return result