494 lines
20 KiB
C#
494 lines
20 KiB
C#
using NeonSprawl.Server.Game.Contracts;
|
|
using NeonSprawl.Server.Game.Crafting;
|
|
using NeonSprawl.Server.Game.Encounters;
|
|
using NeonSprawl.Server.Game.Factions;
|
|
using NeonSprawl.Server.Game.Gathering;
|
|
using NeonSprawl.Server.Game.Items;
|
|
using NeonSprawl.Server.Game.Mastery;
|
|
using NeonSprawl.Server.Game.Quests;
|
|
using NeonSprawl.Server.Game.Rewards;
|
|
|
|
namespace NeonSprawl.Server.Tests.Game.Quests;
|
|
|
|
public sealed class QuestObjectiveWiringTests
|
|
{
|
|
private const string PlayerId = "dev-local-1";
|
|
private const string AlphaNodeId = "prototype_resource_node_alpha";
|
|
private const string DeltaNodeId = "prototype_urban_bulk_delta";
|
|
private const string CombatEncounterId = "prototype_combat_pocket";
|
|
private const string GatherQuestId = PrototypeE7M1QuestCatalogRules.GatherIntroQuestId;
|
|
private const string RefineQuestId = PrototypeE7M1QuestCatalogRules.RefineIntroQuestId;
|
|
private const string CombatQuestId = PrototypeE7M1QuestCatalogRules.CombatIntroQuestId;
|
|
private const string ChainQuestId = PrototypeE7M1QuestCatalogRules.ChainQuestId;
|
|
private const string GatherObjectiveId = PrototypeE7M1QuestCatalogRules.GatherIntroFirstObjectiveId;
|
|
private const string ChainGatherObjectiveId = PrototypeE7M1QuestCatalogRules.ChainFirstObjectiveId;
|
|
|
|
[Fact]
|
|
public async Task GatherIntro_ShouldComplete_WhenScrapGatheredThreeTimes()
|
|
{
|
|
// Arrange
|
|
await using var factory = new InMemoryWebApplicationFactory();
|
|
var deps = ResolveDependencies(factory);
|
|
Assert.True(TryAccept(deps, GatherQuestId).Success);
|
|
|
|
// Act
|
|
for (var i = 0; i < 3; i++)
|
|
{
|
|
Assert.True(TryGather(deps, AlphaNodeId).Success);
|
|
}
|
|
|
|
// Assert
|
|
Assert.True(deps.ProgressStore.TryGetProgress(PlayerId, GatherQuestId, out var progress));
|
|
Assert.Equal(QuestProgressStatus.Completed, progress.Status);
|
|
Assert.Equal(
|
|
(3 * GatherSkillXpConstants.ActivityXpPerResourceNodeGather) + 25,
|
|
deps.XpStore.GetXpTotals(PlayerId).GetValueOrDefault("salvage"));
|
|
Assert.True(deps.DeliveryStore.TryGet(PlayerId, GatherQuestId, out var deliveryEvent));
|
|
Assert.Single(deliveryEvent.GrantedSkillXp);
|
|
Assert.Equal(25, deliveryEvent.GrantedSkillXp[0].Amount);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GatherIntro_ShouldNotDoubleGrantXp_WhenCompleteReplayed()
|
|
{
|
|
// Arrange
|
|
await using var factory = new InMemoryWebApplicationFactory();
|
|
var deps = ResolveDependencies(factory);
|
|
Assert.True(TryAccept(deps, GatherQuestId).Success);
|
|
for (var i = 0; i < 3; i++)
|
|
{
|
|
Assert.True(TryGather(deps, AlphaNodeId).Success);
|
|
}
|
|
|
|
Assert.True(deps.DeliveryStore.TryGet(PlayerId, GatherQuestId, out var firstEvent));
|
|
var salvageXpBeforeReplay = deps.XpStore.GetXpTotals(PlayerId).GetValueOrDefault("salvage");
|
|
|
|
// Act
|
|
var replay = TryMarkComplete(deps, GatherQuestId);
|
|
|
|
// Assert
|
|
Assert.True(replay.Success);
|
|
Assert.Equal(salvageXpBeforeReplay, deps.XpStore.GetXpTotals(PlayerId).GetValueOrDefault("salvage"));
|
|
Assert.True(deps.DeliveryStore.TryGet(PlayerId, GatherQuestId, out var replayEvent));
|
|
Assert.Equal(firstEvent.IdempotencyKey, replayEvent.IdempotencyKey);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RefineIntro_ShouldComplete_WhenRefineScrapStandardCraftSucceeds()
|
|
{
|
|
// Arrange
|
|
await using var factory = new InMemoryWebApplicationFactory();
|
|
var deps = ResolveDependencies(factory);
|
|
AcceptAndMarkComplete(deps, GatherQuestId);
|
|
Assert.True(TryAccept(deps, RefineQuestId).Success);
|
|
SeedStack(deps, "scrap_metal_bulk", 5);
|
|
|
|
// Act
|
|
var craft = TryCraft(deps, "refine_scrap_standard");
|
|
|
|
// Assert
|
|
Assert.True(craft.Success);
|
|
Assert.True(deps.ProgressStore.TryGetProgress(PlayerId, RefineQuestId, out var progress));
|
|
Assert.Equal(QuestProgressStatus.Completed, progress.Status);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CombatIntro_ShouldComplete_WhenEncounterCompletes()
|
|
{
|
|
// Arrange
|
|
await using var factory = new InMemoryWebApplicationFactory();
|
|
var deps = ResolveDependencies(factory);
|
|
Assert.True(TryAccept(deps, CombatQuestId).Success);
|
|
|
|
// Act
|
|
QuestObjectiveWiring.TryProcessEncounterCompleteSuccess(
|
|
PlayerId,
|
|
CombatEncounterId,
|
|
deps.QuestRegistry,
|
|
deps.ProgressStore,
|
|
deps.InventoryStore,
|
|
deps.ItemRegistry,
|
|
deps.SkillRegistry,
|
|
deps.XpStore,
|
|
deps.LevelCurve,
|
|
deps.PerkUnlockEngine,
|
|
deps.PerkStore,
|
|
deps.DeliveryStore,
|
|
deps.StandingStore,
|
|
deps.AuditStore,
|
|
deps.TimeProvider);
|
|
|
|
// Assert
|
|
Assert.True(deps.ProgressStore.TryGetProgress(PlayerId, CombatQuestId, out var progress));
|
|
Assert.Equal(QuestProgressStatus.Completed, progress.Status);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ChainQuest_ShouldAdvanceThroughMixedObjectives_WhenPrerequisitesMet()
|
|
{
|
|
// Arrange
|
|
await using var factory = new InMemoryWebApplicationFactory();
|
|
var deps = ResolveDependencies(factory);
|
|
AcceptAndMarkComplete(deps, GatherQuestId);
|
|
AcceptAndMarkComplete(deps, RefineQuestId);
|
|
CompleteCombatEncounter(deps);
|
|
Assert.True(TryAccept(deps, ChainQuestId).Success);
|
|
|
|
// Act — step 0: gather 5 scrap (delta node yield)
|
|
Assert.True(TryGather(deps, DeltaNodeId).Success);
|
|
Assert.True(deps.ProgressStore.TryGetProgress(PlayerId, ChainQuestId, out var afterGather));
|
|
Assert.Equal(1, afterGather.CurrentStepIndex);
|
|
|
|
// Act — step 1: refine craft
|
|
SeedStack(deps, "scrap_metal_bulk", 5);
|
|
Assert.True(TryCraft(deps, "refine_scrap_standard").Success);
|
|
Assert.True(deps.ProgressStore.TryGetProgress(PlayerId, ChainQuestId, out var afterRefine));
|
|
Assert.Equal(2, afterRefine.CurrentStepIndex);
|
|
|
|
// Act — step 2: field stim craft
|
|
SeedStack(deps, "refined_plate_stock", 2);
|
|
SeedStack(deps, "scrap_metal_bulk", 1);
|
|
var salvageXpBeforeComplete = deps.XpStore.GetXpTotals(PlayerId).GetValueOrDefault("salvage");
|
|
deps.InventoryStore.TryGetSnapshot(PlayerId, out var beforeInventory);
|
|
var kitBefore = CountBagItem(beforeInventory!, "survey_drone_kit");
|
|
Assert.True(TryCraft(deps, "make_field_stim_mk0").Success);
|
|
|
|
// Assert — terminal inventory_has_item (contract_handoff_token from combat intro)
|
|
Assert.True(deps.ProgressStore.TryGetProgress(PlayerId, ChainQuestId, out var completed));
|
|
Assert.Equal(QuestProgressStatus.Completed, completed.Status);
|
|
Assert.Equal(3, completed.CurrentStepIndex);
|
|
Assert.True(deps.DeliveryStore.TryGet(PlayerId, ChainQuestId, out var deliveryEvent));
|
|
Assert.Single(deliveryEvent.GrantedItems);
|
|
Assert.Equal("survey_drone_kit", deliveryEvent.GrantedItems[0].ItemId);
|
|
Assert.Single(deliveryEvent.GrantedSkillXp);
|
|
Assert.Equal(50, deliveryEvent.GrantedSkillXp[0].Amount);
|
|
Assert.Equal(salvageXpBeforeComplete + 50, deps.XpStore.GetXpTotals(PlayerId).GetValueOrDefault("salvage"));
|
|
deps.InventoryStore.TryGetSnapshot(PlayerId, out var afterInventory);
|
|
Assert.Equal(kitBefore + 1, CountBagItem(afterInventory!, "survey_drone_kit"));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ChainQuest_ShouldStayActive_WhenBagFullOnTerminalWiringComplete()
|
|
{
|
|
// Arrange
|
|
await using var factory = new InMemoryWebApplicationFactory();
|
|
var deps = ResolveDependencies(factory);
|
|
AcceptAndMarkComplete(deps, GatherQuestId);
|
|
AcceptAndMarkComplete(deps, RefineQuestId);
|
|
AcceptAndMarkComplete(deps, CombatQuestId);
|
|
SeedStack(deps, PrototypeE7M1QuestCatalogRules.ChainTerminalItemId, 1);
|
|
Assert.True(TryAccept(deps, ChainQuestId).Success);
|
|
Assert.True(deps.ProgressStore.TryUpdateObjectiveCounter(PlayerId, ChainQuestId, ChainGatherObjectiveId, 5, out _));
|
|
Assert.True(TryAdvanceStep(deps, ChainQuestId, 1).Success);
|
|
Assert.True(deps.ProgressStore.TryUpdateObjectiveCounter(PlayerId, ChainQuestId, "chain_obj_refine", 1, out _));
|
|
Assert.True(TryAdvanceStep(deps, ChainQuestId, 2).Success);
|
|
Assert.True(deps.ProgressStore.TryUpdateObjectiveCounter(PlayerId, ChainQuestId, "chain_obj_stim", 1, out _));
|
|
FillRemainingBagSlots(deps);
|
|
deps.InventoryStore.TryGetSnapshot(PlayerId, out var beforeInventory);
|
|
var kitBefore = CountBagItem(beforeInventory!, "survey_drone_kit");
|
|
|
|
// Act
|
|
var advance = TryAdvanceStep(deps, ChainQuestId, 3);
|
|
|
|
// Assert
|
|
Assert.True(advance.Success);
|
|
Assert.True(deps.ProgressStore.TryGetProgress(PlayerId, ChainQuestId, out var progress));
|
|
Assert.Equal(QuestProgressStatus.Active, progress.Status);
|
|
Assert.Equal(3, progress.CurrentStepIndex);
|
|
Assert.False(deps.DeliveryStore.TryGet(PlayerId, ChainQuestId, out _));
|
|
deps.InventoryStore.TryGetSnapshot(PlayerId, out var afterInventory);
|
|
Assert.Equal(kitBefore, CountBagItem(afterInventory!, "survey_drone_kit"));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GatherIntro_ShouldCompleteInOneGather_WhenNodeYieldExceedsObjectiveQuantity()
|
|
{
|
|
// Arrange
|
|
await using var factory = new InMemoryWebApplicationFactory();
|
|
var deps = ResolveDependencies(factory);
|
|
Assert.True(TryAccept(deps, GatherQuestId).Success);
|
|
|
|
// Act
|
|
Assert.True(TryGather(deps, DeltaNodeId).Success);
|
|
|
|
// Assert
|
|
Assert.True(deps.ProgressStore.TryGetProgress(PlayerId, GatherQuestId, out var progress));
|
|
Assert.Equal(QuestProgressStatus.Completed, progress.Status);
|
|
Assert.Equal(3, progress.ObjectiveCounters[GatherObjectiveId]);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task InventoryHasItem_ShouldCompleteChainTerminalStep_WhenTokenAlreadyHeldOnStepAdvance()
|
|
{
|
|
// Arrange
|
|
await using var factory = new InMemoryWebApplicationFactory();
|
|
var deps = ResolveDependencies(factory);
|
|
AcceptAndMarkComplete(deps, GatherQuestId);
|
|
AcceptAndMarkComplete(deps, RefineQuestId);
|
|
AcceptAndMarkComplete(deps, CombatQuestId);
|
|
SeedStack(deps, PrototypeE7M1QuestCatalogRules.ChainTerminalItemId, 1);
|
|
Assert.True(TryAccept(deps, ChainQuestId).Success);
|
|
Assert.True(deps.ProgressStore.TryUpdateObjectiveCounter(PlayerId, ChainQuestId, ChainGatherObjectiveId, 5, out _));
|
|
Assert.True(TryAdvanceStep(deps, ChainQuestId, 1).Success);
|
|
Assert.True(deps.ProgressStore.TryUpdateObjectiveCounter(PlayerId, ChainQuestId, "chain_obj_refine", 1, out _));
|
|
Assert.True(TryAdvanceStep(deps, ChainQuestId, 2).Success);
|
|
Assert.True(deps.ProgressStore.TryUpdateObjectiveCounter(PlayerId, ChainQuestId, "chain_obj_stim", 1, out _));
|
|
|
|
// Act
|
|
var advance = TryAdvanceStep(deps, ChainQuestId, 3);
|
|
|
|
// Assert
|
|
Assert.True(advance.Success);
|
|
Assert.True(deps.ProgressStore.TryGetProgress(PlayerId, ChainQuestId, out var progress));
|
|
Assert.Equal(QuestProgressStatus.Completed, progress.Status);
|
|
}
|
|
|
|
private static void CompleteCombatEncounter(QuestWiringTestDependencies deps)
|
|
{
|
|
Assert.True(TryAccept(deps, CombatQuestId).Success);
|
|
DefeatAllRequiredTargets(deps);
|
|
var result = EncounterCompletionOperations.TryCompleteAndGrant(
|
|
PlayerId,
|
|
CombatEncounterId,
|
|
deps.EncounterRegistry,
|
|
deps.RewardTableRegistry,
|
|
deps.EncounterProgressStore,
|
|
deps.CompletionStore,
|
|
deps.CompleteEventStore,
|
|
deps.ItemRegistry,
|
|
deps.InventoryStore,
|
|
deps.QuestRegistry,
|
|
deps.ProgressStore,
|
|
deps.SkillRegistry,
|
|
deps.XpStore,
|
|
deps.LevelCurve,
|
|
deps.PerkUnlockEngine,
|
|
deps.PerkStore,
|
|
deps.DeliveryStore,
|
|
deps.StandingStore,
|
|
deps.AuditStore,
|
|
deps.ContractInstanceStore,
|
|
deps.ContractOutcomeStore,
|
|
deps.ContractTemplateRegistry,
|
|
deps.TimeProvider);
|
|
Assert.True(result.Success);
|
|
}
|
|
|
|
private static void DefeatAllRequiredTargets(QuestWiringTestDependencies deps)
|
|
{
|
|
foreach (var npcId in new[] { "prototype_npc_melee", "prototype_npc_ranged", "prototype_npc_elite" })
|
|
{
|
|
_ = EncounterProgressOperations.TryActivateOnFirstEngagement(
|
|
PlayerId,
|
|
npcId,
|
|
deps.EncounterRegistry,
|
|
deps.EncounterProgressStore,
|
|
deps.CompletionStore);
|
|
_ = EncounterProgressOperations.TryMarkTargetDefeated(
|
|
PlayerId,
|
|
npcId,
|
|
deps.EncounterRegistry,
|
|
deps.EncounterProgressStore,
|
|
deps.CompletionStore);
|
|
}
|
|
}
|
|
|
|
private static QuestStateOperationResult TryAccept(QuestWiringTestDependencies deps, string questId) =>
|
|
QuestStateOperations.TryAccept(
|
|
PlayerId,
|
|
questId,
|
|
deps.QuestRegistry,
|
|
deps.ProgressStore,
|
|
deps.InventoryStore,
|
|
deps.ItemRegistry,
|
|
deps.SkillRegistry,
|
|
deps.XpStore,
|
|
deps.LevelCurve,
|
|
deps.PerkUnlockEngine,
|
|
deps.PerkStore,
|
|
deps.DeliveryStore,
|
|
deps.StandingStore,
|
|
deps.AuditStore,
|
|
deps.TimeProvider);
|
|
|
|
private static QuestStateOperationResult TryAdvanceStep(QuestWiringTestDependencies deps, string questId, int step) =>
|
|
QuestStateOperations.TryAdvanceStep(
|
|
PlayerId,
|
|
questId,
|
|
step,
|
|
deps.QuestRegistry,
|
|
deps.ProgressStore,
|
|
deps.InventoryStore,
|
|
deps.ItemRegistry,
|
|
deps.SkillRegistry,
|
|
deps.XpStore,
|
|
deps.LevelCurve,
|
|
deps.PerkUnlockEngine,
|
|
deps.PerkStore,
|
|
deps.DeliveryStore,
|
|
deps.StandingStore,
|
|
deps.AuditStore,
|
|
deps.TimeProvider);
|
|
|
|
private static QuestStateOperationResult TryMarkComplete(QuestWiringTestDependencies deps, string questId) =>
|
|
QuestStateOperations.TryMarkComplete(
|
|
PlayerId,
|
|
questId,
|
|
deps.QuestRegistry,
|
|
deps.ProgressStore,
|
|
deps.ItemRegistry,
|
|
deps.InventoryStore,
|
|
deps.SkillRegistry,
|
|
deps.XpStore,
|
|
deps.LevelCurve,
|
|
deps.PerkUnlockEngine,
|
|
deps.PerkStore,
|
|
deps.DeliveryStore,
|
|
deps.StandingStore,
|
|
deps.AuditStore,
|
|
deps.TimeProvider);
|
|
|
|
private static void AcceptAndMarkComplete(QuestWiringTestDependencies deps, string questId)
|
|
{
|
|
Assert.True(TryAccept(deps, questId).Success);
|
|
Assert.True(TryMarkComplete(deps, questId).Success);
|
|
}
|
|
|
|
private static GatherResult TryGather(QuestWiringTestDependencies deps, string nodeId) =>
|
|
GatherOperations.TryGather(
|
|
PlayerId,
|
|
nodeId,
|
|
deps.NodeRegistry,
|
|
deps.ItemRegistry,
|
|
deps.InventoryStore,
|
|
deps.SkillRegistry,
|
|
deps.XpStore,
|
|
deps.LevelCurve,
|
|
deps.PerkUnlockEngine,
|
|
deps.InstanceStore,
|
|
deps.QuestRegistry,
|
|
deps.ProgressStore,
|
|
deps.PerkStore,
|
|
deps.DeliveryStore,
|
|
deps.StandingStore,
|
|
deps.AuditStore,
|
|
deps.TimeProvider);
|
|
|
|
private static CraftResult TryCraft(QuestWiringTestDependencies deps, string recipeId) =>
|
|
CraftOperations.TryCraft(
|
|
PlayerId,
|
|
recipeId,
|
|
quantity: 1,
|
|
deps.RecipeRegistry,
|
|
deps.ItemRegistry,
|
|
deps.InventoryStore,
|
|
deps.SkillRegistry,
|
|
deps.XpStore,
|
|
deps.LevelCurve,
|
|
deps.PerkUnlockEngine,
|
|
deps.QuestRegistry,
|
|
deps.ProgressStore,
|
|
deps.PerkStore,
|
|
deps.DeliveryStore,
|
|
deps.StandingStore,
|
|
deps.AuditStore,
|
|
deps.TimeProvider);
|
|
|
|
private static int CountBagItem(PlayerInventorySnapshot snapshot, string itemId)
|
|
{
|
|
var total = 0;
|
|
foreach (var slot in snapshot.BagSlots)
|
|
{
|
|
if (string.Equals(slot.ItemId, itemId, StringComparison.Ordinal))
|
|
{
|
|
total += slot.Quantity;
|
|
}
|
|
}
|
|
|
|
return total;
|
|
}
|
|
|
|
private static void FillRemainingBagSlots(QuestWiringTestDependencies deps)
|
|
{
|
|
deps.InventoryStore.TryGetSnapshot(PlayerId, out var snapshot);
|
|
var emptySlots = snapshot!.BagSlots.Count(static slot => slot.IsEmpty);
|
|
for (var i = 0; i < emptySlots; i++)
|
|
{
|
|
var add = PlayerInventoryOperations.TryAddStack(
|
|
PlayerId,
|
|
"survey_drone_kit",
|
|
quantity: 1,
|
|
deps.ItemRegistry,
|
|
deps.InventoryStore);
|
|
Assert.Equal(PlayerInventoryMutationKind.Applied, add.Kind);
|
|
}
|
|
}
|
|
|
|
private static void SeedStack(QuestWiringTestDependencies deps, string itemId, int quantity)
|
|
{
|
|
var outcome = PlayerInventoryOperations.TryAddStack(
|
|
PlayerId,
|
|
itemId,
|
|
quantity,
|
|
deps.ItemRegistry,
|
|
deps.InventoryStore);
|
|
Assert.Equal(PlayerInventoryMutationKind.Applied, outcome.Kind);
|
|
}
|
|
|
|
private static QuestWiringTestDependencies ResolveDependencies(InMemoryWebApplicationFactory factory)
|
|
{
|
|
var services = factory.Services;
|
|
return new QuestWiringTestDependencies(
|
|
services.GetRequiredService<IQuestDefinitionRegistry>(),
|
|
services.GetRequiredService<IPlayerQuestStateStore>(),
|
|
services.GetRequiredService<IPlayerInventoryStore>(),
|
|
services.GetRequiredService<IItemDefinitionRegistry>(),
|
|
services.GetRequiredService<IResourceNodeDefinitionRegistry>(),
|
|
services.GetRequiredService<IResourceNodeInstanceStore>(),
|
|
services.GetRequiredService<IRecipeDefinitionRegistry>(),
|
|
services.GetRequiredService<ISkillDefinitionRegistry>(),
|
|
services.GetRequiredService<IPlayerSkillProgressionStore>(),
|
|
services.GetRequiredService<ISkillLevelCurve>(),
|
|
services.GetRequiredService<PerkUnlockEngine>(),
|
|
services.GetRequiredService<IEncounterDefinitionRegistry>(),
|
|
services.GetRequiredService<IRewardTableDefinitionRegistry>(),
|
|
services.GetRequiredService<IEncounterProgressStore>(),
|
|
services.GetRequiredService<IEncounterCompletionStore>(),
|
|
services.GetRequiredService<IEncounterCompleteEventStore>(),
|
|
services.GetRequiredService<IPlayerPerkStateStore>(),
|
|
services.GetRequiredService<IRewardDeliveryStore>(),
|
|
services.GetRequiredService<IFactionStandingStore>(),
|
|
services.GetRequiredService<IReputationDeltaStore>(),
|
|
services.GetRequiredService<IContractInstanceStore>(),
|
|
services.GetRequiredService<IContractOutcomeStore>(),
|
|
services.GetRequiredService<IContractTemplateRegistry>(),
|
|
TimeProvider.System);
|
|
}
|
|
|
|
private readonly record struct QuestWiringTestDependencies(
|
|
IQuestDefinitionRegistry QuestRegistry,
|
|
IPlayerQuestStateStore ProgressStore,
|
|
IPlayerInventoryStore InventoryStore,
|
|
IItemDefinitionRegistry ItemRegistry,
|
|
IResourceNodeDefinitionRegistry NodeRegistry,
|
|
IResourceNodeInstanceStore InstanceStore,
|
|
IRecipeDefinitionRegistry RecipeRegistry,
|
|
ISkillDefinitionRegistry SkillRegistry,
|
|
IPlayerSkillProgressionStore XpStore,
|
|
ISkillLevelCurve LevelCurve,
|
|
PerkUnlockEngine PerkUnlockEngine,
|
|
IEncounterDefinitionRegistry EncounterRegistry,
|
|
IRewardTableDefinitionRegistry RewardTableRegistry,
|
|
IEncounterProgressStore EncounterProgressStore,
|
|
IEncounterCompletionStore CompletionStore,
|
|
IEncounterCompleteEventStore CompleteEventStore,
|
|
IPlayerPerkStateStore PerkStore,
|
|
IRewardDeliveryStore DeliveryStore,
|
|
IFactionStandingStore StandingStore,
|
|
IReputationDeltaStore AuditStore,
|
|
IContractInstanceStore ContractInstanceStore,
|
|
IContractOutcomeStore ContractOutcomeStore,
|
|
IContractTemplateRegistry ContractTemplateRegistry,
|
|
TimeProvider TimeProvider);
|
|
}
|