66 lines
1.8 KiB
C#
66 lines
1.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Game.Features.Interactions.Contracts;
|
|
using Godot;
|
|
|
|
namespace Game.Features.Interactions.Godot;
|
|
|
|
public partial class InteractionWorldController : Node, IInteractionWorld
|
|
{
|
|
public const string RegistryGroup = "interaction_world_registry";
|
|
|
|
private readonly Dictionary<InteractionTargetId, WorldInteractionController> _targets = [];
|
|
|
|
public override void _EnterTree()
|
|
{
|
|
AddToGroup(RegistryGroup);
|
|
}
|
|
|
|
public void RegisterSceneTargets()
|
|
{
|
|
foreach (Node node in GetTree().GetNodesInGroup(WorldInteractionController.InteractionGroup))
|
|
{
|
|
if (node is WorldInteractionController target)
|
|
{
|
|
Register(target);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Register(WorldInteractionController target)
|
|
{
|
|
if (_targets.TryGetValue(target.Id, out WorldInteractionController existing))
|
|
{
|
|
if (ReferenceEquals(existing, target))
|
|
{
|
|
return;
|
|
}
|
|
|
|
throw new InvalidOperationException($"Duplicate interaction target id: {target.Id}.");
|
|
}
|
|
|
|
_targets.Add(target.Id, target);
|
|
target.RegisterWith(this);
|
|
}
|
|
|
|
public void Unregister(InteractionTargetId targetId)
|
|
{
|
|
_targets.Remove(targetId);
|
|
}
|
|
|
|
public InteractionResult TryInteract(InteractionRequest request)
|
|
{
|
|
if (!_targets.TryGetValue(request.TargetId, out WorldInteractionController target))
|
|
{
|
|
return InteractionResult.Fail(InteractionStatus.TargetNotFound, $"Target {request.TargetId} was not found.");
|
|
}
|
|
|
|
if (!target.CanInteract)
|
|
{
|
|
return InteractionResult.Fail(InteractionStatus.Unavailable, "The target is not currently available.");
|
|
}
|
|
|
|
return target.Execute(request.PlayerId);
|
|
}
|
|
}
|