64 lines
2.3 KiB
C#
64 lines
2.3 KiB
C#
using NeonSprawl.Server.Game.Encounters;
|
|
using NeonSprawl.Server.Game.Factions;
|
|
using NeonSprawl.Server.Game.Items;
|
|
using NeonSprawl.Server.Game.Skills;
|
|
|
|
namespace NeonSprawl.Server.Game.Contracts;
|
|
|
|
/// <summary>
|
|
/// Issue-time economy and reward-bundle validation for contract templates (NEO-150).
|
|
/// Mirrors startup catalog gates for defense in depth at <see cref="ContractGeneratorOperations.TryIssue"/>.
|
|
/// </summary>
|
|
public static class ContractEconomyValidation
|
|
{
|
|
/// <summary>
|
|
/// Validates band caps and cross-refs for one template against live registries.
|
|
/// </summary>
|
|
public static bool TryValidateTemplate(
|
|
ContractTemplateRow template,
|
|
IEncounterDefinitionRegistry encounterRegistry,
|
|
IItemDefinitionRegistry itemRegistry,
|
|
ISkillDefinitionRegistry skillRegistry,
|
|
IFactionDefinitionRegistry factionRegistry,
|
|
out string? reasonCode)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(encounterRegistry);
|
|
ArgumentNullException.ThrowIfNull(itemRegistry);
|
|
ArgumentNullException.ThrowIfNull(skillRegistry);
|
|
ArgumentNullException.ThrowIfNull(factionRegistry);
|
|
|
|
reasonCode = null;
|
|
var rowsById = new Dictionary<string, ContractTemplateRow>(StringComparer.Ordinal)
|
|
{
|
|
[template.Id] = template,
|
|
};
|
|
|
|
if (PrototypeE7M4ContractCatalogRules.TryGetBandCapGateError(rowsById) is not null)
|
|
{
|
|
reasonCode = ContractGeneratorReasonCodes.EconomyCapExceeded;
|
|
return false;
|
|
}
|
|
|
|
var knownEncounterIds = encounterRegistry.GetDefinitionsInIdOrder()
|
|
.Select(static d => d.Id)
|
|
.ToHashSet(StringComparer.Ordinal);
|
|
var knownFactionIds = factionRegistry.GetDefinitionsInIdOrder()
|
|
.Select(static d => d.Id)
|
|
.ToHashSet(StringComparer.Ordinal);
|
|
var skillDefsById = skillRegistry.GetDefinitionsInIdOrder()
|
|
.ToDictionary(static d => d.Id, StringComparer.Ordinal);
|
|
|
|
if (PrototypeE7M4ContractCatalogRules.TryGetCrossRefError(
|
|
rowsById,
|
|
knownEncounterIds,
|
|
knownFactionIds,
|
|
skillDefsById) is not null)
|
|
{
|
|
reasonCode = ContractGeneratorReasonCodes.InvalidRewardBundle;
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|