diff options
| author | mik1893 <michele.roscelli@gmail.com> | 2015-07-15 18:43:19 +0200 |
|---|---|---|
| committer | mik1893 <michele.roscelli@gmail.com> | 2015-07-15 18:43:19 +0200 |
| commit | 90fcfb3f2d71e15d162cb52b915b53a11bc42212 (patch) | |
| tree | 2958e0ce9236b0f9041193c58359253baff2545d /src/server/game/Entities | |
| parent | 35f0d8e9c1e89c3095c82e0dd89d9f8f08f288a3 (diff) | |
| parent | 1e0213bc57922719d4f7e8897cb7e8871c138fdc (diff) | |
Merge pull request #14974 from pete318/stealth_work
Stealth changes (Player stealthed vs NPCs) - 3.3.5
Diffstat (limited to 'src/server/game/Entities')
| -rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 22 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Object.h | 6 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 26 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 1 |
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 6392c3ee51b..fc55c09bffa 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1539,7 +1539,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; @@ -1611,7 +1611,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; @@ -1622,7 +1622,7 @@ bool WorldObject::CanNeverSee(WorldObject const* obj) const return GetMap() != obj->GetMap() || !InSamePhase(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; @@ -1637,7 +1637,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; @@ -1674,7 +1674,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. @@ -1724,9 +1724,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 a560afa7f1b..e673e346a5f 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -514,7 +514,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; @@ -634,9 +634,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; }; namespace Trinity diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index c9c70e97513..b3b757e6a2e 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -288,6 +288,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. @@ -11877,8 +11899,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()) : !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()))) + // 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()) : !CanSeeOrDetect(target, (bySpell && bySpell->IsAffectingArea()) || (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 a61b406cbbd..39b1c34be55 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1480,6 +1480,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); |
