aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp114
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.h3
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp2
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp6
-rw-r--r--src/server/game/Entities/Creature/Creature.h15
-rw-r--r--src/server/game/Entities/Creature/CreatureGroups.cpp2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp9
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
-rw-r--r--src/server/game/Movement/MotionMaster.cpp14
-rw-r--r--src/server/game/Movement/MotionMaster.h4
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp28
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp4
-rw-r--r--src/server/scripts/Commands/cs_wp.cpp2
14 files changed, 142 insertions, 65 deletions
diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h
index 8377f05d8c7..1078c16f8de 100644
--- a/src/server/game/AI/CoreAI/UnitAI.h
+++ b/src/server/game/AI/CoreAI/UnitAI.h
@@ -330,8 +330,10 @@ class TC_GAME_API UnitAI
// Called when the dialog status between a player and the creature is requested.
virtual uint32 GetDialogStatus(Player* /*player*/);
+ virtual void WaypointPathStarted(uint32 /*nodeId*/, uint32 /*pathId*/) { }
virtual void WaypointStarted(uint32 /*nodeId*/, uint32 /*pathId*/) { }
virtual void WaypointReached(uint32 /*nodeId*/, uint32 /*pathId*/) { }
+ virtual void WaypointPathEnded(uint32 /*nodeId*/, uint32 /*pathId*/) { }
private:
UnitAI(UnitAI const& right) = delete;
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 583daea0491..6bff5022b70 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -31,8 +31,8 @@
SmartAI::SmartAI(Creature* creature) : CreatureAI(creature), mIsCharmed(false), mFollowCreditType(0), mFollowArrivedTimer(0), mFollowCredit(0), mFollowArrivedEntry(0), mFollowDist(0.f), mFollowAngle(0.f),
_escortState(SMART_ESCORT_NONE), _escortNPCFlags(0), _escortInvokerCheckTimer(1000), _currentWaypointNode(0), _waypointReached(false), _waypointPauseTimer(0), _waypointPauseForced(false), _repeatWaypointPath(false),
- _OOCReached(false), _waypointPathEnded(false), mRun(true), mEvadeDisabled(false), mCanAutoAttack(true), mCanCombatMove(true), mInvincibilityHpLevel(0), mDespawnTime(0), mDespawnState(0), mJustReset(false),
- mConditionsTimer(0), _gossipReturn(false), mEscortQuestID(0)
+ _OOCReached(false), _waypointPathEnded(false), mRun(true), mEvadeDisabled(false), mCanAutoAttack(true), mCanCombatMove(true), mInvincibilityHpLevel(0), mDespawnTime(0), mDespawnState(0), mConditionsTimer(0),
+ _gossipReturn(false), mEscortQuestID(0)
{
mHasConditions = sConditionMgr->HasConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE, creature->GetEntry());
}
@@ -128,6 +128,17 @@ bool SmartAI::LoadPath(uint32 entry)
void SmartAI::PausePath(uint32 delay, bool forced)
{
+ if (!HasEscortState(SMART_ESCORT_ESCORTING))
+ {
+ me->PauseMovement(delay, MOTION_SLOT_IDLE, forced);
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE)
+ {
+ std::pair<uint32, uint32> waypointInfo = me->GetCurrentWaypointInfo();
+ GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_PAUSED, nullptr, waypointInfo.first, waypointInfo.second);
+ }
+ return;
+ }
+
if (HasEscortState(SMART_ESCORT_PAUSED))
{
TC_LOG_ERROR("misc", "SmartAI::PausePath: Creature entry %u wanted to pause waypoint (current waypoint: %u) movement while already paused, ignoring.", me->GetEntry(), _currentWaypointNode);
@@ -152,6 +163,30 @@ void SmartAI::PausePath(uint32 delay, bool forced)
void SmartAI::StopPath(uint32 DespawnTime, uint32 quest, bool fail)
{
+ if (!HasEscortState(SMART_ESCORT_ESCORTING))
+ {
+ std::pair<uint32, uint32> waypointInfo = { 0, 0 };
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE)
+ waypointInfo = me->GetCurrentWaypointInfo();
+
+ if (mDespawnState != 2)
+ SetDespawnTime(DespawnTime);
+
+ me->GetMotionMaster()->MoveIdle();
+
+ if (waypointInfo.first)
+ GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_STOPPED, nullptr, waypointInfo.first, waypointInfo.second);
+
+ if (!fail)
+ {
+ if (waypointInfo.first)
+ GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_ENDED, nullptr, waypointInfo.first, waypointInfo.second);
+ if (mDespawnState == 1)
+ StartDespawn();
+ }
+ return;
+ }
+
if (quest)
mEscortQuestID = quest;
@@ -263,6 +298,9 @@ void SmartAI::ReturnToLastOOCPos()
void SmartAI::UpdatePath(const uint32 diff)
{
+ if (!HasEscortState(SMART_ESCORT_ESCORTING))
+ return;
+
if (_escortInvokerCheckTimer < diff)
{
if (!IsEscortInvokerInRange())
@@ -384,6 +422,16 @@ bool SmartAI::IsEscortInvokerInRange()
return true;
}
+///@todo move escort related logic
+void SmartAI::WaypointPathStarted(uint32 nodeId, uint32 pathId)
+{
+ if (!HasEscortState(SMART_ESCORT_ESCORTING))
+ {
+ GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_START, nullptr, nodeId, pathId);
+ return;
+ }
+}
+
///@todo Implement new smart event SMART_EVENT_WAYPOINT_STARTED
void SmartAI::WaypointStarted(uint32 /*nodeId*/, uint32 /*pathId*/)
{
@@ -391,6 +439,12 @@ void SmartAI::WaypointStarted(uint32 /*nodeId*/, uint32 /*pathId*/)
void SmartAI::WaypointReached(uint32 nodeId, uint32 pathId)
{
+ if (!HasEscortState(SMART_ESCORT_ESCORTING))
+ {
+ GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_REACHED, nullptr, nodeId, pathId);
+ return;
+ }
+
_currentWaypointNode = nodeId;
GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_REACHED, nullptr, _currentWaypointNode, pathId);
@@ -410,6 +464,16 @@ void SmartAI::WaypointReached(uint32 nodeId, uint32 pathId)
}
}
+///@todo move escort related logic
+void SmartAI::WaypointPathEnded(uint32 nodeId, uint32 pathId)
+{
+ if (!HasEscortState(SMART_ESCORT_ESCORTING))
+ {
+ GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_ENDED, nullptr, nodeId, pathId);
+ return;
+ }
+}
+
void SmartAI::MovementInform(uint32 type, uint32 id)
{
if (type == POINT_MOTION_TYPE && id == SMART_ESCORT_LAST_OOC_POINT)
@@ -443,10 +507,16 @@ void SmartAI::EnterEvadeMode(EvadeReason /*why*/)
me->AddUnitState(UNIT_STATE_EVADE);
- GetScript()->ProcessEventsFor(SMART_EVENT_EVADE);//must be after aura clear so we can cast spells from db
+ GetScript()->ProcessEventsFor(SMART_EVENT_EVADE); // must be after _EnterEvadeMode (spells, auras, ...)
SetRun(mRun);
- if (HasEscortState(SMART_ESCORT_ESCORTING))
+
+ if (Unit* owner = me->GetCharmerOrOwner())
+ {
+ me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ me->ClearUnitState(UNIT_STATE_EVADE);
+ }
+ else if (HasEscortState(SMART_ESCORT_ESCORTING))
{
AddEscortState(SMART_ESCORT_RETURNING);
ReturnToLastOOCPos();
@@ -457,11 +527,6 @@ void SmartAI::EnterEvadeMode(EvadeReason /*why*/)
// evade is not cleared in MoveFollow, so we can't keep it
me->ClearUnitState(UNIT_STATE_EVADE);
}
- else if (Unit* owner = me->GetCharmerOrOwner())
- {
- me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
- me->ClearUnitState(UNIT_STATE_EVADE);
- }
else
me->GetMotionMaster()->MoveTargetedHome();
@@ -538,12 +603,15 @@ void SmartAI::JustAppeared()
mDespawnTime = 0;
mDespawnState = 0;
_escortState = SMART_ESCORT_NONE;
+
me->SetVisible(true);
+
if (me->GetFaction() != me->GetCreatureTemplate()->faction)
me->RestoreFaction();
- mJustReset = true;
- JustReachedHome();
+
+ GetScript()->OnReset();
GetScript()->ProcessEventsFor(SMART_EVENT_RESPAWN);
+
mFollowGuid.Clear(); // do not reset follower on Reset(), we need it after combat evade
mFollowDist = 0;
mFollowAngle = 0;
@@ -556,24 +624,18 @@ void SmartAI::JustAppeared()
void SmartAI::JustReachedHome()
{
GetScript()->OnReset();
+ GetScript()->ProcessEventsFor(SMART_EVENT_REACHED_HOME);
- if (!mJustReset)
+ CreatureGroup* formation = me->GetFormation();
+ if (!formation || formation->getLeader() == me || !formation->isFormed())
{
- GetScript()->ProcessEventsFor(SMART_EVENT_REACHED_HOME);
-
- CreatureGroup* formation = me->GetFormation();
- if (!formation || formation->getLeader() == me || !formation->isFormed())
- {
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == IDLE_MOTION_TYPE && me->GetWaypointPath())
- me->GetMotionMaster()->MovePath(me->GetWaypointPath(), true);
- else
- me->ResumeMovement();
- }
- else if (formation->isFormed())
- me->GetMotionMaster()->MoveIdle(); // wait the order of leader
+ if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_IDLE) != WAYPOINT_MOTION_TYPE && me->GetWaypointPath())
+ me->GetMotionMaster()->MovePath(me->GetWaypointPath(), true);
+ else
+ me->ResumeMovement();
}
-
- mJustReset = false;
+ else if (formation->isFormed())
+ me->GetMotionMaster()->MoveIdle(); // wait the order of leader
}
void SmartAI::EnterCombat(Unit* enemy)
diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h
index 6c6bfc3ed11..d967a7512cc 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.h
+++ b/src/server/game/AI/SmartScripts/SmartAI.h
@@ -68,8 +68,10 @@ class TC_GAME_API SmartAI : public CreatureAI
void StopFollow(bool complete);
bool IsEscortInvokerInRange();
+ void WaypointPathStarted(uint32 nodeId, uint32 pathId) override;
void WaypointStarted(uint32 nodeId, uint32 pathId) override;
void WaypointReached(uint32 nodeId, uint32 pathId) override;
+ void WaypointPathEnded(uint32 nodeId, uint32 pathId) override;
void SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker);
SmartScript* GetScript() { return &mScript; }
@@ -235,7 +237,6 @@ class TC_GAME_API SmartAI : public CreatureAI
uint32 mDespawnTime;
uint32 mDespawnState;
- bool mJustReset;
// Vehicle conditions
bool mHasConditions;
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index b3336a483dd..a27a0596528 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -3041,7 +3041,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
case SMART_EVENT_WAYPOINT_STOPPED:
case SMART_EVENT_WAYPOINT_ENDED:
{
- if (!me || (e.event.waypoint.pointID && var0 != e.event.waypoint.pointID) || (e.event.waypoint.pathID && GetPathId() != e.event.waypoint.pathID))
+ if (!me || (e.event.waypoint.pointID && var0 != e.event.waypoint.pointID) || (e.event.waypoint.pathID && var1 != e.event.waypoint.pathID))
return;
ProcessAction(e, unit);
break;
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 54d1d86a7ae..1501e2f2c5b 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -236,7 +236,7 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapObject(), m_groupLootTimer(0), lootingGroupLowGUID(0), m_PlayerDamageReq(0), m_lootRecipient(), m_lootRecipientGroup(0), _pickpocketLootRestore(0),
m_corpseRemoveTime(0), m_respawnTime(0), m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_boundaryCheckTime(2500), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE),
m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_cannotReachTarget(false), m_cannotReachTimer(0),
- m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_waypointID(0), m_path_id(0),
+ m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), _waypointPathId(0), _currentWaypointNodeInfo(0, 0),
m_formation(nullptr), m_triggerJustAppeared(true), m_respawnCompatibilityMode(false), m_focusSpell(nullptr), m_focusDelay(0), m_shouldReacquireTarget(false), m_suppressedOrientation(0.0f), _lastDamagedTime(0),
_regenerateHealth(true), _regenerateHealthLock(false)
{
@@ -2489,9 +2489,9 @@ bool Creature::LoadCreaturesAddon()
if (cainfo->emote != 0)
SetUInt32Value(UNIT_NPC_EMOTESTATE, cainfo->emote);
- //Load Path
+ // Load Path
if (cainfo->path_id != 0)
- m_path_id = cainfo->path_id;
+ _waypointPathId = cainfo->path_id;
if (!cainfo->auras.empty())
{
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index a76bfbfb280..4a7c3362f30 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -291,11 +291,12 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
void GetTransportHomePosition(float& x, float& y, float& z, float& ori) const { m_transportHomePosition.GetPosition(x, y, z, ori); }
Position const& GetTransportHomePosition() const { return m_transportHomePosition; }
- uint32 GetWaypointPath() const { return m_path_id; }
- void LoadPath(uint32 pathid) { m_path_id = pathid; }
+ uint32 GetWaypointPath() const { return _waypointPathId; }
+ void LoadPath(uint32 pathid) { _waypointPathId = pathid; }
- uint32 GetCurrentWaypointID() const { return m_waypointID; }
- void UpdateWaypointID(uint32 wpID) { m_waypointID = wpID; }
+ // nodeId, pathId
+ std::pair<uint32, uint32> GetCurrentWaypointInfo() const { return _currentWaypointNodeInfo; }
+ void UpdateCurrentWaypointInfo(uint32 nodeId, uint32 pathId) { _currentWaypointNodeInfo = { nodeId, pathId }; }
bool IsReturningHome() const;
@@ -406,9 +407,9 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
void ForcedDespawn(uint32 timeMSToDespawn = 0, Seconds const& forceRespawnTimer = Seconds(0));
bool CheckNoGrayAggroConfig(uint32 playerLevel, uint32 creatureLevel) const; // No aggro from gray creatures
- //WaypointMovementGenerator vars
- uint32 m_waypointID;
- uint32 m_path_id;
+ // Waypoint path
+ uint32 _waypointPathId;
+ std::pair<uint32/*nodeId*/, uint32/*pathId*/> _currentWaypointNodeInfo;
//Formation var
CreatureGroup* m_formation;
diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp
index bdc3f53fec5..4297a745ccc 100644
--- a/src/server/game/Entities/Creature/CreatureGroups.cpp
+++ b/src/server/game/Entities/Creature/CreatureGroups.cpp
@@ -236,7 +236,7 @@ void CreatureGroup::LeaderMoveTo(Position const& destination, uint32 id /*= 0*/,
continue;
if (itr->second->point_1)
- if (m_leader->GetCurrentWaypointID() == itr->second->point_1 - 1 || m_leader->GetCurrentWaypointID() == itr->second->point_2 - 1)
+ if (m_leader->GetCurrentWaypointInfo().first == itr->second->point_1 || m_leader->GetCurrentWaypointInfo().first == itr->second->point_2)
itr->second->follow_angle = float(M_PI) * 2 - itr->second->follow_angle;
float angle = itr->second->follow_angle;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index ffb53507fa4..bd4c71c06e6 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -11406,15 +11406,16 @@ void Unit::StopMoving()
init.Stop();
}
-void Unit::PauseMovement(uint32 timer/* = 0*/, uint8 slot/* = 0*/)
+void Unit::PauseMovement(uint32 timer/* = 0*/, uint8 slot/* = 0*/, bool forced/* = true*/)
{
if (slot >= MAX_MOTION_SLOT)
return;
- if (MovementGenerator* movementGenerator = GetMotionMaster()->GetMotionSlot(slot))
+ if (MovementGenerator* movementGenerator = GetMotionMaster()->GetMotionSlot(MovementSlot(slot)))
movementGenerator->Pause(timer);
- StopMoving();
+ if (forced)
+ StopMoving();
}
void Unit::ResumeMovement(uint32 timer/* = 0*/, uint8 slot/* = 0*/)
@@ -11422,7 +11423,7 @@ void Unit::ResumeMovement(uint32 timer/* = 0*/, uint8 slot/* = 0*/)
if (slot >= MAX_MOTION_SLOT)
return;
- if (MovementGenerator* movementGenerator = GetMotionMaster()->GetMotionSlot(slot))
+ if (MovementGenerator* movementGenerator = GetMotionMaster()->GetMotionSlot(MovementSlot(slot)))
movementGenerator->Resume(timer);
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index e76dcbd84f4..cfe2f840915 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1794,7 +1794,7 @@ class TC_GAME_API Unit : public WorldObject
bool IsStopped() const { return !(HasUnitState(UNIT_STATE_MOVING)); }
void StopMoving();
- void PauseMovement(uint32 timer = 0, uint8 slot = 0); // timer in ms
+ void PauseMovement(uint32 timer = 0, uint8 slot = 0, bool forced = true); // timer in ms
void ResumeMovement(uint32 timer = 0, uint8 slot = 0); // timer in ms
void AddUnitMovementFlag(uint32 f) { m_movementInfo.flags |= f; }
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index b2027144487..3f77e472189 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -155,17 +155,19 @@ MovementGeneratorType MotionMaster::GetCurrentMovementGeneratorType() const
return top()->GetMovementGeneratorType();
}
-MovementGeneratorType MotionMaster::GetMotionSlotType(int slot) const
+MovementGeneratorType MotionMaster::GetMotionSlotType(MovementSlot slot) const
{
- if (!_slot[slot])
+ if (empty() || slot >= MAX_MOTION_SLOT || !_slot[slot])
return MAX_MOTION_TYPE;
- else
- return _slot[slot]->GetMovementGeneratorType();
+
+ return _slot[slot]->GetMovementGeneratorType();
}
-MovementGenerator* MotionMaster::GetMotionSlot(int slot) const
+MovementGenerator* MotionMaster::GetMotionSlot(MovementSlot slot) const
{
- ASSERT(slot >= 0);
+ if (empty() || slot >= MAX_MOTION_SLOT || !_slot[slot])
+ return nullptr;
+
return _slot[slot];
}
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index dcee98cdaaa..d132d8b30d0 100644
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -110,8 +110,8 @@ class TC_GAME_API MotionMaster
void MovementExpired(bool reset = true);
MovementGeneratorType GetCurrentMovementGeneratorType() const;
- MovementGeneratorType GetMotionSlotType(int slot) const;
- MovementGenerator* GetMotionSlot(int slot) const;
+ MovementGeneratorType GetMotionSlotType(MovementSlot slot) const;
+ MovementGenerator* GetMotionSlot(MovementSlot slot) const;
void PropagateSpeedChange();
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
index c772cc055a6..3fba420059e 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
@@ -59,6 +59,10 @@ void WaypointMovementGenerator<Creature>::LoadPath(Creature* creature)
}
_nextMoveTime.Reset(1000);
+
+ // inform AI
+ if (creature->AI())
+ creature->AI()->WaypointPathStarted(1, _path->id);
}
void WaypointMovementGenerator<Creature>::DoInitialize(Creature* creature)
@@ -90,6 +94,7 @@ void WaypointMovementGenerator<Creature>::OnArrived(Creature* creature)
if (!_path || _path->nodes.empty())
return;
+ ASSERT(_currentNode < _path->nodes.size(), "WaypointMovementGenerator::OnArrived: tried to reference a node id (%u) which is not included in path (%u)", _currentNode, _path->id);
WaypointNode const &waypoint = _path->nodes.at(_currentNode);
if (waypoint.delay)
{
@@ -108,12 +113,10 @@ void WaypointMovementGenerator<Creature>::OnArrived(Creature* creature)
if (creature->AI())
{
creature->AI()->MovementInform(WAYPOINT_MOTION_TYPE, _currentNode);
-
- ASSERT(_currentNode < _path->nodes.size(), "WaypointMovementGenerator::OnArrived: tried to reference a node id (%u) which is not included in path (%u)", _currentNode, _path->id);
- creature->AI()->WaypointReached(_path->nodes[_currentNode].id, _path->id);
+ creature->AI()->WaypointReached(waypoint.id, _path->id);
}
- creature->UpdateWaypointID(_currentNode);
+ creature->UpdateCurrentWaypointInfo(waypoint.id, _path->id);
}
bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
@@ -135,10 +138,11 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
if (_isArrivalDone)
{
+ ASSERT(_currentNode < _path->nodes.size(), "WaypointMovementGenerator::StartMove: tried to reference a node id (%u) which is not included in path (%u)", _currentNode, _path->id);
+ WaypointNode const &waypoint = _path->nodes.at(_currentNode);
+
if ((_currentNode == _path->nodes.size() - 1) && !_repeating) // If that's our last waypoint
{
- WaypointNode const &waypoint = _path->nodes.at(_currentNode);
-
float x = waypoint.x;
float y = waypoint.y;
float z = waypoint.z;
@@ -160,6 +164,11 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
// else if (vehicle) - this should never happen, vehicle offsets are const
}
_done = true;
+ creature->UpdateCurrentWaypointInfo(0, 0);
+
+ // inform AI
+ if (creature->AI())
+ creature->AI()->WaypointPathEnded(waypoint.id, _path->id);
return true;
}
@@ -167,12 +176,10 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
// inform AI
if (creature->AI())
- {
- ASSERT(_currentNode < _path->nodes.size(), "WaypointMovementGenerator::StartMove: tried to reference a node id (%u) which is not included in path (%u)", _currentNode, _path->id);
- creature->AI()->WaypointStarted(_path->nodes[_currentNode].id, _path->id);
- }
+ creature->AI()->WaypointStarted(waypoint.id, _path->id);
}
+ ASSERT(_currentNode < _path->nodes.size(), "WaypointMovementGenerator::StartMove: tried to reference a node id (%u) which is not included in path (%u)", _currentNode, _path->id);
WaypointNode const &waypoint = _path->nodes.at(_currentNode);
Position formationDest(waypoint.x, waypoint.y, waypoint.z, (waypoint.orientation && waypoint.delay) ? waypoint.orientation : 0.0f);
@@ -284,6 +291,7 @@ bool WaypointMovementGenerator<Creature>::GetResetPos(Creature*, float& x, float
if (!_path || _path->nodes.empty())
return false;
+ ASSERT(_currentNode < _path->nodes.size(), "WaypointMovementGenerator::GetResetPos: tried to reference a node id (%u) which is not included in path (%u)", _currentNode, _path->id);
WaypointNode const &waypoint = _path->nodes.at(_currentNode);
x = waypoint.x;
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 0b51b8b167c..a830a19bcea 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -2135,9 +2135,9 @@ public:
float x, y, z;
motionMaster->GetDestination(x, y, z);
- for (uint8 i = 0; i < MAX_MOTION_SLOT; ++i)
+ for (uint8 itr = 0; itr < MAX_MOTION_SLOT; ++itr)
{
- MovementGenerator* movementGenerator = motionMaster->GetMotionSlot(i);
+ MovementGenerator* movementGenerator = motionMaster->GetMotionSlot(MovementSlot(itr));
if (!movementGenerator)
{
handler->SendSysMessage("Empty");
diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp
index 609b4bd8918..582cc7b8c79 100644
--- a/src/server/scripts/Commands/cs_wp.cpp
+++ b/src/server/scripts/Commands/cs_wp.cpp
@@ -260,7 +260,7 @@ public:
stmt->setUInt32(0, guildLow);
WorldDatabase.Execute(stmt);
- target->UpdateWaypointID(0);
+ target->UpdateCurrentWaypointInfo(0, 0);
stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE);
stmt->setUInt8(0, uint8(IDLE_MOTION_TYPE));