diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/Creature.cpp | 58 | ||||
-rw-r--r-- | src/game/Creature.h | 7 | ||||
-rw-r--r-- | src/game/CreatureEventAI.cpp | 32 | ||||
-rw-r--r-- | src/game/CreatureEventAI.h | 6 | ||||
-rw-r--r-- | src/game/CreatureEventAIMgr.cpp | 2 | ||||
-rw-r--r-- | src/game/FleeingMovementGenerator.cpp | 30 | ||||
-rw-r--r-- | src/game/FleeingMovementGenerator.h | 17 | ||||
-rw-r--r-- | src/game/GridNotifiers.h | 57 | ||||
-rw-r--r-- | src/game/IdleMovementGenerator.cpp | 16 | ||||
-rw-r--r-- | src/game/IdleMovementGenerator.h | 10 | ||||
-rw-r--r-- | src/game/MotionMaster.cpp | 42 | ||||
-rw-r--r-- | src/game/MotionMaster.h | 9 | ||||
-rw-r--r-- | src/game/PointMovementGenerator.cpp | 9 | ||||
-rw-r--r-- | src/game/PointMovementGenerator.h | 12 | ||||
-rw-r--r-- | src/game/TargetedMovementGenerator.cpp | 5 | ||||
-rw-r--r-- | src/game/Unit.cpp | 11 | ||||
-rw-r--r-- | src/game/World.cpp | 2 | ||||
-rw-r--r-- | src/game/World.h | 2 | ||||
-rw-r--r-- | src/trinitycore/trinitycore.conf.dist | 13 |
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 |