diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/server/game/AI/CreatureAI.cpp | 7 | ||||
-rwxr-xr-x | src/server/game/Entities/Unit/Unit.cpp | 13 | ||||
-rwxr-xr-x | src/server/game/Entities/Unit/Unit.h | 8 |
3 files changed, 28 insertions, 0 deletions
diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp index 17cef3ec1a1..e5868117da8 100755 --- a/src/server/game/AI/CreatureAI.cpp +++ b/src/server/game/AI/CreatureAI.cpp @@ -153,13 +153,20 @@ void CreatureAI::EnterEvadeMode() me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle(), MOTION_SLOT_ACTIVE); } else + { + // Required to prevent attacking creatures that are evading and cause them to reenter combat + // Does not apply to MoveFollow + me->AddUnitState(UNIT_STATE_EVADE); me->GetMotionMaster()->MoveTargetedHome(); + } } Reset(); if (me->IsVehicle()) // use the same sequence of addtoworld, aireset may remove all summons! me->GetVehicleKit()->Reset(true); + + me->SetLastDamagedTime(0); } /*void CreatureAI::AttackedBy(Unit* attacker) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 6e9ebb38e48..b5729ba516f 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -173,6 +173,7 @@ Unit::Unit(bool isWorldObject): WorldObject(isWorldObject) , m_vehicleKit(NULL) , m_unitTypeMask(UNIT_MASK_NONE) , m_HostileRefManager(this) + , _lastDamagedTime(0) { #ifdef _MSC_VER #pragma warning(default:4355) @@ -12416,6 +12417,10 @@ int32 Unit::ModifyHealth(int32 dVal) if (dVal == 0) return 0; + // Part of Evade mechanics. Only track health lost, not gained. + if (dVal < 0 && GetTypeId() != TYPEID_PLAYER && !isPet()) + SetLastDamagedTime(time(NULL)); + int32 curHealth = (int32)GetHealth(); int32 val = dVal + curHealth; @@ -13042,6 +13047,14 @@ Unit* Creature::SelectVictim() return target; } + // Case where mob is being kited. + // Mob may not be in range to attack or may have dropped target. In any case, + // don't evade if damage received within the last 10 seconds + // Does not apply to world bosses to prevent kiting to cities + if (!isWorldBoss() && !GetInstanceId()) + if (time(NULL) - GetLastDamagedTime() <= MAX_AGGRO_RESET_TIME) + return target; + // last case when creature must not go to evade mode: // it in combat but attacker not make any damage and not enter to aggro radius to have record in threat list // for example at owner command to pet attack some far away creature diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 8eb822831aa..5a639de574c 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -262,6 +262,8 @@ enum UnitRename #define MAX_SPELL_POSSESS 8 #define MAX_SPELL_CONTROL_BAR 10 +#define MAX_AGGRO_RESET_TIME 10 // in seconds + enum Swing { NOSWING = 0, @@ -2218,6 +2220,10 @@ class Unit : public WorldObject // Movement info Movement::MoveSpline * movespline; + // Part of Evade mechanics + time_t GetLastDamagedTime() const { return _lastDamagedTime; } + void SetLastDamagedTime(time_t val) { _lastDamagedTime = val; } + protected: explicit Unit (bool isWorldObject); @@ -2339,6 +2345,8 @@ class Unit : public WorldObject Spell const* _focusSpell; ///> Locks the target during spell cast for proper facing bool _isWalkingBeforeCharm; // Are we walking before we were charmed? + + time_t _lastDamagedTime; // Part of Evade mechanics }; namespace Trinity |