feat(Core/Movement): port smooth waypoint movement from Cataclysm Preservation Project (#25106)
Co-authored-by: blinkysc <blinkysc@users.noreply.github.com> Co-authored-by: Ovahlord <dreadkiller@gmx.de> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Kitzunu <Kitzunu@users.noreply.github.com>
This commit is contained in:
parent
3da6e30196
commit
4201acddd5
69 changed files with 844 additions and 386 deletions
|
|
@ -148,27 +148,28 @@ void SmartAI::UpdateFollow(const uint32 diff)
|
|||
}
|
||||
}
|
||||
|
||||
WaypointData const* SmartAI::GetNextWayPoint()
|
||||
WaypointNode const* SmartAI::GetNextWayPoint()
|
||||
{
|
||||
if (!mWayPoints || mWayPoints->empty())
|
||||
if (!mWayPoints || mWayPoints->Nodes.empty())
|
||||
return nullptr;
|
||||
|
||||
mCurrentWPID++;
|
||||
auto itr = mWayPoints->find(mCurrentWPID);
|
||||
if (itr != mWayPoints->end())
|
||||
{
|
||||
mLastWP = &(*itr).second;
|
||||
if (mLastWP->id != mCurrentWPID)
|
||||
LOG_ERROR("scripts.ai.sai", "SmartAI::GetNextWayPoint: Got not expected waypoint id {}, expected {}", mLastWP->id, mCurrentWPID);
|
||||
// mCurrentWPID is 1-based for SmartAI escort paths
|
||||
if (mCurrentWPID > mWayPoints->Nodes.size())
|
||||
return nullptr;
|
||||
|
||||
return &(*itr).second;
|
||||
}
|
||||
return nullptr;
|
||||
// Nodes are 0-indexed, mCurrentWPID is 1-based
|
||||
WaypointNode const& node = mWayPoints->Nodes[mCurrentWPID - 1];
|
||||
mLastWP = &node;
|
||||
if (mLastWP->Id != mCurrentWPID)
|
||||
LOG_ERROR("scripts.ai.sai", "SmartAI::GetNextWayPoint: Got not expected waypoint id {}, expected {}", mLastWP->Id, mCurrentWPID);
|
||||
|
||||
return mLastWP;
|
||||
}
|
||||
|
||||
void SmartAI::GenerateWayPointArray(Movement::PointsArray* points)
|
||||
{
|
||||
if (!mWayPoints || mWayPoints->empty())
|
||||
if (!mWayPoints || mWayPoints->Nodes.empty())
|
||||
return;
|
||||
|
||||
// Flying unit, just fill array
|
||||
|
|
@ -177,16 +178,12 @@ void SmartAI::GenerateWayPointArray(Movement::PointsArray* points)
|
|||
// xinef: first point in vector is unit real position
|
||||
points->clear();
|
||||
points->push_back(G3D::Vector3(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()));
|
||||
uint32 wpCounter = mCurrentWPID;
|
||||
auto itr = mWayPoints->find(wpCounter++);
|
||||
do
|
||||
// mCurrentWPID is 1-based
|
||||
for (uint32 i = mCurrentWPID > 0 ? mCurrentWPID - 1 : 0; i < mWayPoints->Nodes.size(); ++i)
|
||||
{
|
||||
WaypointData const& wp = (*itr).second;
|
||||
points->push_back(G3D::Vector3(wp.x, wp.y, wp.z));
|
||||
|
||||
itr = mWayPoints->find(wpCounter++);
|
||||
WaypointNode const& wp = mWayPoints->Nodes[i];
|
||||
points->push_back(G3D::Vector3(wp.X, wp.Y, wp.Z));
|
||||
}
|
||||
while (itr != mWayPoints->end());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -195,15 +192,15 @@ void SmartAI::GenerateWayPointArray(Movement::PointsArray* points)
|
|||
std::vector<G3D::Vector3> pVector;
|
||||
// xinef: first point in vector is unit real position
|
||||
pVector.push_back(G3D::Vector3(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()));
|
||||
uint32 wpCounter = mCurrentWPID;
|
||||
|
||||
uint32 length = (mWayPoints->size() - mCurrentWPID) * size;
|
||||
uint32 startIdx = mCurrentWPID > 0 ? mCurrentWPID - 1 : 0;
|
||||
uint32 length = (uint32)((mWayPoints->Nodes.size() - startIdx) * size);
|
||||
|
||||
uint32 cnt = 0;
|
||||
for (auto itr = mWayPoints->find(wpCounter); itr != mWayPoints->end() && cnt++ <= length; ++itr)
|
||||
for (uint32 i = startIdx; i < mWayPoints->Nodes.size() && cnt++ <= length; ++i)
|
||||
{
|
||||
WaypointData const& wp = (*itr).second;
|
||||
pVector.push_back(G3D::Vector3(wp.x, wp.y, wp.z));
|
||||
WaypointNode const& wp = mWayPoints->Nodes[i];
|
||||
pVector.push_back(G3D::Vector3(wp.X, wp.Y, wp.Z));
|
||||
}
|
||||
|
||||
if (pVector.size() > 2) // more than source + dest
|
||||
|
|
@ -243,10 +240,10 @@ void SmartAI::StartPath(ForcedMovement forcedMovement, uint32 path, bool repeat,
|
|||
return;
|
||||
}
|
||||
|
||||
if (!mWayPoints || mWayPoints->empty())
|
||||
if (!mWayPoints || mWayPoints->Nodes.empty())
|
||||
return;
|
||||
|
||||
if (WaypointData const* wp = GetNextWayPoint())
|
||||
if (WaypointNode const* wp = GetNextWayPoint())
|
||||
{
|
||||
AddEscortState(SMART_ESCORT_ESCORTING);
|
||||
mCanRepeatPath = repeat;
|
||||
|
|
@ -262,7 +259,7 @@ void SmartAI::StartPath(ForcedMovement forcedMovement, uint32 path, bool repeat,
|
|||
GenerateWayPointArray(&pathPoints);
|
||||
|
||||
me->GetMotionMaster()->MoveSplinePath(&pathPoints, mForcedMovement);
|
||||
GetScript()->ProcessEventsFor(SMART_EVENT_ESCORT_START, nullptr, wp->id, GetScript()->GetPathId());
|
||||
GetScript()->ProcessEventsFor(SMART_EVENT_ESCORT_START, nullptr, wp->Id, GetScript()->GetPathId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -321,10 +318,11 @@ void SmartAI::PausePath(uint32 delay, bool forced)
|
|||
me->StopMoving();
|
||||
me->GetMotionMaster()->MoveIdle();//force stop
|
||||
|
||||
auto waypoint = mWayPoints->find(mCurrentWPID);
|
||||
if (waypoint->second.orientation.has_value())
|
||||
if (mCurrentWPID > 0 && mCurrentWPID <= mWayPoints->Nodes.size())
|
||||
{
|
||||
me->SetFacingTo(*waypoint->second.orientation);
|
||||
WaypointNode const& waypoint = mWayPoints->Nodes[mCurrentWPID - 1];
|
||||
if (waypoint.Orientation.has_value())
|
||||
me->SetFacingTo(*waypoint.Orientation);
|
||||
}
|
||||
}
|
||||
GetScript()->ProcessEventsFor(SMART_EVENT_ESCORT_PAUSED, nullptr, mCurrentWPID, GetScript()->GetPathId());
|
||||
|
|
@ -655,7 +653,7 @@ void SmartAI::MovepointReached(uint32 id)
|
|||
|
||||
if (mLastWP)
|
||||
{
|
||||
me->SetPosition(mLastWP->x, mLastWP->y, mLastWP->z, me->GetOrientation());
|
||||
me->SetPosition(mLastWP->X, mLastWP->Y, mLastWP->Z, me->GetOrientation());
|
||||
me->SetHomePosition(me->GetPosition());
|
||||
}
|
||||
|
||||
|
|
@ -1278,6 +1276,32 @@ void SmartAI::PathEndReached(uint32 /*pathId*/)
|
|||
me->LoadPath(0);
|
||||
}
|
||||
|
||||
void SmartAI::WaypointPathStarted(uint32 /*pathId*/)
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void SmartAI::WaypointPathEnded(uint32 nodeId, uint32 pathId)
|
||||
{
|
||||
if (!HasEscortState(SMART_ESCORT_ESCORTING))
|
||||
{
|
||||
GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_ENDED, nullptr, nodeId, pathId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void SmartAI::DistancingEnded()
|
||||
{
|
||||
SetCurrentRangeMode(true, _pendingDistancing);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue