extends RefCounted static func intercept(world_hit: Dictionary, start: Vector2, end: Vector2, mask: int, excluded: Array[RID], tree: SceneTree) -> Dictionary: var nearest := world_hit var distance := start.distance_squared_to(world_hit.position) if not world_hit.is_empty() else INF var segment := end-start var length_squared := segment.length_squared() if length_squared < 0.000001: return nearest for target in tree.get_nodes_in_group("shielded_combatants"): if not is_instance_valid(target) or target.is_queued_for_deletion(): continue if (int(target.collision_layer)&mask)==0 or target.get_rid() in excluded: continue if float(target.hull)<=0.0: continue if target.has_method("is_mini_boosting") and (bool(target.is_docked) or bool(target._is_destroyed)): continue var shield: Node2D if target.has_method("get_active_shield_visual"): shield = target.get_active_shield_visual() elif float(target.shields) > 0.0: shield = target.get_node_or_null("ShieldVisual") as Node2D if shield == null: continue var radius := float(shield.shield_radius)*shield.global_transform.x.length() var offset := start-shield.global_position var b := offset.dot(segment) var c := offset.length_squared()-radius*radius var discriminant := b*b-length_squared*c if discriminant < 0.0: continue var t := (-b-sqrt(discriminant))/length_squared if c < 0.0: t = 0.0 if t < 0.0 or t > 1.0: continue var point := start+segment*t var candidate := start.distance_squared_to(point) if candidate < distance: distance = candidate nearest = {"position":point,"collider":target,"normal":(point-shield.global_position).normalized(),"shield":true} return nearest