167 lines
No EOL
6.3 KiB
C#
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;
|
|
}
|
|
} |