Core/NPC: Creatures now alert when they detect stealthed players (#1060)

Creatures stop when they detect a stealthed player like in retail.
Closes #1020
This commit is contained in:
Jinyang li
2018-11-01 03:25:23 +08:00
committed by Barbz
parent 59f0d086a6
commit 4b6342b42f
13 changed files with 166 additions and 20 deletions

View File

@@ -1551,8 +1551,8 @@ 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;
@@ -1647,12 +1647,12 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo
if (obj->IsInvisibleDueToDespawn())
return false;
// pussywizard: arena spectator
// pussywizard: arena spectator
if (this->GetTypeId() == TYPEID_PLAYER)
if (((const Player*)this)->IsSpectator() && ((const Player*)this)->FindMap()->IsBattleArena() && (obj->m_invisibility.GetFlags() || obj->m_stealth.GetFlags()))
return false;
if (!CanDetect(obj, ignoreStealth, !distanceCheck))
if (!CanDetect(obj, ignoreStealth, !distanceCheck, checkAlert))
return false;
return true;
@@ -1665,7 +1665,7 @@ bool WorldObject::CanNeverSee(WorldObject const* obj) const
return GetMap() != obj->GetMap() || !InSamePhase(obj);
}
bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth, bool checkClient) const
bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth, bool checkClient, bool checkAlert) const
{
const WorldObject* seer = this;
@@ -1682,7 +1682,7 @@ bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth, bool che
if (!seer->CanDetectInvisibilityOf(obj)) // xinef: added ignoreStealth, allow AoE spells to hit invisible targets!
return false;
if (!seer->CanDetectStealthOf(obj))
if (!seer->CanDetectStealthOf(obj, checkAlert))
{
// xinef: ignore units players have at client, this cant be cheated!
if (checkClient)
@@ -1740,7 +1740,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.
@@ -1797,9 +1797,22 @@ bool WorldObject::CanDetectStealthOf(WorldObject const* obj) const
// Calculate max distance
float visibilityRange = float(detectionValue) * 0.3f + combatReach;
if (visibilityRange > MAX_PLAYER_STEALTH_DETECT_RANGE)
Unit const* unit = ToUnit();
// 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;
if (checkAlert)
visibilityRange += (visibilityRange * 0.08f) + 1.5f;
Unit const* targetUnit = obj->ToUnit();
// If checking for alert, and creature's visibility range is greater than aggro distance, No alert
if (checkAlert && unit && unit->ToCreature() && visibilityRange >= unit->ToCreature()->GetAttackDistance(targetUnit) + unit->ToCreature()->m_CombatDistance)
return false;
if (distance > visibilityRange)
return false;
}