diff --git a/Source/Framework/Constants/CliDBConst.cs b/Source/Framework/Constants/CliDBConst.cs index 67b2dfb7c..5043bbb23 100644 --- a/Source/Framework/Constants/CliDBConst.cs +++ b/Source/Framework/Constants/CliDBConst.cs @@ -877,6 +877,7 @@ namespace Framework.Constants FlyWarriorChargeEnd = 821 } + [Flags] public enum AreaFlags { Snow = 0x01, // Snow (Only Dun Morogh, Naxxramas, Razorfen Downs And Winterspring) @@ -911,6 +912,7 @@ namespace Framework.Constants Unk9 = 0x40000000, } + [Flags] public enum AreaFlags2 { DontShowSanctuary = 0x200, // Hides sanctuary status from zone text color (Script_GetZonePVPInfo) diff --git a/Source/Game/Achievements/CriteriaHandler.cs b/Source/Game/Achievements/CriteriaHandler.cs index d9a0bc9d6..291da6d60 100644 --- a/Source/Game/Achievements/CriteriaHandler.cs +++ b/Source/Game/Achievements/CriteriaHandler.cs @@ -1450,7 +1450,7 @@ namespace Game.Achievements uint zoneId = referencePlayer.GetAreaId(); AreaTableRecord areaEntry = CliDB.AreaTableStorage.LookupByKey(zoneId); if (areaEntry != null) - if (areaEntry.Flags[0].HasAnyFlag(AreaFlags.Unk9)) + if (areaEntry.Flags.HasFlag(AreaFlags.Unk9)) zoneId = areaEntry.ParentAreaID; if (zoneId != reqValue) return false; @@ -1463,7 +1463,7 @@ namespace Game.Achievements uint zoneId = unit.GetAreaId(); AreaTableRecord areaEntry = CliDB.AreaTableStorage.LookupByKey(zoneId); if (areaEntry != null) - if (areaEntry.Flags[0].HasAnyFlag(AreaFlags.Unk9)) + if (areaEntry.Flags.HasFlag(AreaFlags.Unk9)) zoneId = areaEntry.ParentAreaID; if (zoneId != reqValue) return false; diff --git a/Source/Game/DataStorage/Structs/A_Records.cs b/Source/Game/DataStorage/Structs/A_Records.cs index 08fe960f6..cfcc946fb 100644 --- a/Source/Game/DataStorage/Structs/A_Records.cs +++ b/Source/Game/DataStorage/Structs/A_Records.cs @@ -142,7 +142,8 @@ namespace Game.DataStorage public byte WildBattlePetLevelMax; public byte WindSettingsID; public uint ContentTuningID; - public AreaFlags[] Flags = new AreaFlags[2]; + public AreaFlags Flags; + public AreaFlags2 Flags2; public ushort[] LiquidTypeID = new ushort[4]; public bool IsSanctuary() @@ -150,14 +151,14 @@ namespace Game.DataStorage if (ContinentID == 609) return true; - return Flags[0].HasAnyFlag(AreaFlags.Sanctuary); + return Flags.HasAnyFlag(AreaFlags.Sanctuary); } public bool IsFlyable() { - if (Flags[0].HasAnyFlag(AreaFlags.Outland)) + if (Flags.HasAnyFlag(AreaFlags.Outland)) { - if (!Flags[0].HasAnyFlag(AreaFlags.NoFlyZone)) + if (!Flags.HasAnyFlag(AreaFlags.NoFlyZone)) return true; } diff --git a/Source/Game/Entities/Player/Player.Map.cs b/Source/Game/Entities/Player/Player.Map.cs index bc94fadfe..86f53359f 100644 --- a/Source/Game/Entities/Player/Player.Map.cs +++ b/Source/Game/Entities/Player/Player.Map.cs @@ -112,7 +112,7 @@ namespace Game.Entities AreaTableRecord area = CliDB.AreaTableStorage.LookupByKey(newArea); bool oldFFAPvPArea = pvpInfo.IsInFFAPvPArea; - pvpInfo.IsInFFAPvPArea = area != null && area.Flags[0].HasAnyFlag(AreaFlags.Arena); + pvpInfo.IsInFFAPvPArea = area != null && area.Flags.HasFlag(AreaFlags.Arena); UpdatePvPState(true); // check if we were in ffa arena and we left @@ -140,7 +140,7 @@ namespace Game.Entities RemovePvpFlag(UnitPVPStateFlags.Sanctuary); AreaFlags areaRestFlag = (GetTeam() == Team.Alliance) ? AreaFlags.RestZoneAlliance : AreaFlags.RestZoneHorde; - if (area != null && area.Flags[0].HasAnyFlag(areaRestFlag)) + if (area != null && area.Flags.HasFlag(areaRestFlag)) _restMgr.SetRestFlag(RestFlag.FactionArea); else _restMgr.RemoveRestFlag(RestFlag.FactionArea); @@ -192,7 +192,7 @@ namespace Game.Entities UpdateHostileAreaState(zone); - if (zone.Flags[0].HasAnyFlag(AreaFlags.Capital)) // Is in a capital city + if (zone.Flags.HasFlag(AreaFlags.Capital)) // Is in a capital city { if (!pvpInfo.IsInHostileArea || zone.IsSanctuary()) _restMgr.SetRestFlag(RestFlag.City); @@ -237,17 +237,17 @@ namespace Game.Entities if (area.IsSanctuary()) // sanctuary and arena cannot be overriden pvpInfo.IsInHostileArea = false; - else if (area.Flags[0].HasAnyFlag(AreaFlags.Arena)) + else if (area.Flags.HasFlag(AreaFlags.Arena)) pvpInfo.IsInHostileArea = true; else if (overrideZonePvpType == ZonePVPTypeOverride.None) { if (area != null) { - if (InBattleground() || area.Flags[0].HasAnyFlag(AreaFlags.Combat) || (area.PvpCombatWorldStateID != -1 && Global.WorldMgr.GetWorldState((WorldStates)area.PvpCombatWorldStateID) != 0)) + if (InBattleground() || area.Flags.HasFlag(AreaFlags.Combat) || (area.PvpCombatWorldStateID != -1 && Global.WorldMgr.GetWorldState((WorldStates)area.PvpCombatWorldStateID) != 0)) pvpInfo.IsInHostileArea = true; - else if (Global.WorldMgr.IsPvPRealm() || area.Flags[0].HasAnyFlag(AreaFlags.Unk3)) + else if (Global.WorldMgr.IsPvPRealm() || area.Flags.HasFlag(AreaFlags.Unk3)) { - if (area.Flags[0].HasAnyFlag(AreaFlags.ContestedArea)) + if (area.Flags.HasFlag(AreaFlags.ContestedArea)) pvpInfo.IsInHostileArea = Global.WorldMgr.IsPvPRealm(); else { diff --git a/Source/Game/Entities/Player/Player.PvP.cs b/Source/Game/Entities/Player/Player.PvP.cs index cd3fd8284..d4215986e 100644 --- a/Source/Game/Entities/Player/Player.PvP.cs +++ b/Source/Game/Entities/Player/Player.PvP.cs @@ -511,7 +511,7 @@ namespace Game.Entities if (area.IsSanctuary()) return false; - if (area.Flags[0].HasAnyFlag(AreaFlags.Arena)) + if (area.Flags.HasFlag(AreaFlags.Arena)) return true; if (Global.BattleFieldMgr.GetBattlefieldToZoneId(area.Id) != null) diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index c1dbde0af..d78f26935 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -2575,10 +2575,10 @@ namespace Game.Entities public bool CanJoinConstantChannelInZone(ChatChannelsRecord channel, AreaTableRecord zone) { - if (channel.Flags.HasAnyFlag(ChannelDBCFlags.ZoneDep) && zone.Flags[0].HasAnyFlag(AreaFlags.ArenaInstance)) + if (channel.Flags.HasAnyFlag(ChannelDBCFlags.ZoneDep) && zone.Flags.HasFlag(AreaFlags.ArenaInstance)) return false; - if (channel.Flags.HasAnyFlag(ChannelDBCFlags.CityOnly) && !zone.Flags[0].HasAnyFlag(AreaFlags.Capital)) + if (channel.Flags.HasAnyFlag(ChannelDBCFlags.CityOnly) && !zone.Flags.HasFlag(AreaFlags.Capital)) return false; if (channel.Flags.HasAnyFlag(ChannelDBCFlags.GuildReq) && GetGuildId() != 0) @@ -4491,7 +4491,7 @@ namespace Game.Entities AreaTableRecord zone = CliDB.AreaTableStorage.LookupByKey(GetAreaId()); // Such zones are considered unreachable as a ghost and the player must be automatically revived - if ((!IsAlive() && zone != null && zone.Flags[0].HasAnyFlag(AreaFlags.NeedFly)) || GetTransport() != null || GetPositionZ() < GetMap().GetMinHeight(GetPhaseShift(), GetPositionX(), GetPositionY())) + if ((!IsAlive() && zone != null && zone.Flags.HasFlag(AreaFlags.NeedFly)) || GetTransport() != null || GetPositionZ() < GetMap().GetMinHeight(GetPhaseShift(), GetPositionX(), GetPositionY())) { ResurrectPlayer(0.5f); SpawnCorpseBones(); @@ -4992,6 +4992,38 @@ namespace Game.Entities return true; } + bool IsInFriendlyArea() + { + var areaEntry = CliDB.AreaTableStorage.LookupByKey(GetAreaId()); + if (areaEntry != null) + return IsFriendlyArea(areaEntry); + + return false; + } + + bool IsFriendlyArea(AreaTableRecord areaEntry) + { + Cypher.Assert(areaEntry != null); + + var factionTemplate = GetFactionTemplateEntry(); + if (factionTemplate == null) + return false; + + if ((factionTemplate.FriendGroup & areaEntry.FactionGroupMask) == 0) + return false; + + return true; + } + + bool CanEnableWarModeInArea() + { + var area = CliDB.AreaTableStorage.LookupByKey(GetAreaId()); + if (area == null || !IsFriendlyArea(area)) + return false; + + return area.Flags2.HasFlag(AreaFlags2.CanEnableWarMode); + } + // Used in triggers for check "Only to targets that grant experience or honor" req public bool IsHonorOrXPTarget(Unit victim) { diff --git a/Source/Game/Handlers/BattleGroundHandler.cs b/Source/Game/Handlers/BattleGroundHandler.cs index 8eca7a630..dfaddbb31 100644 --- a/Source/Game/Handlers/BattleGroundHandler.cs +++ b/Source/Game/Handlers/BattleGroundHandler.cs @@ -652,7 +652,7 @@ namespace Game } AreaTableRecord atEntry = CliDB.AreaTableStorage.LookupByKey(GetPlayer().GetAreaId()); - if (atEntry == null || !atEntry.Flags[0].HasAnyFlag(AreaFlags.CanHearthAndResurrect)) + if (atEntry == null || !atEntry.Flags.HasFlag(AreaFlags.CanHearthAndResurrect)) return; GetPlayer().BuildPlayerRepop(); diff --git a/Source/Game/Maps/Map.cs b/Source/Game/Maps/Map.cs index f9c63cb82..fb17f865d 100644 --- a/Source/Game/Maps/Map.cs +++ b/Source/Game/Maps/Map.cs @@ -1783,9 +1783,9 @@ namespace Game.Maps { if (wmoEntry != null && atEntry != null) { - if (atEntry.Flags[0].HasAnyFlag(AreaFlags.Outside)) + if (atEntry.Flags.HasFlag(AreaFlags.Outside)) return true; - if (atEntry.Flags[0].HasAnyFlag(AreaFlags.Inside)) + if (atEntry.Flags.HasFlag(AreaFlags.Inside)) return false; } diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index 584989aea..171527a1e 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -5460,7 +5460,7 @@ namespace Game.Spells BattleField Bf = Global.BattleFieldMgr.GetBattlefieldToZoneId(m_originalCaster.GetZoneId()); var area = CliDB.AreaTableStorage.LookupByKey(m_originalCaster.GetAreaId()); if (area != null) - if (area.Flags[0].HasAnyFlag(AreaFlags.NoFlyZone) || (Bf != null && !Bf.CanFlyIn())) + if (area.Flags.HasFlag(AreaFlags.NoFlyZone) || (Bf != null && !Bf.CanFlyIn())) return SpellCastResult.NotHere; } break; diff --git a/Source/Game/Spells/SpellEffects.cs b/Source/Game/Spells/SpellEffects.cs index 423584145..52847a244 100644 --- a/Source/Game/Spells/SpellEffects.cs +++ b/Source/Game/Spells/SpellEffects.cs @@ -3268,14 +3268,14 @@ namespace Game.Spells // Players can only fight a duel in zones with this flag AreaTableRecord casterAreaEntry = CliDB.AreaTableStorage.LookupByKey(caster.GetAreaId()); - if (casterAreaEntry != null && !casterAreaEntry.Flags[0].HasAnyFlag(AreaFlags.AllowDuels)) + if (casterAreaEntry != null && !casterAreaEntry.Flags.HasFlag(AreaFlags.AllowDuels)) { SendCastResult(SpellCastResult.NoDueling); // Dueling isn't allowed here return; } AreaTableRecord targetAreaEntry = CliDB.AreaTableStorage.LookupByKey(target.GetAreaId()); - if (targetAreaEntry != null && !targetAreaEntry.Flags[0].HasAnyFlag(AreaFlags.AllowDuels)) + if (targetAreaEntry != null && !targetAreaEntry.Flags.HasFlag(AreaFlags.AllowDuels)) { SendCastResult(SpellCastResult.NoDueling); // Dueling isn't allowed here return;