aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
authormik1893 <michele.roscelli@gmail.com>2015-07-15 18:43:19 +0200
committerDDuarte <dnpd.dd@gmail.com>2015-07-19 01:43:05 +0100
commitfa0e5289a87fea15fac2ab0c2ace26ee06288174 (patch)
tree911637b91b6eb8560c9df986c5480fcfb6039598 /src/server/game/Entities
parent0ea0e9ee01383d8a74357000e854dc0777669d6d (diff)
Merge pull request #14974 from pete318/stealth_work
Stealth changes (Player stealthed vs NPCs) - 3.3.5 (cherry picked from commit 90fcfb3f2d71e15d162cb52b915b53a11bc42212) Conflicts: src/server/game/Entities/Object/Object.h src/server/game/Entities/Unit/Unit.cpp
Diffstat (limited to 'src/server/game/Entities')
-rw-r--r--src/server/game/Entities/Object/Object.cpp22
-rw-r--r--src/server/game/Entities/Object/Object.h6
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp26
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
4 files changed, 44 insertions, 11 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index efe4303c961..4a819a892b5 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1944,7 +1944,7 @@ float WorldObject::GetSightRange(const WorldObject* target) const
return 0.0f;
}
-bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, bool distanceCheck) const
+bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, bool distanceCheck, bool checkAlert) const
{
if (this == obj)
return true;
@@ -2016,7 +2016,7 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo
if (obj->IsInvisibleDueToDespawn())
return false;
- if (!CanDetect(obj, ignoreStealth))
+ if (!CanDetect(obj, ignoreStealth, checkAlert))
return false;
return true;
@@ -2027,7 +2027,7 @@ bool WorldObject::CanNeverSee(WorldObject const* obj) const
return GetMap() != obj->GetMap() || !IsInPhase(obj);
}
-bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth) const
+bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth, bool checkAlert) const
{
const WorldObject* seer = this;
@@ -2042,7 +2042,7 @@ bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth) const
if (!ignoreStealth && !seer->CanDetectInvisibilityOf(obj))
return false;
- if (!ignoreStealth && !seer->CanDetectStealthOf(obj))
+ if (!ignoreStealth && !seer->CanDetectStealthOf(obj, checkAlert))
return false;
return true;
@@ -2072,7 +2072,7 @@ bool WorldObject::CanDetectInvisibilityOf(WorldObject const* obj) const
return true;
}
-bool WorldObject::CanDetectStealthOf(WorldObject const* obj) const
+bool WorldObject::CanDetectStealthOf(WorldObject const* obj, bool checkAlert) const
{
// Combat reach is the minimal distance (both in front and behind),
// and it is also used in the range calculation.
@@ -2122,9 +2122,19 @@ bool WorldObject::CanDetectStealthOf(WorldObject const* obj) const
// Calculate max distance
float visibilityRange = float(detectionValue) * 0.3f + combatReach;
- if (visibilityRange > MAX_PLAYER_STEALTH_DETECT_RANGE)
+ // If this unit is an NPC then player detect range doesn't apply
+ if (unit && unit->GetTypeId() == TYPEID_PLAYER && visibilityRange > MAX_PLAYER_STEALTH_DETECT_RANGE)
visibilityRange = MAX_PLAYER_STEALTH_DETECT_RANGE;
+ // When checking for alert state, look 8% further, and then 1.5 yards more than that.
+ if (checkAlert)
+ visibilityRange += (visibilityRange * 0.08f) + 1.5f;
+
+ // If checking for alert, and creature's visibility range is greater than aggro distance, No alert
+ Unit const* tunit = obj->ToUnit();
+ if (checkAlert && unit && unit->ToCreature() && visibilityRange >= unit->ToCreature()->GetAttackDistance(tunit) + unit->ToCreature()->m_CombatDistance)
+ return false;
+
if (distance > visibilityRange)
return false;
}
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index b9a6320a835..ff5ab997385 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -560,7 +560,7 @@ class WorldObject : public Object, public WorldLocation
float GetGridActivationRange() const;
float GetVisibilityRange() const;
float GetSightRange(WorldObject const* target = NULL) const;
- bool CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth = false, bool distanceCheck = false) const;
+ bool CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth = false, bool distanceCheck = false, bool checkAlert = false) const;
FlaggedValuesArray32<int32, uint32, StealthType, TOTAL_STEALTH_TYPES> m_stealth;
FlaggedValuesArray32<int32, uint32, StealthType, TOTAL_STEALTH_TYPES> m_stealthDetect;
@@ -693,9 +693,9 @@ class WorldObject : public Object, public WorldLocation
bool CanNeverSee(WorldObject const* obj) const;
virtual bool CanAlwaysSee(WorldObject const* /*obj*/) const { return false; }
- bool CanDetect(WorldObject const* obj, bool ignoreStealth) const;
+ bool CanDetect(WorldObject const* obj, bool ignoreStealth, bool checkAlert = false) const;
bool CanDetectInvisibilityOf(WorldObject const* obj) const;
- bool CanDetectStealthOf(WorldObject const* obj) const;
+ bool CanDetectStealthOf(WorldObject const* obj, bool checkAlert = false) const;
uint16 m_aiAnimKitId;
uint16 m_movementAnimKitId;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index edf6d75b047..54a79f3e1fd 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -318,6 +318,28 @@ Unit::~Unit()
ASSERT(m_dynObj.empty());
}
+// Check if unit in combat with specific unit
+bool Unit::IsInCombatWith(Unit const* who) const
+{
+ // Check target exists
+ if (!who)
+ return false;
+
+ // Search in threat list
+ ObjectGuid guid = who->GetGUID();
+ for (ThreatContainer::StorageType::const_iterator i = m_ThreatManager.getThreatList().begin(); i != m_ThreatManager.getThreatList().end(); ++i)
+ {
+ HostileReference* ref = (*i);
+
+ // Return true if the unit matches
+ if (ref && ref->getUnitGuid() == guid)
+ return true;
+ }
+
+ // Nothing found, false.
+ return false;
+}
+
void Unit::Update(uint32 p_time)
{
// WARNING! Order of execution here is important, do not change.
@@ -9971,8 +9993,8 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo
if (IsOnVehicle(target) || m_vehicle->GetBase()->IsOnVehicle(target))
return false;
- // can't attack invisible (ignore stealth for aoe spells) also if the area being looked at is from a spell use the dynamic object created instead of the casting unit.
- if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea(GetMap()->GetDifficultyID())) : !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea(GetMap()->GetDifficultyID()))))
+ // can't attack invisible (ignore stealth for aoe spells) also if the area being looked at is from a spell use the dynamic object created instead of the casting unit. Ignore stealth if target is player and unit in combat with same player
+ if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea(GetMap()->GetDifficultyID())) : !CanSeeOrDetect(target, (bySpell && bySpell->IsAffectingArea(GetMap()->GetDifficultyID())) || (target->GetTypeId() == TYPEID_PLAYER && target->HasStealthAura() && target->IsInCombat() && IsInCombatWith(target)))))
return false;
// can't attack dead
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index aead560caa8..8ac08ba24dc 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1557,6 +1557,7 @@ class Unit : public WorldObject
bool IsInFlight() const { return HasUnitState(UNIT_STATE_IN_FLIGHT); }
bool IsInCombat() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); }
+ bool IsInCombatWith(Unit const* who) const;
void CombatStart(Unit* target, bool initialAggro = true);
void SetInCombatState(bool PvP, Unit* enemy = NULL);
void SetInCombatWith(Unit* enemy);