65 lines
2.5 KiB
C#
65 lines
2.5 KiB
C#
using NeonSprawl.Server.Game.Quests;
|
|
|
|
namespace NeonSprawl.Server.Game.Factions;
|
|
|
|
/// <summary>
|
|
/// Evaluates <see cref="FactionGateRuleRow"/> minimum-standing gates (NEO-137).
|
|
/// Quest accept wiring: <see cref="QuestStateOperations.TryAccept"/>.
|
|
/// NEO-141 telemetry hook site: deny return path below.
|
|
/// </summary>
|
|
public static class FactionGateOperations
|
|
{
|
|
/// <summary>
|
|
/// All rules must pass (AND). Empty rules succeed immediately.
|
|
/// Compares player standing vs <see cref="FactionGateRuleRow.MinStanding"/> with <c>standing >= minStanding</c>.
|
|
/// </summary>
|
|
public static FactionGateEvaluateOutcome TryEvaluate(
|
|
string playerId,
|
|
IReadOnlyList<FactionGateRuleRow> rules,
|
|
IFactionStandingStore standingStore)
|
|
{
|
|
var normalizedPlayerId = FactionStandingIds.NormalizePlayerId(playerId);
|
|
if (rules.Count == 0)
|
|
{
|
|
return Success();
|
|
}
|
|
|
|
foreach (var rule in rules)
|
|
{
|
|
var factionId = FactionStandingIds.NormalizeFactionId(rule.FactionId);
|
|
var read = standingStore.TryGetStanding(normalizedPlayerId, factionId);
|
|
if (!read.Success)
|
|
{
|
|
// --- Telemetry hook site (NEO-141): future E9.M1 catalog event `faction_gate_blocked` ---
|
|
// TODO(E9.M1): catalog emit — ops reasonCode (e.g. unknown_faction), playerId, factionId, minStanding, currentStanding (null).
|
|
// No ingest or ILogger here (comments-only).
|
|
return Deny(read.ReasonCode, factionId, rule.MinStanding, null);
|
|
}
|
|
|
|
if (read.Standing < rule.MinStanding)
|
|
{
|
|
// --- Telemetry hook site (NEO-141): future E9.M1 catalog event `faction_gate_blocked` ---
|
|
// TODO(E9.M1): catalog emit — ops reasonCode (gate_blocked), playerId, factionId, minStanding, currentStanding.
|
|
// No ingest or ILogger here (comments-only).
|
|
return Deny(
|
|
FactionGateEvaluateReasonCodes.GateBlocked,
|
|
factionId,
|
|
rule.MinStanding,
|
|
read.Standing);
|
|
}
|
|
}
|
|
|
|
return Success();
|
|
}
|
|
|
|
private static FactionGateEvaluateOutcome Success() =>
|
|
new(true, null, null, null, null);
|
|
|
|
private static FactionGateEvaluateOutcome Deny(
|
|
string? reasonCode,
|
|
string factionId,
|
|
int minStanding,
|
|
int? currentStanding) =>
|
|
new(false, reasonCode, factionId, minStanding, currentStanding);
|
|
}
|