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

227 lines
No EOL
8.8 KiB
C#

using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using PhoenixLib.Events;
using WingsAPI.Game.Extensions.Quicklist;
using WingsEmu.DTOs.Skills;
using WingsEmu.Game._enum;
using WingsEmu.Game._i18n;
using WingsEmu.Game.Algorithm;
using WingsEmu.Game.Entities;
using WingsEmu.Game.Extensions;
using WingsEmu.Game.Managers.StaticData;
using WingsEmu.Game.Networking;
using WingsEmu.Game.Shops.Event;
using WingsEmu.Game.Skills;
using WingsEmu.Packets.Enums.Character;
using WingsEmu.Packets.Enums.Chat;
namespace WingsEmu.Plugins.BasicImplementations.Shop;
public class BuyShopSkillEventHandler : IAsyncEventProcessor<BuyShopSkillEvent>
{
private readonly ICharacterAlgorithm _characterAlgorithm;
private readonly IGameLanguageService _gameLanguage;
private readonly ISkillsManager _skillsManager;
public BuyShopSkillEventHandler(IGameLanguageService gameLanguage, ISkillsManager skillsManager, ICharacterAlgorithm characterAlgorithm)
{
_gameLanguage = gameLanguage;
_skillsManager = skillsManager;
_characterAlgorithm = characterAlgorithm;
}
public async Task HandleAsync(BuyShopSkillEvent e, CancellationToken cancellation)
{
IClientSession session = e.Sender;
short newSkillVnum = e.Slot;
long ownerId = e.OwnerId;
bool accept = e.Accept;
INpcEntity npcEntity = session.CurrentMapInstance.GetNpcById(ownerId);
if (npcEntity.ShopNpc.ShopSkills.All(s => s.SkillVNum != newSkillVnum))
{
return;
}
// skill shop
if (session.PlayerEntity.UseSp)
{
session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.INFORMATION_SHOUTMESSAGE_REMOVE_SP, session.UserLanguage), MsgMessageType.Middle);
return;
}
if (session.PlayerEntity.IsOnVehicle)
{
session.SendChatMessage(session.GetLanguage(GameDialogKey.SKILL_CHATMESSAGE_CANT_LEARN_MORPHED), ChatMessageColorType.Yellow);
return;
}
if (session.PlayerEntity.IsInExchange())
{
return;
}
if (session.PlayerEntity.HasShopOpened)
{
return;
}
if (session.PlayerEntity.CharacterSkills.Values.Any(s => !session.PlayerEntity.SkillCanBeUsed(s)))
{
session.SendMsg(session.GetLanguage(GameDialogKey.SKILL_SHOUTMESSAGE_CANT_LEARN_COOLDOWN), MsgMessageType.Middle);
return;
}
SkillDTO skillInfo = _skillsManager.GetSkill(newSkillVnum);
if (skillInfo == null)
{
return;
}
if (session.PlayerEntity.CharacterSkills.Any(s => s.Value.SkillVNum == newSkillVnum))
{
session.SendChatMessage(session.GetLanguage(GameDialogKey.SKILL_CHATMESSAGE_ALREADY_LEARNT), ChatMessageColorType.Yellow);
return;
}
if (session.PlayerEntity.Gold < skillInfo.Price)
{
session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.INTERACTION_MESSAGE_NOT_ENOUGH_GOLD, session.UserLanguage), MsgMessageType.Middle);
return;
}
if (session.PlayerEntity.GetCp() < skillInfo.CPCost && !skillInfo.IsPassiveSkill())
{
session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.INFORMATION_SHOUTMESSAGE_NOT_ENOUGH_CP, session.UserLanguage), MsgMessageType.Middle);
return;
}
if (skillInfo.IsPassiveSkill())
{
int skillMinimumLevel = 0;
if (skillInfo.MinimumSwordmanLevel == 0 && skillInfo.MinimumArcherLevel == 0 && skillInfo.MinimumMagicianLevel == 0)
{
skillMinimumLevel = skillInfo.MinimumAdventurerLevel;
}
else
{
skillMinimumLevel = session.PlayerEntity.Class switch
{
ClassType.Adventurer => skillInfo.MinimumAdventurerLevel,
ClassType.Swordman => skillInfo.MinimumSwordmanLevel,
ClassType.Archer => skillInfo.MinimumArcherLevel,
ClassType.Magician => skillInfo.MinimumMagicianLevel,
_ => skillMinimumLevel
};
}
if (skillMinimumLevel == 0)
{
session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.SKILL_SHOUTMESSAGE_CANT_LEARN, session.UserLanguage), MsgMessageType.Middle);
return;
}
if (session.PlayerEntity.Level < skillMinimumLevel)
{
session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.INFORMATION_SHOUTMESSAGE_TOO_LOW_LVL, session.UserLanguage), MsgMessageType.Middle);
return;
}
// Find higher passive already in PlayerEntity
CharacterSkill findHigherPassive = session.PlayerEntity.CharacterSkills.Values.FirstOrDefault(x => x.Skill.IsPassiveSkill()
&& x.Skill.CastId == skillInfo.CastId && x.Skill.Id > skillInfo.Id);
if (findHigherPassive != null)
{
session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.SKILL_SHOUTMESSAGE_CANT_LEARN, session.UserLanguage), MsgMessageType.Middle);
return;
}
foreach (CharacterSkill skill in session.PlayerEntity.CharacterSkills.Values)
{
if (skillInfo.CastId == skill.Skill.CastId && skill.Skill.IsPassiveSkill())
{
session.PlayerEntity.CharacterSkills.TryRemove(skill.SkillVNum, out CharacterSkill value);
session.PlayerEntity.Skills.Remove(value);
}
}
}
else
{
if ((byte)session.PlayerEntity.Class != skillInfo.Class)
{
session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.SKILL_SHOUTMESSAGE_CANT_LEARN, session.UserLanguage), MsgMessageType.Middle);
return;
}
if (session.PlayerEntity.JobLevel < skillInfo.LevelMinimum)
{
session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.INFORMATION_MESSAGE_LOW_JOB, session.UserLanguage), MsgMessageType.Middle);
return;
}
if (skillInfo.UpgradeSkill != 0)
{
if (!session.PlayerEntity.CharacterSkills.ContainsKey(skillInfo.UpgradeSkill))
{
session.SendChatMessage(session.GetLanguage(GameDialogKey.SKILL_CHATMESSAGE_CANT_LEARN_NEED_BASE), ChatMessageColorType.Yellow);
return;
}
CharacterSkill oldUpgrade = session.PlayerEntity.CharacterSkills.Values.FirstOrDefault(s =>
s.Skill.UpgradeSkill == skillInfo.UpgradeSkill && s.Skill.UpgradeType == skillInfo.UpgradeType && s.Skill.UpgradeSkill != 0);
if (oldUpgrade != null)
{
if (!accept)
{
session.SendQnaPacket($"buy 2 {npcEntity.Id} {newSkillVnum} 1", session.GetLanguage(GameDialogKey.SKILL_DIALOG_CONFIRM_REPLACE_UPGRADE));
return;
}
session.PlayerEntity.CharacterSkills.TryRemove(oldUpgrade.SkillVNum, out CharacterSkill value);
session.PlayerEntity.Skills.Remove(value);
if (session.PlayerEntity.SkillComponent.SkillUpgrades.TryGetValue(skillInfo.UpgradeSkill, out HashSet<IBattleEntitySkill> hashSet))
{
hashSet.Remove(value);
}
}
}
}
var newSkill = new CharacterSkill { SkillVNum = newSkillVnum };
short upgradeSkill = newSkill.Skill.UpgradeSkill;
if (upgradeSkill != 0)
{
if (!session.PlayerEntity.SkillComponent.SkillUpgrades.TryGetValue(upgradeSkill, out HashSet<IBattleEntitySkill> hashSet))
{
hashSet = new HashSet<IBattleEntitySkill>();
session.PlayerEntity.SkillComponent.SkillUpgrades[upgradeSkill] = hashSet;
}
if (!hashSet.Contains(newSkill))
{
hashSet.Add(newSkill);
}
}
session.PlayerEntity.CharacterSkills[newSkillVnum] = newSkill;
session.PlayerEntity.Skills.Add(newSkill);
session.PlayerEntity.Gold -= skillInfo.Price;
session.RefreshGold();
session.RefreshPassiveBCards();
session.RefreshSkillList();
session.RefreshQuicklist();
session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.SKILL_SHOUTMESSAGE_LEARNED, session.UserLanguage), MsgMessageType.Middle);
session.RefreshLevel(_characterAlgorithm);
session.SendSound(SoundType.BUY_SKILL);
await session.EmitEventAsync(new ShopSkillBoughtEvent
{
SkillVnum = newSkillVnum
});
}
}