Core/Misc: waypoint movement
- Creature: update current waypoint to store nodeId and pathId - MotionMaster: change variable type on GetMotionSlotType and GetMotionSlot to keep consistency and prevent errors (ASSERT is now no longer needed) - UnitAI: add new waypoint hooks WaypointPathStarted and WaypointPathEnded - SAI: handle WAYPOINT related events if creature is no escorting * SMART_EVENT_WAYPOINT_RESUMED still not implemented for no escorting TODO: the new hooks can save, now duplicated, logic on EscortAI and SAI closes #20777 updates #20310 updates 21bd52cb99 (cherry picked from commit e10d7dd45cfc073c791cd5e5f3f964d14b37df3d)
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user