diff --git a/Source/Framework/Constants/PlayerConst.cs b/Source/Framework/Constants/PlayerConst.cs index f0c6f3e63..1f0a20cca 100644 --- a/Source/Framework/Constants/PlayerConst.cs +++ b/Source/Framework/Constants/PlayerConst.cs @@ -757,4 +757,13 @@ namespace Framework.Constants Default = InEquipment | InInventory, Everywhere = InEquipment | InInventory | InBank | InReagentBank } + + public enum ZonePVPTypeOverride + { + None = 0, + Friendly = 1, + Hostile = 2, + Contested = 3, + Combat = 4 + } } diff --git a/Source/Game/Entities/Player/Player.Map.cs b/Source/Game/Entities/Player/Player.Map.cs index 77a65dfe3..d3ee02e3a 100644 --- a/Source/Game/Entities/Player/Player.Map.cs +++ b/Source/Game/Entities/Player/Player.Map.cs @@ -222,15 +222,17 @@ namespace Game.Entities } } - void UpdateHostileAreaState(AreaTableRecord area) + public void UpdateHostileAreaState(AreaTableRecord area) { + ZonePVPTypeOverride overrideZonePvpType = GetOverrideZonePVPType(); + pvpInfo.IsInHostileArea = false; if (area.IsSanctuary()) // sanctuary and arena cannot be overriden pvpInfo.IsInHostileArea = false; else if (area.Flags[0].HasAnyFlag(AreaFlags.Arena)) pvpInfo.IsInHostileArea = true; - else + else if (overrideZonePvpType == ZonePVPTypeOverride.None) { if (area != null) { @@ -253,11 +255,30 @@ namespace Game.Entities } } } + else + { + switch (overrideZonePvpType) + { + case ZonePVPTypeOverride.Friendly: + pvpInfo.IsInHostileArea = false; + break; + case ZonePVPTypeOverride.Hostile: + case ZonePVPTypeOverride.Contested: + case ZonePVPTypeOverride.Combat: + pvpInfo.IsInHostileArea = true; + break; + default: + break; + } + } // Treat players having a quest flagging for PvP as always in hostile area pvpInfo.IsHostile = pvpInfo.IsInHostileArea || HasPvPForcingQuest(); } + public ZonePVPTypeOverride GetOverrideZonePVPType() { return (ZonePVPTypeOverride)(uint)m_activePlayerData.OverrideZonePVPType; } + public void SetOverrideZonePVPType(ZonePVPTypeOverride type) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.OverrideZonePVPType), (uint)type); } + public InstanceBind GetBoundInstance(uint mapid, Difficulty difficulty, bool withExpired = false) { // some instances only have one difficulty diff --git a/Source/Game/Spells/Auras/AuraEffect.cs b/Source/Game/Spells/Auras/AuraEffect.cs index f90d34148..579e83773 100644 --- a/Source/Game/Spells/Auras/AuraEffect.cs +++ b/Source/Game/Spells/Auras/AuraEffect.cs @@ -888,7 +888,7 @@ namespace Game.Spells public bool HasAmount() { return m_amount != 0; } public void SetAmount(int _amount) { m_amount = _amount; m_canBeRecalculated = false; } - int GetPeriodicTimer() { return m_periodicTimer; } + public int GetPeriodicTimer() { return m_periodicTimer; } public void SetPeriodicTimer(int periodicTimer) { m_periodicTimer = periodicTimer; } void RecalculateAmount() @@ -3502,17 +3502,17 @@ namespace Game.Spells { float amount = target.GetTotalAuraMultiplier(AuraType.ModIncreaseEnergyPercent, aurEff => { - if (aurEff.GetMiscValue() == (int)powerType) - return true; - return false; - }); + if (aurEff.GetMiscValue() == (int)powerType) + return true; + return false; + }); amount *= target.GetTotalAuraMultiplier(AuraType.ModMaxPowerPct, aurEff => { - if (aurEff.GetMiscValue() == (int)powerType) - return true; - return false; - }); + if (aurEff.GetMiscValue() == (int)powerType) + return true; + return false; + }); target.SetStatPctModifier(unitMod, UnitModifierPctType.Total, amount); } @@ -6198,6 +6198,27 @@ namespace Game.Spells } } } + + [AuraEffectHandler(AuraType.ModOverrideZonePvpType)] + void HandleModOverrideZonePVPType(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply) + { + if (!mode.HasAnyFlag(AuraEffectHandleModes.Real)) + return; + + Player target = aurApp.GetTarget().ToPlayer(); + if (target == null) + return; + + if (apply) + target.SetOverrideZonePVPType((ZonePVPTypeOverride)GetMiscValue()); + else if (target.HasAuraType(AuraType.ModOverrideZonePvpType)) + target.SetOverrideZonePVPType((ZonePVPTypeOverride)target.GetAuraEffectsByType(AuraType.ModOverrideZonePvpType).Last().GetMiscValue()); + else + target.SetOverrideZonePVPType(ZonePVPTypeOverride.None); + + target.UpdateHostileAreaState(CliDB.AreaTableStorage.LookupByKey(target.GetZoneId())); + target.UpdatePvPState(); + } #endregion }