|
class_name AStarNavServer |
|
extends RefCounted |
|
|
|
static var map: TileMap |
|
|
|
static var astar: AStarGrid2D |
|
|
|
static var cell_size: Vector2i |
|
|
|
static func _static_init() -> void: |
|
map = null |
|
astar = null |
|
cell_size = Vector2i(0, 0) |
|
|
|
static func load_tile_map(tm: TileMap) -> void: |
|
map = tm |
|
astar = AStarGrid2D.new() |
|
cell_size = tm.tile_set.tile_size |
|
map.ready.connect(init_astar) |
|
|
|
static func init_astar() -> void: |
|
astar.region = map.get_used_rect() |
|
astar.cell_size = cell_size |
|
astar.offset = cell_size * 0.5 |
|
astar.default_compute_heuristic = AStarGrid2D.HEURISTIC_MANHATTAN |
|
astar.default_estimate_heuristic = AStarGrid2D.HEURISTIC_MANHATTAN |
|
astar.diagonal_mode = AStarGrid2D.DIAGONAL_MODE_NEVER |
|
astar.jumping_enabled = true |
|
astar.update() |
|
|
|
var floor_tiles: Array[Vector2i] = map.get_used_cells(0) |
|
var world_tiles: Array[Vector2i] = map.get_used_cells(1) |
|
|
|
for tile in floor_tiles: |
|
if world_tiles.has(tile): |
|
astar.set_point_solid(tile) |
|
|
|
map.ready.disconnect(init_astar) |
|
|
|
static func round_global_position(global_position: Vector2) -> Vector2: |
|
return map.map_to_local(map.local_to_map(global_position)) |
|
|
|
static func is_point_walkable(local_position: Vector2) -> bool: |
|
var map_position = map.local_to_map(local_position) |
|
if astar.is_in_boundsv(map_position): |
|
return not astar.is_point_solid(map_position) |
|
return false |
|
|
|
static func find_path(from: Vector2, to: Vector2) -> PackedVector2Array: |
|
if not is_point_walkable(to): |
|
return PackedVector2Array() |
|
var start = map.local_to_map(from) |
|
var end = map.local_to_map(to) |
|
var path: PackedVector2Array = astar.get_point_path(start, end) |
|
return path.duplicate() |
|
|
|
static func calculate_velocity(agent_position: Vector2, target: Vector2, path: PackedVector2Array, target_reached: Signal) -> Vector2: |
|
if path.size() <= 0: |
|
return Vector2() |
|
if agent_position.distance_to(path[0]) < 1.0: |
|
path.remove_at(0) |
|
if path.size() <= 0: |
|
if agent_position.distance_squared_to(target) < (cell_size.length_squared() * 0.25): |
|
target_reached.emit() |
|
return Vector2() |
|
return calculate_velocity(agent_position, target, path, target_reached) |
|
return agent_position.direction_to(path[0]) |