neon-sprawl/server/NeonSprawl.Server/Game/Quests/QuestFixtureOperations.cs

114 lines
3.3 KiB
C#

namespace NeonSprawl.Server.Game.Quests;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.Rewards;
/// <summary>Applies dev-only quest progress fixture writes (NEO-137 Bruno/manual QA).</summary>
public static class QuestFixtureOperations
{
/// <summary>
/// Marks each quest completed via store activate + mark-complete (no reward delivery).
/// Idempotent when a quest is already completed.
/// </summary>
public static bool TryApply(
string playerId,
QuestFixtureRequest body,
IQuestDefinitionRegistry questRegistry,
IFactionDefinitionRegistry factionRegistry,
IPlayerQuestStateStore progressStore,
IFactionStandingStore standingStore,
IRewardDeliveryStore deliveryStore,
IReputationDeltaStore auditStore,
TimeProvider timeProvider)
{
if (body.CompletedQuestIds.Count == 0 &&
body.ResetQuestIds.Count == 0 &&
body.ResetFactionIds.Count == 0)
{
return true;
}
if (!progressStore.CanWritePlayer(playerId))
{
return false;
}
foreach (var questId in body.ResetQuestIds)
{
if (!questRegistry.TryNormalizeKnown(questId, out var normalizedQuestId))
{
return false;
}
if (!progressStore.TryClearProgress(playerId, normalizedQuestId))
{
return false;
}
if (!deliveryStore.TryClear(playerId, normalizedQuestId))
{
return false;
}
if (!auditStore.TryClearQuestCompletionAudit(playerId, normalizedQuestId))
{
return false;
}
}
foreach (var factionId in body.ResetFactionIds)
{
if (!factionRegistry.TryGetDefinition(factionId, out var definition) || definition is null)
{
return false;
}
if (!standingStore.TryClearStanding(playerId, definition.Id))
{
return false;
}
}
foreach (var questId in body.CompletedQuestIds)
{
if (!questRegistry.TryNormalizeKnown(questId, out var normalizedQuestId))
{
return false;
}
if (progressStore.TryGetProgress(playerId, normalizedQuestId, out var existing) &&
existing.Status == QuestProgressStatus.Completed)
{
continue;
}
if (!progressStore.TryGetProgress(playerId, normalizedQuestId, out _))
{
if (!progressStore.TryActivate(playerId, normalizedQuestId, out _))
{
return false;
}
}
if (progressStore.TryMarkComplete(
playerId,
normalizedQuestId,
timeProvider.GetUtcNow(),
out _))
{
continue;
}
if (progressStore.TryGetProgress(playerId, normalizedQuestId, out var afterAttempt) &&
afterAttempt.Status == QuestProgressStatus.Completed)
{
continue;
}
return false;
}
return true;
}
}