diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 17 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Stores.h | 1 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 15 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 56 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraDefines.h | 2 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 2 |
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 |