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

111 lines
No EOL
4 KiB
C#

// WingsEmu
//
// Developed by NosWings Team
using System.Collections.Generic;
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.Game.Helpers.Damages;
using WingsEmu.Game.Mates;
using WingsEmu.Packets.Enums;
namespace WingsEmu.Plugins.BasicImplementations.BCards.Handlers;
public class BCardSpecialBehaviorHandler : IBCardEffectAsyncHandler
{
private readonly IBuffFactory _buffFactory;
public BCardSpecialBehaviorHandler(IBuffFactory buffFactory) => _buffFactory = buffFactory;
public BCardType HandledType => BCardType.SpecialBehaviour;
public void Execute(IBCardEffectContext ctx)
{
IBattleEntity target = ctx.Target;
IBattleEntity sender = ctx.Sender;
byte subType = ctx.BCard.SubType;
int firstData = ctx.BCard.FirstData;
int secondData = ctx.BCard.SecondData;
switch ((AdditionalTypes.SpecialBehaviour)subType)
{
case AdditionalTypes.SpecialBehaviour.InflictOnTeam:
IEnumerable<IBattleEntity> allies = target.Position.GetAlliesInRange(target, (byte)firstData);
foreach (IBattleEntity entity in allies)
{
if (entity.BuffComponent.HasBuff(secondData))
{
continue;
}
if (!ShouldGiveDebuff(target, entity))
{
continue;
}
Buff buff = _buffFactory.CreateBuff(secondData, sender);
entity.AddBuffAsync(buff);
}
break;
case AdditionalTypes.SpecialBehaviour.TeleportRandom:
Position newPosition = sender.MapInstance.GetRandomPosition();
sender.TeleportOnMap(newPosition.X, newPosition.Y);
break;
case AdditionalTypes.SpecialBehaviour.JumpToEveryObject:
if (sender is not IMonsterEntity monsterEntity)
{
return;
}
if (monsterEntity.Target == null)
{
return;
}
IBattleEntity monsterTarget = monsterEntity.Target;
IEnumerable<IMonsterEntity> monsters = monsterEntity.MapInstance.GetAliveMonstersInRange(monsterEntity.Position, (byte)firstData);
foreach (IMonsterEntity monster in monsters)
{
if (monster.Id == monsterEntity.Id)
{
continue;
}
monster.MapInstance.AddEntityToTargets(monster, monsterTarget);
if (monsterTarget is not IPlayerEntity playerEntity)
{
continue;
}
playerEntity.Session.SendEffectEntity(monster, EffectType.TargetedByOthers);
}
break;
}
}
private bool ShouldGiveDebuff(IBattleEntity debuffer, IBattleEntity receiver)
{
bool give = debuffer switch
{
IPlayerEntity player when receiver is IPlayerEntity receiverPlayer => player.IsInGroupOf(receiverPlayer)
|| player.Family != null && receiverPlayer.Family != null && player.Family.Id == receiverPlayer.Family.Id,
IPlayerEntity player when receiver is IMateEntity mateEntity => player.IsInGroupOf(mateEntity.Owner)
|| player.Family != null && mateEntity.Owner.Family != null && player.Family.Id == mateEntity.Owner.Family.Id,
IMateEntity mateEntity when receiver is IPlayerEntity receiverPlayer => mateEntity.Owner.Id == receiverPlayer.Id,
IMateEntity mateEntity when receiver is IMateEntity mate => mateEntity.Owner.Id == mate.Owner.Id,
INpcEntity => false,
_ => true
};
return give;
}
}