260 lines
No EOL
12 KiB
C#
260 lines
No EOL
12 KiB
C#
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using WingsAPI.Game.Extensions.ItemExtension.Inventory;
|
|
using WingsEmu.DTOs.Items;
|
|
using WingsEmu.Game._enum;
|
|
using WingsEmu.Game._i18n;
|
|
using WingsEmu.Game._ItemUsage;
|
|
using WingsEmu.Game._ItemUsage.Configuration;
|
|
using WingsEmu.Game._ItemUsage.Event;
|
|
using WingsEmu.Game.Battle;
|
|
using WingsEmu.Game.Entities;
|
|
using WingsEmu.Game.Extensions;
|
|
using WingsEmu.Game.Extensions.Mates;
|
|
using WingsEmu.Game.Inventory;
|
|
using WingsEmu.Game.Items;
|
|
using WingsEmu.Game.Managers.StaticData;
|
|
using WingsEmu.Game.Mates;
|
|
using WingsEmu.Game.Mates.Events;
|
|
using WingsEmu.Game.Networking;
|
|
using WingsEmu.Game.Npcs;
|
|
using WingsEmu.Packets.Enums;
|
|
using WingsEmu.Packets.Enums.Chat;
|
|
|
|
namespace WingsEmu.Plugins.BasicImplementations.ItemUsage.Equipment.Box;
|
|
|
|
/// <summary>
|
|
/// This handler is used by player related bead (bead with custom item in or without item)
|
|
/// </summary>
|
|
public class UserBeadHandler : IItemUsageByVnumHandler
|
|
{
|
|
private readonly IGameItemInstanceFactory _gameItemInstanceFactory;
|
|
private readonly IGameLanguageService _languageService;
|
|
private readonly IMateEntityFactory _mateEntityFactory;
|
|
private readonly INpcMonsterManager _npcMonsterManager;
|
|
private readonly ISpPartnerConfiguration _spPartner;
|
|
|
|
public UserBeadHandler(IGameLanguageService languageService, INpcMonsterManager npcMonsterManager, ISpPartnerConfiguration spPartner, IGameItemInstanceFactory gameItemInstanceFactory,
|
|
IMateEntityFactory mateEntityFactory)
|
|
{
|
|
_languageService = languageService;
|
|
_npcMonsterManager = npcMonsterManager;
|
|
_spPartner = spPartner;
|
|
_gameItemInstanceFactory = gameItemInstanceFactory;
|
|
_mateEntityFactory = mateEntityFactory;
|
|
}
|
|
|
|
public long[] Vnums => new[] { (long)ItemVnums.PET_BEAD, (long)ItemVnums.PARTNER_BEAD, (long)ItemVnums.MOUNT_BEAD, (long)ItemVnums.FAIRY_BEAD };
|
|
|
|
public async Task HandleAsync(IClientSession session, InventoryUseItemEvent e)
|
|
{
|
|
int beadVnum = e.Item.ItemInstance.ItemVNum;
|
|
|
|
InventoryItem box = session.PlayerEntity.GetItemBySlotAndType(e.Item.Slot, InventoryType.Equipment);
|
|
|
|
if (box == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (box.ItemInstance.Type != ItemInstanceType.BoxInstance)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GameItemInstance boxInstanceItem = box.ItemInstance;
|
|
|
|
switch (beadVnum)
|
|
{
|
|
case (int)ItemVnums.FAIRY_BEAD when boxInstanceItem.HoldingVNum == 0 || boxInstanceItem.HoldingVNum == null:
|
|
session.SendGuriPacket(26, 0, e.Item.Slot);
|
|
return;
|
|
case (int)ItemVnums.FAIRY_BEAD:
|
|
{
|
|
if (!session.PlayerEntity.HasSpaceFor(boxInstanceItem.HoldingVNum.Value))
|
|
{
|
|
session.SendMsg(session.GetLanguage(GameDialogKey.INTERACTION_MESSAGE_NOT_ENOUGH_PLACE), MsgMessageType.Middle);
|
|
session.SendChatMessage(session.GetLanguage(GameDialogKey.INTERACTION_MESSAGE_NOT_ENOUGH_PLACE), ChatMessageColorType.Yellow);
|
|
return;
|
|
}
|
|
|
|
GameItemInstance newFairy = _gameItemInstanceFactory.CreateItem(boxInstanceItem.HoldingVNum.Value);
|
|
|
|
await session.AddNewItemToInventory(newFairy, true, ChatMessageColorType.Green, true);
|
|
newFairy.ElementRate = boxInstanceItem.ElementRate;
|
|
newFairy.BoundCharacterId = session.PlayerEntity.Id;
|
|
newFairy.Xp = boxInstanceItem.Xp;
|
|
await session.RemoveItemFromInventory(item: e.Item);
|
|
return;
|
|
}
|
|
case (int)ItemVnums.MOUNT_BEAD when boxInstanceItem.HoldingVNum == 0 || boxInstanceItem.HoldingVNum == null:
|
|
session.SendGuriPacket(24, 0, e.Item.Slot);
|
|
return;
|
|
case (int)ItemVnums.MOUNT_BEAD:
|
|
{
|
|
if (!session.PlayerEntity.HasSpaceFor(boxInstanceItem.HoldingVNum.Value))
|
|
{
|
|
session.SendMsg(session.GetLanguage(GameDialogKey.INTERACTION_MESSAGE_NOT_ENOUGH_PLACE), MsgMessageType.Middle);
|
|
session.SendChatMessage(session.GetLanguage(GameDialogKey.INTERACTION_MESSAGE_NOT_ENOUGH_PLACE), ChatMessageColorType.Yellow);
|
|
return;
|
|
}
|
|
|
|
GameItemInstance newMount = _gameItemInstanceFactory.CreateItem(boxInstanceItem.HoldingVNum.Value);
|
|
await session.AddNewItemToInventory(newMount, true, ChatMessageColorType.Green, true);
|
|
await session.RemoveItemFromInventory(item: box);
|
|
return;
|
|
}
|
|
case (int)ItemVnums.PET_BEAD:
|
|
case (int)ItemVnums.PARTNER_BEAD:
|
|
{
|
|
if (e.Option == 0)
|
|
{
|
|
if (boxInstanceItem.HoldingVNum != null && boxInstanceItem.HoldingVNum != 0)
|
|
{
|
|
session.SendQnaPacket($"u_i 1 {session.PlayerEntity.Id} {(int)box.InventoryType} {e.Item.Slot} 1",
|
|
_languageService.GetLanguage(GameDialogKey.ITEM_DIALOG_ASK_OPEN_PET_BEAD, session.UserLanguage));
|
|
return;
|
|
}
|
|
|
|
if (e.Packet.Length < 4)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!int.TryParse(e.Packet[3], out int mateId))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!session.PlayerEntity.MateComponent.GetMates(x => x.Id == mateId && x.MateType == (beadVnum == (int)ItemVnums.PET_BEAD ? MateType.Pet : MateType.Partner)).Any())
|
|
{
|
|
return;
|
|
}
|
|
|
|
session.SendQnaPacket($"u_i 1 {session.PlayerEntity.Id} {(int)box.InventoryType} {e.Item.Slot} {mateId}",
|
|
_languageService.GetLanguage(GameDialogKey.ITEM_DIALOG_ASK_PET_STORE, session.UserLanguage));
|
|
return;
|
|
}
|
|
|
|
if (boxInstanceItem.HoldingVNum == 0 || boxInstanceItem.HoldingVNum == null)
|
|
{
|
|
if (e.Packet.Length < 6)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!int.TryParse(e.Packet[6], out int petId))
|
|
{
|
|
return;
|
|
}
|
|
|
|
IMateEntity mateEntity = session.PlayerEntity.MateComponent.GetMate(s => s.Id == petId && s.MateType == (beadVnum == (int)ItemVnums.PET_BEAD ? MateType.Pet : MateType.Partner));
|
|
if (mateEntity == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!mateEntity.IsAlive())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (mateEntity.IsTeamMember)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (mateEntity.IsLimited)
|
|
{
|
|
session.SendMsg(session.GetLanguage(GameDialogKey.ITEM_SHOUTMESSAGE_IS_LIMITED), MsgMessageType.Middle);
|
|
return;
|
|
}
|
|
|
|
if (mateEntity.MapInstance.Id != session.PlayerEntity.Miniland.Id)
|
|
{
|
|
session.SendMsg(_languageService.GetLanguage(GameDialogKey.ITEM_SHOUTMESSAGE_ONLY_IN_MINILAND, session.UserLanguage), MsgMessageType.Middle);
|
|
return;
|
|
}
|
|
|
|
boxInstanceItem.MateType = mateEntity.MateType;
|
|
boxInstanceItem.HoldingVNum = mateEntity.NpcMonsterVNum;
|
|
boxInstanceItem.SpLevel = mateEntity.Level;
|
|
boxInstanceItem.SpDamage = mateEntity.Attack;
|
|
boxInstanceItem.SpDefence = mateEntity.Defence;
|
|
boxInstanceItem.Xp = mateEntity.Experience;
|
|
|
|
await session.EmitEventAsync(new MateRemoveEvent
|
|
{
|
|
MateEntity = mateEntity
|
|
});
|
|
|
|
GameDialogKey gameKey = mateEntity.MateType == MateType.Pet ? GameDialogKey.PET_INFO_STORED : GameDialogKey.PARTNER_INFO_STORED;
|
|
session.SendInfo(_languageService.GetLanguage(gameKey, session.UserLanguage));
|
|
return;
|
|
}
|
|
|
|
if (boxInstanceItem.HoldingVNum == 0 || boxInstanceItem.HoldingVNum == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
IMonsterData data = _npcMonsterManager.GetNpc(boxInstanceItem.HoldingVNum.Value);
|
|
if (data == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var heldMonster = new MonsterData(data);
|
|
|
|
if (session.CurrentMapInstance != session.PlayerEntity.Miniland)
|
|
{
|
|
session.SendMsg(_languageService.GetLanguage(GameDialogKey.ITEM_SHOUTMESSAGE_ONLY_IN_MINILAND, session.UserLanguage), MsgMessageType.Middle);
|
|
return;
|
|
}
|
|
|
|
if (session.PlayerEntity.MateComponent.GetMates(x => x.MonsterVNum == heldMonster.MonsterVNum && x.MateType == MateType.Partner).Any() && boxInstanceItem.MateType == MateType.Partner)
|
|
{
|
|
session.SendMsg(_languageService.GetLanguage(GameDialogKey.PARTNER_SHOUTMESSAGE_ALREADY_HAVE_SAME_PARTNER, session.UserLanguage), MsgMessageType.Middle);
|
|
return;
|
|
}
|
|
|
|
if (!boxInstanceItem.MateType.HasValue)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!session.PlayerEntity.CanReceiveMate(boxInstanceItem.MateType.Value))
|
|
{
|
|
session.SendMsg(
|
|
_languageService.GetLanguage(
|
|
boxInstanceItem.MateType == MateType.Pet ? GameDialogKey.INFORMATION_SHOUTMESSAGE_MAX_PET_COUNT : GameDialogKey.INFORMATION_SHOUTMESSAGE_MAX_PARTNER_COUNT,
|
|
session.UserLanguage), MsgMessageType.Middle);
|
|
return;
|
|
}
|
|
|
|
IMateEntity mate = _mateEntityFactory.CreateMateEntity(session.PlayerEntity, heldMonster, boxInstanceItem.MateType.Value,
|
|
boxInstanceItem.SpLevel == 0 ? (byte)1 : boxInstanceItem.SpLevel);
|
|
mate.Attack = boxInstanceItem.SpDamage;
|
|
mate.Defence = boxInstanceItem.SpDefence;
|
|
mate.Experience = boxInstanceItem.Xp;
|
|
|
|
await session.EmitEventAsync(new MateInitializeEvent
|
|
{
|
|
MateEntity = mate
|
|
});
|
|
|
|
session.CurrentMapInstance.AddMate(mate);
|
|
session.CurrentMapInstance.Broadcast(s => mate.GenerateIn(_languageService, s.UserLanguage, _spPartner));
|
|
session.SendCondMate(mate);
|
|
string mateName = mate.MateName == mate.Name ? _languageService.GetLanguage(GameDataType.NpcMonster, mate.Name, session.UserLanguage) : mate.MateName;
|
|
GameDialogKey key = mate.MateType == MateType.Pet ? GameDialogKey.PET_CHATMESSAGE_BEAD_EXTRACT : GameDialogKey.PARTNER_CHATMESSAGE_BEAD_EXTRACT;
|
|
session.SendChatMessage(_languageService.GetLanguageFormat(key, session.UserLanguage, mateName), ChatMessageColorType.Green);
|
|
|
|
await session.RemoveItemFromInventory(item: e.Item);
|
|
key = mate.MateType == MateType.Pet ? GameDialogKey.PET_INFO_LEAVE_BEAD : GameDialogKey.PARTNER_INFO_LEAVE_BEAD;
|
|
session.SendInfo(_languageService.GetLanguage(key, session.UserLanguage));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} |