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)
|
if (owner)
|
||||||
{
|
{
|
||||||
// Hunter trap: Search units which are unfriendly to the trap's 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);
|
var searcher = new UnitLastSearcher(this, checker);
|
||||||
Cell.VisitAllObjects(this, searcher, radius);
|
Cell.VisitAllObjects(this, searcher, radius);
|
||||||
target = searcher.GetTarget();
|
target = searcher.GetTarget();
|
||||||
|
|||||||
@@ -1248,10 +1248,17 @@ namespace Game.Entities
|
|||||||
if (distance < combatReach)
|
if (distance < combatReach)
|
||||||
return true;
|
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;
|
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)
|
for (int i = 0; i < (int)StealthType.Max; ++i)
|
||||||
{
|
{
|
||||||
if (!Convert.ToBoolean(obj.m_stealth.GetFlags() & (1 << i)))
|
if (!Convert.ToBoolean(obj.m_stealth.GetFlags() & (1 << i)))
|
||||||
@@ -2056,8 +2063,8 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit unit = ToUnit();
|
Unit unit = ToUnit() ?? selfPlayerOwner;
|
||||||
Unit targetUnit = target.ToUnit();
|
Unit targetUnit = target.ToUnit() ?? targetPlayerOwner;
|
||||||
if (unit && unit.HasUnitFlag(UnitFlags.PlayerControlled))
|
if (unit && unit.HasUnitFlag(UnitFlags.PlayerControlled))
|
||||||
{
|
{
|
||||||
if (targetUnit && targetUnit.HasUnitFlag(UnitFlags.PlayerControlled))
|
if (targetUnit && targetUnit.HasUnitFlag(UnitFlags.PlayerControlled))
|
||||||
@@ -2452,7 +2459,7 @@ namespace Game.Entities
|
|||||||
if (IsFriendlyTo(target) || target.IsFriendlyTo(this))
|
if (IsFriendlyTo(target) || target.IsFriendlyTo(this))
|
||||||
return false;
|
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;
|
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)
|
// 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
|
// additional checks - only PvP case
|
||||||
if (playerAffectingAttacker && playerAffectingTarget)
|
if (playerAffectingAttacker && playerAffectingTarget)
|
||||||
{
|
{
|
||||||
if (unitTarget.IsPvP())
|
if (playerAffectingTarget.IsPvP())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (unit.IsFFAPvP() && unitTarget.IsFFAPvP())
|
if (playerAffectingAttacker.IsFFAPvP() && playerAffectingTarget.IsFFAPvP())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return unit.HasPvpFlag(UnitPVPStateFlags.Unk1) ||
|
return playerAffectingAttacker.HasPvpFlag(UnitPVPStateFlags.Unk1) ||
|
||||||
unitTarget.HasPvpFlag(UnitPVPStateFlags.Unk1);
|
playerAffectingTarget.HasPvpFlag(UnitPVPStateFlags.Unk1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1962,10 +1962,9 @@ namespace Game.Maps
|
|||||||
|
|
||||||
public class NearestAttackableNoTotemUnitInObjectRangeCheck : ICheck<Unit>
|
public class NearestAttackableNoTotemUnitInObjectRangeCheck : ICheck<Unit>
|
||||||
{
|
{
|
||||||
public NearestAttackableNoTotemUnitInObjectRangeCheck(WorldObject obj, Unit funit, float range)
|
public NearestAttackableNoTotemUnitInObjectRangeCheck(WorldObject obj, float range)
|
||||||
{
|
{
|
||||||
i_obj = obj;
|
i_obj = obj;
|
||||||
i_funit = funit;
|
|
||||||
i_range = range;
|
i_range = range;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1983,7 +1982,7 @@ namespace Game.Maps
|
|||||||
if (!u.IsTargetableForAttack(false))
|
if (!u.IsTargetableForAttack(false))
|
||||||
return 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;
|
return false;
|
||||||
|
|
||||||
i_range = i_obj.GetDistance(u);
|
i_range = i_obj.GetDistance(u);
|
||||||
@@ -1991,7 +1990,6 @@ namespace Game.Maps
|
|||||||
}
|
}
|
||||||
|
|
||||||
WorldObject i_obj;
|
WorldObject i_obj;
|
||||||
Unit i_funit;
|
|
||||||
float i_range;
|
float i_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4639,7 +4639,9 @@ namespace Game.Spells
|
|||||||
{
|
{
|
||||||
// Check explicit target for m_originalCaster - todo: get rid of such workarounds
|
// Check explicit target for m_originalCaster - todo: get rid of such workarounds
|
||||||
WorldObject caster = m_caster;
|
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;
|
caster = m_originalCaster;
|
||||||
|
|
||||||
castResult = m_spellInfo.CheckExplicitTarget(caster, m_targets.GetObjectTarget(), m_targets.GetItemTarget());
|
castResult = m_spellInfo.CheckExplicitTarget(caster, m_targets.GetObjectTarget(), m_targets.GetItemTarget());
|
||||||
|
|||||||
Reference in New Issue
Block a user