266 lines
No EOL
8.4 KiB
C#
266 lines
No EOL
8.4 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using WingsEmu.DTOs.Maps;
|
|
using WingsEmu.Game._i18n;
|
|
using WingsEmu.Game.Characters;
|
|
using WingsEmu.Game.Configurations;
|
|
using WingsEmu.Game.Helpers.Damages;
|
|
using WingsEmu.Game.Items;
|
|
using WingsEmu.Game.Maps;
|
|
using WingsEmu.Game.Mates;
|
|
using WingsEmu.Game.Mates.Events;
|
|
using WingsEmu.Game.Networking;
|
|
using WingsEmu.Packets.Enums;
|
|
using WingsEmu.Packets.Enums.Battle;
|
|
|
|
namespace WingsEmu.Game.Extensions.Mates;
|
|
|
|
public static class MateExtensions
|
|
{
|
|
public static int GetModifier(this IMateEntity mate)
|
|
{
|
|
return mate.AttackType switch
|
|
{
|
|
AttackType.Melee => mate.MeleeHpFactor,
|
|
AttackType.Ranged => mate.RangeDodgeFactor,
|
|
AttackType.Magical => mate.MagicMpFactor,
|
|
_ => 0
|
|
};
|
|
}
|
|
|
|
|
|
public static void TeleportNearCharacter(this IMateEntity mateEntity)
|
|
{
|
|
IClientSession session = mateEntity.Owner?.Session;
|
|
if (session?.CurrentMapInstance == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
mateEntity.ChangePosition(new Position((short)(session.PlayerEntity.PositionX + (mateEntity.MateType == MateType.Partner ? -1 : 1)), (short)(session.PlayerEntity.PositionY + 1)));
|
|
|
|
if (mateEntity.MapInstance.HasMapFlag(MapFlags.IS_BASE_MAP))
|
|
{
|
|
mateEntity.MapX = mateEntity.Position.X;
|
|
mateEntity.MapX = mateEntity.Position.Y;
|
|
}
|
|
|
|
if (mateEntity.MapInstance.MapInstanceType == MapInstanceType.Miniland && mateEntity.MapInstance.Id == mateEntity.Owner.Miniland.Id)
|
|
{
|
|
mateEntity.MinilandX = mateEntity.Position.X;
|
|
mateEntity.MinilandX = mateEntity.Position.Y;
|
|
}
|
|
|
|
bool isBlocked = session.PlayerEntity.MapInstance.IsBlockedZone(mateEntity.PositionX, mateEntity.PositionY);
|
|
|
|
if (!isBlocked)
|
|
{
|
|
return;
|
|
}
|
|
|
|
mateEntity.ChangePosition(new Position(session.PlayerEntity.PositionX, session.PlayerEntity.PositionY));
|
|
|
|
if (mateEntity.MapInstance.MapInstanceType == MapInstanceType.Miniland && mateEntity.MapInstance.Id == mateEntity.Owner.Miniland.Id)
|
|
{
|
|
mateEntity.MinilandX = mateEntity.Position.X;
|
|
mateEntity.MinilandX = mateEntity.Position.Y;
|
|
}
|
|
|
|
if (!mateEntity.MapInstance.HasMapFlag(MapFlags.IS_BASE_MAP))
|
|
{
|
|
return;
|
|
}
|
|
|
|
mateEntity.MapX = mateEntity.Position.X;
|
|
mateEntity.MapX = mateEntity.Position.Y;
|
|
}
|
|
|
|
public static void TeleportToCharacter(this IMateEntity mateEntity)
|
|
{
|
|
IClientSession session = mateEntity.Owner?.Session;
|
|
if (session == null || session.PlayerEntity.IsOnVehicle)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
mateEntity.ChangePosition(new Position(session.PlayerEntity.PositionX, session.PlayerEntity.PositionY));
|
|
session.BroadcastMateTeleport(mateEntity);
|
|
}
|
|
|
|
public static bool IsInCombat(this IMateEntity mateEntity, DateTime date) => mateEntity.LastDefence.AddSeconds(4) > date || mateEntity.LastSkillUse.AddSeconds(2) > date;
|
|
|
|
public static bool CanAttack(this IMateEntity mateEntity) => !mateEntity.Owner.IsOnVehicle && mateEntity.Loyalty != 0 && mateEntity.CanPerformAttack();
|
|
|
|
public static bool CanMove(this IMateEntity mateEntity)
|
|
{
|
|
if (mateEntity.Loyalty <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return mateEntity.CanPerformMove();
|
|
}
|
|
|
|
public static void RemoveLoyalty(this IMateEntity mateEntity, short loyalty, GameMinMaxConfiguration minMaxConfiguration, IGameLanguageService languageService)
|
|
{
|
|
if (mateEntity.Loyalty < minMaxConfiguration.MinMateLoyalty)
|
|
{
|
|
mateEntity.Loyalty = minMaxConfiguration.MinMateLoyalty;
|
|
return;
|
|
}
|
|
|
|
mateEntity.Loyalty -= Math.Abs(loyalty);
|
|
|
|
if (mateEntity.Loyalty < minMaxConfiguration.MinMateLoyalty)
|
|
{
|
|
mateEntity.Loyalty = minMaxConfiguration.MinMateLoyalty;
|
|
}
|
|
|
|
mateEntity.Owner.Session.SendPetInfo(mateEntity, languageService);
|
|
}
|
|
|
|
public static void AddLoyalty(this IMateEntity mateEntity, short loyalty, GameMinMaxConfiguration minMaxConfiguration, IGameLanguageService languageService)
|
|
{
|
|
if (mateEntity.Loyalty == minMaxConfiguration.MaxMateLoyalty)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (mateEntity.Loyalty > minMaxConfiguration.MaxMateLoyalty)
|
|
{
|
|
mateEntity.Loyalty = minMaxConfiguration.MaxMateLoyalty;
|
|
return;
|
|
}
|
|
|
|
mateEntity.Loyalty += Math.Abs(loyalty);
|
|
|
|
if (mateEntity.Loyalty > minMaxConfiguration.MaxMateLoyalty)
|
|
{
|
|
mateEntity.Loyalty = minMaxConfiguration.MaxMateLoyalty;
|
|
}
|
|
|
|
mateEntity.Owner.Session.SendPetInfo(mateEntity, languageService);
|
|
}
|
|
|
|
public static bool CanWearItem(this IMateEntity entity, IGameItem gameItem)
|
|
{
|
|
if (gameItem.EquipmentSlot != EquipmentType.Sp && gameItem.EquipmentSlot != EquipmentType.Armor && gameItem.EquipmentSlot != EquipmentType.MainWeapon)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (gameItem.IsPartnerSpecialist)
|
|
{
|
|
AttackType mateSpecialist = gameItem.PartnerClass switch
|
|
{
|
|
0 => AttackType.Melee,
|
|
1 => AttackType.Ranged,
|
|
2 => AttackType.Magical,
|
|
_ => AttackType.Other
|
|
};
|
|
|
|
return mateSpecialist == entity.AttackType;
|
|
}
|
|
|
|
AttackType mateClass = gameItem.Class switch
|
|
{
|
|
0 => AttackType.Melee,
|
|
2 => AttackType.Melee,
|
|
4 => AttackType.Ranged,
|
|
8 => AttackType.Magical,
|
|
_ => AttackType.Other
|
|
};
|
|
|
|
return mateClass == entity.AttackType;
|
|
}
|
|
|
|
public static bool CanWearSpecialist(this IMateEntity entity, IGameItem gameItem) => gameItem.IsPartnerSpecialist && entity.AttackType == (AttackType)gameItem.PartnerClass;
|
|
|
|
public static int GetSpCooldown(this IMateEntity mate) => !mate.SpCooldownEnd.HasValue ? 0 : (int)(mate.SpCooldownEnd.Value - DateTime.UtcNow).TotalSeconds;
|
|
|
|
public static bool IsSpCooldownElapsed(this IMateEntity mate)
|
|
{
|
|
if (!mate.SpCooldownEnd.HasValue)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return mate.SpCooldownEnd.Value < DateTime.UtcNow;
|
|
}
|
|
|
|
public static bool HavePartnerSkill(this IMateEntity mateEntity, byte slot)
|
|
{
|
|
bool skill = slot switch
|
|
{
|
|
0 => mateEntity.Specialist.PartnerSkill1,
|
|
1 => mateEntity.Specialist.PartnerSkill2,
|
|
2 => mateEntity.Specialist.PartnerSkill3,
|
|
_ => false
|
|
};
|
|
|
|
return skill;
|
|
}
|
|
|
|
public static async Task RemovePartnerSp(this IMateEntity mateEntity)
|
|
{
|
|
if (!mateEntity.IsUsingSp)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await mateEntity.Owner.Session.EmitEventAsync(new MateSpUntransformEvent
|
|
{
|
|
MateEntity = mateEntity
|
|
});
|
|
}
|
|
|
|
public static void RefreshPartnerSkills(this IMateEntity mateEntity)
|
|
{
|
|
if (mateEntity.MateType != MateType.Partner)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (mateEntity.MonsterSkills?.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
mateEntity.Owner.Session.RefreshSkillList();
|
|
}
|
|
|
|
public static bool SkillRankS(this IMateEntity mateEntity, byte slot) => mateEntity.Specialist?.PartnerSkills?.Find(s => s.Rank == 7 && s.Slot == slot) != null;
|
|
|
|
public static byte GetFreeMateSlot(this IPlayerEntity player, bool isPartner)
|
|
{
|
|
byte slot;
|
|
byte maxCount = isPartner ? player.MaxPartnerCount : player.MaxPetCount;
|
|
for (slot = 0; slot < maxCount; slot++)
|
|
{
|
|
IMateEntity getMate = isPartner
|
|
? player.MateComponent.GetMate(m => m.PetSlot == slot && m.MateType == MateType.Partner)
|
|
: player.MateComponent.GetMate(m => m.PetSlot == slot && m.MateType == MateType.Pet);
|
|
|
|
if (getMate != null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return slot;
|
|
}
|
|
|
|
public static void RefreshEquipmentValues(this IMateEntity mateEntity, GameItemInstance gameItemInstance, bool clearValues)
|
|
{
|
|
if (clearValues)
|
|
{
|
|
mateEntity.BCardComponent.ClearEquipmentBCards(gameItemInstance.GameItem.EquipmentSlot);
|
|
return;
|
|
}
|
|
|
|
mateEntity.BCardComponent.AddEquipmentBCards(gameItemInstance.GameItem.EquipmentSlot, gameItemInstance.GameItem.BCards);
|
|
}
|
|
} |