279 lines
No EOL
10 KiB
C#
279 lines
No EOL
10 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using WingsEmu.Game._enum;
|
|
using WingsEmu.Game._i18n;
|
|
using WingsEmu.Game._NpcDialog;
|
|
using WingsEmu.Game._NpcDialog.Event;
|
|
using WingsEmu.Game.Entities;
|
|
using WingsEmu.Game.Entities.Extensions;
|
|
using WingsEmu.Game.Extensions;
|
|
using WingsEmu.Game.Extensions.Mates;
|
|
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.Game.TimeSpaces;
|
|
using WingsEmu.Game.TimeSpaces.Events;
|
|
using WingsEmu.Packets.Enums;
|
|
using WingsEmu.Packets.Enums.Battle;
|
|
using WingsEmu.Packets.Enums.Chat;
|
|
|
|
namespace WingsEmu.Plugins.BasicImplementations.NpcDialogs.TimeSpace;
|
|
|
|
public class GetPartnerHandler : INpcDialogAsyncHandler
|
|
{
|
|
private readonly IGameItemInstanceFactory _gameItemInstanceFactory;
|
|
private readonly IGameLanguageService _gameLanguage;
|
|
private readonly IMateEntityFactory _mateEntityFactory;
|
|
private readonly INpcMonsterManager _npcMonsterManager;
|
|
|
|
public GetPartnerHandler(INpcMonsterManager npcMonsterManager, IMateEntityFactory mateEntityFactory, IGameItemInstanceFactory gameItemInstanceFactory, IGameLanguageService gameLanguage)
|
|
{
|
|
_npcMonsterManager = npcMonsterManager;
|
|
_mateEntityFactory = mateEntityFactory;
|
|
_gameItemInstanceFactory = gameItemInstanceFactory;
|
|
_gameLanguage = gameLanguage;
|
|
}
|
|
|
|
public NpcRunType[] NpcRunTypes => new[] { NpcRunType.GET_PARTNER };
|
|
|
|
public async Task Execute(IClientSession session, NpcDialogEvent e)
|
|
{
|
|
if (!session.HasCurrentMapInstance)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!session.PlayerEntity.TimeSpaceComponent.IsInTimeSpaceParty)
|
|
{
|
|
return;
|
|
}
|
|
|
|
TimeSpaceParty timeSpace = session.PlayerEntity.TimeSpaceComponent.TimeSpace;
|
|
List<INpcEntity> partners = session.PlayerEntity.TimeSpaceComponent.Partners;
|
|
|
|
if (timeSpace.Instance.StartTimeFreeze.HasValue)
|
|
{
|
|
await session.EmitEventAsync(new TimeSpaceAddTimeToTimerEvent
|
|
{
|
|
Time = DateTime.UtcNow - timeSpace.Instance.StartTimeFreeze.Value
|
|
});
|
|
|
|
timeSpace.Instance.StartTimeFreeze = null;
|
|
}
|
|
|
|
if (!timeSpace.Instance.TimeSpaceSubInstances.TryGetValue(session.CurrentMapInstance.Id, out TimeSpaceSubInstance timeSpaceSubInstance))
|
|
{
|
|
return;
|
|
}
|
|
|
|
await session.EmitEventAsync(new TimeSpaceStartTaskEvent
|
|
{
|
|
TimeSpaceSubInstance = timeSpaceSubInstance
|
|
});
|
|
|
|
if (timeSpaceSubInstance.Task != null && timeSpaceSubInstance.Task.StartDialog.HasValue)
|
|
{
|
|
timeSpaceSubInstance.Task.StartDialog = null;
|
|
if (timeSpaceSubInstance.Task.StartDialogIsObjective)
|
|
{
|
|
timeSpaceSubInstance.Task.StartDialogIsObjective = false;
|
|
timeSpace.Instance.TimeSpaceObjective.ConversationsHad++;
|
|
await session.EmitEventAsync(new TimeSpaceRefreshObjectiveProgressEvent());
|
|
}
|
|
}
|
|
|
|
if (timeSpace.Instance.ObtainablePartnerVnum == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
INpcEntity timeSpacePartner = partners.FirstOrDefault(x => x.MonsterVNum == timeSpace.Instance.ObtainablePartnerVnum.Value);
|
|
if (!partners.Any() || timeSpacePartner == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
IMonsterData partner = _npcMonsterManager.GetNpc(timeSpace.Instance.ObtainablePartnerVnum.Value);
|
|
if (partner == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (session.PlayerEntity.MateComponent.GetMates(x => x.MonsterVNum == partner.MonsterVNum && x.MateType == MateType.Partner).Any())
|
|
{
|
|
session.SendChatMessage(session.GetLanguage(GameDialogKey.PARTNER_SHOUTMESSAGE_ALREADY_HAVE_SAME_PARTNER), ChatMessageColorType.Yellow);
|
|
return;
|
|
}
|
|
|
|
if (!session.PlayerEntity.CanReceiveMate(MateType.Partner))
|
|
{
|
|
session.SendChatMessage(session.GetLanguage(GameDialogKey.INFORMATION_SHOUTMESSAGE_MAX_PARTNER_COUNT), ChatMessageColorType.Yellow);
|
|
return;
|
|
}
|
|
|
|
session.PlayerEntity.BroadcastEffectInRange(EffectType.NormalLevelUpSubEffect);
|
|
timeSpacePartner.BroadcastEffectInRange(EffectType.NormalLevelUpSubEffect);
|
|
timeSpacePartner.MapInstance.Broadcast(timeSpacePartner.GenerateOut());
|
|
timeSpacePartner.MapInstance.RemoveNpc(timeSpacePartner);
|
|
|
|
session.PlayerEntity.TimeSpaceComponent.Partners.Remove(timeSpacePartner);
|
|
|
|
byte partnerLevel = session.PlayerEntity.Level < partner.BaseLevel ? session.PlayerEntity.Level : partner.BaseLevel;
|
|
|
|
IMateEntity mateEntity = _mateEntityFactory.CreateMateEntity(session.PlayerEntity, new MonsterData(partner), MateType.Partner, partnerLevel);
|
|
await session.EmitEventAsync(new MateInitializeEvent
|
|
{
|
|
MateEntity = mateEntity
|
|
});
|
|
|
|
CreatePartnerEquipment(session, mateEntity);
|
|
|
|
if (session.PlayerEntity.MateComponent.GetTeamMember(x => x.MateType == MateType.Partner) != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await session.EmitEventAsync(new MateJoinTeamEvent
|
|
{
|
|
MateEntity = mateEntity,
|
|
IsNewCreated = true
|
|
});
|
|
}
|
|
|
|
private void CreatePartnerEquipment(IClientSession session, IMateEntity mateEntity)
|
|
{
|
|
if (mateEntity.Level < 15)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int weapon = 0;
|
|
int armor = 0;
|
|
|
|
switch (mateEntity.AttackType)
|
|
{
|
|
case AttackType.Melee:
|
|
|
|
switch (mateEntity.Level)
|
|
{
|
|
case >= 20 and <= 30:
|
|
weapon = 19; // Short Sword
|
|
armor = 162; // Durable Armour
|
|
break;
|
|
case > 30 and <= 48:
|
|
weapon = 21; // Short Sword
|
|
armor = 97; // Leather Armour
|
|
break;
|
|
default:
|
|
weapon = 139; // Katzbalger
|
|
armor = 102; // Armour of Morale
|
|
break;
|
|
}
|
|
|
|
break;
|
|
case AttackType.Ranged:
|
|
|
|
switch (mateEntity.Level)
|
|
{
|
|
case >= 20 and <= 30:
|
|
weapon = 33; // Small Bow
|
|
armor = 108; // Lambskin Tunic
|
|
break;
|
|
case > 30 and <= 49:
|
|
weapon = 143; // Flame Bow
|
|
armor = 169; // Tunic of Nature
|
|
break;
|
|
default:
|
|
weapon = 146; // Wild Bow
|
|
armor = 116; // Peccary Tunic
|
|
break;
|
|
}
|
|
|
|
break;
|
|
case AttackType.Magical:
|
|
|
|
switch (mateEntity.Level)
|
|
{
|
|
case >= 20 and <= 30:
|
|
weapon = 47; // Red Bead Wand
|
|
armor = 121; // Cotton Robe
|
|
break;
|
|
case > 30 and <= 49:
|
|
weapon = 150; // Magic Wand of Flame
|
|
armor = 175; // Soft Robe
|
|
break;
|
|
default:
|
|
weapon = 153; // Magic Spell Wand
|
|
armor = 129; // Silk Robe
|
|
break;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
GameItemInstance weaponItem = _gameItemInstanceFactory.CreateItem(weapon, 1, 5, 5);
|
|
|
|
switch (weaponItem.GameItem.EquipmentSlot)
|
|
{
|
|
case EquipmentType.SecondaryWeapon:
|
|
case EquipmentType.MainWeapon:
|
|
switch (weaponItem.GameItem.Class)
|
|
{
|
|
case (int)ItemClassType.Swordsman:
|
|
weaponItem.ItemVNum = weaponItem.GameItem.EquipmentSlot == (int)EquipmentType.MainWeapon ? (int)ItemVnums.PARTNER_WEAPON_MELEE : (int)ItemVnums.PARTNER_WEAPON_RANGED;
|
|
break;
|
|
case (int)ItemClassType.Archer:
|
|
weaponItem.ItemVNum = weaponItem.GameItem.EquipmentSlot == (int)EquipmentType.MainWeapon ? (int)ItemVnums.PARTNER_WEAPON_RANGED : (int)ItemVnums.PARTNER_WEAPON_MELEE;
|
|
break;
|
|
case (int)ItemClassType.Mage:
|
|
weaponItem.ItemVNum = weaponItem.GameItem.EquipmentSlot == (int)EquipmentType.MainWeapon ? (int)ItemVnums.PARTNER_WEAPON_MAGIC : (int)ItemVnums.PARTNER_WEAPON_RANGED;
|
|
break;
|
|
case (int)ItemClassType.MartialArtist:
|
|
weaponItem.ItemVNum = (int)ItemVnums.PARTNER_WEAPON_MELEE;
|
|
break;
|
|
default:
|
|
session.SendShopEndPacket(ShopEndType.Npc);
|
|
return;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
weaponItem.EquipmentOptions?.Clear();
|
|
weaponItem.OriginalItemVnum = weapon;
|
|
weaponItem.BoundCharacterId = null;
|
|
|
|
GameItemInstance armorItem = _gameItemInstanceFactory.CreateItem(armor, 1, 5, 5);
|
|
switch (armorItem.GameItem.Class)
|
|
{
|
|
case (int)ItemClassType.Swordsman:
|
|
case (int)ItemClassType.MartialArtist:
|
|
armorItem.ItemVNum = (int)ItemVnums.PARTNER_ARMOR_MELEE;
|
|
break;
|
|
case (int)ItemClassType.Archer:
|
|
armorItem.ItemVNum = (int)ItemVnums.PARTNER_ARMOR_RANGED;
|
|
break;
|
|
case (int)ItemClassType.Mage:
|
|
armorItem.ItemVNum = (int)ItemVnums.PARTNER_ARMOR_MAGIC;
|
|
break;
|
|
}
|
|
|
|
armorItem.EquipmentOptions?.Clear();
|
|
armorItem.OriginalItemVnum = armor;
|
|
armorItem.BoundCharacterId = null;
|
|
|
|
session.PlayerEntity.PartnerEquipItem(weaponItem, mateEntity.PetSlot);
|
|
session.PlayerEntity.PartnerEquipItem(armorItem, mateEntity.PetSlot);
|
|
session.SendScpPackets();
|
|
session.SendScnPackets();
|
|
mateEntity.RefreshEquipmentValues(weaponItem, false);
|
|
mateEntity.RefreshEquipmentValues(armorItem, false);
|
|
session.SendPetInfo(mateEntity, _gameLanguage);
|
|
session.SendCondMate(mateEntity);
|
|
}
|
|
} |