Core/Auras: Updated mount capability check and implemented SPELL_AURA_MOUNT_RESTRICTIONS

This commit is contained in:
Ovalord committed 2017-12-14 01:00:11 +01:00
1 parent 3147aab824
commit 088ce63ac7
10 files changed
+92 -37

No files matched your search

+14 -3
View File
@@ -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
+17
View File
@@ -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;
}
+1
View File
@@ -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);
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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";
+52 -18
View File
@@ -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
+1 -8
View File
@@ -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
+3 -4
View File
@@ -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;
}