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

167 lines
No EOL
6.3 KiB
C#

// WingsEmu
//
// Developed by NosWings Team
using System;
using System.Collections.Generic;
using System.Linq;
using WingsAPI.Game.Extensions.Quicklist;
using WingsEmu.DTOs.Quicklist;
using WingsEmu.DTOs.Skills;
using WingsEmu.Game;
using WingsEmu.Game._enum;
using WingsEmu.Game._i18n;
using WingsEmu.Game.Battle;
using WingsEmu.Game.Buffs;
using WingsEmu.Game.Characters;
using WingsEmu.Game.Entities;
using WingsEmu.Game.Extensions;
using WingsEmu.Game.Networking;
using WingsEmu.Game.Skills;
using WingsEmu.Packets.Enums;
using WingsEmu.Packets.Enums.Chat;
namespace WingsEmu.Plugins.BasicImplementations.BCards.Handlers;
public class BCardMeditationSkillHandler : IBCardEffectAsyncHandler
{
private readonly IBuffFactory _buffFactory;
private readonly IGameLanguageService _gameLanguage;
private readonly IMeditationManager _meditationManager;
private readonly IRandomGenerator _randomGenerator;
private readonly ISacrificeManager _sacrificeManager;
public BCardMeditationSkillHandler(IRandomGenerator randomGenerator, IBuffFactory buffFactory, IGameLanguageService gameLanguage, ISacrificeManager sacrificeManager,
IMeditationManager meditationManager)
{
_randomGenerator = randomGenerator;
_buffFactory = buffFactory;
_gameLanguage = gameLanguage;
_sacrificeManager = sacrificeManager;
_meditationManager = meditationManager;
}
public BCardType HandledType => BCardType.MeditationSkill;
public async void Execute(IBCardEffectContext ctx)
{
IBattleEntity sender = ctx.Sender;
byte subType = ctx.BCard.SubType;
int firstData = ctx.BCard.FirstData;
if (sender is not IPlayerEntity character)
{
return;
}
IClientSession session = character.Session;
if (subType != (byte)AdditionalTypes.MeditationSkill.CausingChance)
{
switch (subType)
{
case (byte)AdditionalTypes.MeditationSkill.ShortMeditation:
_meditationManager.SaveMeditation(session.PlayerEntity, (short)ctx.BCard.SecondData, DateTime.UtcNow.AddSeconds(4));
break;
case (byte)AdditionalTypes.MeditationSkill.RegularMeditation:
_meditationManager.SaveMeditation(session.PlayerEntity, (short)ctx.BCard.SecondData, DateTime.UtcNow.AddSeconds(8));
break;
case (byte)AdditionalTypes.MeditationSkill.LongMeditation:
_meditationManager.SaveMeditation(session.PlayerEntity, (short)ctx.BCard.SecondData, DateTime.UtcNow.AddSeconds(12));
break;
case (byte)AdditionalTypes.MeditationSkill.Sacrifice:
// check if target has sacrifice
IBattleEntity caster = _sacrificeManager.GetCaster(ctx.Target);
IBattleEntity target = null;
if (caster != null)
{
target = _sacrificeManager.GetTarget(caster);
}
if (caster != null && target != null)
{
await caster.RemoveSacrifice(target, _sacrificeManager, _gameLanguage);
Buff targetBuff = _buffFactory.CreateBuff((short)BuffVnums.NOBLE_GESTURE, sender);
await ctx.Target.AddBuffAsync(targetBuff);
}
Buff buff = _buffFactory.CreateBuff(ctx.BCard.SecondData, sender);
await sender.AddBuffAsync(buff);
if (target is IPlayerEntity characterTarget)
{
characterTarget.Session.SendMsg(
_gameLanguage.GetLanguageFormat(GameDialogKey.SKILL_SHOUTMESSAGE_SACRIFICE, characterTarget.Session.UserLanguage, session.PlayerEntity.Name, characterTarget.Name),
MsgMessageType.SmallMiddle);
session.SendMsg(_gameLanguage.GetLanguageFormat(GameDialogKey.SKILL_SHOUTMESSAGE_SACRIFICE, session.UserLanguage, session.PlayerEntity.Name, characterTarget.Name),
MsgMessageType.SmallMiddle);
}
_sacrificeManager.SaveSacrifice(character, ctx.Target);
break;
}
return;
}
if (_randomGenerator.RandomNumber() > firstData)
{
return;
}
if (!ctx.BCard.SkillVNum.HasValue)
{
return;
}
if (!character.UseSp)
{
return;
}
if (character.Specialist == null)
{
return;
}
if (character.Specialist.SpLevel < 20)
{
return;
}
SkillInfo skill = ctx.Skill;
ComboSkillState comboSkillState = session.PlayerEntity.GetComboState();
if (comboSkillState == null)
{
return;
}
SkillDTO newSkill = character.GetSkills().FirstOrDefault(x => x.Skill.Id == ctx.BCard.SecondData)?.Skill;
if (newSkill == null)
{
return;
}
int usedSkillVnum = skill.Vnum;
ComboSkillState combo = character.GetComboState();
// Check if current skill is combo and find the original one
if (combo != null)
{
usedSkillVnum = character.GetSkills().FirstOrDefault(x =>
x.Skill.SkillType == SkillType.NormalPlayerSkill && x.Skill.CastId == combo.OriginalSkillCastId && x.Skill.Id > 200)?.Skill.Id ?? skill.Vnum;
}
int characterMorph = character.Specialist != null && character.UseSp ? character.Specialist.GameItem.Morph : 0;
List<CharacterQuicklistEntryDto> quick = character.QuicklistComponent.GetQuicklist();
IEnumerable<CharacterQuicklistEntryDto> skillShot = quick.Where(s => s.SkillVnum.HasValue && s.SkillVnum.Value == usedSkillVnum && s.Morph == characterMorph && s.Type == QuicklistType.SKILLS);
character.Session.SendMSlotPacket((byte)newSkill.CastId);
foreach (CharacterQuicklistEntryDto quickListEntry in skillShot)
{
character.Session.SendQuicklistSlot(quickListEntry, newSkill.CastId);
}
session.PlayerEntity.IncreaseComboState((byte)newSkill.CastId);
character.LastSkillCombo = DateTime.UtcNow;
}
}