using System.Collections.Generic; using Babushka.scripts.CSharp.Common.Services; using Babushka.scripts.CSharp.Low_Code.Variables; using Godot; namespace Babushka.scripts.CSharp.Common.CharacterControls; /// /// Defines an Node with a used for detecting nodes. /// public partial class Detector : Area2D { [Export] private bool _active = true; [Export] private ShapeCast2D _shapeCast2D; [Export] private VariableResource _itemToTriggerResource; private List _areasInDetector = new(); public bool IsActive { get => _active; set { Visible = value; _active = value; } } public override void _Ready() { AreaEntered += OnEnteredInteractable; AreaExited += OnExitedInteractable; } /// /// Called every time this node enters an Area2D. /// /// public void OnEnteredInteractable(Area2D area) { if (!_active || !InputService.Instance.InputEnabled) return; PopulateList(); CalculateClosestInteractable(); } /// /// Called whenever this node exits an Area2D. /// /// public void OnExitedInteractable(Area2D area) { if (!_active || !InputService.Instance.InputEnabled) return; PopulateList(); CalculateClosestInteractable(); } private void PopulateList() { // repopulate the list of areas in the detector to account for enabled / disabled areas var currentOverlap = GetOverlappingAreas(); _areasInDetector = new List(); foreach (var area2D in currentOverlap) { if (area2D is DetectableInteractionArea detectable) { ulong id = detectable.GetInstanceId(); _areasInDetector.Add(id); } } } private void CalculateClosestInteractable() { float smallestDistance = float.MaxValue; string closestInteractable = null; foreach (var area in _areasInDetector) { Area2D? area2D = InstanceFromId(area) as Area2D; if(area2D == null) continue; float distance = area2D.GlobalPosition.DistanceSquaredTo(ToGlobal(_shapeCast2D.TargetPosition)); if (distance < smallestDistance) { closestInteractable = area.ToString(); smallestDistance = distance; } } _itemToTriggerResource.Payload = closestInteractable; } }