diff options
-rw-r--r-- | src/server/game/AI/CoreAI/UnitAI.h | 2 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartAI.cpp | 114 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartAI.h | 3 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.h | 15 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/CreatureGroups.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 2 | ||||
-rw-r--r-- | src/server/game/Movement/MotionMaster.cpp | 14 | ||||
-rw-r--r-- | src/server/game/Movement/MotionMaster.h | 4 | ||||
-rw-r--r-- | src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp | 28 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_misc.cpp | 4 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_wp.cpp | 2 |
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 498fd736a41..84684b02c9d 100644 --- a/src/server/game/AI/CoreAI/UnitAI.h +++ b/src/server/game/AI/CoreAI/UnitAI.h @@ -333,8 +333,10 @@ class TC_GAME_API UnitAI // Called when the dialog status between a player and the creature is requested. virtual QuestGiverStatus 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 6ddf7113499..3935591fc73 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(); @@ -539,12 +604,15 @@ void SmartAI::JustAppeared() mRespawnTime = 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; @@ -557,24 +625,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 50a587df900..804cf7ab0d4 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; } @@ -238,7 +240,6 @@ class TC_GAME_API SmartAI : public CreatureAI uint32 mDespawnTime; uint32 mRespawnTime; 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 42c0c126a48..ad93b8f8a19 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -3169,7 +3169,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 ccb0e3dcbe3..bb9ed8527eb 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -284,7 +284,7 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapObject(), m_groupLootTimer(0), m_PlayerDamageReq(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(UI64LIT(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) { @@ -2675,9 +2675,9 @@ bool Creature::LoadCreaturesAddon() if (cainfo->visibilityDistanceType != VisibilityDistanceType::Normal) SetVisibilityDistanceOverride(cainfo->visibilityDistanceType); - //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 853039a20e8..e98a740a398 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -290,11 +290,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; @@ -405,9 +406,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 ed9dce1cb9b..3f6cbd9279c 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.cpp +++ b/src/server/game/Entities/Creature/CreatureGroups.cpp @@ -235,7 +235,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 cfc05a31f23..2e3c994863a 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -10727,15 +10727,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*/) @@ -10743,7 +10744,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 f0e79c36768..bc49df35ca9 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1913,7 +1913,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.AddMovementFlag(f); } diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 07623c3a261..b3d0e45339b 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -153,17 +153,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 d8d2e4e1258..87700c6aec1 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -125,8 +125,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 3feb4bfdb62..e0f310fdbff 100644 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -63,6 +63,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) @@ -94,6 +98,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) { @@ -112,12 +117,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) @@ -139,10 +142,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; @@ -164,6 +168,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; } @@ -171,12 +180,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); @@ -288,6 +295,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 c7563bf298d..b70687f67bb 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -2182,9 +2182,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 69dc1f8c51a..ad3ccf37669 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -270,7 +270,7 @@ public: stmt->setUInt64(0, guidLow); 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)); |