diff --git a/src/ChunkManager.cpp b/src/ChunkManager.cpp index dd689dd..dcb9a1e 100644 --- a/src/ChunkManager.cpp +++ b/src/ChunkManager.cpp @@ -56,6 +56,17 @@ void ChunkManager::removePlayer(std::pair chunkPos, CNSocket* sock) { // TODO: if players and NPCs are empty, free chunk and remove it from surrounding views } +void ChunkManager::removeNPC(std::pair chunkPos, int32_t id) { + if (!checkChunk(chunkPos)) + return; // do nothing if chunk doesn't even exist + + Chunk* chunk = chunks[chunkPos]; + + chunk->NPCs.erase(id); // gone + + // TODO: if players and NPCs are empty, free chunk and remove it from surrounding views +} + bool ChunkManager::checkChunk(std::pair chunk) { return chunks.find(chunk) != chunks.end(); } diff --git a/src/ChunkManager.hpp b/src/ChunkManager.hpp index 3e08ee8..97d061a 100644 --- a/src/ChunkManager.hpp +++ b/src/ChunkManager.hpp @@ -22,6 +22,7 @@ namespace ChunkManager { void addNPC(int posX, int posY, int32_t id); void addPlayer(int posX, int posY, CNSocket* sock); void removePlayer(std::pair chunkPos, CNSocket* sock); + void removeNPC(std::pair chunkPos, int32_t id); bool checkChunk(std::pair chunk); std::pair grabChunk(int posX, int posY); std::vector grabChunks(std::pair chunkPos); diff --git a/src/NPCManager.cpp b/src/NPCManager.cpp index 92039e8..18dec0b 100644 --- a/src/NPCManager.cpp +++ b/src/NPCManager.cpp @@ -121,6 +121,24 @@ void NPCManager::removeNPC(int32_t id) { std::cout << "npc removed!" << std::endl; } +void NPCManager::updateNPCPosition(int32_t id, int X, int Y, int Z) { + BaseNPC* npc = NPCs[id]; + + std::pair oldPos = ChunkManager::grabChunk(npc->appearanceData.iX, npc->appearanceData.iY); + npc->appearanceData.iX = X; + npc->appearanceData.iY = Y; + npc->appearanceData.iZ = Z; + std::pair newPos = ChunkManager::grabChunk(X, Y); + + // nothing to be done + if (newPos == oldPos) + return; + + // pull NPC from old chunk and add to new chunk + ChunkManager::removeNPC(oldPos, npc->appearanceData.iNPC_ID); + ChunkManager::addNPC(X, Y, npc->appearanceData.iNPC_ID); +} + void NPCManager::npcVendorBuy(CNSocket* sock, CNPacketData* data) { if (data->size != sizeof(sP_CL2FE_REQ_PC_VENDOR_ITEM_BUY)) return; // malformed packet diff --git a/src/NPCManager.hpp b/src/NPCManager.hpp index 9373cf3..aee6553 100644 --- a/src/NPCManager.hpp +++ b/src/NPCManager.hpp @@ -22,6 +22,7 @@ namespace NPCManager { void addNPC(std::vector viewableChunks, int32_t); void removeNPC(int32_t); + void updateNPCPosition(int32_t, int X, int Y, int Z); void npcBarkHandler(CNSocket* sock, CNPacketData* data); void npcSummonHandler(CNSocket* sock, CNPacketData* data); diff --git a/src/TableData.cpp b/src/TableData.cpp index fdd2f66..fe9d5d3 100644 --- a/src/TableData.cpp +++ b/src/TableData.cpp @@ -255,19 +255,7 @@ void TableData::constructPath(nlohmann::json::iterator _pathData) { for (_point++; _point != pathPoints.end(); _point++) { point = _point.value(); WarpLocation coords = { point["iX"] , point["iY"] , point["iZ"] }; - // Calculate distance between this point and the last - int dXY = hypot(last.x - coords.x, last.y - coords.y); // XY plane distance - int distanceBetween = hypot(dXY, last.z - coords.z); // total distance - int lerps = distanceBetween / (int)pathData["iMonkeySpeed"]; // integer division to ensure a whole number of in-between points - for (int i = 0; i < lerps; i++) { - WarpLocation lerp; - // lerp math - float frac = (i + 1) * 1.0f / (lerps + 1); - lerp.x = (last.x * (1.0f - frac)) + (coords.x * frac); - lerp.y = (last.y * (1.0f - frac)) + (coords.y * frac); - lerp.z = (last.z * (1.0f - frac)) + (coords.z * frac); - points.push(lerp); // add lerp'd point to the queue - } + TransportManager::lerp(&points, last, coords, pathData["iMonkeySpeed"]); points.push(coords); // add keyframe to the queue last = coords; // update start pos } diff --git a/src/TransportManager.cpp b/src/TransportManager.cpp index 59fa11d..67f97ae 100644 --- a/src/TransportManager.cpp +++ b/src/TransportManager.cpp @@ -4,6 +4,7 @@ #include "TransportManager.hpp" #include +#include std::map TransportManager::Routes; std::map TransportManager::Locations; @@ -26,6 +27,7 @@ void TransportManager::init() { busPoints.push(start); TransportManager::lerp(&busPoints, start, end, 1000); busPoints.push(end); + TransportManager::lerp(&busPoints, end, start, 1000); NPCQueues[bus->appearanceData.iNPC_ID] = busPoints; } @@ -271,10 +273,9 @@ void TransportManager::stepNPCPathing() { int distanceBetween = hypot(dXY, point.z - npc->appearanceData.iZ); // total distance // update NPC location to update viewables - npc->appearanceData.iX = point.x; - npc->appearanceData.iY = point.y; - npc->appearanceData.iZ = point.z; + NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, point.x, point.y, point.z); + // get chunks in view auto chunk = ChunkManager::grabChunk(npc->appearanceData.iX, npc->appearanceData.iY); auto chunks = ChunkManager::grabChunks(chunk); @@ -322,7 +323,7 @@ void TransportManager::stepNPCPathing() { /* * Linearly interpolate between two points and insert the results into a queue. */ -static void TransportManager::lerp(std::queue* queue, WarpLocation start, WarpLocation end, int gapSize) { +void TransportManager::lerp(std::queue* queue, WarpLocation start, WarpLocation end, int gapSize) { int dXY = hypot(end.x - start.x, end.y - start.y); // XY plane distance int distanceBetween = hypot(dXY, end.z - start.z); // total distance int lerps = distanceBetween / gapSize; // integer division to ensure a whole number of in-between points diff --git a/src/TransportManager.hpp b/src/TransportManager.hpp index 9c42b02..0d62a33 100644 --- a/src/TransportManager.hpp +++ b/src/TransportManager.hpp @@ -31,5 +31,5 @@ namespace TransportManager { void stepNPCPathing(); void stepSkywaySystem(); - static void lerp(std::queue*, WarpLocation, WarpLocation, int); + void lerp(std::queue*, WarpLocation, WarpLocation, int); }