extends GDGSAIProximity
class_name GDGSAIRadiusProximity

# Determines any agent that is in the specified list as being neighbors with the owner agent if
# they lie within the specified radius.
# @category - Proximities

# The radius around the owning agent to find neighbors in
var radius : float = 0.0

var _last_frame : int = 0
var _scene_tree : SceneTree


func _init() -> void:
	_scene_tree = Engine.get_main_loop()

# Returns a number of neighbors based on a `callback` function.
#
# `_find_neighbors` calls `callback` for each agent in the `agents` array that lie within
# the radius around the owning agent and adds one to the count if its `callback` returns true.
# @tags - virtual
func _find_neighbors(callback : FuncRef) -> int:
	var agent_count : int = agents.size()
	var neighbor_count : int = 0

	var current_frame : int
	
	if _scene_tree:
		current_frame = _scene_tree.get_frame()  
	else:
		current_frame = -_last_frame
	
	if current_frame != _last_frame:
		_last_frame = current_frame

		var owner_position : Vector3 = agent.position

		for i in range(agent_count):
			var current_agent : GDGSAISteeringAgent = agents[i] as GDGSAISteeringAgent

			if current_agent != agent:
				var distance_squared : float = owner_position.distance_squared_to(current_agent.position)

				var range_to : float = radius + current_agent.bounding_radius

				if distance_squared < range_to * range_to:
					if callback.call_func(current_agent):
						current_agent.is_tagged = true
						neighbor_count += 1
						continue

			current_agent.is_tagged = false
	else:
		for i in range(agent_count):
			var current_agent : GDGSAISteeringAgent = agents[i] as GDGSAISteeringAgent

			if current_agent != agent and current_agent.is_tagged:
				if callback.call_func(current_agent):
					neighbor_count += 1

	return neighbor_count
