mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-26 06:50:06 +00:00
updateNPCPosition now tracks chunks
This commit is contained in:
parent
279cb78d5f
commit
8f84c4c2f8
@ -20,8 +20,6 @@ void ChunkManager::addNPC(int posX, int posY, int32_t id) {
|
|||||||
Chunk* chunk = chunks[pos];
|
Chunk* chunk = chunks[pos];
|
||||||
|
|
||||||
chunk->NPCs.insert(id);
|
chunk->NPCs.insert(id);
|
||||||
|
|
||||||
NPCManager::addNPC(grabChunks(pos), id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChunkManager::addPlayer(int posX, int posY, CNSocket* sock) {
|
void ChunkManager::addPlayer(int posX, int posY, CNSocket* sock) {
|
||||||
|
@ -211,7 +211,7 @@ void MobManager::deadStep(Mob *mob, time_t currTime) {
|
|||||||
// if it was summoned, remove it permanently
|
// if it was summoned, remove it permanently
|
||||||
if (mob->summoned) {
|
if (mob->summoned) {
|
||||||
std::cout << "[INFO] Deallocating killed summoned mob" << std::endl;
|
std::cout << "[INFO] Deallocating killed summoned mob" << std::endl;
|
||||||
NPCManager::removeNPC(mob->appearanceData.iNPC_ID);
|
NPCManager::destroyNPC(mob->appearanceData.iNPC_ID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -279,6 +279,8 @@ void MobManager::combatStep(Mob *mob, time_t currTime) {
|
|||||||
|
|
||||||
auto targ = lerp(mob->appearanceData.iX, mob->appearanceData.iY, mob->target->plr->x, mob->target->plr->y, speed);
|
auto targ = lerp(mob->appearanceData.iX, mob->appearanceData.iY, mob->target->plr->x, mob->target->plr->y, speed);
|
||||||
|
|
||||||
|
NPCManager::updateNPCPosition(mob->appearanceData.iNPC_ID, targ.first, targ.second, mob->appearanceData.iZ);
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_NPC_MOVE, pkt);
|
INITSTRUCT(sP_FE2CL_NPC_MOVE, pkt);
|
||||||
|
|
||||||
pkt.iNPC_ID = mob->appearanceData.iNPC_ID;
|
pkt.iNPC_ID = mob->appearanceData.iNPC_ID;
|
||||||
@ -330,6 +332,8 @@ void MobManager::roamingStep(Mob *mob, time_t currTime) {
|
|||||||
|
|
||||||
auto targ = lerp(mob->appearanceData.iX, mob->appearanceData.iY, farX, farY, speed);
|
auto targ = lerp(mob->appearanceData.iX, mob->appearanceData.iY, farX, farY, speed);
|
||||||
|
|
||||||
|
NPCManager::updateNPCPosition(mob->appearanceData.iNPC_ID, targ.first, targ.second, mob->appearanceData.iZ);
|
||||||
|
|
||||||
pkt.iNPC_ID = mob->appearanceData.iNPC_ID;
|
pkt.iNPC_ID = mob->appearanceData.iNPC_ID;
|
||||||
pkt.iSpeed = speed;
|
pkt.iSpeed = speed;
|
||||||
pkt.iToX = mob->appearanceData.iX = targ.first;
|
pkt.iToX = mob->appearanceData.iX = targ.first;
|
||||||
|
@ -38,6 +38,38 @@ void NPCManager::init() {
|
|||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_ITEM_COMBINATION, npcCombineItems);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_ITEM_COMBINATION, npcCombineItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NPCManager::removeNPC(std::vector<Chunk*> viewableChunks, int32_t id) {
|
||||||
|
BaseNPC* npc = NPCs[id];
|
||||||
|
|
||||||
|
switch (npc->npcClass) {
|
||||||
|
case NPC_BUS:
|
||||||
|
INITSTRUCT(sP_FE2CL_TRANSPORTATION_EXIT, exitBusData);
|
||||||
|
exitBusData.eTT = 3;
|
||||||
|
exitBusData.iT_ID = id;
|
||||||
|
|
||||||
|
for (Chunk* chunk : viewableChunks) {
|
||||||
|
for (CNSocket* sock : chunk->players) {
|
||||||
|
// send to socket
|
||||||
|
sock->sendPacket((void*)&exitBusData, P_FE2CL_TRANSPORTATION_EXIT, sizeof(sP_FE2CL_TRANSPORTATION_EXIT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// create struct
|
||||||
|
INITSTRUCT(sP_FE2CL_NPC_EXIT, exitData);
|
||||||
|
exitData.iNPC_ID = id;
|
||||||
|
|
||||||
|
// remove it from the clients
|
||||||
|
for (Chunk* chunk : viewableChunks) {
|
||||||
|
for (CNSocket* sock : chunk->players) {
|
||||||
|
// send to socket
|
||||||
|
sock->sendPacket((void*)&exitData, P_FE2CL_NPC_EXIT, sizeof(sP_FE2CL_NPC_EXIT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NPCManager::addNPC(std::vector<Chunk*> viewableChunks, int32_t id) {
|
void NPCManager::addNPC(std::vector<Chunk*> viewableChunks, int32_t id) {
|
||||||
BaseNPC* npc = NPCs[id];
|
BaseNPC* npc = NPCs[id];
|
||||||
|
|
||||||
@ -68,7 +100,7 @@ void NPCManager::addNPC(std::vector<Chunk*> viewableChunks, int32_t id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPCManager::removeNPC(int32_t id) {
|
void NPCManager::destroyNPC(int32_t id) {
|
||||||
// sanity check
|
// sanity check
|
||||||
if (NPCs.find(id) == NPCs.end()) {
|
if (NPCs.find(id) == NPCs.end()) {
|
||||||
std::cout << "npc not found : " << id << std::endl;
|
std::cout << "npc not found : " << id << std::endl;
|
||||||
@ -77,50 +109,22 @@ void NPCManager::removeNPC(int32_t id) {
|
|||||||
|
|
||||||
BaseNPC* entity = NPCs[id];
|
BaseNPC* entity = NPCs[id];
|
||||||
|
|
||||||
std::pair<int, int> pos = ChunkManager::grabChunk(entity->appearanceData.iX, entity->appearanceData.iY);
|
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (ChunkManager::chunks.find(pos) == ChunkManager::chunks.end()) {
|
if (ChunkManager::chunks.find(entity->chunkPos) == ChunkManager::chunks.end()) {
|
||||||
std::cout << "chunk not found!" << std::endl;
|
std::cout << "chunk not found!" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove NPC from the chunk
|
// remove NPC from the chunk
|
||||||
Chunk* chunk = ChunkManager::chunks[pos];
|
Chunk* chunk = ChunkManager::chunks[entity->chunkPos];
|
||||||
chunk->NPCs.erase(id);
|
chunk->NPCs.erase(id);
|
||||||
|
|
||||||
switch (entity->npcClass) {
|
// remove from viewable chunks
|
||||||
case NPC_BUS:
|
removeNPC(entity->currentChunks, id);
|
||||||
INITSTRUCT(sP_FE2CL_TRANSPORTATION_EXIT, exitBusData);
|
|
||||||
exitBusData.eTT = 3;
|
|
||||||
exitBusData.iT_ID = id;
|
|
||||||
|
|
||||||
for (Chunk* chunk : ChunkManager::grabChunks(pos)) {
|
// remove from mob manager
|
||||||
for (CNSocket* sock : chunk->players) {
|
|
||||||
// send to socket
|
|
||||||
sock->sendPacket((void*)&exitBusData, P_FE2CL_TRANSPORTATION_EXIT, sizeof(sP_FE2CL_TRANSPORTATION_EXIT));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NPC_MOB:
|
|
||||||
// remove from mob list if it's a mob
|
|
||||||
if (MobManager::Mobs.find(id) != MobManager::Mobs.end())
|
if (MobManager::Mobs.find(id) != MobManager::Mobs.end())
|
||||||
MobManager::Mobs.erase(id);
|
MobManager::Mobs.erase(id);
|
||||||
// fall through
|
|
||||||
default:
|
|
||||||
// create struct
|
|
||||||
INITSTRUCT(sP_FE2CL_NPC_EXIT, exitData);
|
|
||||||
exitData.iNPC_ID = id;
|
|
||||||
|
|
||||||
// remove it from the clients
|
|
||||||
for (Chunk* chunk : ChunkManager::grabChunks(pos)) {
|
|
||||||
for (CNSocket* sock : chunk->players) {
|
|
||||||
// send to socket
|
|
||||||
sock->sendPacket((void*)&exitData, P_FE2CL_NPC_EXIT, sizeof(sP_FE2CL_NPC_EXIT));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// finally, remove it from the map and free it
|
// finally, remove it from the map and free it
|
||||||
NPCs.erase(id);
|
NPCs.erase(id);
|
||||||
@ -132,19 +136,31 @@ void NPCManager::removeNPC(int32_t id) {
|
|||||||
void NPCManager::updateNPCPosition(int32_t id, int X, int Y, int Z) {
|
void NPCManager::updateNPCPosition(int32_t id, int X, int Y, int Z) {
|
||||||
BaseNPC* npc = NPCs[id];
|
BaseNPC* npc = NPCs[id];
|
||||||
|
|
||||||
std::pair<int, int> oldPos = ChunkManager::grabChunk(npc->appearanceData.iX, npc->appearanceData.iY);
|
|
||||||
npc->appearanceData.iX = X;
|
npc->appearanceData.iX = X;
|
||||||
npc->appearanceData.iY = Y;
|
npc->appearanceData.iY = Y;
|
||||||
npc->appearanceData.iZ = Z;
|
npc->appearanceData.iZ = Z;
|
||||||
std::pair<int, int> newPos = ChunkManager::grabChunk(X, Y);
|
std::pair<int, int> newPos = ChunkManager::grabChunk(X, Y);
|
||||||
|
|
||||||
// nothing to be done
|
// nothing to be done (but we should also update currentChunks to add/remove stale chunks)
|
||||||
if (newPos == oldPos)
|
if (newPos == npc->chunkPos) {
|
||||||
|
npc->currentChunks = ChunkManager::grabChunks(newPos);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// pull NPC from old chunk and add to new chunk
|
std::vector<Chunk*> allChunks = ChunkManager::grabChunks(newPos);
|
||||||
ChunkManager::removeNPC(oldPos, npc->appearanceData.iNPC_ID);
|
|
||||||
ChunkManager::addNPC(X, Y, npc->appearanceData.iNPC_ID);
|
// send npc exit to stale chunks
|
||||||
|
removeNPC(ChunkManager::getDeltaChunks(npc->currentChunks, allChunks), id);
|
||||||
|
|
||||||
|
// send npc enter to new chunks
|
||||||
|
addNPC(ChunkManager::getDeltaChunks(allChunks, npc->currentChunks), id);
|
||||||
|
|
||||||
|
// update chunks
|
||||||
|
ChunkManager::removeNPC(npc->chunkPos, id);
|
||||||
|
ChunkManager::addNPC(X, Y, id);
|
||||||
|
|
||||||
|
npc->chunkPos = newPos;
|
||||||
|
npc->currentChunks = allChunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPCManager::sendToViewable(BaseNPC *npc, void *buf, uint32_t type, size_t size) {
|
void NPCManager::sendToViewable(BaseNPC *npc, void *buf, uint32_t type, size_t size) {
|
||||||
@ -482,7 +498,7 @@ void NPCManager::npcUnsummonHandler(CNSocket* sock, CNPacketData* data) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
sP_CL2FE_REQ_NPC_UNSUMMON* req = (sP_CL2FE_REQ_NPC_UNSUMMON*)data->buf;
|
sP_CL2FE_REQ_NPC_UNSUMMON* req = (sP_CL2FE_REQ_NPC_UNSUMMON*)data->buf;
|
||||||
NPCManager::removeNPC(req->iNPC_ID);
|
NPCManager::destroyNPC(req->iNPC_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPCManager::npcSummonHandler(CNSocket* sock, CNPacketData* data) {
|
void NPCManager::npcSummonHandler(CNSocket* sock, CNPacketData* data) {
|
||||||
@ -513,6 +529,7 @@ void NPCManager::npcSummonHandler(CNSocket* sock, CNPacketData* data) {
|
|||||||
} else
|
} else
|
||||||
NPCs[resp.NPCAppearanceData.iNPC_ID] = new BaseNPC(plr->x, plr->y, plr->z, req->iNPCType, resp.NPCAppearanceData.iNPC_ID);
|
NPCs[resp.NPCAppearanceData.iNPC_ID] = new BaseNPC(plr->x, plr->y, plr->z, req->iNPCType, resp.NPCAppearanceData.iNPC_ID);
|
||||||
|
|
||||||
|
updateNPCPosition(resp.NPCAppearanceData.iNPC_ID, plr->x, plr->y, plr->z);
|
||||||
ChunkManager::addNPC(plr->x, plr->y, resp.NPCAppearanceData.iNPC_ID);
|
ChunkManager::addNPC(plr->x, plr->y, resp.NPCAppearanceData.iNPC_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,8 +24,9 @@ namespace NPCManager {
|
|||||||
extern int32_t nextId;
|
extern int32_t nextId;
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
void addNPC(std::vector<Chunk*> viewableChunks, int32_t);
|
void addNPC(std::vector<Chunk*> viewableChunks, int32_t id);
|
||||||
void removeNPC(int32_t);
|
void removeNPC(std::vector<Chunk*> viewableChunks, int32_t id);
|
||||||
|
void destroyNPC(int32_t);
|
||||||
void updateNPCPosition(int32_t, int X, int Y, int Z);
|
void updateNPCPosition(int32_t, int X, int Y, int Z);
|
||||||
|
|
||||||
void sendToViewable(BaseNPC* npc, void* buf, uint32_t type, size_t size);
|
void sendToViewable(BaseNPC* npc, void* buf, uint32_t type, size_t size);
|
||||||
|
@ -27,7 +27,7 @@ void TableData::init() {
|
|||||||
BaseNPC *tmp = new BaseNPC(npc["x"], npc["y"], npc["z"], npc["id"], nextId);
|
BaseNPC *tmp = new BaseNPC(npc["x"], npc["y"], npc["z"], npc["id"], nextId);
|
||||||
|
|
||||||
NPCManager::NPCs[nextId] = tmp;
|
NPCManager::NPCs[nextId] = tmp;
|
||||||
ChunkManager::addNPC(npc["x"], npc["y"], nextId);
|
NPCManager::updateNPCPosition(nextId, npc["x"], npc["y"], npc["z"]);
|
||||||
nextId++;
|
nextId++;
|
||||||
|
|
||||||
if (npc["id"] == 641 || npc["id"] == 642)
|
if (npc["id"] == 641 || npc["id"] == 642)
|
||||||
@ -172,7 +172,7 @@ void TableData::init() {
|
|||||||
|
|
||||||
NPCManager::NPCs[nextId] = tmp;
|
NPCManager::NPCs[nextId] = tmp;
|
||||||
MobManager::Mobs[nextId] = (Mob*)NPCManager::NPCs[nextId];
|
MobManager::Mobs[nextId] = (Mob*)NPCManager::NPCs[nextId];
|
||||||
ChunkManager::addNPC(npc["iX"], npc["iY"], nextId);
|
NPCManager::updateNPCPosition(nextId, npc["iX"], npc["iY"], npc["iZ"]);
|
||||||
|
|
||||||
nextId++;
|
nextId++;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user