server-master/srcs/_plugins/WingsEmu.Plugins.BasicImplementation/BCards/Handlers/BCardSpecialDamageHandler.cs
2026-02-10 18:21:30 +01:00

130 lines
No EOL
3.9 KiB
C#

using System.Collections.Generic;
using WingsEmu.Game;
using WingsEmu.Game._enum;
using WingsEmu.Game.Battle;
using WingsEmu.Game.Buffs;
using WingsEmu.Game.Characters;
using WingsEmu.Game.Entities;
using WingsEmu.Game.Extensions;
using WingsEmu.Packets.Enums;
namespace WingsEmu.Plugins.BasicImplementations.BCards.Handlers;
public class BCardSpecialDamageHandler : IBCardEffectAsyncHandler
{
private readonly IRandomGenerator _randomGenerator;
public BCardSpecialDamageHandler(IRandomGenerator randomGenerator) => _randomGenerator = randomGenerator;
public BCardType HandledType => BCardType.SpecialDamageAndExplosions;
public void Execute(IBCardEffectContext ctx)
{
IBattleEntity sender = ctx.Sender;
IBattleEntity target = ctx.Target;
if (sender == null)
{
return;
}
if (target == null)
{
return;
}
if (sender.MapInstance?.Id != target.MapInstance?.Id)
{
return;
}
int firstData = ctx.BCard.FirstDataValue(sender.Level);
int secondData = ctx.BCard.SecondDataValue(sender.Level);
switch ((AdditionalTypes.SpecialDamageAndExplosions)ctx.BCard.SubType)
{
case AdditionalTypes.SpecialDamageAndExplosions.ChanceExplosion:
if (!target.IsAlive())
{
return;
}
if (_randomGenerator.RandomNumber() > firstData)
{
return;
}
if (target.Hp - secondData <= 0)
{
target.Hp = 1;
}
else
{
target.Hp -= secondData;
}
target.BroadcastEffectInRange(EffectType.FireExplosion);
if (target is not IPlayerEntity playerEntity)
{
return;
}
playerEntity.Session.RefreshStat();
break;
case AdditionalTypes.SpecialDamageAndExplosions.ExplosionCauses:
IEnumerable<IBattleEntity> targets = sender.GetEnemiesInRange(sender, (byte)firstData);
foreach (IBattleEntity skillTarget in targets)
{
skillTarget.BroadcastEffectInRange(EffectType.SmokePuff);
if (skillTarget.Hp - secondData <= 0)
{
skillTarget.BroadcastDamage(skillTarget.Hp - 1);
skillTarget.Hp = 1;
}
else
{
skillTarget.Hp -= secondData;
skillTarget.BroadcastDamage(secondData);
}
if (skillTarget is not IPlayerEntity player)
{
continue;
}
player.Session.RefreshStat();
}
break;
case AdditionalTypes.SpecialDamageAndExplosions.ExplosionCausesNegated:
targets = target.GetAlliesInRange(target, (byte)firstData);
foreach (IBattleEntity skillTarget in targets)
{
skillTarget.BroadcastEffectInRange(EffectType.FireExplosion);
if (skillTarget.Hp - secondData <= 0)
{
skillTarget.BroadcastDamage(skillTarget.Hp - 1);
skillTarget.Hp = 1;
}
else
{
skillTarget.Hp -= secondData;
skillTarget.BroadcastDamage(secondData);
}
if (skillTarget is not IPlayerEntity player)
{
continue;
}
player.Session.RefreshStat();
}
break;
}
}
}