aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp17
-rw-r--r--src/server/game/DataStores/DB2Stores.h1
-rw-r--r--src/server/game/DataStores/DBCEnums.h15
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp56
-rw-r--r--src/server/game/Spells/Auras/SpellAuraDefines.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp2
6 files changed, 78 insertions, 15 deletions
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp
index a695af58b6b..978bccb2807 100644
--- a/src/server/game/DataStores/DB2Stores.cpp
+++ b/src/server/game/DataStores/DB2Stores.cpp
@@ -1150,6 +1150,23 @@ std::vector<uint32> DB2Manager::GetAreasForGroup(uint32 areaGroupId) const
return std::vector<uint32>();
}
+bool DB2Manager::IsInArea(uint32 objectAreaId, uint32 areaId)
+{
+ do
+ {
+ if (objectAreaId == areaId)
+ return true;
+
+ AreaTableEntry const* objectArea = sAreaTableStore.LookupEntry(objectAreaId);
+ if (!objectArea)
+ break;
+
+ objectAreaId = objectArea->ParentAreaID;
+ } while (objectAreaId);
+
+ return false;
+}
+
std::vector<ArtifactPowerEntry const*> DB2Manager::GetArtifactPowers(uint8 artifactId) const
{
auto itr = _artifactPowers.find(artifactId);
diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h
index e1d31f7141b..8a56c17efd6 100644
--- a/src/server/game/DataStores/DB2Stores.h
+++ b/src/server/game/DataStores/DB2Stores.h
@@ -254,6 +254,7 @@ public:
std::map<uint64, int32> const& GetHotfixData() const;
std::vector<uint32> GetAreasForGroup(uint32 areaGroupId) const;
+ static bool IsInArea(uint32 objectAreaId, uint32 areaId);
std::vector<ArtifactPowerEntry const*> GetArtifactPowers(uint8 artifactId) const;
std::unordered_set<uint32> const* GetArtifactPowerLinks(uint32 artifactPowerId) const;
ArtifactPowerRankEntry const* GetArtifactPowerRank(uint32 artifactPowerId, uint8 rank) const;
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 4a77223a17f..ecade307f26 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -138,6 +138,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 ArtifactPowerFlag : uint8
{
ARTIFACT_POWER_FLAG_GOLD = 0x01,
@@ -784,8 +792,11 @@ enum MapDifficultyFlags : uint8
enum MountCapabilityFlags
{
- MOUNT_CAPABILITY_FLAG_CAN_PITCH = 0x4, // client checks MOVEMENTFLAG2_FULL_SPEED_PITCHING
- MOUNT_CAPABILITY_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 MountFlags
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index ae62f96cc3d..a2a7d5b1697 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -7698,12 +7698,28 @@ MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const
if (!capabilities)
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 (MountTypeXCapabilityEntry const* mountTypeXCapability : *capabilities)
{
MountCapabilityEntry const* mountCapability = sMountCapabilityStore.LookupEntry(mountTypeXCapability->MountCapabilityID);
@@ -7713,32 +7729,50 @@ 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_CAPABILITY_FLAG_CAN_PITCH))
+ if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_GROUND && !(mountFlags & AREA_MOUNT_FLAG_GROUND_ALLOWED))
+ continue;
+ if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_FLYING && !(mountFlags & AREA_MOUNT_FLAG_FLYING_ALLOWED))
+ continue;
+ 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;
}
- else if (HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING))
+
+ if (!isSubmerged)
{
- if (!(mountCapability->Flags & MOUNT_CAPABILITY_FLAG_CAN_SWIM))
+ 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 (!(mountCapability->Flags & 0x1)) // unknown flags, checked in 4.2.2 14545 client
+ else if (isInWater)
{
- if (!(mountCapability->Flags & 0x2))
+ if (!(mountCapability->Flags & MOUNT_CAPABILITY_FLAG_UNDERWATER))
continue;
}
+ else if (!(mountCapability->Flags & MOUNT_CAPABILITY_FLAG_FLOAT))
+ continue;
- if (mountCapability->RequiredMap != -1 && int32(GetMapId()) != mountCapability->RequiredMap)
+ if (mountCapability->RequiredMap != -1 &&
+ int32(GetMapId()) != mountCapability->RequiredMap &&
+ GetMap()->GetEntry()->CosmeticParentMapID != mountCapability->RequiredMap &&
+ GetMap()->GetEntry()->ParentMapID != mountCapability->RequiredMap)
continue;
- if (mountCapability->RequiredArea && (mountCapability->RequiredArea != zoneId && mountCapability->RequiredArea != areaId))
+ if (mountCapability->RequiredArea && !DB2Manager::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;
diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h
index b485a052739..9ec7f9fd949 100644
--- a/src/server/game/Spells/Auras/SpellAuraDefines.h
+++ b/src/server/game/Spells/Auras/SpellAuraDefines.h
@@ -403,7 +403,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
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index afb8f30604f..08a712c326a 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -401,7 +401,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