From 1e0213bc57922719d4f7e8897cb7e8871c138fdc Mon Sep 17 00:00:00 2001 From: pete318 Date: Sun, 28 Jun 2015 23:42:47 +0000 Subject: The following stealth changes are implemented. - Combat no longer removes stealth, only damage does - Creatures will pursue a stealthed unit they cannot see if they're already in combat with them - When a player is ~~3 yards~~ 8% + 1.5 yards away from the usual stealth detection distance, the creature will perform the "alerted" effect. - When sitting/sleeping creatures are distracted or alerted, they will stand up - Idle movement creatures will return to their original (spawn) orientation after distract/alert - When entering combat with a distracted/alerted creature, distract state is removed - NPC no longer have a limit to stealth visibility (granted by stealth modifier spells/buffs) - If alert visibility is greater than aggro range, no alert sent --- src/server/game/Entities/Unit/Unit.cpp | 26 ++++++++++++++++++++++++-- src/server/game/Entities/Unit/Unit.h | 1 + 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'src/server/game/Entities/Unit') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 17915e53cfb..f551df6c260 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. @@ -11885,8 +11907,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); -- cgit v1.2.3