Only loop NPC movement if the NPC has a looping path assigned

Allows paths to terminate.
Also fixes a bug where follower NPCs sometimes oscillate their positions.
This commit is contained in:
gsemaj 2021-05-09 08:37:36 -04:00
parent e5d9e7217e
commit 6f59001be1
5 changed files with 14 additions and 4 deletions

View File

@ -1119,12 +1119,14 @@ static void pathCommand(std::string full, std::vector<std::string>& args, CNSock
if (args.size() > 3 && args[3] == "r") { // relativity specified
relative = true;
}
// return NPC to home
// return NPC to home and set path to repeat
Transport::NPCQueues.erase(npc->appearanceData.iNPC_ID); // delete transport queue
BaseNPC* home = entry->second[0];
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, home->x, home->y, home->z, npc->instanceID, 0);
npc->disappearFromViewOf(sock);
npc->enterIntoViewOf(sock);
npc->loopingPath = true;
// do lerping magic
entry->second.push_back(home); // temporary end point for loop completion
@ -1162,6 +1164,7 @@ static void pathCommand(std::string full, std::vector<std::string>& args, CNSock
NPCPath finishedPath;
finishedPath.escortTaskID = -1;
finishedPath.isRelative = relative;
finishedPath.isLoop = true;
finishedPath.speed = speed;
finishedPath.points = finalPoints;
finishedPath.targetIDs.push_back(npc->appearanceData.iNPC_ID);

View File

@ -76,6 +76,7 @@ struct EntityRef {
class BaseNPC : public Entity {
public:
sNPCAppearanceData appearanceData = {};
bool loopingPath = false;
BaseNPC(int _X, int _Y, int _Z, int angle, uint64_t iID, int t, int id) { // XXX
x = _X;

View File

@ -320,6 +320,7 @@ static void loadPaths(json& pathData, int32_t* nextId) {
int speed = pathVal.find("iBaseSpeed") == pathVal.end() ? NPC_DEFAULT_SPEED : (int)pathVal["iBaseSpeed"];
int taskID = pathVal.find("iTaskID") == pathVal.end() ? -1 : (int)pathVal["iTaskID"];
bool relative = pathVal.find("bRelative") == pathVal.end() ? false : (bool)pathVal["bRelative"];
bool loop = pathVal.find("bLoop") == pathVal.end() ? true : (bool)pathVal["bLoop"]; // loop by default
// target IDs
for (json::iterator _tID = pathVal["aNPCIDs"].begin(); _tID != pathVal["aNPCIDs"].end(); _tID++)
@ -340,6 +341,7 @@ static void loadPaths(json& pathData, int32_t* nextId) {
pathTemplate.points = pathPoints;
pathTemplate.speed = speed;
pathTemplate.isRelative = relative;
pathTemplate.isLoop = loop;
pathTemplate.escortTaskID = taskID;
Transport::NPCPaths.push_back(pathTemplate);
@ -672,6 +674,7 @@ static void loadGruntworkPre(json& gruntwork, int32_t* nextId) {
int speed = (int)path["iBaseSpeed"];
int taskID = (int)path["iTaskID"];
bool relative = (bool)path["bRelative"];
bool loop = (bool)path["bLoop"];
// target IDs
for (json::iterator _tID = path["aNPCIDs"].begin(); _tID != path["aNPCIDs"].end(); _tID++)
@ -693,6 +696,7 @@ static void loadGruntworkPre(json& gruntwork, int32_t* nextId) {
pathTemplate.speed = speed;
pathTemplate.isRelative = relative;
pathTemplate.escortTaskID = taskID;
pathTemplate.isLoop = loop;
Transport::NPCPaths.push_back(pathTemplate);
TableData::FinishedNPCPaths.push_back(pathTemplate); // keep in gruntwork
@ -1300,6 +1304,7 @@ void TableData::flush() {
pathObj["iTaskID"] = path.escortTaskID;
pathObj["bRelative"] = path.isRelative;
pathObj["aPoints"] = points;
pathObj["bLoop"] = path.isLoop;
// don't write 'null' if there aren't any targets
if(targetIDs.size() > 0)

View File

@ -310,10 +310,9 @@ static void stepNPCPathing() {
}
/*
* Move processed point to the back to maintain cycle, unless this is a
* dynamically calculated mob route.
* If this path should be repeated, move processed point to the back to maintain cycle.
*/
if (!(npc->type == EntityType::MOB && !((Mob*)npc)->staticPath))
if (npc->loopingPath)
queue->push(point);
it++; // go to next entry in map
@ -388,6 +387,7 @@ void Transport::constructPathNPC(int32_t id, NPCPath* path) {
BaseNPC* npc = NPCManager::NPCs[id];
if (npc->type == EntityType::MOB)
((Mob*)(npc))->staticPath = true;
npc->loopingPath = path->isLoop;
// Interpolate
std::vector<Vec3> pathPoints = path->points;

View File

@ -33,6 +33,7 @@ struct NPCPath {
int speed;
int escortTaskID;
bool isRelative;
bool isLoop;
};
namespace Transport {