aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/Creature.cpp58
-rw-r--r--src/game/Creature.h7
-rw-r--r--src/game/CreatureEventAI.cpp32
-rw-r--r--src/game/CreatureEventAI.h6
-rw-r--r--src/game/CreatureEventAIMgr.cpp2
-rw-r--r--src/game/FleeingMovementGenerator.cpp30
-rw-r--r--src/game/FleeingMovementGenerator.h17
-rw-r--r--src/game/GridNotifiers.h57
-rw-r--r--src/game/IdleMovementGenerator.cpp16
-rw-r--r--src/game/IdleMovementGenerator.h10
-rw-r--r--src/game/MotionMaster.cpp42
-rw-r--r--src/game/MotionMaster.h9
-rw-r--r--src/game/PointMovementGenerator.cpp9
-rw-r--r--src/game/PointMovementGenerator.h12
-rw-r--r--src/game/TargetedMovementGenerator.cpp5
-rw-r--r--src/game/Unit.cpp11
-rw-r--r--src/game/World.cpp2
-rw-r--r--src/game/World.h2
-rw-r--r--src/trinitycore/trinitycore.conf.dist13
19 files changed, 244 insertions, 96 deletions
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 007e224b1e7..4ba8e66fc9f 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -139,6 +139,7 @@ m_gossipOptionLoaded(false),
m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false),
m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
m_creatureInfo(NULL), m_reactState(REACT_AGGRESSIVE), m_formation(NULL), m_summonMask(SUMMON_MASK_NONE)
+, m_AlreadySearchedAssistance(false)
{
m_regenTimer = 200;
m_valuesCount = UNIT_END;
@@ -611,6 +612,41 @@ void Creature::RegenerateHealth()
ModifyHealth(addvalue);
}
+void Creature::DoFleeToGetAssistance()
+{
+ if (!getVictim())
+ return;
+
+ if(HasAuraType(SPELL_AURA_PREVENTS_FLEEING))
+ return;
+
+ float radius = sWorld.getConfig(CONFIG_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS);
+ if (radius >0)
+ {
+ Creature* pCreature = NULL;
+
+ CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY()));
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+ MaNGOS::NearestAssistCreatureInCreatureRangeCheck u_check(this, getVictim(), radius);
+ MaNGOS::CreatureLastSearcher<MaNGOS::NearestAssistCreatureInCreatureRangeCheck> searcher(this, pCreature, u_check);
+
+ TypeContainerVisitor<MaNGOS::CreatureLastSearcher<MaNGOS::NearestAssistCreatureInCreatureRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
+
+ CellLock<GridReadGuard> cell_lock(cell, p);
+ cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap());
+
+ SetNoSearchAssistance(true);
+ if(!pCreature)
+ //SetFeared(true, getVictim()->GetGUID(), 0 ,sWorld.getConfig(CONFIG_CREATURE_FAMILY_FLEE_DELAY));
+ //TODO: use 31365
+ SetControlled(true, UNIT_STAT_FLEEING);
+ else
+ GetMotionMaster()->MoveSeekAssistance(pCreature->GetPositionX(), pCreature->GetPositionY(), pCreature->GetPositionZ());
+ }
+}
+
bool Creature::AIM_Initialize(CreatureAI* ai)
{
// make sure nothing can change the AI during AI update
@@ -1676,6 +1712,7 @@ void Creature::setDeathState(DeathState s)
if (canFly() && FallGround())
return;
+ SetNoSearchAssistance(false);
Unit::setDeathState(CORPSE);
//Dismiss group if is leader
@@ -1919,22 +1956,6 @@ bool Creature::IsVisibleInGridForPlayer(Player const* pl) const
return false;
}
-void Creature::DoFleeToGetAssistance(float radius) // Optional parameter
-{
- if (!getVictim())
- return;
-
- Creature* pCreature = NULL;
- Trinity::NearestAssistCreatureInCreatureRangeCheck u_check(this,getVictim(),radius);
- Trinity::CreatureLastSearcher<Trinity::NearestAssistCreatureInCreatureRangeCheck> searcher(this, pCreature, u_check);
- VisitNearbyGridObject(radius, searcher);
-
- if(!pCreature)
- SetControlled(true, UNIT_STAT_FLEEING);
- else
- GetMotionMaster()->MovePoint(0,pCreature->GetPositionX(),pCreature->GetPositionY(),pCreature->GetPositionZ());
-}
-
Unit* Creature::SelectNearestTarget(float dist) const
{
CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY()));
@@ -1959,14 +1980,13 @@ Unit* Creature::SelectNearestTarget(float dist) const
return target;
}
-void Creature::CallAssistance(float radius)
+void Creature::CallAssistance()
{
if( !m_AlreadyCallAssistance && getVictim() && !isPet() && !isCharmed())
{
SetNoCallAssistance(true);
- if(!radius)
- radius = sWorld.getConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS);
+ float radius = sWorld.getConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS);
if(radius > 0)
{
diff --git a/src/game/Creature.h b/src/game/Creature.h
index e89af04126c..aeecc19a3ba 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -634,9 +634,11 @@ class TRINITY_DLL_SPEC Creature : public Unit
float GetAttackDistance(Unit const* pl) const;
Unit* SelectNearestTarget(float dist = 0) const;
- void CallAssistance(float radius = 0);
+ void DoFleeToGetAssistance();
+ void CallAssistance();
void SetNoCallAssistance(bool val) { m_AlreadyCallAssistance = val; }
- void DoFleeToGetAssistance(float radius = 50);
+ void SetNoSearchAssistance(bool val) { m_AlreadySearchedAssistance = val; }
+ bool HasSearchedAssistance() { return m_AlreadySearchedAssistance; }
bool CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction = true) const;
MovementGeneratorType GetDefaultMovementType() const { return m_defaultMovementType; }
@@ -746,6 +748,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
uint32 m_equipmentId;
bool m_AlreadyCallAssistance;
+ bool m_AlreadySearchedAssistance;
bool m_regenHealth;
bool m_AI_locked;
bool m_isDeadByDefault;
diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp
index 7625ce0b74f..44a8dd6b31b 100644
--- a/src/game/CreatureEventAI.cpp
+++ b/src/game/CreatureEventAI.cpp
@@ -130,8 +130,6 @@ CreatureEventAI::CreatureEventAI(Creature *c ) : CreatureAI(c)
AttackDistance = 0;
AttackAngle = 0.0f;
- IsFleeing = false;
-
//Handle Spawned Events
if (!bEmptyList)
{
@@ -617,12 +615,8 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
case ACTION_T_EVADE:
EnterEvadeMode();
break;
- case ACTION_T_FLEE:
- if(me->HasAuraType(SPELL_AURA_PREVENTS_FLEEING))
- break;
- TimetoFleeLeft = 8000;
- me->DoFleeToGetAssistance();
- IsFleeing = true;
+ case ACTION_T_FLEE_FOR_ASSIST:
+ m_creature->DoFleeToGetAssistance();
break;
case ACTION_T_QUEST_EVENT_ALL:
if (pActionInvoker && pActionInvoker->GetTypeId() == TYPEID_PLAYER)
@@ -808,7 +802,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
void CreatureEventAI::JustRespawned()
{
- IsFleeing = false;
Reset();
if (bEmptyList)
@@ -827,9 +820,6 @@ void CreatureEventAI::Reset()
EventUpdateTime = EVENT_UPDATE_TIME;
EventDiff = 0;
- TimetoFleeLeft = 0;
- IsFleeing = false;
-
if (bEmptyList)
return;
@@ -888,7 +878,6 @@ void CreatureEventAI::EnterEvadeMode()
void CreatureEventAI::JustDied(Unit* killer)
{
- IsFleeing = false;
Reset();
if (bEmptyList)
@@ -1033,23 +1022,6 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
if (!m_creature->isAlive())
return;
- if (IsFleeing)
- {
- if(TimetoFleeLeft < diff)
- {
- me->SetControlled(false, UNIT_STAT_FLEEING);
- me->SetNoCallAssistance(false);
- me->CallAssistance();
- if(me->getVictim())
- me->GetMotionMaster()->MoveChase(me->getVictim());
- IsFleeing = false;
- }
- else
- TimetoFleeLeft -= diff;
-
- return;
- }
-
if (!bEmptyList)
{
//Events are only updated once every EVENT_UPDATE_TIME ms to prevent lag with large amount of events
diff --git a/src/game/CreatureEventAI.h b/src/game/CreatureEventAI.h
index 3434a9cb55e..e8dcbaeca40 100644
--- a/src/game/CreatureEventAI.h
+++ b/src/game/CreatureEventAI.h
@@ -28,7 +28,6 @@ class Player;
class WorldObject;
#define EVENT_UPDATE_TIME 500
-#define SPELL_RUN_AWAY 8225
#define MAX_ACTIONS 3
#define MAX_PHASE 32
@@ -88,7 +87,7 @@ enum EventAI_ActionType
ACTION_T_SET_PHASE = 22, // Phase
ACTION_T_INC_PHASE = 23, // Value (may be negative to decrement phase, should not be 0)
ACTION_T_EVADE = 24, // No Params
- ACTION_T_FLEE = 25, // No Params
+ ACTION_T_FLEE_FOR_ASSIST = 25, // No Params
ACTION_T_QUEST_EVENT_ALL = 26, // QuestID
ACTION_T_CAST_EVENT_ALL = 27, // CreatureId, SpellId
ACTION_T_REMOVEAURASFROMSPELL = 28, // Target, Spellid
@@ -580,8 +579,5 @@ class TRINITY_DLL_SPEC CreatureEventAI : public CreatureAI
bool MeleeEnabled; //If we allow melee auto attack
uint32 AttackDistance; //Distance to attack from
float AttackAngle; //Angle of attack
-
- uint32 TimetoFleeLeft;
- bool IsFleeing;
};
#endif
diff --git a/src/game/CreatureEventAIMgr.cpp b/src/game/CreatureEventAIMgr.cpp
index 9bd262a5f9f..5a163089d4c 100644
--- a/src/game/CreatureEventAIMgr.cpp
+++ b/src/game/CreatureEventAIMgr.cpp
@@ -626,7 +626,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, action.update_template.creatureId);
break;
case ACTION_T_EVADE: //No Params
- case ACTION_T_FLEE: //No Params
+ case ACTION_T_FLEE_FOR_ASSIST: //No Params
case ACTION_T_DIE: //No Params
case ACTION_T_ZONE_COMBAT_PULSE: //No Params
case ACTION_T_AUTO_ATTACK: //AllowAttackState (0 = stop attack, anything else means continue attacking)
diff --git a/src/game/FleeingMovementGenerator.cpp b/src/game/FleeingMovementGenerator.cpp
index 538d513b298..31fc350af70 100644
--- a/src/game/FleeingMovementGenerator.cpp
+++ b/src/game/FleeingMovementGenerator.cpp
@@ -19,6 +19,7 @@
*/
#include "Creature.h"
+#include "CreatureAI.h"
#include "MapManager.h"
#include "FleeingMovementGenerator.h"
#include "DestinationHolderImp.h"
@@ -410,3 +411,32 @@ template void FleeingMovementGenerator<Creature>::Reset(Creature &);
template bool FleeingMovementGenerator<Player>::Update(Player &, const uint32 &);
template bool FleeingMovementGenerator<Creature>::Update(Creature &, const uint32 &);
+void TimedFleeingMovementGenerator::Finalize(Unit &owner)
+{
+ owner.clearUnitState(UNIT_STAT_FLEEING);
+ if (Unit* victim = owner.getVictim())
+ {
+ if (owner.isAlive())
+ {
+ owner.AttackStop();
+ ((Creature*)&owner)->AI()->AttackStart(victim);
+ }
+ }
+}
+
+bool TimedFleeingMovementGenerator::Update(Unit & owner, const uint32 & time_diff)
+{
+ if( !owner.isAlive() )
+ return false;
+
+ if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
+ return true;
+
+ i_totalFleeTime.Update(time_diff);
+ if (i_totalFleeTime.Passed())
+ return false;
+
+ // This calls grant-parent Update method hiden by FleeingMovementGenerator::Update(Creature &, const uint32 &) version
+ // This is done instead of casting Unit& to Creature& and call parent method, then we can use Unit directly
+ return MovementGeneratorMedium< Creature, FleeingMovementGenerator<Creature> >::Update(owner, time_diff);
+}
diff --git a/src/game/FleeingMovementGenerator.h b/src/game/FleeingMovementGenerator.h
index 0b580ab1504..0bc4bdb9757 100644
--- a/src/game/FleeingMovementGenerator.h
+++ b/src/game/FleeingMovementGenerator.h
@@ -61,5 +61,22 @@ class TRINITY_DLL_SPEC FleeingMovementGenerator
DestinationHolder< Traveller<T> > i_destinationHolder;
};
+
+class MANGOS_DLL_SPEC TimedFleeingMovementGenerator
+: public FleeingMovementGenerator<Creature>
+{
+ public:
+ TimedFleeingMovementGenerator(uint64 fright, uint32 time) :
+ FleeingMovementGenerator<Creature>(fright),
+ i_totalFleeTime(time) {}
+
+ MovementGeneratorType GetMovementGeneratorType() { return TIMED_FLEEING_MOTION_TYPE; }
+ bool Update(Unit &, const uint32 &);
+ void Finalize(Unit &);
+
+ private:
+ TimeTracker i_totalFleeTime;
+};
+
#endif
diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h
index 2295f72e4c9..21ef9d0c81b 100644
--- a/src/game/GridNotifiers.h
+++ b/src/game/GridNotifiers.h
@@ -950,31 +950,6 @@ namespace Trinity
NearestHostileUnitInAttackDistanceCheck(NearestHostileUnitInAttackDistanceCheck const&);
};
- class NearestAssistCreatureInCreatureRangeCheck
- {
- public:
- NearestAssistCreatureInCreatureRangeCheck(Creature* obj,Unit* enemy, float range)
- : i_obj(obj), i_enemy(enemy), i_range(range) {}
-
- bool operator()(Creature* u)
- {
- if(u->getFaction() == i_obj->getFaction() && !u->isInCombat() && !u->GetCharmerOrOwnerGUID() && u->IsHostileTo(i_enemy) && u->isAlive()&& i_obj->IsWithinDistInMap(u, i_range) && i_obj->IsWithinLOSInMap(u))
- {
- i_range = i_obj->GetDistance(u); // use found unit range as new range limit for next check
- return true;
- }
- return false;
- }
- float GetLastRange() const { return i_range; }
- private:
- Creature* const i_obj;
- Unit* const i_enemy;
- float i_range;
-
- // prevent clone this object
- NearestAssistCreatureInCreatureRangeCheck(NearestAssistCreatureInCreatureRangeCheck const&);
- };
-
class AnyAssistCreatureInRangeCheck
{
public:
@@ -1006,6 +981,38 @@ namespace Trinity
float i_range;
};
+ class NearestAssistCreatureInCreatureRangeCheck
+ {
+ public:
+ NearestAssistCreatureInCreatureRangeCheck(Creature* obj, Unit* enemy, float range)
+ : i_obj(obj), i_enemy(enemy), i_range(range) {}
+
+ bool operator()(Creature* u)
+ {
+ if(u == i_obj)
+ return false;
+ if(!u->CanAssistTo(i_obj,i_enemy))
+ return false;
+
+ if(!i_obj->IsWithinDistInMap(u, i_range))
+ return false;
+
+ if(!i_obj->IsWithinLOSInMap(u))
+ return false;
+
+ i_range = i_obj->GetDistance(u); // use found unit range as new range limit for next check
+ return true;
+ }
+ float GetLastRange() const { return i_range; }
+ private:
+ Creature* const i_obj;
+ Unit* const i_enemy;
+ float i_range;
+
+ // prevent clone this object
+ NearestAssistCreatureInCreatureRangeCheck(NearestAssistCreatureInCreatureRangeCheck const&);
+ };
+
// Success at unit in range, range update for next check (this can be use with CreatureLastSearcher to find nearest creature)
class NearestCreatureEntryWithLiveStateInObjectRangeCheck
{
diff --git a/src/game/IdleMovementGenerator.cpp b/src/game/IdleMovementGenerator.cpp
index 2428c49a77a..44575302e75 100644
--- a/src/game/IdleMovementGenerator.cpp
+++ b/src/game/IdleMovementGenerator.cpp
@@ -19,7 +19,8 @@
*/
#include "IdleMovementGenerator.h"
-#include "Unit.h"
+#include "CreatureAI.h"
+#include "Creature.h"
IdleMovementGenerator si_idleMovement;
@@ -60,3 +61,16 @@ DistractMovementGenerator::Update(Unit& owner, const uint32& time_diff)
return true;
}
+void
+AssistanceDistractMovementGenerator::Finalize(Unit &unit)
+{
+ unit.clearUnitState(UNIT_STAT_DISTRACTED);
+ if (Unit* victim = unit.getVictim())
+ {
+ if (unit.isAlive())
+ {
+ unit.AttackStop();
+ ((Creature*)&unit)->AI()->AttackStart(victim);
+ }
+ }
+}
diff --git a/src/game/IdleMovementGenerator.h b/src/game/IdleMovementGenerator.h
index 7ada9f08f52..2d5b7d94314 100644
--- a/src/game/IdleMovementGenerator.h
+++ b/src/game/IdleMovementGenerator.h
@@ -51,5 +51,15 @@ class TRINITY_DLL_SPEC DistractMovementGenerator : public MovementGenerator
uint32 m_timer;
};
+class MANGOS_DLL_SPEC AssistanceDistractMovementGenerator : public DistractMovementGenerator
+{
+ public:
+ AssistanceDistractMovementGenerator(uint32 timer) :
+ DistractMovementGenerator(timer) {}
+
+ MovementGeneratorType GetMovementGeneratorType() { return ASSISTANCE_DISTRACT_MOTION_TYPE; }
+ void Finalize(Unit& unit);
+};
+
#endif
diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp
index 52b9ba56e3e..da811ab02ed 100644
--- a/src/game/MotionMaster.cpp
+++ b/src/game/MotionMaster.cpp
@@ -365,7 +365,37 @@ MotionMaster::MoveCharge(float x, float y, float z, float speed)
}
void
-MotionMaster::MoveFleeing(Unit* enemy)
+MotionMaster::MoveSeekAssistance(float x, float y, float z)
+{
+ if(i_owner->GetTypeId()==TYPEID_PLAYER)
+ {
+ sLog.outError("Player (GUID: %u) attempt to seek assistance",i_owner->GetGUIDLow());
+ }
+ else
+ {
+ DEBUG_LOG("Creature (Entry: %u GUID: %u) seek assistance (X: %f Y: %f Z: %f)",
+ i_owner->GetEntry(), i_owner->GetGUIDLow(), x, y, z );
+ Mutate(new AssistanceMovementGenerator(x,y,z), MOTION_SLOT_ACTIVE);
+ }
+}
+
+void
+MotionMaster::MoveSeekAssistanceDistract(uint32 time)
+{
+ if(i_owner->GetTypeId()==TYPEID_PLAYER)
+ {
+ sLog.outError("Player (GUID: %u) attempt to call distract after assistance",i_owner->GetGUIDLow());
+ }
+ else
+ {
+ DEBUG_LOG("Creature (Entry: %u GUID: %u) is distracted after assistance call (Time: %u)",
+ i_owner->GetEntry(), i_owner->GetGUIDLow(), time );
+ Mutate(new AssistanceDistractMovementGenerator(time), MOTION_SLOT_ACTIVE);
+ }
+}
+
+void
+MotionMaster::MoveFleeing(Unit* enemy, uint32 time)
{
if(!enemy)
return;
@@ -382,11 +412,15 @@ MotionMaster::MoveFleeing(Unit* enemy)
}
else
{
- DEBUG_LOG("Creature (Entry: %u GUID: %u) flee from %s (GUID: %u)",
+ DEBUG_LOG("Creature (Entry: %u GUID: %u) flee from %s (GUID: %u)%s",
i_owner->GetEntry(), i_owner->GetGUIDLow(),
enemy->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
- enemy->GetTypeId()==TYPEID_PLAYER ? enemy->GetGUIDLow() : ((Creature*)enemy)->GetDBTableGUIDLow() );
- Mutate(new FleeingMovementGenerator<Creature>(enemy->GetGUID()), MOTION_SLOT_CONTROLLED);
+ enemy->GetTypeId()==TYPEID_PLAYER ? enemy->GetGUIDLow() : ((Creature*)enemy)->GetDBTableGUIDLow(),
+ time ? " for a limited time" : "");
+ if (time)
+ Mutate(new TimedFleeingMovementGenerator(enemy->GetGUID(), time), MOTION_SLOT_CONTROLLED);
+ else
+ Mutate(new FleeingMovementGenerator<Creature>(enemy->GetGUID()), MOTION_SLOT_CONTROLLED);
}
}
diff --git a/src/game/MotionMaster.h b/src/game/MotionMaster.h
index ea71495d216..be2960624cd 100644
--- a/src/game/MotionMaster.h
+++ b/src/game/MotionMaster.h
@@ -45,7 +45,10 @@ enum MovementGeneratorType
POINT_MOTION_TYPE = 8, // PointMovementGenerator.h
FLEEING_MOTION_TYPE = 9, // FleeingMovementGenerator.h
DISTRACT_MOTION_TYPE = 10, // IdleMovementGenerator.h
- NULL_MOTION_TYPE = 11,
+ ASSISTANCE_MOTION_TYPE= 11, // PointMovementGenerator.h (first part of flee for assistance)
+ ASSISTANCE_DISTRACT_MOTION_TYPE = 12, // IdleMovementGenerator.h (second part of flee for assistance)
+ TIMED_FLEEING_MOTION_TYPE = 13, // FleeingMovementGenerator.h (alt.second part of flee for assistance)
+ NULL_MOTION_TYPE = 14,
};
enum MovementSlot
@@ -138,12 +141,14 @@ class TRINITY_DLL_SPEC MotionMaster //: private std::stack<MovementGenerator *>
void MoveFollow(Unit* target, float dist, float angle, MovementSlot slot = MOTION_SLOT_ACTIVE);
void MoveChase(Unit* target, float dist = 0.0f, float angle = 0.0f);
void MoveConfused();
- void MoveFleeing(Unit* enemy);
+ void MoveFleeing(Unit* enemy, uint32 time = 0);
void MovePoint(uint32 id, float x,float y,float z);
void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE);
void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ);
void MoveJumpTo(float angle, float speedXY, float speedZ);
void MoveJump(float x, float y, float z, float speedXY, float speedZ);
+ void MoveSeekAssistance(float x,float y,float z);
+ void MoveSeekAssistanceDistract(uint32 timer);
void MoveTaxiFlight(uint32 path, uint32 pathnode);
void MoveDistract(uint32 time);
void MovePath(uint32 path_id, bool repeatable);
diff --git a/src/game/PointMovementGenerator.cpp b/src/game/PointMovementGenerator.cpp
index dedb4f0829c..c972683ce0b 100644
--- a/src/game/PointMovementGenerator.cpp
+++ b/src/game/PointMovementGenerator.cpp
@@ -23,6 +23,7 @@
#include "Creature.h"
#include "CreatureAI.h"
#include "DestinationHolderImp.h"
+#include "World.h"
//----- Point Movement Generator
template<class T>
@@ -92,3 +93,11 @@ template void PointMovementGenerator<Player>::Finalize(Player&);
template void PointMovementGenerator<Creature>::Initialize(Creature&);
template bool PointMovementGenerator<Creature>::Update(Creature&, const uint32 &diff);
template void PointMovementGenerator<Creature>::Finalize(Creature&);
+
+void AssistanceMovementGenerator::Finalize(Unit &unit)
+{
+ ((Creature*)&unit)->SetNoCallAssistance(false);
+ ((Creature*)&unit)->CallAssistance();
+ if (unit.isAlive())
+ unit.GetMotionMaster()->MoveSeekAssistanceDistract(sWorld.getConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY));
+}
diff --git a/src/game/PointMovementGenerator.h b/src/game/PointMovementGenerator.h
index 7551e3827b4..baeb8b26dbd 100644
--- a/src/game/PointMovementGenerator.h
+++ b/src/game/PointMovementGenerator.h
@@ -51,5 +51,17 @@ class TRINITY_DLL_SPEC PointMovementGenerator
DestinationHolder< Traveller<T> > i_destinationHolder;
bool arrived;
};
+
+class MANGOS_DLL_SPEC AssistanceMovementGenerator
+: public PointMovementGenerator<Creature>
+{
+ public:
+ AssistanceMovementGenerator(float _x, float _y, float _z) :
+ PointMovementGenerator<Creature>(0, _x, _y, _z) {}
+
+ MovementGeneratorType GetMovementGeneratorType() { return ASSISTANCE_MOTION_TYPE; }
+ void Finalize(Unit &);
+};
+
#endif
diff --git a/src/game/TargetedMovementGenerator.cpp b/src/game/TargetedMovementGenerator.cpp
index fcbdb8b30e5..452fb670e74 100644
--- a/src/game/TargetedMovementGenerator.cpp
+++ b/src/game/TargetedMovementGenerator.cpp
@@ -94,7 +94,10 @@ template<class T>
void
TargetedMovementGenerator<T>::Initialize(T &owner)
{
- owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->HasSearchedAssistance())
+ owner.AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ else
+ owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 6aeefa6e4aa..b66564756a0 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -8085,10 +8085,11 @@ bool Unit::AttackStop()
InterruptSpell(CURRENT_MELEE_SPELL);
- if( GetTypeId()==TYPEID_UNIT )
+ // reset only at real combat stop
+ if(GetTypeId()==TYPEID_UNIT )
{
- // reset call assistance
((Creature*)this)->SetNoCallAssistance(false);
+ ((Creature*)this)->SetNoSearchAssistance(false);
}
SendAttackStop(victim);
@@ -12321,7 +12322,7 @@ void Unit::SendMovementFlagUpdate()
}
/*
-void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID)
+void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID, uint32 time)
{
if( apply )
{
@@ -12335,7 +12336,7 @@ void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID)
Unit* caster = ObjectAccessor::GetUnit(*this,casterGUID);
- GetMotionMaster()->MoveFleeing(caster); // caster==NULL processed in MoveFleeing
+ GetMotionMaster()->MoveFleeing(caster, time); // caster==NULL processed in MoveFleeing
}
else
{
@@ -13332,7 +13333,7 @@ void Unit::SetFeared(bool apply)
caster = ObjectAccessor::GetUnit(*this, fearAuras.front()->GetCasterGUID());
if(!caster)
caster = getAttackerForHelper();
- GetMotionMaster()->MoveFleeing(caster); // caster==NULL processed in MoveFleeing
+ GetMotionMaster()->MoveFleeing(caster, fearAuras.empty() ? sWorld.getConfig(CONFIG_CREATURE_FAMILY_FLEE_DELAY) : 0); // caster==NULL processed in MoveFleeing
}
else
{
diff --git a/src/game/World.cpp b/src/game/World.cpp
index b514895a328..b6cda4ee067 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -909,8 +909,10 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_EVENT_ANNOUNCE] = sConfig.GetIntDefault("Event.Announce",0);
+ m_configs[CONFIG_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS] = sConfig.GetIntDefault("CreatureFamilyFleeAssistanceRadius",30);
m_configs[CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS] = sConfig.GetIntDefault("CreatureFamilyAssistanceRadius",10);
m_configs[CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY] = sConfig.GetIntDefault("CreatureFamilyAssistanceDelay",1500);
+ m_configs[CONFIG_CREATURE_FAMILY_FLEE_DELAY] = sConfig.GetIntDefault("CreatureFamilyFleeDelay",7000);
m_configs[CONFIG_WORLD_BOSS_LEVEL_DIFF] = sConfig.GetIntDefault("WorldBossLevelDiff",3);
diff --git a/src/game/World.h b/src/game/World.h
index 635eceef24e..2c0889e0e9f 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -169,8 +169,10 @@ enum WorldConfigs
CONFIG_CHATFLOOD_MESSAGE_DELAY,
CONFIG_CHATFLOOD_MUTE_TIME,
CONFIG_EVENT_ANNOUNCE,
+ CONFIG_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS,
CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS,
CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY,
+ CONFIG_CREATURE_FAMILY_FLEE_DELAY,
CONFIG_WORLD_BOSS_LEVEL_DIFF,
CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF,
CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF,
diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist
index 2748c92529a..25f716a77a9 100644
--- a/src/trinitycore/trinitycore.conf.dist
+++ b/src/trinitycore/trinitycore.conf.dist
@@ -819,8 +819,13 @@ TalentsInspecting = 1
# 1.5 - 150%
# 0 - off (0%)
#
+# CreatureFamilyFleeAssistanceRadius
+# Radius which creature will use to seek for a near creature for assistance. Creature will flee to this creature.
+# Default: 30
+# 0 - off
+#
# CreatureFamilyAssistanceRadius
-# Creature family assistance radius
+# Radius which creature will use to call assistance without moving
# Default: 10
# 0 - off
#
@@ -828,6 +833,10 @@ TalentsInspecting = 1
# Reaction time for creature assistance call
# Default: 1500 (1.5s)
#
+# CreatureFamilyFleeDelay
+# Time during which creature can flee when no assistant found
+# Default: 7000 (7s)
+#
# WorldBossLevelDiff
# Difference for boss dynamic level with target
# Default: 3
@@ -884,8 +893,10 @@ TalentsInspecting = 1
ThreatRadius = 60
Rate.Creature.Aggro = 1
+CreatureFamilyFleeAssistanceRadius = 30
CreatureFamilyAssistanceRadius = 10
CreatureFamilyAssistanceDelay = 1500
+CreatureFamilyFleeDelay = 7000
WorldBossLevelDiff = 3
Corpse.Decay.NORMAL = 60
Corpse.Decay.RARE = 300