neon-sprawl/server/NeonSprawl.Server/Game/Encounters/EncounterCombatWiring.cs

122 lines
3.9 KiB
C#

using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.Quests;
using NeonSprawl.Server.Game.Rewards;
using NeonSprawl.Server.Game.Skills;
namespace NeonSprawl.Server.Game.Encounters;
/// <summary>
/// NEO-106: wires ability-cast combat outcomes to encounter activation, defeat progress, and completion grants.
/// Best-effort on the cast accept path — outcome does not change <c>AbilityCastResponse</c> JSON.
/// </summary>
public static class EncounterCombatWiring
{
/// <summary>
/// On damaging hits, activates encounter progress; on lethal hits, records defeat and may grant rewards.
/// </summary>
public static void TryProcessCastOutcome(
string playerId,
string targetNpcInstanceId,
int damageDealt,
bool targetDefeated,
IEncounterDefinitionRegistry encounterRegistry,
IRewardTableDefinitionRegistry rewardTableRegistry,
IEncounterProgressStore encounterProgressStore,
IEncounterCompletionStore completionStore,
IEncounterCompleteEventStore completeEventStore,
IItemDefinitionRegistry itemRegistry,
IPlayerInventoryStore inventoryStore,
IQuestDefinitionRegistry questRegistry,
IPlayerQuestStateStore questProgressStore,
ISkillDefinitionRegistry skillRegistry,
IPlayerSkillProgressionStore skillProgressionStore,
ISkillLevelCurve levelCurve,
PerkUnlockEngine perkUnlockEngine,
IPlayerPerkStateStore perkStore,
IRewardDeliveryStore deliveryStore,
IFactionStandingStore standingStore,
IReputationDeltaStore auditStore,
TimeProvider timeProvider,
ILogger? logger = null)
{
if (damageDealt > 0)
{
EncounterProgressOperations.TryActivateOnFirstEngagement(
playerId,
targetNpcInstanceId,
encounterRegistry,
encounterProgressStore,
completionStore);
}
if (!targetDefeated)
{
return;
}
if (!EncounterProgressOperations.TryMarkTargetDefeated(
playerId,
targetNpcInstanceId,
encounterRegistry,
encounterProgressStore,
completionStore))
{
return;
}
if (!EncounterProgressOperations.TryResolveEncounterForNpc(
targetNpcInstanceId,
encounterRegistry,
out var encounterId,
out _))
{
return;
}
if (!EncounterProgressOperations.IsAllRequiredTargetsDefeated(
playerId,
encounterId,
encounterRegistry,
encounterProgressStore))
{
return;
}
var completion = EncounterCompletionOperations.TryCompleteAndGrant(
playerId,
encounterId,
encounterRegistry,
rewardTableRegistry,
encounterProgressStore,
completionStore,
completeEventStore,
itemRegistry,
inventoryStore,
questRegistry,
questProgressStore,
skillRegistry,
skillProgressionStore,
levelCurve,
perkUnlockEngine,
perkStore,
deliveryStore,
standingStore,
auditStore,
timeProvider);
if (!completion.Success)
{
logger?.LogDebug(
"Encounter completion grant skipped for player {PlayerId} encounter {EncounterId} ({ReasonCode})",
playerId,
encounterId,
completion.ReasonCode);
return;
}
// encounter_complete / reward_attribution hooks: EncounterCompletionOperations.TryCompleteAndGrant (NEO-109).
}
}