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 readonly 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; if (area is DetectableInteractionArea detectable) { ulong id = detectable.GetInstanceId(); _areasInDetector.Add(id); CalculateClosestInteractable(); } } /// /// Called whenever this node exits an Area2D. /// /// public void OnExitedInteractable(Area2D area) { if (!_active || !InputService.Instance.InputEnabled) return; if (area is DetectableInteractionArea detectable) { ulong id = detectable.GetInstanceId(); if( _areasInDetector.Contains(id)) _areasInDetector.Remove(id); CalculateClosestInteractable(); } } private void CalculateClosestInteractable() { GD.Print($"Areas in detector: {_areasInDetector.Count}"); 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; } } GD.Print($"Closest interactable: {closestInteractable}"); _itemToTriggerResource.Payload = closestInteractable; } }