Core/Gameobjects: Improve stealth detection

Port From (https://github.com/TrinityCore/TrinityCore/commit/60e66621dae44cb832ebb0bdb5e168f9ab114ecb)
This commit is contained in:
hondacrx
2022-02-18 12:51:16 -05:00
parent 743d0158d6
commit a604bbd7f9
4 changed files with 22 additions and 15 deletions
@@ -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();
+16 -9
View File
@@ -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;
+2 -4
View File
@@ -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;
}
+3 -1
View File
@@ -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());