Core/Auras: Updated mount capability check and implemented SPELL_AURA_MOUNT_RESTRICTIONS
This commit is contained in:
1 parent
3147aab824
commit
088ce63ac7
10 files changed
+92
-37
No files matched your search
@@ -345,6 +345,14 @@ enum AreaFlags
|
||||
AREA_FLAG_UNK9 = 0x40000000
|
||||
};
|
||||
|
||||
enum AreaMountFlags
|
||||
{
|
||||
AREA_MOUNT_FLAG_GROUND_ALLOWED = 0x1,
|
||||
AREA_MOUNT_FLAG_FLYING_ALLOWED = 0x2,
|
||||
AREA_MOUNT_FLAG_FLOAT_ALLOWED = 0x4,
|
||||
AREA_MOUNT_FLAG_UNDERWATER_ALLOWED = 0x8
|
||||
};
|
||||
|
||||
enum Difficulty
|
||||
{
|
||||
REGULAR_DIFFICULTY = 0,
|
||||
@@ -449,10 +457,13 @@ enum ItemLimitCategoryMode
|
||||
ITEM_LIMIT_CATEGORY_MODE_EQUIP = 1 // limit applied to amount equipped items (including used gems)
|
||||
};
|
||||
|
||||
enum MountFlags
|
||||
enum MountCapabilityFlags
|
||||
{
|
||||
MOUNT_FLAG_CAN_PITCH = 0x4, // client checks MOVEMENTFLAG2_FULL_SPEED_PITCHING
|
||||
MOUNT_FLAG_CAN_SWIM = 0x8, // client checks MOVEMENTFLAG_SWIMMING
|
||||
MOUNT_CAPABILITY_FLAG_GROUND = 0x1,
|
||||
MOUNT_CAPABILITY_FLAG_FLYING = 0x2,
|
||||
MOUNT_CAPABILITY_FLAG_FLOAT = 0x4,
|
||||
MOUNT_CAPABILITY_FLAG_UNDERWATER = 0x8,
|
||||
MOUNT_CAPABIILTY_FLAG_IGNORE_RESTRICTIONS = 0x20,
|
||||
};
|
||||
|
||||
enum SkillRaceClassInfoFlags
|
||||
|
||||
@@ -1385,3 +1385,20 @@ EmotesTextSoundEntry const* FindTextSoundEmoteFor(uint32 emote, uint32 race, uin
|
||||
auto itr = sEmotesTextSoundMap.find(EmotesTextSoundKey(emote, race, gender));
|
||||
return itr != sEmotesTextSoundMap.end() ? itr->second : nullptr;
|
||||
}
|
||||
|
||||
bool IsInArea(uint32 objectAreaId, uint32 areaId)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (objectAreaId == areaId)
|
||||
return true;
|
||||
|
||||
AreaTableEntry const* objectArea = sAreaTableStore.LookupEntry(objectAreaId);
|
||||
if (!objectArea)
|
||||
break;
|
||||
|
||||
objectAreaId = objectArea->zone;
|
||||
} while (objectAreaId);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -76,6 +76,7 @@ TC_GAME_API CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint
|
||||
TC_GAME_API CharSectionsEntry const* GetCharSectionEntry(uint8 race, CharSectionType genType, uint8 gender, uint8 type, uint8 color);
|
||||
|
||||
uint32 GetPowerIndexByClass(uint32 powerType, uint32 classId);
|
||||
TC_GAME_API bool IsInArea(uint32 objectAreaId, uint32 areaId);
|
||||
TC_GAME_API LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty);
|
||||
|
||||
uint32 GetDefaultMapLight(uint32 mapId);
|
||||
|
||||
@@ -629,7 +629,7 @@ struct AreaTableEntry
|
||||
float MaxDepth; // 17,
|
||||
float AmbientMultiplier; // 18 client only?
|
||||
uint32 LightId; // 19
|
||||
//uint32 unk20; // 20 4.0.0 - Mounting related
|
||||
uint32 MountFlags; // 20
|
||||
//uint32 unk21; // 21 4.0.0
|
||||
//uint32 unk22; // 22 4.0.0
|
||||
//uint32 unk23; // 23 4.0.0
|
||||
|
||||
@@ -27,7 +27,7 @@ const std::string CustomAchievementfmt = "pppaaaapapaapp";
|
||||
const std::string CustomAchievementIndex = "ID";
|
||||
char const AnimKitfmt[] = "nxx";
|
||||
char const AchievementCriteriafmt[] = "niiiliiiisiiiiixxiiiiii";
|
||||
char const AreaTableEntryfmt[] = "niiiixxxxxisiiiiiffixxxxxx";
|
||||
char const AreaTableEntryfmt[] = "niiiixxxxxisiiiiiffiixxxxx";
|
||||
char const AreaGroupEntryfmt[] = "niiiiiii";
|
||||
char const AreaPOIEntryfmt[] = "niiiiiiiiiiiffixixxixx";
|
||||
char const AreaTriggerEntryfmt[] = "nifffxxxfffff";
|
||||
|
||||
@@ -8085,18 +8085,35 @@ void Unit::Dismount()
|
||||
MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const
|
||||
{
|
||||
if (!mountType)
|
||||
return NULL;
|
||||
return nullptr;
|
||||
|
||||
MountTypeEntry const* mountTypeEntry = sMountTypeStore.LookupEntry(mountType);
|
||||
if (!mountTypeEntry)
|
||||
return NULL;
|
||||
return nullptr;
|
||||
|
||||
uint32 zoneId, areaId;
|
||||
GetZoneAndAreaId(zoneId, areaId);
|
||||
|
||||
uint32 areaId = GetAreaId();
|
||||
uint32 ridingSkill = 5000;
|
||||
uint32 mountFlags = 0;
|
||||
bool isSubmerged = false;
|
||||
bool isInWater = false;
|
||||
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
ridingSkill = ToPlayer()->GetSkillValue(SKILL_RIDING);
|
||||
|
||||
if (HasAuraType(SPELL_AURA_MOUNT_RESTRICTIONS))
|
||||
{
|
||||
for (AuraEffect const* auraEffect : GetAuraEffectsByType(SPELL_AURA_MOUNT_RESTRICTIONS))
|
||||
mountFlags |= auraEffect->GetMiscValue();
|
||||
}
|
||||
else if (AreaTableEntry const* areaTable = sAreaTableStore.LookupEntry(areaId))
|
||||
mountFlags = areaTable->MountFlags;
|
||||
|
||||
LiquidData liquid;
|
||||
ZLiquidStatus liquidStatus = GetMap()->GetLiquidStatus(GetPositionX(), GetPositionY(), GetPositionZ(), MAP_ALL_LIQUIDS, &liquid);
|
||||
isSubmerged = (liquidStatus & LIQUID_MAP_UNDER_WATER) != 0 || HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
|
||||
isInWater = (liquidStatus & (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER)) != 0;
|
||||
|
||||
for (uint32 i = MAX_MOUNT_CAPABILITIES; i > 0; --i)
|
||||
{
|
||||
MountCapabilityEntry const* mountCapability = sMountCapabilityStore.LookupEntry(mountTypeEntry->MountCapability[i - 1]);
|
||||
@@ -8106,38 +8123,55 @@ MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const
|
||||
if (ridingSkill < mountCapability->RequiredRidingSkill)
|
||||
continue;
|
||||
|
||||
if (HasExtraUnitMovementFlag(MOVEMENTFLAG2_FULL_SPEED_PITCHING))
|
||||
if (!(mountCapability->Flags & MOUNT_CAPABIILTY_FLAG_IGNORE_RESTRICTIONS))
|
||||
{
|
||||
if (!(mountCapability->Flags & MOUNT_FLAG_CAN_PITCH))
|
||||
if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_GROUND && !(mountFlags & AREA_MOUNT_FLAG_GROUND_ALLOWED))
|
||||
continue;
|
||||
}
|
||||
else if (HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING))
|
||||
{
|
||||
if (!(mountCapability->Flags & MOUNT_FLAG_CAN_SWIM))
|
||||
if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_FLYING && !(mountFlags & AREA_MOUNT_FLAG_FLYING_ALLOWED))
|
||||
continue;
|
||||
}
|
||||
else if (!(mountCapability->Flags & 0x1)) // unknown flags, checked in 4.2.2 14545 client
|
||||
{
|
||||
if (!(mountCapability->Flags & 0x2))
|
||||
if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_FLOAT && !(mountFlags & AREA_MOUNT_FLAG_FLOAT_ALLOWED))
|
||||
continue;
|
||||
if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_UNDERWATER && !(mountFlags & AREA_MOUNT_FLAG_UNDERWATER_ALLOWED))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mountCapability->RequiredMap != -1 && int32(GetMapId()) != mountCapability->RequiredMap)
|
||||
if (!isSubmerged)
|
||||
{
|
||||
if (!isInWater)
|
||||
{
|
||||
// player is completely out of water
|
||||
if (!(mountCapability->Flags & MOUNT_CAPABILITY_FLAG_GROUND))
|
||||
continue;
|
||||
}
|
||||
else if (!(mountCapability->Flags & MOUNT_CAPABILITY_FLAG_UNDERWATER))
|
||||
continue;
|
||||
}
|
||||
else if (isInWater)
|
||||
{
|
||||
if (!(mountCapability->Flags & MOUNT_CAPABILITY_FLAG_UNDERWATER))
|
||||
continue;
|
||||
}
|
||||
else if (!(mountCapability->Flags & MOUNT_CAPABILITY_FLAG_FLOAT))
|
||||
continue;
|
||||
|
||||
if (mountCapability->RequiredArea && (mountCapability->RequiredArea != zoneId && mountCapability->RequiredArea != areaId))
|
||||
if (mountCapability->RequiredMap != -1 &&
|
||||
int32(GetMapId()) != mountCapability->RequiredMap &&
|
||||
GetMap()->GetEntry()->rootPhaseMap != mountCapability->RequiredMap)
|
||||
continue;
|
||||
|
||||
if (mountCapability->RequiredArea && !IsInArea(areaId, mountCapability->RequiredArea))
|
||||
continue;
|
||||
|
||||
if (mountCapability->RequiredAura && !HasAura(mountCapability->RequiredAura))
|
||||
continue;
|
||||
|
||||
if (mountCapability->RequiredSpell && (GetTypeId() != TYPEID_PLAYER || !ToPlayer()->HasSpell(mountCapability->RequiredSpell)))
|
||||
if (mountCapability->RequiredSpell && !HasSpell(mountCapability->RequiredSpell))
|
||||
continue;
|
||||
|
||||
return mountCapability;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Unit::IsServiceProvider() const
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "MovementStructures.h"
|
||||
#include "Vehicle.h"
|
||||
#include "GameTime.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
|
||||
#define MOVEMENT_PACKET_TIME_DELAY 0
|
||||
|
||||
@@ -187,10 +188,6 @@ void WorldSession::HandleMoveWorldportAckOpcode()
|
||||
GetPlayer()->GetZoneAndAreaId(newzone, newarea);
|
||||
GetPlayer()->UpdateZone(newzone, newarea);
|
||||
|
||||
// can fly check
|
||||
if (!_player->CanFlyInZone(newMap->GetId(), newarea))
|
||||
_player->RemoveAurasByType(SPELL_AURA_FLY);
|
||||
|
||||
// honorless target
|
||||
if (GetPlayer()->pvpInfo.IsHostile)
|
||||
GetPlayer()->CastSpell(GetPlayer(), 2479, true);
|
||||
@@ -266,10 +263,6 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recvPacket)
|
||||
// in friendly area
|
||||
else if (plMover->IsPvP() && !plMover->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP))
|
||||
plMover->UpdatePvP(false, false);
|
||||
|
||||
// can fly check
|
||||
if (!plMover->CanFlyInZone(plMover->GetMapId(), newzone))
|
||||
plMover->RemoveAurasByType(SPELL_AURA_FLY);
|
||||
}
|
||||
|
||||
// resummon pet
|
||||
|
||||
@@ -395,7 +395,7 @@ enum AuraType
|
||||
SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_TRIGGERED = 333, // Spells cast with this override have no cast time or power cost
|
||||
SPELL_AURA_MOD_BLIND = 334, // NYI
|
||||
SPELL_AURA_335 = 335,
|
||||
SPELL_AURA_MOD_FLYING_RESTRICTIONS = 336, // NYI
|
||||
SPELL_AURA_MOUNT_RESTRICTIONS = 336,
|
||||
SPELL_AURA_MOD_VENDOR_ITEMS_PRICES = 337,
|
||||
SPELL_AURA_MOD_DURABILITY_LOSS = 338,
|
||||
SPELL_AURA_INCREASE_SKILL_GAIN_CHANCE = 339, // NYI
|
||||
|
||||
@@ -394,7 +394,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
|
||||
&AuraEffect::HandleNoImmediateEffect, //333 SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_TRIGGERED implemented in Unit::GetCastSpellInfo
|
||||
&AuraEffect::HandleNULL, //334 SPELL_AURA_MOD_BLIND
|
||||
&AuraEffect::HandleNULL, //335 SPELL_AURA_335
|
||||
&AuraEffect::HandleNULL, //336 SPELL_AURA_MOD_FLYING_RESTRICTIONS
|
||||
&AuraEffect::HandleNULL, //336 SPELL_AURA_MOUNT_RESTRICTIONS implemented in Unit::GetMountCapability
|
||||
&AuraEffect::HandleNoImmediateEffect, //337 SPELL_AURA_MOD_VENDOR_ITEMS_PRICES
|
||||
&AuraEffect::HandleNoImmediateEffect, //338 SPELL_AURA_MOD_DURABILITY_LOSS
|
||||
&AuraEffect::HandleNULL, //339 SPELL_AURA_INCREASE_SKILL_GAIN_CHANCE
|
||||
|
||||
@@ -1649,11 +1649,10 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a
|
||||
// continent limitation (virtual continent)
|
||||
if (HasAttribute(SPELL_ATTR4_CAST_ONLY_IN_OUTLAND))
|
||||
{
|
||||
AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(area_id);
|
||||
if (!areaEntry)
|
||||
areaEntry = sAreaTableStore.LookupEntry(zone_id);
|
||||
uint32 v_map = GetVirtualMapForMapAndZone(map_id, zone_id);
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(v_map);
|
||||
|
||||
if (!areaEntry || !areaEntry->IsFlyable() || !player->CanFlyInZone(map_id, zone_id))
|
||||
if (!mapEntry || mapEntry->addon < 1 || !mapEntry->IsContinent())
|
||||
return SPELL_FAILED_INCORRECT_AREA;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user