[9198] Replace targeted movegen by 2 new: chase/follow movegens.

NOTE: this is mostly just formal adding 2 movegens with very limited cleanups.
Real result from adding 2 new movegens possible after apply more deep cleanups/fixes
in UNIT_STAT_CHASE/UNIT_STAT_FOLLOW set. But this will need more cereful changes
because we have currently sometime strange dependences and places for set for this flags.
Similar cleanups required for other movegen related flags. Infact i have related patches but
need more testing before apply step by step.
This commit is contained in:
VladimirMangos 2010-01-17 09:28:49 +03:00
parent 2e9bf5ad6a
commit 8a03785470
17 changed files with 232 additions and 138 deletions

View file

@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
`version` varchar(120) default NULL, `version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0', `cache_id` int(10) default '0',
`required_9160_02_mangos_spell_chain` bit(1) default NULL `required_9198_01_mangos_mangos_string` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
-- --
@ -3590,6 +3590,9 @@ INSERT INTO `mangos_string` VALUES
(1129,'%d - %s %s (Map:%u X:%f Y:%f Z:%f)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1129,'%d - %s %s (Map:%u X:%f Y:%f Z:%f)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1130,'event started %u "%s"',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1130,'event started %u "%s"',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1131,'event stopped %u "%s"',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1131,'event stopped %u "%s"',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1132,' Follow player %s (lowguid %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1133,' Follow creature %s (lowguid %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1134,' Follow <NULL>',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1200,'You try to view cinemitic %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1200,'You try to view cinemitic %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1201,'You try to view movie %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); (1201,'You try to view movie %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
/*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */; /*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */;

View file

@ -0,0 +1,8 @@
ALTER TABLE db_version CHANGE COLUMN required_9160_02_mangos_spell_chain required_9198_01_mangos_mangos_string bit;
DELETE FROM mangos_string WHERE entry in (1132,1133,1134);
INSERT INTO mangos_string VALUES
(1132,' Follow player %s (lowguid %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1133,' Follow creature %s (lowguid %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1134,' Follow <NULL>',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);

View file

@ -244,6 +244,7 @@ pkgdata_DATA = \
9156_02_mangos_spell_proc_event.sql \ 9156_02_mangos_spell_proc_event.sql \
9160_01_mangos_spell_proc_event.sql \ 9160_01_mangos_spell_proc_event.sql \
9160_02_mangos_spell_chain.sql \ 9160_02_mangos_spell_chain.sql \
9198_01_mangos_mangos_string.sql \
README README
## Additional files to include when running 'make dist' ## Additional files to include when running 'make dist'
@ -468,4 +469,5 @@ EXTRA_DIST = \
9156_02_mangos_spell_proc_event.sql \ 9156_02_mangos_spell_proc_event.sql \
9160_01_mangos_spell_proc_event.sql \ 9160_01_mangos_spell_proc_event.sql \
9160_02_mangos_spell_chain.sql \ 9160_02_mangos_spell_chain.sql \
9198_01_mangos_mangos_string.sql \
README README

View file

@ -108,8 +108,8 @@ void AggressorAI::EnterEvadeMode()
{ {
m_creature->RemoveAllAuras(); m_creature->RemoveAllAuras();
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead // Remove ChaseMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
if( m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE ) if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
m_creature->GetMotionMaster()->MoveTargetedHome(); m_creature->GetMotionMaster()->MoveTargetedHome();
} }

View file

@ -474,13 +474,16 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
//Melee current victim if flag not set //Melee current victim if flag not set
if (!(action.cast.castFlags & CAST_NO_MELEE_IF_OOM)) if (!(action.cast.castFlags & CAST_NO_MELEE_IF_OOM))
{ {
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE) switch(m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType())
{ {
case CHASE_MOTION_TYPE:
case FOLLOW_MOTION_TYPE:
AttackDistance = 0.0f; AttackDistance = 0.0f;
AttackAngle = 0.0f; AttackAngle = 0.0f;
m_creature->GetMotionMaster()->Clear(false); m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
break;
} }
} }
@ -589,7 +592,7 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
if(Unit* victim = m_creature->getVictim()) if(Unit* victim = m_creature->getVictim())
m_creature->SendMeleeAttackStop(victim); m_creature->SendMeleeAttackStop(victim);
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE) if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
{ {
m_creature->GetMotionMaster()->Clear(false); m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveIdle(); m_creature->GetMotionMaster()->MoveIdle();
@ -651,7 +654,7 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
if (CombatMovementEnabled) if (CombatMovementEnabled)
{ {
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE) if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
{ {
//Drop current movement gen //Drop current movement gen
m_creature->GetMotionMaster()->Clear(false); m_creature->GetMotionMaster()->Clear(false);

View file

@ -100,8 +100,8 @@ void GuardAI::EnterEvadeMode()
m_creature->CombatStop(true); m_creature->CombatStop(true);
i_state = STATE_NORMAL; i_state = STATE_NORMAL;
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead // Remove ChaseMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE) if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
m_creature->GetMotionMaster()->MoveTargetedHome(); m_creature->GetMotionMaster()->MoveTargetedHome();
} }

View file

@ -498,9 +498,9 @@ enum MangosStrings
LANG_MOVEGENS_WAYPOINT = 529, LANG_MOVEGENS_WAYPOINT = 529,
LANG_MOVEGENS_ANIMAL_RANDOM = 530, LANG_MOVEGENS_ANIMAL_RANDOM = 530,
LANG_MOVEGENS_CONFUSED = 531, LANG_MOVEGENS_CONFUSED = 531,
LANG_MOVEGENS_TARGETED_PLAYER = 532, LANG_MOVEGENS_CHASE_PLAYER = 532,
LANG_MOVEGENS_TARGETED_CREATURE = 533, LANG_MOVEGENS_CHASE_CREATURE = 533,
LANG_MOVEGENS_TARGETED_NULL = 534, LANG_MOVEGENS_CHASE_NULL = 534,
LANG_MOVEGENS_HOME_CREATURE = 535, LANG_MOVEGENS_HOME_CREATURE = 535,
LANG_MOVEGENS_HOME_PLAYER = 536, LANG_MOVEGENS_HOME_PLAYER = 536,
LANG_MOVEGENS_FLIGHT = 537, LANG_MOVEGENS_FLIGHT = 537,
@ -816,7 +816,10 @@ enum MangosStrings
LANG_TAXINODE_ENTRY_LIST_CONSOLE = 1129, LANG_TAXINODE_ENTRY_LIST_CONSOLE = 1129,
LANG_EVENT_STARTED = 1130, LANG_EVENT_STARTED = 1130,
LANG_EVENT_STOPPED = 1131, LANG_EVENT_STOPPED = 1131,
// Room for more level 3 1132-1199 not used LANG_MOVEGENS_FOLLOW_PLAYER = 1132,
LANG_MOVEGENS_FOLLOW_CREATURE = 1133,
LANG_MOVEGENS_FOLLOW_NULL = 1134,
// Room for more level 3 1135-1199 not used
// Debug commands // Debug commands
LANG_CINEMATIC_NOT_EXIST = 1200, LANG_CINEMATIC_NOT_EXIST = 1200,

View file

@ -1745,15 +1745,15 @@ bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
} }
if (creature->GetMotionMaster()->empty() || if (creature->GetMotionMaster()->empty() ||
creature->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE) creature->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=FOLLOW_MOTION_TYPE)
{ {
PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU); PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
SetSentErrorMessage(true); SetSentErrorMessage(true);
return false; return false;
} }
TargetedMovementGenerator<Creature> const* mgen FollowMovementGenerator<Creature> const* mgen
= static_cast<TargetedMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top())); = static_cast<FollowMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top()));
if(mgen->GetTarget()!=player) if(mgen->GetTarget()!=player)
{ {

View file

@ -5571,26 +5571,37 @@ bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break; case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break; case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break; case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
case TARGETED_MOTION_TYPE:
case CHASE_MOTION_TYPE:
{ {
Unit* target = NULL;
if(unit->GetTypeId()==TYPEID_PLAYER) if(unit->GetTypeId()==TYPEID_PLAYER)
{ target = static_cast<ChaseMovementGenerator<Player> const*>(*itr)->GetTarget();
TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(*itr);
Unit* target = mgen->GetTarget();
if(target)
PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow());
else else
SendSysMessage(LANG_MOVEGENS_TARGETED_NULL); target = static_cast<ChaseMovementGenerator<Creature> const*>(*itr)->GetTarget();
if (!target)
SendSysMessage(LANG_MOVEGENS_CHASE_NULL);
else if (target->GetTypeId()==TYPEID_PLAYER)
PSendSysMessage(LANG_MOVEGENS_CHASE_PLAYER,target->GetName(),target->GetGUIDLow());
else
PSendSysMessage(LANG_MOVEGENS_CHASE_CREATURE,target->GetName(),target->GetGUIDLow());
break;
} }
else case FOLLOW_MOTION_TYPE:
{ {
TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(*itr); Unit* target = NULL;
Unit* target = mgen->GetTarget(); if(unit->GetTypeId()==TYPEID_PLAYER)
if(target) target = static_cast<FollowMovementGenerator<Player> const*>(*itr)->GetTarget();
PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow());
else else
SendSysMessage(LANG_MOVEGENS_TARGETED_NULL); target = static_cast<FollowMovementGenerator<Creature> const*>(*itr)->GetTarget();
}
if (!target)
SendSysMessage(LANG_MOVEGENS_FOLLOW_NULL);
else if (target->GetTypeId()==TYPEID_PLAYER)
PSendSysMessage(LANG_MOVEGENS_FOLLOW_PLAYER,target->GetName(),target->GetGUIDLow());
else
PSendSysMessage(LANG_MOVEGENS_FOLLOW_CREATURE,target->GetName(),target->GetGUIDLow());
break; break;
} }
case HOME_MOTION_TYPE: case HOME_MOTION_TYPE:

View file

@ -159,7 +159,7 @@ MotionMaster::DirectExpire(bool reset)
pop(); pop();
// also drop stored under top() targeted motions // also drop stored under top() targeted motions
while( !empty() && top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE ) while (!empty() && (top()->GetMovementGeneratorType() == CHASE_MOTION_TYPE || top()->GetMovementGeneratorType() == FOLLOW_MOTION_TYPE))
{ {
MovementGenerator *temp = top(); MovementGenerator *temp = top();
pop(); pop();
@ -192,7 +192,7 @@ MotionMaster::DelayedExpire()
m_expList = new ExpireList(); m_expList = new ExpireList();
// also drop stored under top() targeted motions // also drop stored under top() targeted motions
while( !empty() && top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE ) while (!empty() && (top()->GetMovementGeneratorType() == CHASE_MOTION_TYPE || top()->GetMovementGeneratorType() == FOLLOW_MOTION_TYPE))
{ {
MovementGenerator *temp = top(); MovementGenerator *temp = top();
pop(); pop();
@ -236,7 +236,7 @@ MotionMaster::MoveTargetedHome()
DEBUG_LOG("Following %s (GUID: %u)", DEBUG_LOG("Following %s (GUID: %u)",
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature", target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() ); target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() );
Mutate(new TargetedMovementGenerator<Creature>(*target,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE)); Mutate(new FollowMovementGenerator<Creature>(*target,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE));
} }
} }
else else
@ -275,7 +275,7 @@ MotionMaster::MoveChase(Unit* target, float dist, float angle)
i_owner->GetGUIDLow(), i_owner->GetGUIDLow(),
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature", target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? i_owner->GetGUIDLow() : ((Creature*)i_owner)->GetDBTableGUIDLow() ); target->GetTypeId()==TYPEID_PLAYER ? i_owner->GetGUIDLow() : ((Creature*)i_owner)->GetDBTableGUIDLow() );
Mutate(new TargetedMovementGenerator<Player>(*target,dist,angle)); Mutate(new ChaseMovementGenerator<Player>(*target,dist,angle));
} }
else else
{ {
@ -283,7 +283,7 @@ MotionMaster::MoveChase(Unit* target, float dist, float angle)
i_owner->GetEntry(), i_owner->GetGUIDLow(), i_owner->GetEntry(), i_owner->GetGUIDLow(),
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature", target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() ); target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() );
Mutate(new TargetedMovementGenerator<Creature>(*target,dist,angle)); Mutate(new ChaseMovementGenerator<Creature>(*target,dist,angle));
} }
} }
@ -302,7 +302,7 @@ MotionMaster::MoveFollow(Unit* target, float dist, float angle)
DEBUG_LOG("Player (GUID: %u) follow to %s (GUID: %u)", i_owner->GetGUIDLow(), DEBUG_LOG("Player (GUID: %u) follow to %s (GUID: %u)", i_owner->GetGUIDLow(),
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature", target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? i_owner->GetGUIDLow() : ((Creature*)i_owner)->GetDBTableGUIDLow() ); target->GetTypeId()==TYPEID_PLAYER ? i_owner->GetGUIDLow() : ((Creature*)i_owner)->GetDBTableGUIDLow() );
Mutate(new TargetedMovementGenerator<Player>(*target,dist,angle)); Mutate(new FollowMovementGenerator<Player>(*target,dist,angle));
} }
else else
{ {
@ -310,7 +310,7 @@ MotionMaster::MoveFollow(Unit* target, float dist, float angle)
i_owner->GetEntry(), i_owner->GetGUIDLow(), i_owner->GetEntry(), i_owner->GetGUIDLow(),
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature", target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() ); target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() );
Mutate(new TargetedMovementGenerator<Creature>(*target,dist,angle)); Mutate(new FollowMovementGenerator<Creature>(*target,dist,angle));
} }
} }
@ -470,8 +470,5 @@ bool MotionMaster::GetDestination(float &x, float &y, float &z)
void MotionMaster::UpdateFinalDistanceToTarget(float fDistance) void MotionMaster::UpdateFinalDistanceToTarget(float fDistance)
{ {
if (!empty()) if (!empty())
{
if (top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE)
top()->UpdateFinalDistance(fDistance); top()->UpdateFinalDistance(fDistance);
} }
}

View file

@ -38,7 +38,7 @@ enum MovementGeneratorType
MAX_DB_MOTION_TYPE = 3, // *** this and below motion types can't be set in DB. MAX_DB_MOTION_TYPE = 3, // *** this and below motion types can't be set in DB.
ANIMAL_RANDOM_MOTION_TYPE = MAX_DB_MOTION_TYPE, // Just a dummy ANIMAL_RANDOM_MOTION_TYPE = MAX_DB_MOTION_TYPE, // Just a dummy
CONFUSED_MOTION_TYPE = 4, // ConfusedMovementGenerator.h CONFUSED_MOTION_TYPE = 4, // ConfusedMovementGenerator.h
TARGETED_MOTION_TYPE = 5, // TargetedMovementGenerator.h CHASE_MOTION_TYPE = 5, // TargetedMovementGenerator.h
HOME_MOTION_TYPE = 6, // HomeMovementGenerator.h HOME_MOTION_TYPE = 6, // HomeMovementGenerator.h
FLIGHT_MOTION_TYPE = 7, // WaypointMovementGenerator.h FLIGHT_MOTION_TYPE = 7, // WaypointMovementGenerator.h
POINT_MOTION_TYPE = 8, // PointMovementGenerator.h POINT_MOTION_TYPE = 8, // PointMovementGenerator.h
@ -47,6 +47,7 @@ enum MovementGeneratorType
ASSISTANCE_MOTION_TYPE= 11, // PointMovementGenerator.h (first part of flee for assistance) 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) 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) TIMED_FLEEING_MOTION_TYPE = 13, // FleeingMovementGenerator.h (alt.second part of flee for assistance)
FOLLOW_MOTION_TYPE = 14, // TargetedMovementGenerator.h
}; };
enum MMCleanFlag enum MMCleanFlag

View file

@ -122,7 +122,7 @@ ReactorAI::EnterEvadeMode()
m_creature->CombatStop(true); m_creature->CombatStop(true);
m_creature->SetLootRecipient(NULL); m_creature->SetLootRecipient(NULL);
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead // Remove ChaseMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
if( m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE ) if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
m_creature->GetMotionMaster()->MoveTargetedHome(); m_creature->GetMotionMaster()->MoveTargetedHome();
} }

View file

@ -26,22 +26,10 @@
#define SMALL_ALPHA 0.05f #define SMALL_ALPHA 0.05f
#include <cmath> #include <cmath>
/*
struct StackCleaner
{
Creature &i_creature;
StackCleaner(Creature &creature) : i_creature(creature) {}
void Done(void) { i_creature.StopMoving(); }
~StackCleaner()
{
i_creature->Clear();
}
};
*/
//-----------------------------------------------//
template<class T> template<class T>
void void TargetedMovementGeneratorMedium<T>::_setTargetLocation(T &owner)
TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
{ {
if (!i_target.isValid() || !i_target->IsInWorld()) if (!i_target.isValid() || !i_target->IsInWorld())
return; return;
@ -89,55 +77,26 @@ TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
} }
template<> template<>
void TargetedMovementGenerator<Player>::Initialize(Player &owner) void TargetedMovementGeneratorMedium<Player>::UpdateFinalDistance(float fDistance)
{
_setTargetLocation(owner);
}
template<>
void TargetedMovementGenerator<Creature>::Initialize(Creature &owner)
{
if (owner.isInCombat())
owner.RemoveMonsterMoveFlag(MONSTER_MOVE_WALK);
if (((Creature*)&owner)->canFly())
owner.AddMonsterMoveFlag(MONSTER_MOVE_FLY);
_setTargetLocation(owner);
}
template<>
void TargetedMovementGenerator<Player>::UpdateFinalDistance(float fDistance)
{ {
// nothing to do for Player // nothing to do for Player
} }
template<> template<>
void TargetedMovementGenerator<Creature>::UpdateFinalDistance(float fDistance) void TargetedMovementGeneratorMedium<Creature>::UpdateFinalDistance(float fDistance)
{ {
i_offset = fDistance; i_offset = fDistance;
i_recalculateTravel = true; i_recalculateTravel = true;
} }
template<class T> template<class T>
void TargetedMovementGenerator<T>::Finalize(T &owner) Unit* TargetedMovementGeneratorMedium<T>::GetTarget() const
{ {
owner.clearUnitState(UNIT_STAT_CHASE | UNIT_STAT_FOLLOW); return i_target.getTarget();
} }
template<class T> template<class T>
void TargetedMovementGenerator<T>::Interrupt(T &owner) bool TargetedMovementGeneratorMedium<T>::Update(T &owner, const uint32 & time_diff)
{
}
template<class T>
void TargetedMovementGenerator<T>::Reset(T &owner)
{
Initialize(owner);
}
template<class T>
bool TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
{ {
if (!i_target.isValid() || !i_target->IsInWorld()) if (!i_target.isValid() || !i_target->IsInWorld())
return false; return false;
@ -208,21 +167,90 @@ bool TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
return true; return true;
} }
template<class T> //-----------------------------------------------//
Unit* TargetedMovementGenerator<T>::GetTarget() const template<>
void ChaseMovementGenerator<Player>::Initialize(Player &owner)
{ {
return i_target.getTarget(); _setTargetLocation(owner);
} }
template void TargetedMovementGenerator<Player>::_setTargetLocation(Player &); template<>
template void TargetedMovementGenerator<Creature>::_setTargetLocation(Creature &); void ChaseMovementGenerator<Creature>::Initialize(Creature &owner)
template void TargetedMovementGenerator<Player>::Finalize(Player &); {
template void TargetedMovementGenerator<Creature>::Finalize(Creature &); owner.RemoveMonsterMoveFlag(MONSTER_MOVE_WALK);
template void TargetedMovementGenerator<Player>::Interrupt(Player &);
template void TargetedMovementGenerator<Creature>::Interrupt(Creature &); if (((Creature*)&owner)->canFly())
template void TargetedMovementGenerator<Player>::Reset(Player &); owner.AddMonsterMoveFlag(MONSTER_MOVE_FLY);
template void TargetedMovementGenerator<Creature>::Reset(Creature &);
template bool TargetedMovementGenerator<Player>::Update(Player &, const uint32 &); _setTargetLocation(owner);
template bool TargetedMovementGenerator<Creature>::Update(Creature &, const uint32 &); }
template Unit* TargetedMovementGenerator<Player>::GetTarget() const;
template Unit* TargetedMovementGenerator<Creature>::GetTarget() const; template<class T>
void ChaseMovementGenerator<T>::Finalize(T &owner)
{
owner.clearUnitState(UNIT_STAT_CHASE | UNIT_STAT_FOLLOW);
}
template<class T>
void ChaseMovementGenerator<T>::Interrupt(T &owner)
{
}
template<class T>
void ChaseMovementGenerator<T>::Reset(T &owner)
{
Initialize(owner);
}
//-----------------------------------------------//
template<>
void FollowMovementGenerator<Player>::Initialize(Player &owner)
{
_setTargetLocation(owner);
}
template<>
void FollowMovementGenerator<Creature>::Initialize(Creature &owner)
{
if (((Creature*)&owner)->canFly())
owner.AddMonsterMoveFlag(MONSTER_MOVE_FLY);
_setTargetLocation(owner);
}
template<class T>
void FollowMovementGenerator<T>::Finalize(T &owner)
{
owner.clearUnitState(UNIT_STAT_CHASE | UNIT_STAT_FOLLOW);
}
template<class T>
void FollowMovementGenerator<T>::Interrupt(T &owner)
{
}
template<class T>
void FollowMovementGenerator<T>::Reset(T &owner)
{
Initialize(owner);
}
//-----------------------------------------------//
template Unit* TargetedMovementGeneratorMedium<Player>::GetTarget() const;
template Unit* TargetedMovementGeneratorMedium<Creature>::GetTarget() const;
template bool TargetedMovementGeneratorMedium<Player>::Update(Player &, const uint32 &);
template bool TargetedMovementGeneratorMedium<Creature>::Update(Creature &, const uint32 &);
template void ChaseMovementGenerator<Player>::Finalize(Player &);
template void ChaseMovementGenerator<Creature>::Finalize(Creature &);
template void ChaseMovementGenerator<Player>::Interrupt(Player &);
template void ChaseMovementGenerator<Creature>::Interrupt(Creature &);
template void ChaseMovementGenerator<Player>::Reset(Player &);
template void ChaseMovementGenerator<Creature>::Reset(Creature &);
template void FollowMovementGenerator<Player>::Finalize(Player &);
template void FollowMovementGenerator<Creature>::Finalize(Creature &);
template void FollowMovementGenerator<Player>::Interrupt(Player &);
template void FollowMovementGenerator<Creature>::Interrupt(Creature &);
template void FollowMovementGenerator<Player>::Reset(Player &);
template void FollowMovementGenerator<Creature>::Reset(Creature &);

View file

@ -34,23 +34,24 @@ class MANGOS_DLL_SPEC TargetedMovementGeneratorBase
}; };
template<class T> template<class T>
class MANGOS_DLL_SPEC TargetedMovementGenerator class MANGOS_DLL_SPEC TargetedMovementGeneratorMedium
: public MovementGeneratorMedium< T, TargetedMovementGenerator<T> >, public TargetedMovementGeneratorBase : public MovementGeneratorMedium< T, TargetedMovementGeneratorMedium<T> >, public TargetedMovementGeneratorBase
{ {
public: protected:
TargetedMovementGeneratorMedium() : MovementGeneratorMedium< T, TargetedMovementGeneratorMedium<T> >(), TargetedMovementGeneratorBase() {}
TargetedMovementGenerator(Unit &target) TargetedMovementGeneratorMedium(Unit &target)
: TargetedMovementGeneratorBase(target), i_offset(0), i_angle(0), i_recalculateTravel(false) {} : TargetedMovementGeneratorBase(target), i_offset(0), i_angle(0), i_recalculateTravel(false) {}
TargetedMovementGenerator(Unit &target, float offset, float angle) TargetedMovementGeneratorMedium(Unit &target, float offset, float angle)
: TargetedMovementGeneratorBase(target), i_offset(offset), i_angle(angle), i_recalculateTravel(false) {} : TargetedMovementGeneratorBase(target), i_offset(offset), i_angle(angle), i_recalculateTravel(false) {}
~TargetedMovementGenerator() {} ~TargetedMovementGeneratorMedium() {}
void Initialize(T &); public:
void Finalize(T &); void Initialize(T &) {}
void Interrupt(T &); void Finalize(T &) {}
void Reset(T &); void Interrupt(T &) {}
void Reset(T &) {}
bool Update(T &, const uint32 &); bool Update(T &, const uint32 &);
MovementGeneratorType GetMovementGeneratorType() { return TARGETED_MOTION_TYPE; }
Unit* GetTarget() const; Unit* GetTarget() const;
@ -64,7 +65,7 @@ class MANGOS_DLL_SPEC TargetedMovementGenerator
void unitSpeedChanged() { i_recalculateTravel=true; } void unitSpeedChanged() { i_recalculateTravel=true; }
void UpdateFinalDistance(float fDistance); void UpdateFinalDistance(float fDistance);
private: protected:
void _setTargetLocation(T &); void _setTargetLocation(T &);
@ -73,4 +74,41 @@ class MANGOS_DLL_SPEC TargetedMovementGenerator
DestinationHolder< Traveller<T> > i_destinationHolder; DestinationHolder< Traveller<T> > i_destinationHolder;
bool i_recalculateTravel; bool i_recalculateTravel;
}; };
template<class T>
class MANGOS_DLL_SPEC ChaseMovementGenerator : public TargetedMovementGeneratorMedium<T>
{
public:
ChaseMovementGenerator(Unit &target) : TargetedMovementGeneratorMedium(target) {}
ChaseMovementGenerator(Unit &target, float offset, float angle)
: TargetedMovementGeneratorMedium(target, offset, angle) {}
~ChaseMovementGenerator() {}
MovementGeneratorType GetMovementGeneratorType() { return CHASE_MOTION_TYPE; }
void Initialize(T &);
void Finalize(T &);
void Interrupt(T &);
void Reset(T &);
bool Update(T &, const uint32 &);
};
template<class T>
class MANGOS_DLL_SPEC FollowMovementGenerator : public TargetedMovementGeneratorMedium<T>
{
public:
FollowMovementGenerator(Unit &target) : TargetedMovementGeneratorMedium(target) {}
FollowMovementGenerator(Unit &target, float offset, float angle)
: TargetedMovementGeneratorMedium(target, offset, angle) {}
~FollowMovementGenerator() {}
MovementGeneratorType GetMovementGeneratorType() { return FOLLOW_MOTION_TYPE; }
void Initialize(T &);
void Finalize(T &);
void Interrupt(T &);
void Reset(T &);
bool Update(T &, const uint32 &);
};
#endif #endif

View file

@ -10873,7 +10873,7 @@ bool Unit::SelectHostileTarget()
// it in combat but attacker not make any damage and not enter to aggro radius to have record in threat list // 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 // for example at owner command to pet attack some far away creature
// Note: creature not have targeted movement generator but have attacker in this case // Note: creature not have targeted movement generator but have attacker in this case
if (GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE || hasUnitState(UNIT_STAT_FOLLOW)) if (GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
{ {
for(AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr) for(AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr)
{ {

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "9197" #define REVISION_NR "9198"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__ #ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__ #define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_9136_07_characters_characters" #define REVISION_DB_CHARACTERS "required_9136_07_characters_characters"
#define REVISION_DB_MANGOS "required_9160_02_mangos_spell_chain" #define REVISION_DB_MANGOS "required_9198_01_mangos_mangos_string"
#define REVISION_DB_REALMD "required_9010_01_realmd_realmlist" #define REVISION_DB_REALMD "required_9010_01_realmd_realmlist"
#endif // __REVISION_SQL_H__ #endif // __REVISION_SQL_H__