Core/Creatures: Implemented CREATURE_STATIC_FLAG_2_IGNORE_SANCTUARY (ignore SPELL_EFFECT_SANCTUARY, used by Vanish)
Port From (https://github.com/TrinityCore/TrinityCore/commit/1369b8708458fb5020b6ab7a9608123459d4eb26)
This commit is contained in:
@@ -316,7 +316,7 @@ namespace Framework.Constants
|
|||||||
NoWoundedSlowdown = 0x00000040,
|
NoWoundedSlowdown = 0x00000040,
|
||||||
UseCreatorBonuses = 0x00000080,
|
UseCreatorBonuses = 0x00000080,
|
||||||
IgnoreFeignDeath = 0x00000100, // CreatureFlagExtraIgnoreFeignDeath
|
IgnoreFeignDeath = 0x00000100, // CreatureFlagExtraIgnoreFeignDeath
|
||||||
IgnoreSanctuary = 0x00000200,
|
IgnoreSanctuary = 0x00000200, // Ignores SPELL_EFFECT_SANCTUARY
|
||||||
ActionTriggersWhileCharmed = 0x00000400,
|
ActionTriggersWhileCharmed = 0x00000400,
|
||||||
InteractWhileDead = 0x00000800, // CreatureTypeFlagInteractWhileDead
|
InteractWhileDead = 0x00000800, // CreatureTypeFlagInteractWhileDead
|
||||||
NoInterruptSchoolCooldown = 0x00001000,
|
NoInterruptSchoolCooldown = 0x00001000,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
using Framework.Constants;
|
using Framework.Constants;
|
||||||
using Game.AI;
|
using Game.AI;
|
||||||
using Game.Entities;
|
using Game.Entities;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
@@ -58,9 +59,9 @@ namespace Game.Combat
|
|||||||
|
|
||||||
public void Update(uint tdiff)
|
public void Update(uint tdiff)
|
||||||
{
|
{
|
||||||
foreach(var pair in _pvpRefs.ToList())
|
foreach (var pair in _pvpRefs.ToList())
|
||||||
{
|
{
|
||||||
PvPCombatReference refe = pair.Value;
|
PvPCombatReference refe = pair.Value;
|
||||||
if (refe.first == _owner && !refe.Update(tdiff)) // only update if we're the first unit involved (otherwise double decrement)
|
if (refe.first == _owner && !refe.Update(tdiff)) // only update if we're the first unit involved (otherwise double decrement)
|
||||||
{
|
{
|
||||||
_pvpRefs.Remove(pair.Key);
|
_pvpRefs.Remove(pair.Key);
|
||||||
@@ -217,10 +218,11 @@ namespace Game.Combat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SuppressPvPCombat()
|
public void SuppressPvPCombat(Func<Unit, bool> unitFilter = null)
|
||||||
{
|
{
|
||||||
foreach (var pair in _pvpRefs)
|
foreach (var (_, combatRef) in _pvpRefs)
|
||||||
pair.Value.Suppress(_owner);
|
if (unitFilter == null || unitFilter(combatRef.GetOther(_owner)))
|
||||||
|
combatRef.Suppress(_owner);
|
||||||
|
|
||||||
if (UpdateOwnerCombatState())
|
if (UpdateOwnerCombatState())
|
||||||
{
|
{
|
||||||
@@ -230,18 +232,24 @@ namespace Game.Combat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndAllPvECombat()
|
public void EndAllPvECombat(Func<Unit, bool> unitFilter = null)
|
||||||
{
|
{
|
||||||
// cannot have threat without combat
|
// cannot have threat without combat
|
||||||
_owner.GetThreatManager().RemoveMeFromThreatLists();
|
_owner.GetThreatManager().RemoveMeFromThreatLists(unitFilter);
|
||||||
_owner.GetThreatManager().ClearAllThreat();
|
_owner.GetThreatManager().ClearAllThreat();
|
||||||
while (!_pveRefs.Empty())
|
|
||||||
_pveRefs.First().Value.EndCombat();
|
List<CombatReference> combatReferencesToRemove = new();
|
||||||
|
foreach (var (_, combatRef) in _pveRefs)
|
||||||
|
if (unitFilter == null || unitFilter(combatRef.GetOther(_owner)))
|
||||||
|
combatReferencesToRemove.Add(combatRef);
|
||||||
|
|
||||||
|
foreach (CombatReference combatRef in combatReferencesToRemove)
|
||||||
|
combatRef.EndCombat();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RevalidateCombat()
|
public void RevalidateCombat()
|
||||||
{
|
{
|
||||||
foreach(var (guid, refe) in _pveRefs.ToList())
|
foreach (var (guid, refe) in _pveRefs.ToList())
|
||||||
{
|
{
|
||||||
if (!CanBeginCombat(_owner, refe.GetOther(_owner)))
|
if (!CanBeginCombat(_owner, refe.GetOther(_owner)))
|
||||||
{
|
{
|
||||||
@@ -260,10 +268,21 @@ namespace Game.Combat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EndAllPvPCombat()
|
public void EndAllPvPCombat(Func<Unit, bool> unitFilter = null)
|
||||||
{
|
{
|
||||||
while (!_pvpRefs.Empty())
|
List<CombatReference> combatReferencesToRemove = new();
|
||||||
_pvpRefs.First().Value.EndCombat();
|
foreach (var (_, combatRef) in _pvpRefs)
|
||||||
|
if (unitFilter == null || unitFilter(combatRef.GetOther(_owner)))
|
||||||
|
combatReferencesToRemove.Add(combatRef);
|
||||||
|
|
||||||
|
foreach (CombatReference combatRef in combatReferencesToRemove)
|
||||||
|
combatRef.EndCombat();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EndAllCombat(Func<Unit, bool> unitFilter = null)
|
||||||
|
{
|
||||||
|
EndAllPvECombat(unitFilter);
|
||||||
|
EndAllPvPCombat(unitFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void NotifyAICombat(Unit me, Unit other)
|
public static void NotifyAICombat(Unit me, Unit other)
|
||||||
|
|||||||
@@ -610,13 +610,15 @@ namespace Game.Combat
|
|||||||
threatened.GetThreatManager().AddThreat(assistant, 0.0f, spell, true);
|
threatened.GetThreatManager().AddThreat(assistant, 0.0f, spell, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveMeFromThreatLists()
|
public void RemoveMeFromThreatLists(Func<Unit, bool> unitFilter)
|
||||||
{
|
{
|
||||||
while (!_threatenedByMe.Empty())
|
List<ThreatReference> threatReferencesToRemove = new();
|
||||||
{
|
foreach (var (_, refe) in _threatenedByMe)
|
||||||
var refe = _threatenedByMe.FirstOrDefault().Value;
|
if (unitFilter == null || unitFilter(refe.GetOwner()))
|
||||||
|
threatReferencesToRemove.Add(refe);
|
||||||
|
|
||||||
|
foreach (ThreatReference refe in threatReferencesToRemove)
|
||||||
refe._mgr.ClearThreat(_owner);
|
refe._mgr.ClearThreat(_owner);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateMyTempModifiers()
|
public void UpdateMyTempModifiers()
|
||||||
|
|||||||
@@ -3564,6 +3564,8 @@ namespace Game.Entities
|
|||||||
public void SetNoSearchAssistance(bool val) { m_AlreadySearchedAssistance = val; }
|
public void SetNoSearchAssistance(bool val) { m_AlreadySearchedAssistance = val; }
|
||||||
public bool HasSearchedAssistance() { return m_AlreadySearchedAssistance; }
|
public bool HasSearchedAssistance() { return m_AlreadySearchedAssistance; }
|
||||||
public bool CanIgnoreFeignDeath() { return GetCreatureTemplate().FlagsExtra.HasFlag(CreatureFlagsExtra.IgnoreFeighDeath); }
|
public bool CanIgnoreFeignDeath() { return GetCreatureTemplate().FlagsExtra.HasFlag(CreatureFlagsExtra.IgnoreFeighDeath); }
|
||||||
|
public bool IsIgnoringSanctuarySpellEffect() { return _staticFlags.HasFlag(CreatureStaticFlags2.IgnoreSanctuary); }
|
||||||
|
public void SetIngoreSanctuarySpellEffect(bool ignoreSanctuary) { _staticFlags.ApplyFlag(CreatureStaticFlags2.IgnoreSanctuary, ignoreSanctuary); }
|
||||||
|
|
||||||
public override MovementGeneratorType GetDefaultMovementType() { return DefaultMovementType; }
|
public override MovementGeneratorType GetDefaultMovementType() { return DefaultMovementType; }
|
||||||
public void SetDefaultMovementType(MovementGeneratorType mgt) { DefaultMovementType = mgt; }
|
public void SetDefaultMovementType(MovementGeneratorType mgt) { DefaultMovementType = mgt; }
|
||||||
|
|||||||
@@ -55,23 +55,29 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public virtual void AtDisengage() { }
|
public virtual void AtDisengage() { }
|
||||||
|
|
||||||
public void CombatStop(bool includingCast = false, bool mutualPvP = true)
|
public void CombatStop(bool includingCast = false, bool mutualPvP = true, Func<Unit, bool> unitFilter = null)
|
||||||
{
|
{
|
||||||
if (includingCast && IsNonMeleeSpellCast(false))
|
if (includingCast && IsNonMeleeSpellCast(false))
|
||||||
InterruptNonMeleeSpells(false);
|
InterruptNonMeleeSpells(false);
|
||||||
|
|
||||||
AttackStop();
|
AttackStop();
|
||||||
RemoveAllAttackers();
|
if (unitFilter == null)
|
||||||
|
RemoveAllAttackers();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
List<Unit> attackersToRemove = attackerList.Where(unitFilter).ToList();
|
||||||
|
foreach (Unit attacker in attackersToRemove)
|
||||||
|
attacker.AttackStop();
|
||||||
|
}
|
||||||
|
|
||||||
if (IsTypeId(TypeId.Player))
|
if (IsTypeId(TypeId.Player))
|
||||||
ToPlayer().SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
|
ToPlayer().SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
|
||||||
|
|
||||||
|
m_combatManager.EndAllPvECombat(unitFilter);
|
||||||
if (mutualPvP)
|
if (mutualPvP)
|
||||||
ClearInCombat();
|
m_combatManager.EndAllPvPCombat(unitFilter);
|
||||||
else
|
else // vanish and brethren are weird
|
||||||
{ // vanish and brethren are weird
|
m_combatManager.SuppressPvPCombat(unitFilter);
|
||||||
m_combatManager.EndAllPvECombat();
|
|
||||||
m_combatManager.SuppressPvPCombat();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CombatStopWithPets(bool includingCast = false)
|
public void CombatStopWithPets(bool includingCast = false)
|
||||||
|
|||||||
@@ -2840,16 +2840,23 @@ namespace Game.Spells
|
|||||||
if (unitTarget == null)
|
if (unitTarget == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var isAffectedBySanctuary = bool (Unit attacker) =>
|
||||||
|
{
|
||||||
|
Creature attackerCreature = attacker.ToCreature();
|
||||||
|
return attackerCreature == null || !attackerCreature.IsIgnoringSanctuarySpellEffect();
|
||||||
|
};
|
||||||
|
|
||||||
if (unitTarget.IsPlayer() && !unitTarget.GetMap().IsDungeon())
|
if (unitTarget.IsPlayer() && !unitTarget.GetMap().IsDungeon())
|
||||||
{
|
{
|
||||||
// stop all pve combat for players outside dungeons, suppress pvp combat
|
// stop all pve combat for players outside dungeons, suppress pvp combat
|
||||||
unitTarget.CombatStop(false, false);
|
unitTarget.CombatStop(false, false, isAffectedBySanctuary);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// in dungeons (or for nonplayers), reset this unit on all enemies' threat lists
|
// in dungeons (or for nonplayers), reset this unit on all enemies' threat lists
|
||||||
foreach (var pair in unitTarget.GetThreatManager().GetThreatenedByMeList())
|
foreach (var (_, refe) in unitTarget.GetThreatManager().GetThreatenedByMeList())
|
||||||
pair.Value.ScaleThreat(0.0f);
|
if (isAffectedBySanctuary(refe.GetOwner()))
|
||||||
|
refe.ScaleThreat(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// makes spells cast before this time fizzle
|
// makes spells cast before this time fizzle
|
||||||
|
|||||||
Reference in New Issue
Block a user