feat: add player-aware world interaction system
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user