server-master/srcs/_plugins/WingsEmu.Plugins.BasicImplementation/Event/Battle/ProcessBuffEventHandler.cs
2026-02-10 18:21:30 +01:00

123 lines
No EOL
5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using PhoenixLib.Events;
using WingsEmu.Core.Extensions;
using WingsEmu.DTOs.BCards;
using WingsEmu.DTOs.Skills;
using WingsEmu.Game._enum;
using WingsEmu.Game.Battle;
using WingsEmu.Game.Buffs;
using WingsEmu.Game.Entities;
using WingsEmu.Game.Extensions;
using WingsEmu.Game.Helpers.Damages;
using WingsEmu.Game.Mates;
using WingsEmu.Packets.Enums.Battle;
namespace WingsEmu.Plugins.BasicImplementations.Event.Battle;
public class ProcessBuffEventHandler : IAsyncEventProcessor<ProcessBuffEvent>
{
private static readonly byte MAX_TARGETS = 50;
private readonly IBCardEffectHandlerContainer _bCardEffectHandler;
public ProcessBuffEventHandler(IBCardEffectHandlerContainer bCardEffectHandler) => _bCardEffectHandler = bCardEffectHandler;
public async Task HandleAsync(ProcessBuffEvent e, CancellationToken cancellation)
{
IBattleEntity caster = e.Caster;
IBattleEntity target = e.Target;
SkillCast skillCast = e.SkillCast;
SkillInfo skill = skillCast.Skill;
Position position = e.Position;
BCardDTO[] beforeAttackOnMainTarget = skill.BCardsType.TryGetValue(SkillCastType.BEFORE_ATTACK_ON_MAIN_TARGET, out HashSet<BCardDTO> beforeOnMain)
? beforeOnMain.ToArray()
: Array.Empty<BCardDTO>();
BCardDTO[] beforeAttackSelf = skill.BCardsType.TryGetValue(SkillCastType.BEFORE_ATTACK_SELF, out HashSet<BCardDTO> beforeSelf) ? beforeSelf.ToArray() : Array.Empty<BCardDTO>();
BCardDTO[] beforeAttackAllTargets = skill.BCardsType.TryGetValue(SkillCastType.BEFORE_ATTACK_ALL_TARGETS, out HashSet<BCardDTO> beforeAttackAll)
? beforeAttackAll.ToArray()
: Array.Empty<BCardDTO>();
IEnumerable<IBattleEntity> entities = null;
if (skill.TargetType == TargetType.NonTarget)
{
switch (skill.TargetAffectedEntities)
{
case TargetAffectedEntities.DebuffForEnemies:
entities = position.GetEnemiesInRange(caster, skill.AoERange);
break;
case TargetAffectedEntities.BuffForAllies:
entities = skill.HitType switch
{
TargetHitType.TargetOnly => Lists.Create(caster),
TargetHitType.AlliesInAffectedAoE => position.GetAlliesInRange(caster, skill.AoERange)
};
break;
}
}
else
{
switch (skill.TargetAffectedEntities)
{
case TargetAffectedEntities.DebuffForEnemies:
entities = skill.HitType switch
{
TargetHitType.TargetOnly => Lists.Create(target),
TargetHitType.EnemiesInAffectedAoE => target.GetEnemiesInRange(caster, skill.AoERange),
TargetHitType.PlayerAndHisMates => target.GetEnemiesInRange(caster, skill.AoERange).Where(x => x is IMateEntity mate && mate.Owner?.Id == caster.Id && mate.IsTeamMember),
_ => null
};
break;
case TargetAffectedEntities.BuffForAllies:
entities = skill.HitType switch
{
TargetHitType.TargetOnly => Lists.Create(target),
TargetHitType.AlliesInAffectedAoE => target.GetAlliesInRange(caster, skill.AoERange),
TargetHitType.PlayerAndHisMates => target.GetAlliesInRange(caster, skill.AoERange).Where(x => x is IMateEntity mate && mate.Owner?.Id == caster.Id && mate.IsTeamMember),
_ => null
};
break;
}
}
if (entities == null)
{
caster.CancelCastingSkill();
return;
}
var entitiesToReturn = entities.Take(MAX_TARGETS).ToList();
if (skill.TargetType == TargetType.Self && skill.TargetAffectedEntities == TargetAffectedEntities.BuffForAllies && !entitiesToReturn.Contains(caster))
{
entitiesToReturn.Add(caster);
}
foreach (BCardDTO bCard in beforeAttackSelf)
{
_bCardEffectHandler.Execute(caster, caster, bCard, skill, position);
}
if (target != null && skill.TargetType != TargetType.NonTarget)
{
foreach (BCardDTO bCard in beforeAttackOnMainTarget)
{
_bCardEffectHandler.Execute(target, caster, bCard, skill, position);
}
}
foreach (BCardDTO bCard in beforeAttackAllTargets)
{
foreach (IBattleEntity entity in entitiesToReturn)
{
_bCardEffectHandler.Execute(entity, caster, bCard, skill, position);
}
}
caster.MapInstance.AddBuffRequest(new BuffRequest(caster, entitiesToReturn, skillCast, position, target));
}
}