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

154 lines
No EOL
5.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using PhoenixLib.Events;
using WingsAPI.Game.Extensions.PacketGeneration;
using WingsAPI.Packets.Enums;
using WingsEmu.DTOs.Skills;
using WingsEmu.Game._i18n;
using WingsEmu.Game.Battle;
using WingsEmu.Game.Characters.Events;
using WingsEmu.Game.Extensions;
using WingsEmu.Game.Extensions.Mates;
using WingsEmu.Game.Inventory.Event;
using WingsEmu.Game.Managers;
using WingsEmu.Game.Managers.StaticData;
using WingsEmu.Game.Mates;
using WingsEmu.Game.Networking;
using WingsEmu.Game.Networking.Broadcasting;
using WingsEmu.Game.Skills;
using WingsEmu.Packets.Enums;
namespace WingsEmu.Plugins.BasicImplementations.Event.Items;
public class PartnerSpecialistSkillEventHandler : IAsyncEventProcessor<PartnerSpecialistSkillEvent>
{
private readonly IDelayManager _delayManager;
private readonly IGameLanguageService _gameLanguage;
private readonly IPartnerSpecialistSkillRoll _partnerSpecialistSkill;
private readonly ISkillsManager _skillsManager;
public PartnerSpecialistSkillEventHandler(ISkillsManager skillsManager, IGameLanguageService languageService, IDelayManager delayManager, IPartnerSpecialistSkillRoll partnerSpecialistSkill)
{
_skillsManager = skillsManager;
_gameLanguage = languageService;
_delayManager = delayManager;
_partnerSpecialistSkill = partnerSpecialistSkill;
}
public async Task HandleAsync(PartnerSpecialistSkillEvent e, CancellationToken cancellation)
{
IClientSession session = e.Sender;
byte partnerSlot = e.PartnerSlot;
byte skillSlot = e.SkillSlot;
bool roll = e.Roll;
IMateEntity partnerInTeam = session.PlayerEntity.MateComponent.GetTeamMember(s => s.MateType == MateType.Partner && s.PetSlot == partnerSlot);
if (partnerInTeam == null)
{
session.SendModal(_gameLanguage.GetLanguage(GameDialogKey.PARTNER_INFO_NO_PARTNER_IN_TEAM, session.UserLanguage), ModalType.Confirm);
return;
}
if (!partnerInTeam.IsAlive())
{
return;
}
if (session.PlayerEntity.IsOnVehicle)
{
return;
}
if (skillSlot > 2)
{
await session.NotifyStrangeBehavior(StrangeBehaviorSeverity.ABUSING, "Tried to learn PSP skill when slot > 2");
return;
}
if (partnerInTeam.Specialist == null)
{
session.SendModal(_gameLanguage.GetLanguage(GameDialogKey.PARTNER_MESSAGE_NO_SP_EQUIPPED, session.UserLanguage), ModalType.Confirm);
return;
}
if (partnerInTeam.IsUsingSp)
{
session.SendModal(_gameLanguage.GetLanguage(GameDialogKey.PARTNER_INFO_IS_WEARING_SP, session.UserLanguage), ModalType.Confirm);
return;
}
if (partnerInTeam.Level < 30)
{
session.SendModal(_gameLanguage.GetLanguage(GameDialogKey.PARTNER_INFO_LEVEL_IS_TOO_LOW, session.UserLanguage), ModalType.Confirm);
return;
}
if (partnerInTeam.Specialist.Agility < 100 && !session.IsGameMaster())
{
session.SendModal(_gameLanguage.GetLanguage(GameDialogKey.PARTNER_INFO_NEED_AGILITY_POINTS, session.UserLanguage), ModalType.Confirm);
return;
}
if (partnerInTeam.HavePartnerSkill(skillSlot))
{
return;
}
if (!roll)
{
DateTime waitUntil = await _delayManager.RegisterAction(partnerInTeam, DelayedActionType.PartnerLearnSkill);
session.SendMateDelay(partnerInTeam, (int)(waitUntil - DateTime.UtcNow).TotalMilliseconds, GuriType.Identifying, $"#ps_op^{partnerSlot}^{skillSlot}^1");
session.CurrentMapInstance?.Broadcast(partnerInTeam.GenerateMateDance(), new RangeBroadcast(partnerInTeam.PositionX, partnerInTeam.PositionY));
return;
}
bool canLearn = await _delayManager.CanPerformAction(partnerInTeam, DelayedActionType.PartnerLearnSkill);
if (!canLearn)
{
return;
}
await _delayManager.CompleteAction(partnerInTeam, DelayedActionType.PartnerLearnSkill);
switch (skillSlot)
{
case 0:
partnerInTeam.Specialist.PartnerSkill1 = true;
break;
case 1:
partnerInTeam.Specialist.PartnerSkill2 = true;
break;
case 2:
partnerInTeam.Specialist.PartnerSkill3 = true;
break;
default:
return;
}
RollChances(partnerInTeam, skillSlot);
partnerInTeam.Specialist.Agility = 0;
session.SendMatePskiPacket(partnerInTeam);
session.SendPetInfo(partnerInTeam, _gameLanguage);
session.SendModal(_gameLanguage.GetLanguage(GameDialogKey.PARTNER_INFO_SP_NEW_SKILL, session.UserLanguage), ModalType.Confirm);
}
private void RollChances(IMateEntity mateEntity, byte slot)
{
mateEntity.Specialist.PartnerSkills ??= new List<PartnerSkill>(3);
foreach (SkillDTO ski in _skillsManager.GetSkills().Where(ski
=> ski.SkillType == SkillType.PartnerSkill && ski.UpgradeType == mateEntity.Specialist.GameItem.SpMorphId && ski.CastId == slot))
{
mateEntity.Specialist.PartnerSkills.Add(new PartnerSkill
{
LastUse = DateTime.MinValue,
Rank = _partnerSpecialistSkill.GetRandomSkillRank(),
Slot = (byte)ski.CastId,
SkillId = ski.Id
});
}
}
}