server-master/srcs/WingsAPI.Game/Battle/Managers/SkillExecutor.cs
2026-02-10 18:21:30 +01:00

126 lines
No EOL
4.5 KiB
C#

using System;
using System.Linq;
using WingsEmu.DTOs.BCards;
using WingsEmu.Game._enum;
using WingsEmu.Game.Buffs;
using WingsEmu.Game.Characters;
using WingsEmu.Game.Entities;
using WingsEmu.Game.Extensions;
using WingsEmu.Game.Helpers.Damages;
using WingsEmu.Game.Skills;
using WingsEmu.Packets.Enums;
using WingsEmu.Packets.ServerPackets.Battle;
namespace WingsEmu.Game.Battle;
public class SkillExecutor : ISkillExecutor
{
private readonly IBCardEffectHandlerContainer _bCardEffectHandlerContainer;
public SkillExecutor(IBCardEffectHandlerContainer bCardEffectHandlerContainer) => _bCardEffectHandlerContainer = bCardEffectHandlerContainer;
public void ExecuteDamageSkill(IBattleEntity caster, IBattleEntity target, SkillCast skill, Position positionBeforeDash = default)
{
if (IsDestroyerBomb(caster, skill))
{
return;
}
caster.BroadcastCastPacket(target, skill.Skill);
var hitProcessable = new HitProcessable(caster, target, skill, positionBeforeDash);
caster.MapInstance.AddCastHitRequest(hitProcessable);
}
public void ExecuteDamageZoneHitSkill(IBattleEntity caster, SkillCast skill, Position position)
{
caster.BroadcastCastNonTarget(skill.Skill);
var hitProcessable = new HitProcessable(caster, null, skill, position);
caster.MapInstance.AddCastHitRequest(hitProcessable);
}
public void ExecuteBuffZoneHitSkill(IBattleEntity caster, SkillCast skill, Position position)
{
caster.BroadcastCastNonTarget(skill.Skill);
var buffProcessable = new BuffProcessable(caster, null, skill, position);
caster.MapInstance.AddCastBuffRequest(buffProcessable);
}
public void ExecuteDebuffZoneHitSkill(IBattleEntity caster, SkillCast skill, Position position)
{
caster.BroadcastCastNonTarget(skill.Skill);
var buffProcessable = new BuffProcessable(caster, null, skill, position);
caster.MapInstance.AddCastBuffRequest(buffProcessable);
}
public void ExecuteBuffSkill(IBattleEntity caster, IBattleEntity target, SkillCast skill)
{
SkillInfo skillInfo = skill.Skill;
bool isTeleport = skillInfo.Vnum == (short)SkillsVnums.ARCH_TELEPORT;
caster.BroadcastCastPacket(target, skillInfo);
if (isTeleport)
{
caster.BroadcastSuPacket(caster, skillInfo, 0, SuPacketHitMode.NoDamageSuccess);
foreach (BCardDTO x in skillInfo.BCards)
{
_bCardEffectHandlerContainer.Execute(caster, caster, x, skillInfo);
}
return;
}
caster.MapInstance.AddCastBuffRequest(new BuffProcessable(caster, target, skill));
}
public void ExecuteDebuffSkill(IBattleEntity caster, IBattleEntity target, SkillCast skill)
{
caster.BroadcastCastPacket(target, skill.Skill);
caster.MapInstance.AddCastBuffRequest(new BuffProcessable(caster, target, skill));
}
private bool IsDestroyerBomb(IBattleEntity caster, SkillCast skill)
{
if (skill.Skill.Vnum != (short)SkillsVnums.BOMB)
{
return false;
}
if (caster is not IPlayerEntity character)
{
return false;
}
if (!character.SkillComponent.BombEntityId.HasValue)
{
return false;
}
long characterId = character.Id;
IMonsterEntity bomb = character.MapInstance.GetAliveMonsters(x => x.Id == character.SkillComponent.BombEntityId
&& x.SummonerId == characterId && x.SummonerType == VisualType.Player && x.MonsterVNum == (short)MonsterVnum.BOMB).FirstOrDefault();
if (bomb == null)
{
character.SkillComponent.BombEntityId = null;
return false;
}
IBattleEntitySkill bombSkill = bomb.Skills.FirstOrDefault();
if (bombSkill == null)
{
character.SkillComponent.BombEntityId = null;
return false;
}
character.CancelCastingSkill();
SkillInfo fakeBombSkill = character.GetFakeBombSkill();
fakeBombSkill.Cooldown = (short)(skill.Skill.Cooldown == 0 ? 0 : fakeBombSkill.Cooldown);
character.Session.SendSkillCooldownResetAfter(fakeBombSkill.CastId, fakeBombSkill.Cooldown);
bomb.EmitEvent(new BattleExecuteSkillEvent(bomb, bomb, bombSkill.Skill.GetInfo(), DateTime.UtcNow));
character.SetSkillCooldown(fakeBombSkill);
character.SkillComponent.BombEntityId = null;
return true;
}
}