Core/Gameobjects: Improve stealth detection
Port From (https://github.com/TrinityCore/TrinityCore/commit/60e66621dae44cb832ebb0bdb5e168f9ab114ecb)
This commit is contained in:
@@ -663,7 +663,7 @@ namespace Game.Entities
|
||||
if (owner)
|
||||
{
|
||||
// Hunter trap: Search units which are unfriendly to the trap's owner
|
||||
var checker = new NearestAttackableNoTotemUnitInObjectRangeCheck(this, owner, radius);
|
||||
var checker = new NearestAttackableNoTotemUnitInObjectRangeCheck(this, radius);
|
||||
var searcher = new UnitLastSearcher(this, checker);
|
||||
Cell.VisitAllObjects(this, searcher, radius);
|
||||
target = searcher.GetTarget();
|
||||
|
||||
@@ -1248,10 +1248,17 @@ namespace Game.Entities
|
||||
if (distance < combatReach)
|
||||
return true;
|
||||
|
||||
if (!HasInArc(MathFunctions.PI, obj))
|
||||
// Only check back for units, it does not make sense for gameobjects
|
||||
if (unit && !HasInArc(MathF.PI, obj))
|
||||
return false;
|
||||
|
||||
GameObject go = obj.ToGameObject();
|
||||
// Traps should detect stealth always
|
||||
GameObject go = ToGameObject();
|
||||
if (go != null)
|
||||
if (go.GetGoType() == GameObjectTypes.Trap)
|
||||
return true;
|
||||
|
||||
go = obj.ToGameObject();
|
||||
for (int i = 0; i < (int)StealthType.Max; ++i)
|
||||
{
|
||||
if (!Convert.ToBoolean(obj.m_stealth.GetFlags() & (1 << i)))
|
||||
@@ -2056,8 +2063,8 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
Unit unit = ToUnit();
|
||||
Unit targetUnit = target.ToUnit();
|
||||
Unit unit = ToUnit() ?? selfPlayerOwner;
|
||||
Unit targetUnit = target.ToUnit() ?? targetPlayerOwner;
|
||||
if (unit && unit.HasUnitFlag(UnitFlags.PlayerControlled))
|
||||
{
|
||||
if (targetUnit && targetUnit.HasUnitFlag(UnitFlags.PlayerControlled))
|
||||
@@ -2452,7 +2459,7 @@ namespace Game.Entities
|
||||
if (IsFriendlyTo(target) || target.IsFriendlyTo(this))
|
||||
return false;
|
||||
|
||||
Player playerAffectingAttacker = unit != null && unit.HasUnitFlag(UnitFlags.PlayerControlled) ? GetAffectingPlayer() : null;
|
||||
Player playerAffectingAttacker = unit != null && unit.HasUnitFlag(UnitFlags.PlayerControlled) ? GetAffectingPlayer() : IsGameObject() ? GetAffectingPlayer() : null;
|
||||
Player playerAffectingTarget = unitTarget != null && unitTarget.HasUnitFlag(UnitFlags.PlayerControlled) ? target.GetAffectingPlayer() : null;
|
||||
|
||||
// Not all neutral creatures can be attacked (even some unfriendly faction does not react aggresive to you, like Sporaggar)
|
||||
@@ -2500,14 +2507,14 @@ namespace Game.Entities
|
||||
// additional checks - only PvP case
|
||||
if (playerAffectingAttacker && playerAffectingTarget)
|
||||
{
|
||||
if (unitTarget.IsPvP())
|
||||
if (playerAffectingTarget.IsPvP())
|
||||
return true;
|
||||
|
||||
if (unit.IsFFAPvP() && unitTarget.IsFFAPvP())
|
||||
if (playerAffectingAttacker.IsFFAPvP() && playerAffectingTarget.IsFFAPvP())
|
||||
return true;
|
||||
|
||||
return unit.HasPvpFlag(UnitPVPStateFlags.Unk1) ||
|
||||
unitTarget.HasPvpFlag(UnitPVPStateFlags.Unk1);
|
||||
return playerAffectingAttacker.HasPvpFlag(UnitPVPStateFlags.Unk1) ||
|
||||
playerAffectingTarget.HasPvpFlag(UnitPVPStateFlags.Unk1);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1962,10 +1962,9 @@ namespace Game.Maps
|
||||
|
||||
public class NearestAttackableNoTotemUnitInObjectRangeCheck : ICheck<Unit>
|
||||
{
|
||||
public NearestAttackableNoTotemUnitInObjectRangeCheck(WorldObject obj, Unit funit, float range)
|
||||
public NearestAttackableNoTotemUnitInObjectRangeCheck(WorldObject obj, float range)
|
||||
{
|
||||
i_obj = obj;
|
||||
i_funit = funit;
|
||||
i_range = range;
|
||||
}
|
||||
|
||||
@@ -1983,7 +1982,7 @@ namespace Game.Maps
|
||||
if (!u.IsTargetableForAttack(false))
|
||||
return false;
|
||||
|
||||
if (!i_obj.IsWithinDistInMap(u, i_range) || i_funit.IsValidAttackTarget(u))
|
||||
if (!i_obj.IsWithinDistInMap(u, i_range) || i_obj.IsValidAttackTarget(u))
|
||||
return false;
|
||||
|
||||
i_range = i_obj.GetDistance(u);
|
||||
@@ -1991,7 +1990,6 @@ namespace Game.Maps
|
||||
}
|
||||
|
||||
WorldObject i_obj;
|
||||
Unit i_funit;
|
||||
float i_range;
|
||||
}
|
||||
|
||||
|
||||
@@ -4639,7 +4639,9 @@ namespace Game.Spells
|
||||
{
|
||||
// Check explicit target for m_originalCaster - todo: get rid of such workarounds
|
||||
WorldObject caster = m_caster;
|
||||
if (m_originalCaster != null)
|
||||
// in case of gameobjects like traps, we need the gameobject itself to check target validity
|
||||
// otherwise, if originalCaster is far away and cannot detect the target, the trap would not hit the target
|
||||
if (m_originalCaster != null && !caster.IsGameObject())
|
||||
caster = m_originalCaster;
|
||||
|
||||
castResult = m_spellInfo.CheckExplicitTarget(caster, m_targets.GetObjectTarget(), m_targets.GetItemTarget());
|
||||
|
||||
Reference in New Issue
Block a user