[SOLVED] Is there a way to detect collisions/areas on a precise coordinate while ignoring objects on the way there?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By AtlasCrusader

I’m making a grid style game that let’s you move freely around the map while out of combat. But when combat starts, it turn’s into a tactical turn based game. Something akin to Divinity Original Sin, but with the grid structure from D&D.

I’m having trouble figuring out the combat portion. I plan to use AStar for the AI, so I gave each Enemy it’s own TileMap to serve as it’s “awareness”. This way AStar only has to work on something like (15, 15) as opposed to a huge map. I have it to the point where the Enemy can tell me the coordinates of it’s surrounding “tiles”. I tried using RayCast on those coordinates, but it collides with the first object it comes into contact with. Since this is tactical, the entity will need to move around objects and plan it’s moves.
Is there a way to check if there’s a body/Area in a specific coordinate while ignoring any intervening objects?
Or am I way off the mark, and there’s an easier way to go about it?

Someone helped me out on Reddit. He suggested using the
intersect-point

AtlasCrusader | 2020-07-18 18:50

Wanted to share. My players and enemies are in a huge map, but wanted to use AStar for them to get to the target. I have it working by having each entity have a TileMap node that will work as their “awareness, or sight”. This is why I wanted to know my surroundings without raycast, as it’s a tile based game similar to D&D. The current settings of the intersect_point has 63 (binary) for the collision check, as I only care about collision mask’s 0 - 5. The tiles on my game are 32 x 32.

I hard coded the start position and end position. But you should be able to make the changes you need.

extends TileMap

# You can only create an AStar node from code, not from the Scene tab
onready var astar_node = AStar.new()
onready var obstacles = []

# The Tilemap node doesn't have clear bounds so we're defining the map's limits here
#using 17x17 we have an awareness of 8 spaces to every direction from the center
export(Vector2) var map_size = Vector2(17, 17)

#var path_start_position = Vector2() setget _set_path_start_position
var path_start_position = Vector2(8, 8)
#var path_end_position = Vector2() setget _set_path_end_position
var path_end_position = Vector2(6, 9)
var tile_size = 32
var _point_path = []



func _ready():
	var cells_list = astar_add_cells()
	var good_spots = []
	for place in cells_list:
		var coords = global_position + place * tile_size
		if check_coords(coords) != true:
			good_spots.append(place)
		else:
			if place == path_start_position:
				pass
			else:
				obstacles.append(place)
	astar_connect_walkable_cells(good_spots)

#With this function we can check what's inside of each of these coordinates to 
#start picking which places are already occupied
func check_coords(coords):
	var colliding_objects
	var space = get_world_2d().get_space()
	var space_state = Physics2DServer.space_get_direct_state(space)
	colliding_objects = space_state.intersect_point(coords, 225, [], 63, 16)
	if colliding_objects.empty() == true:
		return false
	else:
		return true

func astar_add_cells():
	var points_array = []
	for y in range(map_size.y):
		for x in range(map_size.x):
			var point = Vector2(x, y)
			points_array.append(point)
			var point_index = calculate_point_index(point)
			astar_node.add_point(point_index, Vector3(point.x, point.y, 0.0))
	return points_array

func astar_connect_walkable_cells(good_spots):
	for point in good_spots:
		var point_index = calculate_point_index(point)
		var points_relative = PoolVector2Array([
			Vector2(point.x + 1, point.y),
			Vector2(point.x - 1, point.y),
			Vector2(point.x, point.y + 1),
			Vector2(point.x, point.y - 1)])
		for point_relative in points_relative:
			var point_relative_index = calculate_point_index(point_relative)
			if point_relative in obstacles:
				pass
			else:
				astar_node.connect_points(point_index, point_relative_index, true)
	find_path(path_start_position, path_end_position)

func calculate_point_index(point):
	return point.x + map_size.x * point.y

func find_path(path_start_position, path_end_position):
	_recalculate_path()
	var path_world = []
	for point in _point_path:
		var coordinate = Vector2(point.x, point.y)
		var point_world = global_position + coordinate * tile_size
		path_world.append(point_world)
	path_world.remove(0)
	return path_world


func _recalculate_path():
	var start_point_index = calculate_point_index(path_start_position)
	var end_point_index = calculate_point_index(path_end_position)
	_point_path = astar_node.get_point_path(start_point_index, end_point_index)

AtlasCrusader | 2020-07-19 19:12