Core/Auras: Updated mount capability check and implemented SPELL_AURA_MOUNT_RESTRICTIONS
This commit is contained in:
@@ -1333,12 +1333,21 @@ namespace Framework.Constants
|
||||
CannotExtend = 0x10
|
||||
}
|
||||
|
||||
public enum AreaMountFlags
|
||||
{
|
||||
GroundAllowed = 0x1,
|
||||
FlyingAllowed = 0x2,
|
||||
FloatAllowed = 0x4,
|
||||
UnderwaterAllowed = 0x8
|
||||
}
|
||||
|
||||
public enum MountCapabilityFlags : byte
|
||||
{
|
||||
Unk1 = 0x1,
|
||||
Unk2 = 0x2,
|
||||
CanPitch = 0x4, // client checks MOVEMENTFLAG2_FULL_SPEED_PITCHING
|
||||
CanSwim = 0x8, // client checks MOVEMENTFLAG_SWIMMING
|
||||
Ground = 0x1,
|
||||
Flying = 0x2,
|
||||
Float = 0x4,
|
||||
Underwater = 0x8,
|
||||
IgnoreRestrictions = 0x20
|
||||
}
|
||||
|
||||
public enum MountFlags
|
||||
|
||||
@@ -357,7 +357,7 @@ namespace Framework.Constants
|
||||
OverrideActionbarSpellsTriggered = 333, // Spells cast with this override have no cast time or power cost
|
||||
ModBlind = 334, // Nyi
|
||||
Unk335 = 335,
|
||||
ModFlyingRestrictions = 336, // Nyi
|
||||
MountRestrictions = 336,
|
||||
ModVendorItemsPrices = 337,
|
||||
ModDurabilityLoss = 338,
|
||||
IncreaseSkillGainChance = 339, // Nyi
|
||||
|
||||
@@ -485,6 +485,23 @@ namespace Game.DataStorage
|
||||
return _areaGroupMembers.LookupByKey(areaGroupId);
|
||||
}
|
||||
|
||||
public bool IsInArea(uint objectAreaId, uint areaId)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (objectAreaId == areaId)
|
||||
return true;
|
||||
|
||||
AreaTableRecord objectArea = CliDB.AreaTableStorage.LookupByKey(objectAreaId);
|
||||
if (objectArea == null)
|
||||
break;
|
||||
|
||||
objectAreaId = objectArea.ParentAreaID;
|
||||
} while (objectAreaId != 0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<ArtifactPowerRecord> GetArtifactPowers(byte artifactId)
|
||||
{
|
||||
return _artifactPowers.LookupByKey(artifactId);
|
||||
|
||||
@@ -7215,13 +7215,6 @@ namespace Game.Entities
|
||||
|
||||
public bool CanTameExoticPets() { return IsGameMaster() || HasAuraType(AuraType.AllowTamePetType); }
|
||||
|
||||
public bool CanFlyInZone(uint mapid, uint zone)
|
||||
{
|
||||
// continent checked in SpellInfo.CheckLocation at cast and area update
|
||||
uint v_map = Global.DB2Mgr.GetVirtualMapForMapAndZone(mapid, zone);
|
||||
return v_map != 571 || HasSpell(54197); // 54197 = Cold Weather Flying
|
||||
}
|
||||
|
||||
void SendAttackSwingDeadTarget() { SendPacket(new AttackSwingError(AttackSwingErr.DeadTarget)); }
|
||||
void SendAttackSwingCantAttack() { SendPacket(new AttackSwingError(AttackSwingErr.CantAttack)); }
|
||||
public void SendAttackSwingNotInRange() { SendPacket(new AttackSwingError(AttackSwingErr.NotInRange)); }
|
||||
|
||||
@@ -24,6 +24,7 @@ using Game.Movement;
|
||||
using Game.Network.Packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Game.Spells;
|
||||
|
||||
namespace Game.Entities
|
||||
{
|
||||
@@ -650,12 +651,32 @@ namespace Game.Entities
|
||||
if (capabilities == null)
|
||||
return null;
|
||||
|
||||
uint zoneId, areaId;
|
||||
GetZoneAndAreaId(out zoneId, out areaId);
|
||||
uint areaId = GetAreaId();
|
||||
uint ridingSkill = 5000;
|
||||
AreaMountFlags mountFlags = 0;
|
||||
bool isSubmerged = false;
|
||||
bool isInWater = false;
|
||||
|
||||
if (IsTypeId(TypeId.Player))
|
||||
ridingSkill = ToPlayer().GetSkillValue(SkillType.Riding);
|
||||
|
||||
if (HasAuraType(AuraType.MountRestrictions))
|
||||
{
|
||||
foreach (AuraEffect auraEffect in GetAuraEffectsByType(AuraType.MountRestrictions))
|
||||
mountFlags |= (AreaMountFlags)auraEffect.GetMiscValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
AreaTableRecord areaTable = CliDB.AreaTableStorage.LookupByKey(areaId);
|
||||
if (areaTable != null)
|
||||
mountFlags = (AreaMountFlags)areaTable.MountFlags;
|
||||
}
|
||||
|
||||
LiquidData liquid;
|
||||
ZLiquidStatus liquidStatus = GetMap().getLiquidStatus(GetPositionX(), GetPositionY(), GetPositionZ(), MapConst.MapAllLiquidTypes, out liquid);
|
||||
isSubmerged = liquidStatus.HasAnyFlag(ZLiquidStatus.UnderWater) || HasUnitMovementFlag(MovementFlag.Swimming);
|
||||
isInWater = liquidStatus.HasAnyFlag(ZLiquidStatus.InWater | ZLiquidStatus.UnderWater);
|
||||
|
||||
foreach (var mountTypeXCapability in capabilities)
|
||||
{
|
||||
MountCapabilityRecord mountCapability = CliDB.MountCapabilityStorage.LookupByKey(mountTypeXCapability.MountCapabilityID);
|
||||
@@ -665,32 +686,50 @@ namespace Game.Entities
|
||||
if (ridingSkill < mountCapability.RequiredRidingSkill)
|
||||
continue;
|
||||
|
||||
if (HasUnitMovementFlag2(MovementFlag2.FullSpeedPitching))
|
||||
if (!mountCapability.Flags.HasAnyFlag(MountCapabilityFlags.IgnoreRestrictions))
|
||||
{
|
||||
if (!mountCapability.Flags.HasAnyFlag(MountCapabilityFlags.CanPitch))
|
||||
if (mountCapability.Flags.HasAnyFlag(MountCapabilityFlags.Ground) && !mountFlags.HasAnyFlag(AreaMountFlags.GroundAllowed))
|
||||
continue;
|
||||
}
|
||||
else if (HasUnitMovementFlag(MovementFlag.Swimming))
|
||||
{
|
||||
if (!mountCapability.Flags.HasAnyFlag(MountCapabilityFlags.CanSwim))
|
||||
if (mountCapability.Flags.HasAnyFlag(MountCapabilityFlags.Flying) && !mountFlags.HasAnyFlag(AreaMountFlags.FlyingAllowed))
|
||||
continue;
|
||||
}
|
||||
else if (!mountCapability.Flags.HasAnyFlag(MountCapabilityFlags.Unk1)) // unknown flags, checked in 4.2.2 14545 client
|
||||
{
|
||||
if (!mountCapability.Flags.HasAnyFlag(MountCapabilityFlags.Unk2))
|
||||
if (mountCapability.Flags.HasAnyFlag(MountCapabilityFlags.Float) && !mountFlags.HasAnyFlag(AreaMountFlags.FloatAllowed))
|
||||
continue;
|
||||
if (mountCapability.Flags.HasAnyFlag(MountCapabilityFlags.Underwater) && !mountFlags.HasAnyFlag(AreaMountFlags.UnderwaterAllowed))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mountCapability.RequiredMap != -1 && (GetMapId()) != mountCapability.RequiredMap)
|
||||
if (!isSubmerged)
|
||||
{
|
||||
if (!isInWater)
|
||||
{
|
||||
// player is completely out of water
|
||||
if (!mountCapability.Flags.HasAnyFlag(MountCapabilityFlags.Ground))
|
||||
continue;
|
||||
}
|
||||
else if (!mountCapability.Flags.HasAnyFlag(MountCapabilityFlags.Underwater))
|
||||
continue;
|
||||
}
|
||||
else if (isInWater)
|
||||
{
|
||||
if (!mountCapability.Flags.HasAnyFlag(MountCapabilityFlags.Underwater))
|
||||
continue;
|
||||
}
|
||||
else if (!mountCapability.Flags.HasAnyFlag(MountCapabilityFlags.Float))
|
||||
continue;
|
||||
|
||||
if (mountCapability.RequiredArea != 0 && (mountCapability.RequiredArea != zoneId && mountCapability.RequiredArea != areaId))
|
||||
if (mountCapability.RequiredMap != -1 &&
|
||||
GetMapId() != mountCapability.RequiredMap &&
|
||||
GetMap().GetEntry().CosmeticParentMapID != mountCapability.RequiredMap &&
|
||||
GetMap().GetEntry().ParentMapID != mountCapability.RequiredMap)
|
||||
continue;
|
||||
|
||||
if (mountCapability.RequiredArea != 0 && !Global.DB2Mgr.IsInArea(areaId, mountCapability.RequiredArea))
|
||||
continue;
|
||||
|
||||
if (mountCapability.RequiredAura != 0 && !HasAura(mountCapability.RequiredAura))
|
||||
continue;
|
||||
|
||||
if (mountCapability.RequiredSpell != 0 && (!IsTypeId(TypeId.Player) || !ToPlayer().HasSpell(mountCapability.RequiredSpell)))
|
||||
if (mountCapability.RequiredSpell != 0 && !HasSpell(mountCapability.RequiredSpell))
|
||||
continue;
|
||||
|
||||
return mountCapability;
|
||||
|
||||
@@ -1025,7 +1025,7 @@ namespace Game.Spells
|
||||
[AuraEffectHandler(AuraType.Unk324)]
|
||||
[AuraEffectHandler(AuraType.ModBlind)]
|
||||
[AuraEffectHandler(AuraType.Unk335)]
|
||||
[AuraEffectHandler(AuraType.ModFlyingRestrictions)]
|
||||
[AuraEffectHandler(AuraType.MountRestrictions)]
|
||||
[AuraEffectHandler(AuraType.IncreaseSkillGainChance)]
|
||||
[AuraEffectHandler(AuraType.ModResurrectedHealthByGuildMember)]
|
||||
[AuraEffectHandler(AuraType.ModAutoattackDamage)]
|
||||
|
||||
@@ -896,14 +896,15 @@ namespace Game.Spells
|
||||
|
||||
switch (effect.ApplyAuraName)
|
||||
{
|
||||
case AuraType.Fly:
|
||||
case AuraType.ModShapeshift:
|
||||
{
|
||||
var bounds = Global.SpellMgr.GetSkillLineAbilityMapBounds(Id);
|
||||
foreach (var skillRecord in bounds)
|
||||
SpellShapeshiftFormRecord spellShapeshiftForm = CliDB.SpellShapeshiftFormStorage.LookupByKey(effect.MiscValue);
|
||||
if (spellShapeshiftForm != null)
|
||||
{
|
||||
if (skillRecord.SkillLine == (int)SkillType.Mounts)
|
||||
if (!player.CanFlyInZone(map_id, zone_id))
|
||||
return SpellCastResult.IncorrectArea;
|
||||
uint mountType = spellShapeshiftForm.MountTypeID;
|
||||
if (mountType != 0)
|
||||
if (player.GetMountCapability(mountType) == null)
|
||||
return SpellCastResult.NotHere;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user