Add NPC chunk management + Generalize lerp

This commit is contained in:
Gent 2020-09-23 10:53:06 -04:00
parent 65bd2d120b
commit f2596bfb6a
7 changed files with 38 additions and 18 deletions

View File

@ -56,6 +56,17 @@ void ChunkManager::removePlayer(std::pair<int, int> chunkPos, CNSocket* sock) {
// TODO: if players and NPCs are empty, free chunk and remove it from surrounding views
}
void ChunkManager::removeNPC(std::pair<int, int> 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<int, int> chunk) {
return chunks.find(chunk) != chunks.end();
}

View File

@ -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<int, int> chunkPos, CNSocket* sock);
void removeNPC(std::pair<int, int> chunkPos, int32_t id);
bool checkChunk(std::pair<int, int> chunk);
std::pair<int, int> grabChunk(int posX, int posY);
std::vector<Chunk*> grabChunks(std::pair<int, int> chunkPos);

View File

@ -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<int, int> oldPos = ChunkManager::grabChunk(npc->appearanceData.iX, npc->appearanceData.iY);
npc->appearanceData.iX = X;
npc->appearanceData.iY = Y;
npc->appearanceData.iZ = Z;
std::pair<int, int> 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

View File

@ -22,6 +22,7 @@ namespace NPCManager {
void addNPC(std::vector<Chunk*> 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);

View File

@ -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
}

View File

@ -4,6 +4,7 @@
#include "TransportManager.hpp"
#include <unordered_map>
#include <cmath>
std::map<int32_t, TransportRoute> TransportManager::Routes;
std::map<int32_t, TransportLocation> 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<WarpLocation>* queue, WarpLocation start, WarpLocation end, int gapSize) {
void TransportManager::lerp(std::queue<WarpLocation>* 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

View File

@ -31,5 +31,5 @@ namespace TransportManager {
void stepNPCPathing();
void stepSkywaySystem();
static void lerp(std::queue<WarpLocation>*, WarpLocation, WarpLocation, int);
void lerp(std::queue<WarpLocation>*, WarpLocation, WarpLocation, int);
}