diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index 6e30aaee2e..b98b5566a2 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -349,48 +349,56 @@ enum AchievementCriteriaTypes : uint8 #define ACHIEVEMENT_CRITERIA_TYPE_TOTAL 151 -enum AreaFlags +enum class AreaFlags : uint32 { - AREA_FLAG_SNOW = 0x00000001, // snow (only Dun Morogh, Naxxramas, Razorfen Downs and Winterspring) - AREA_FLAG_UNK1 = 0x00000002, // Razorfen Downs, Naxxramas and Acherus: The Ebon Hold (3.3.5a) - AREA_FLAG_UNK2 = 0x00000004, // Only used for areas on map 571 (development before) - AREA_FLAG_SLAVE_CAPITAL = 0x00000008, // city and city subzones - AREA_FLAG_UNK3 = 0x00000010, // can't find common meaning - AREA_FLAG_SLAVE_CAPITAL2 = 0x00000020, // slave capital city flag? - AREA_FLAG_ALLOW_DUELS = 0x00000040, // allow to duel here - AREA_FLAG_ARENA = 0x00000080, // arena, both instanced and world arenas - AREA_FLAG_CAPITAL = 0x00000100, // main capital city flag - AREA_FLAG_CITY = 0x00000200, // only for one zone named "City" (where it located?) - AREA_FLAG_OUTLAND = 0x00000400, // expansion zones? (only Eye of the Storm not have this flag, but have 0x00004000 flag) - AREA_FLAG_SANCTUARY = 0x00000800, // sanctuary area (PvP disabled) - AREA_FLAG_NEED_FLY = 0x00001000, // Respawn alive at the graveyard without corpse - AREA_FLAG_UNUSED1 = 0x00002000, // Unused in 3.3.5a - AREA_FLAG_OUTLAND2 = 0x00004000, // expansion zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag) - AREA_FLAG_OUTDOOR_PVP = 0x00008000, // pvp objective area? (Death's Door also has this flag although it's no pvp object area) - AREA_FLAG_ARENA_INSTANCE = 0x00010000, // used by instanced arenas only - AREA_FLAG_UNUSED2 = 0x00020000, // Unused in 3.3.5a - AREA_FLAG_CONTESTED_AREA = 0x00040000, // On PvP servers these areas are considered contested, even though the zone it is contained in is a Horde/Alliance territory. - AREA_FLAG_UNK6 = 0x00080000, // Valgarde and Acherus: The Ebon Hold - AREA_FLAG_LOWLEVEL = 0x00100000, // used for some starting areas with area_level <= 15 - AREA_FLAG_TOWN = 0x00200000, // small towns with Inn - AREA_FLAG_REST_ZONE_HORDE = 0x00400000, // Warsong Hold, Acherus: The Ebon Hold, New Agamand Inn, Vengeance Landing Inn, Sunreaver Pavilion (Something to do with team?) - AREA_FLAG_REST_ZONE_ALLIANCE = 0x00800000, // Valgarde, Acherus: The Ebon Hold, Westguard Inn, Silver Covenant Pavilion (Something to do with team?) - AREA_FLAG_COMBAT = 0x01000000, // "combat" area (Script_GetZonePVPInfo), used - AREA_FLAG_INSIDE = 0x02000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors - AREA_FLAG_OUTSIDE = 0x04000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors - AREA_FLAG_CAN_HEARTH_AND_RESURRECT = 0x08000000, // Can Hearth And Resurrect From Area - AREA_FLAG_NO_FLY_ZONE = 0x20000000, // Marks zones where you cannot fly - AREA_FLAG_UNK9 = 0x40000000 + EmitBreathParticles = 0x00000001, + BreathParticlesOverrideParent = 0x00000002, + OnMapDungeon = 0x00000004, + AllowTradeChannel = 0x00000008, + EnemiesPvPFlagged = 0x00000010, + AllowResting = 0x00000020, + AllowDueling = 0x00000040, + FreeForAllPvP = 0x00000080, + LinkedChat = 0x00000100, // Set in cities + LinkedChatSpecialArea = 0x00000200, + ForceThisAreaWhenOnDynamicTransport = 0x00000400, + NoPvP = 0x00000800, + NoGhostOnRelease = 0x00001000, + SubZoneAmbientMultiplier = 0x00002000, + EnableFlightBoundsOnMap = 0x00004000, + PVPPOI = 0x00008000, + NoChatChannels = 0x00010000, + AreaNotInUse = 0x00020000, + Contested = 0x00040000, + NoPlayerSummoning = 0x00080000, + NoDuelingIfTournamentRealm = 0x00100000, + PlayersCallGuards = 0x00200000, + HordeResting = 0x00400000, + AllianceResting = 0x00800000, + CombatZone = 0x01000000, + ForceIndoors = 0x02000000, + ForceOutdoors = 0x04000000, + AllowHearthAndRessurectFromArea = 0x08000000, + NoLocalDefenseChannel = 0x10000000, + OnlyEvaluateGhostBindOnce = 0x20000000, + IsSubzone = 0x40000000, + DontEvaluateGraveyardFromClient = 0x80000000 }; -enum AreaMountFlags +DEFINE_ENUM_FLAG(AreaFlags); + +enum class AreaMountFlags : uint8 { - AREA_MOUNT_FLAG_GROUND_ALLOWED = 0x1, - AREA_MOUNT_FLAG_FLYING_ALLOWED = 0x2, - AREA_MOUNT_FLAG_FLOAT_ALLOWED = 0x4, - AREA_MOUNT_FLAG_UNDERWATER_ALLOWED = 0x8 + None = 0x0, + AllowGroundMounts = 0x1, + AllowFlyingMounts = 0x2, + AllowSurfaceSwimmingMounts = 0x4, + AllowUnderwaterSwimmingMounts = 0x8, + ClientEnforcesMount = 0x10 }; +DEFINE_ENUM_FLAG(AreaMountFlags); + enum Difficulty : uint8 { REGULAR_DIFFICULTY = 0, diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 6f406cc431..7d76d67c58 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -222,21 +222,13 @@ struct AreaTableEntry uint32 World_pvp_ID; // 24 int32 PvpCombatWorldStateID; // 25- worldStateId + EnumFlag GetFlags() const { return static_cast(Flags); } + EnumFlag GetMountFlags() const { return static_cast(MountFlags); } + // helpers bool IsSanctuary() const { - return (Flags & AREA_FLAG_SANCTUARY) != 0; - } - - bool IsFlyable() const - { - if (Flags & AREA_FLAG_OUTLAND) - { - if (!(Flags & AREA_FLAG_NO_FLY_ZONE)) - return true; - } - - return false; + return GetFlags().HasFlag(AreaFlags::NoPvP); } }; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 9101fea1da..029180956c 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4543,7 +4543,7 @@ void Player::RepopAtGraveyard() AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetAreaId()); // Such zones are considered unreachable as a ghost and the player must be automatically revived - if ((!IsAlive() && zone && zone->Flags & AREA_FLAG_NEED_FLY) || GetTransport() || GetPositionZ() < GetMap()->GetMinHeight(GetPhaseShift(), GetPositionX(), GetPositionY())) + if ((!IsAlive() && zone && zone->GetFlags().HasFlag(AreaFlags::NoGhostOnRelease)) || GetTransport() || GetPositionZ() < GetMap()->GetMinHeight(GetPhaseShift(), GetPositionX(), GetPositionY())) { ResurrectPlayer(0.5f); SpawnCorpseBones(); @@ -4587,10 +4587,10 @@ void Player::RepopAtGraveyard() bool Player::CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone) const { - if (channel->Flags & CHANNEL_DBC_FLAG_ZONE_DEP && zone->Flags & AREA_FLAG_ARENA_INSTANCE) + if (channel->Flags & CHANNEL_DBC_FLAG_ZONE_DEP && zone->GetFlags().HasFlag(AreaFlags::NoChatChannels)) return false; - if ((channel->Flags & CHANNEL_DBC_FLAG_CITY_ONLY) && (!(zone->Flags & AREA_FLAG_SLAVE_CAPITAL))) + if ((channel->Flags & CHANNEL_DBC_FLAG_CITY_ONLY) && (!(zone->GetFlags().HasFlag(AreaFlags::AllowTradeChannel)))) return false; if ((channel->Flags & CHANNEL_DBC_FLAG_GUILD_REQ) && GetGuildId()) @@ -6993,7 +6993,7 @@ void Player::UpdateArea(uint32 newArea) AreaTableEntry const* area = sAreaTableStore.LookupEntry(newArea); bool oldFFAPvPArea = pvpInfo.IsInFFAPvPArea; - pvpInfo.IsInFFAPvPArea = area && (area->Flags & AREA_FLAG_ARENA); + pvpInfo.IsInFFAPvPArea = area && (area->GetFlags().HasFlag(AreaFlags::FreeForAllPvP)); UpdatePvPState(true); // check if we were in ffa arena and we left @@ -7015,8 +7015,8 @@ void Player::UpdateArea(uint32 newArea) else RemoveByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, UNIT_BYTE2_FLAG_SANCTUARY); - uint32 const areaRestFlag = (GetTeam() == ALLIANCE) ? AREA_FLAG_REST_ZONE_ALLIANCE : AREA_FLAG_REST_ZONE_HORDE; - if (area && area->Flags & areaRestFlag) + AreaFlags const areaRestFlag = (GetTeam() == ALLIANCE) ? AreaFlags::AllianceResting : AreaFlags::HordeResting; + if (area && area->GetFlags().HasFlag(areaRestFlag)) SetRestFlag(REST_FLAG_IN_FACTION_AREA); else RemoveRestFlag(REST_FLAG_IN_FACTION_AREA); @@ -7063,7 +7063,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) UpdateHostileAreaState(zone); - if (zone->Flags & AREA_FLAG_CAPITAL) // Is in a capital city + if (zone->GetFlags().HasFlag(AreaFlags::LinkedChat)) // Is in a capital city { if (!pvpInfo.IsHostile || zone->IsSanctuary()) SetRestFlag(REST_FLAG_IN_CITY); @@ -7107,17 +7107,17 @@ void Player::UpdateHostileAreaState(AreaTableEntry const* area) if (area->IsSanctuary()) // sanctuary and arena cannot be overriden pvpInfo.IsInHostileArea = false; - else if (area->Flags & AREA_FLAG_ARENA) + else if (area->GetFlags().HasFlag(AreaFlags::FreeForAllPvP)) pvpInfo.IsInHostileArea = true; else { if (area) { - if (InBattleground() || area->Flags & AREA_FLAG_COMBAT || (area->PvpCombatWorldStateID != -1 && sWorldStateMgr->GetValue(area->PvpCombatWorldStateID, GetMap()) != 0)) + if (InBattleground() || area->GetFlags().HasFlag(AreaFlags::CombatZone) || (area->PvpCombatWorldStateID != -1 && sWorldStateMgr->GetValue(area->PvpCombatWorldStateID, GetMap()) != 0)) pvpInfo.IsInHostileArea = true; - else if (sWorld->IsPvPRealm() || (area->Flags & AREA_FLAG_UNK3)) + else if (sWorld->IsPvPRealm() || (area->GetFlags().HasFlag(AreaFlags::EnemiesPvPFlagged))) { - if (area->Flags & AREA_FLAG_CONTESTED_AREA) + if (area->GetFlags().HasFlag(AreaFlags::Contested)) pvpInfo.IsInHostileArea = sWorld->IsPvPRealm(); else { diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 4e36c7f7ce..be522d78c3 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -7901,7 +7901,7 @@ MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const uint32 areaId = GetAreaId(); uint32 ridingSkill = 5000; - uint32 mountFlags = 0; + EnumFlag mountFlags = AreaMountFlags::None; bool isUnderwater = false; bool isInWater = false; @@ -7911,10 +7911,10 @@ MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const if (HasAuraType(SPELL_AURA_MOUNT_RESTRICTIONS)) { for (AuraEffect const* auraEffect : GetAuraEffectsByType(SPELL_AURA_MOUNT_RESTRICTIONS)) - mountFlags |= auraEffect->GetMiscValue(); + mountFlags |= AreaMountFlags(auraEffect->GetMiscValue()); } else if (AreaTableEntry const* areaTable = sAreaTableStore.LookupEntry(areaId)) - mountFlags = areaTable->MountFlags; + mountFlags = areaTable->GetMountFlags(); ZLiquidStatus liquidStatus = GetLiquidStatus(); isUnderwater = (liquidStatus & LIQUID_MAP_UNDER_WATER) != 0; @@ -7931,13 +7931,13 @@ MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const if (!(mountCapability->Flags & MOUNT_CAPABIILTY_FLAG_IGNORE_RESTRICTIONS)) { - if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_GROUND && !(mountFlags & AREA_MOUNT_FLAG_GROUND_ALLOWED)) + if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_GROUND && !(mountFlags.HasFlag(AreaMountFlags::AllowGroundMounts))) continue; - if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_FLYING && !(mountFlags & AREA_MOUNT_FLAG_FLYING_ALLOWED)) + if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_FLYING && !(mountFlags.HasFlag(AreaMountFlags::AllowFlyingMounts))) continue; - if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_FLOAT && !(mountFlags & AREA_MOUNT_FLAG_FLOAT_ALLOWED)) + if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_FLOAT && !(mountFlags.HasFlag(AreaMountFlags::AllowSurfaceSwimmingMounts))) continue; - if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_UNDERWATER && !(mountFlags & AREA_MOUNT_FLAG_UNDERWATER_ALLOWED)) + if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_UNDERWATER && !(mountFlags.HasFlag(AreaMountFlags::AllowUnderwaterSwimmingMounts))) continue; } diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 2290c9c425..b1dd6602ac 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1409,7 +1409,7 @@ void WorldSession::HandleHearthAndResurrect(WorldPacket& /*recvData*/) } AreaTableEntry const* atEntry = sAreaTableStore.LookupEntry(_player->GetAreaId()); - if (!atEntry || !(atEntry->Flags & AREA_FLAG_CAN_HEARTH_AND_RESURRECT)) + if (!atEntry || !(atEntry->GetFlags().HasFlag(AreaFlags::AllowHearthAndRessurectFromArea))) return; _player->BuildPlayerRepop(); diff --git a/src/server/game/Maps/TerrainMgr.cpp b/src/server/game/Maps/TerrainMgr.cpp index e7e12d761f..e15483bc6f 100644 --- a/src/server/game/Maps/TerrainMgr.cpp +++ b/src/server/game/Maps/TerrainMgr.cpp @@ -387,7 +387,7 @@ void TerrainInfo::GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, data.outdoors = true; data.areaId = gridAreaId; if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(data.areaId)) - data.outdoors = (areaEntry->Flags & (AREA_FLAG_INSIDE | AREA_FLAG_OUTSIDE)) != AREA_FLAG_INSIDE; + data.outdoors = areaEntry->GetFlags().HasFlag(AreaFlags::ForceOutdoors) || !areaEntry->GetFlags().HasFlag(AreaFlags::ForceIndoors); } if (!data.areaId) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 46dcb95c99..17d60efc86 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -6474,9 +6474,8 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint if (m_originalCaster && m_originalCaster->GetTypeId() == TYPEID_PLAYER && m_originalCaster->IsAlive()) { Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetMap(), m_originalCaster->GetZoneId()); - if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId())) - if (area->Flags & AREA_FLAG_NO_FLY_ZONE || (Bf && !Bf->CanFlyIn())) - return (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_NOT_HERE; + if (Bf && !Bf->CanFlyIn()) + return SPELL_FAILED_NOT_HERE; } break; } diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 49c726be26..8fec5edec6 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3626,14 +3626,14 @@ void Spell::EffectDuel(SpellEffIndex effIndex) // Players can only fight a duel in zones with this flag AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId()); - if (casterAreaEntry && !(casterAreaEntry->Flags & AREA_FLAG_ALLOW_DUELS)) + if (casterAreaEntry && !(casterAreaEntry->GetFlags().HasFlag(AreaFlags::AllowDueling))) { SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here return; } AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId()); - if (targetAreaEntry && !(targetAreaEntry->Flags & AREA_FLAG_ALLOW_DUELS)) + if (targetAreaEntry && !(targetAreaEntry->GetFlags().HasFlag(AreaFlags::AllowDueling))) { SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here return; diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index bd34fe6747..1f99e53a93 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1747,16 +1747,16 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a // continent limitation (virtual continent) if (HasAttribute(SPELL_ATTR4_ONLY_FLYING_AREAS)) { - uint32 mountFlags = 0; + EnumFlag mountFlags = AreaMountFlags::None; if (player && player->HasAuraType(SPELL_AURA_MOUNT_RESTRICTIONS)) { for (AuraEffect const* auraEffect : player->GetAuraEffectsByType(SPELL_AURA_MOUNT_RESTRICTIONS)) - mountFlags |= auraEffect->GetMiscValue(); + mountFlags |= AreaMountFlags(auraEffect->GetMiscValue()); } else if (AreaTableEntry const* areaTable = sAreaTableStore.LookupEntry(area_id)) - mountFlags = areaTable->MountFlags; + mountFlags = areaTable->GetMountFlags(); - if (!(mountFlags & AREA_MOUNT_FLAG_FLYING_ALLOWED)) + if (!(mountFlags.HasFlag(AreaMountFlags::AllowFlyingMounts))) return SPELL_FAILED_INCORRECT_AREA; } diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 01a0c3fc7c..578e7259ca 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -3249,9 +3249,8 @@ class spell_item_nitro_boosts : public SpellScriptLoader void HandleDummy(SpellEffIndex /* effIndex */) { Unit* caster = GetCaster(); - AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId()); bool success = true; - if (areaEntry && areaEntry->IsFlyable() && !caster->GetMap()->IsDungeon()) + if (!caster->GetMap()->IsDungeon()) success = roll_chance_i(95); // nitro boosts can only fail in flying-enabled locations on 4.3.4 caster->CastSpell(caster, success ? SPELL_NITRO_BOOSTS_SUCCESS : SPELL_NITRO_BOOSTS_BACKFIRE, GetCastItem()); }