// 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 quick = character.QuicklistComponent.GetQuicklist(); IEnumerable 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; } }