neon-sprawl/server/NeonSprawl.Server/Game/Gathering/ResourceNodeInstanceOperati...

52 lines
2.0 KiB
C#

namespace NeonSprawl.Server.Game.Gathering;
/// <summary>Registry-backed lazy init and atomic depletion commits for world node instances (NEO-61).</summary>
public static class ResourceNodeInstanceOperations
{
/// <summary>
/// Decrements remaining gathers by one after lazy-init from catalog <c>maxGathers</c>. Interact wiring (NEO-63)
/// maps <see cref="ResourceNodeInstanceReasonCodes.NodeDepleted"/> to denied interact responses.
/// </summary>
public static ResourceNodeInstanceMutationOutcome TryCommitSuccessfulGatherDecrement(
string interactableId,
IResourceNodeDefinitionRegistry registry,
IResourceNodeInstanceStore store)
{
var key = ResourceNodeInstanceIds.Normalize(interactableId);
if (key.Length == 0 || !registry.TryGetDefinition(key, out var definition))
{
return new ResourceNodeInstanceMutationOutcome(
ResourceNodeInstanceMutationKind.Denied,
ResourceNodeInstanceReasonCodes.UnknownNode,
null);
}
if (!store.TryGetRemainingGathers(key, out _))
{
if (!store.TryEnsureInitialized(key, definition.MaxGathers))
{
throw new InvalidOperationException(
$"Failed to initialize resource node instance '{key}' with maxGathers {definition.MaxGathers}.");
}
}
if (store.TryDecrementRemainingGathers(key, out _, out var remaining))
{
return new ResourceNodeInstanceMutationOutcome(
ResourceNodeInstanceMutationKind.Applied,
null,
new ResourceNodeInstanceSnapshot(key, remaining));
}
if (!store.TryGetRemainingGathers(key, out var current))
{
current = new ResourceNodeInstanceSnapshot(key, 0);
}
return new ResourceNodeInstanceMutationOutcome(
ResourceNodeInstanceMutationKind.Denied,
ResourceNodeInstanceReasonCodes.NodeDepleted,
current);
}
}