aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp2
-rw-r--r--src/server/game/Entities/Object/Object.cpp26
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h5
-rw-r--r--src/server/game/Spells/Spell.cpp4
4 files changed, 22 insertions, 15 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 32567a37e63..f3b86001aed 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -649,7 +649,7 @@ void GameObject::Update(uint32 diff)
if (Unit* owner = GetOwner())
{
// Hunter trap: Search units which are unfriendly to the trap's owner
- Trinity::NearestAttackableNoTotemUnitInObjectRangeCheck checker(this, owner, radius);
+ Trinity::NearestAttackableNoTotemUnitInObjectRangeCheck checker(this, radius);
Trinity::UnitLastSearcher<Trinity::NearestAttackableNoTotemUnitInObjectRangeCheck> searcher(this, target, checker);
Cell::VisitAllObjects(this, searcher, radius);
}
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 17376cd2da8..a0de5074ad9 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1691,9 +1691,15 @@ bool WorldObject::CanDetectStealthOf(WorldObject const* obj, bool checkAlert) co
if (distance < combatReach)
return true;
- if (!HasInArc(float(M_PI), obj))
+ // Only check back for units, it does not make sense for gameobjects
+ if (unit && !HasInArc(float(M_PI), obj))
return false;
+ // Traps should detect stealth always
+ if (GameObject const* go = ToGameObject())
+ if (go->GetGoType() == GAMEOBJECT_TYPE_TRAP)
+ return true;
+
GameObject const* go = obj->ToGameObject();
for (uint32 i = 0; i < TOTAL_STEALTH_TYPES; ++i)
{
@@ -2625,8 +2631,8 @@ ReputationRank WorldObject::GetReactionTo(WorldObject const* target) const
return *repRank;
}
- Unit const* unit = ToUnit();
- Unit const* targetUnit = target->ToUnit();
+ Unit const* unit = Coalesce<const Unit>(ToUnit(), selfPlayerOwner);
+ Unit const* targetUnit = Coalesce<const Unit>(target->ToUnit(), targetPlayerOwner);
if (unit && unit->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED))
{
if (targetUnit && targetUnit->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED))
@@ -2878,7 +2884,7 @@ bool WorldObject::IsValidAttackTarget(WorldObject const* target, SpellInfo const
}
// CvC case - can attack each other only when one of them is hostile
- if (ToUnit() && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && target->ToUnit() && !target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED))
+ if (unit && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && target->ToUnit() && !target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED))
return IsHostileTo(target) || target->IsHostileTo(this);
// PvP, PvC, CvP case
@@ -2886,7 +2892,7 @@ bool WorldObject::IsValidAttackTarget(WorldObject const* target, SpellInfo const
if (IsFriendlyTo(target) || target->IsFriendlyTo(this))
return false;
- Player const* playerAffectingAttacker = ToUnit() && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) ? GetAffectingPlayer() : nullptr;
+ Player const* playerAffectingAttacker = unit && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) ? GetAffectingPlayer() : ToGameObject() ? GetAffectingPlayer() : nullptr;
Player const* playerAffectingTarget = target->ToUnit() && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) ? target->GetAffectingPlayer() : nullptr;
// Not all neutral creatures can be attacked (even some unfriendly faction does not react aggresive to you, like Sporaggar)
@@ -2894,7 +2900,7 @@ bool WorldObject::IsValidAttackTarget(WorldObject const* target, SpellInfo const
{
Player const* player = playerAffectingAttacker ? playerAffectingAttacker : playerAffectingTarget;
- if (Unit const* creature = playerAffectingAttacker ? target->ToUnit() : ToUnit())
+ if (Unit const* creature = playerAffectingAttacker ? target->ToUnit() : unit)
{
if (creature->IsContestedGuard() && player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP))
return true;
@@ -2927,14 +2933,14 @@ bool WorldObject::IsValidAttackTarget(WorldObject const* target, SpellInfo const
// 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->HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, UNIT_BYTE2_FLAG_UNK1) ||
- unitTarget->HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, UNIT_BYTE2_FLAG_UNK1);
+ return playerAffectingAttacker->HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, UNIT_BYTE2_FLAG_UNK1) ||
+ playerAffectingTarget->HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, UNIT_BYTE2_FLAG_UNK1);
}
return true;
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index 71f420482a5..637e1ef2fe6 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -887,7 +887,7 @@ namespace Trinity
class NearestAttackableNoTotemUnitInObjectRangeCheck
{
public:
- NearestAttackableNoTotemUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) { }
+ NearestAttackableNoTotemUnitInObjectRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) { }
bool operator()(Unit* u)
{
@@ -903,7 +903,7 @@ namespace Trinity
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);
@@ -912,7 +912,6 @@ namespace Trinity
private:
WorldObject const* i_obj;
- Unit const* i_funit;
float i_range;
};
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 3e6de8b9baf..ff52652452f 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -5186,7 +5186,9 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
{
// Check explicit target for m_originalCaster - todo: get rid of such workarounds
WorldObject* caster = m_caster;
- if (m_originalCaster)
+ // 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 && !caster->ToGameObject())
caster = m_originalCaster;
SpellCastResult castResult = m_spellInfo->CheckExplicitTarget(caster, m_targets.GetObjectTarget(), m_targets.GetItemTarget());