aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/AI/CreatureAI.cpp7
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp13
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h8
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