mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2025-11-06 03:10:22 +00:00
Experimental chunk refactor.
This commit is contained in:
@@ -54,90 +54,6 @@ void NPCManager::init() {
|
||||
REGISTER_SHARD_TIMER(eggStep, 1000);
|
||||
}
|
||||
|
||||
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;
|
||||
case NPC_EGG:
|
||||
INITSTRUCT(sP_FE2CL_SHINY_EXIT, exitEggData);
|
||||
exitEggData.iShinyID = id;
|
||||
|
||||
for (Chunk* chunk : viewableChunks) {
|
||||
for (CNSocket* sock : chunk->players) {
|
||||
// send to socket
|
||||
sock->sendPacket((void*)&exitEggData, P_FE2CL_SHINY_EXIT, sizeof(sP_FE2CL_SHINY_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) {
|
||||
BaseNPC* npc = NPCs[id];
|
||||
|
||||
switch (npc->npcClass) {
|
||||
case NPC_BUS:
|
||||
INITSTRUCT(sP_FE2CL_TRANSPORTATION_ENTER, enterBusData);
|
||||
enterBusData.AppearanceData = { 3, npc->appearanceData.iNPC_ID, npc->appearanceData.iNPCType, npc->appearanceData.iX, npc->appearanceData.iY, npc->appearanceData.iZ };
|
||||
|
||||
for (Chunk* chunk : viewableChunks) {
|
||||
for (CNSocket* sock : chunk->players) {
|
||||
// send to socket
|
||||
sock->sendPacket((void*)&enterBusData, P_FE2CL_TRANSPORTATION_ENTER, sizeof(sP_FE2CL_TRANSPORTATION_ENTER));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NPC_EGG:
|
||||
INITSTRUCT(sP_FE2CL_SHINY_ENTER, enterEggData);
|
||||
npcDataToEggData(&npc->appearanceData, &enterEggData.ShinyAppearanceData);
|
||||
|
||||
for (Chunk* chunk : viewableChunks) {
|
||||
for (CNSocket* sock : chunk->players) {
|
||||
// send to socket
|
||||
sock->sendPacket((void*)&enterEggData, P_FE2CL_SHINY_ENTER, sizeof(sP_FE2CL_SHINY_ENTER));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// create struct
|
||||
INITSTRUCT(sP_FE2CL_NPC_ENTER, enterData);
|
||||
enterData.NPCAppearanceData = npc->appearanceData;
|
||||
|
||||
for (Chunk* chunk : viewableChunks) {
|
||||
for (CNSocket* sock : chunk->players) {
|
||||
// send to socket
|
||||
sock->sendPacket((void*)&enterData, P_FE2CL_NPC_ENTER, sizeof(sP_FE2CL_NPC_ENTER));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NPCManager::destroyNPC(int32_t id) {
|
||||
// sanity check
|
||||
if (NPCs.find(id) == NPCs.end()) {
|
||||
@@ -146,19 +62,19 @@ void NPCManager::destroyNPC(int32_t id) {
|
||||
}
|
||||
|
||||
BaseNPC* entity = NPCs[id];
|
||||
ChunkPos chunkPos = ChunkManager::chunkPosAt(entity->appearanceData.iX, entity->appearanceData.iY, entity->instanceID);
|
||||
|
||||
// sanity check
|
||||
if (ChunkManager::chunks.find(entity->chunkPos) == ChunkManager::chunks.end()) {
|
||||
if (!ChunkManager::chunkExists(chunkPos)) {
|
||||
std::cout << "chunk not found!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// remove NPC from the chunk
|
||||
Chunk* chunk = ChunkManager::chunks[entity->chunkPos];
|
||||
chunk->NPCs.erase(id);
|
||||
ChunkManager::untrackNPC(chunkPos, id);
|
||||
|
||||
// remove from viewable chunks
|
||||
removeNPC(entity->currentChunks, id);
|
||||
ChunkManager::removeNPCFromChunks(ChunkManager::getViewableChunks(chunkPos), id);
|
||||
|
||||
// remove from mob manager
|
||||
if (MobManager::Mobs.find(id) != MobManager::Mobs.end())
|
||||
@@ -173,58 +89,23 @@ void NPCManager::destroyNPC(int32_t id) {
|
||||
delete entity;
|
||||
}
|
||||
|
||||
void NPCManager::updateNPCPosition(int32_t id, int X, int Y, int Z, int angle) {
|
||||
NPCs[id]->appearanceData.iAngle = angle;
|
||||
updateNPCPosition(id, X, Y, Z);
|
||||
}
|
||||
|
||||
void NPCManager::updateNPCPosition(int32_t id, int X, int Y, int Z) {
|
||||
void NPCManager::updateNPCPosition(int32_t id, int X, int Y, int Z, uint64_t I, int angle) {
|
||||
BaseNPC* npc = NPCs[id];
|
||||
|
||||
npc->appearanceData.iAngle = angle;
|
||||
ChunkPos oldChunk = ChunkManager::chunkPosAt(npc->appearanceData.iX, npc->appearanceData.iY, npc->instanceID);
|
||||
ChunkPos newChunk = ChunkManager::chunkPosAt(X, Y, I);
|
||||
npc->appearanceData.iX = X;
|
||||
npc->appearanceData.iY = Y;
|
||||
npc->appearanceData.iZ = Z;
|
||||
|
||||
ChunkPos newPos = ChunkManager::grabChunk(X, Y, npc->instanceID);
|
||||
|
||||
// nothing to be done (but we should also update currentChunks to add/remove stale chunks)
|
||||
if (newPos == npc->chunkPos) {
|
||||
npc->currentChunks = ChunkManager::grabChunks(newPos);
|
||||
return;
|
||||
}
|
||||
|
||||
ChunkManager::addNPC(X, Y, npc->instanceID, id);
|
||||
std::vector<Chunk*> allChunks = ChunkManager::grabChunks(newPos);
|
||||
|
||||
// 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);
|
||||
|
||||
Chunk *chunk = nullptr;
|
||||
if (ChunkManager::checkChunk(npc->chunkPos))
|
||||
chunk = ChunkManager::chunks[npc->chunkPos];
|
||||
|
||||
if (ChunkManager::removeNPC(npc->chunkPos, id)) {
|
||||
// if the old chunk was deallocated, remove it
|
||||
allChunks.erase(std::remove(allChunks.begin(), allChunks.end(), chunk), allChunks.end());
|
||||
}
|
||||
|
||||
|
||||
|
||||
npc->chunkPos = newPos;
|
||||
npc->currentChunks = allChunks;
|
||||
}
|
||||
|
||||
void NPCManager::updateNPCInstance(int32_t npcID, uint64_t instanceID) {
|
||||
BaseNPC* npc = NPCs[npcID];
|
||||
npc->instanceID = instanceID;
|
||||
updateNPCPosition(npcID, npc->appearanceData.iX, npc->appearanceData.iY, npc->appearanceData.iZ);
|
||||
npc->instanceID = I;
|
||||
if (oldChunk == newChunk)
|
||||
return; // didn't change chunks
|
||||
ChunkManager::updateNPCChunk(id, oldChunk, newChunk);
|
||||
}
|
||||
|
||||
void NPCManager::sendToViewable(BaseNPC *npc, void *buf, uint32_t type, size_t size) {
|
||||
for (Chunk *chunk : npc->currentChunks) {
|
||||
std::set<Chunk*> chunks = ChunkManager::getViewableChunks(ChunkManager::chunkPosAt(npc->appearanceData.iX, npc->appearanceData.iY, npc->instanceID));
|
||||
for (Chunk *chunk : chunks) {
|
||||
for (CNSocket *s : chunk->players) {
|
||||
s->sendPacket(buf, type, size);
|
||||
}
|
||||
@@ -602,7 +483,9 @@ void NPCManager::npcSummonHandler(CNSocket* sock, CNPacketData* data) {
|
||||
} else
|
||||
NPCs[id] = new BaseNPC(plr->x, plr->y, plr->z, 0, plr->instanceID, req->iNPCType, id);
|
||||
|
||||
updateNPCPosition(id, plr->x, plr->y, plr->z);
|
||||
updateNPCPosition(id, plr->x, plr->y, plr->z, plr->instanceID, 0);
|
||||
// force chunk update
|
||||
ChunkManager::updateNPCChunk(id, { 0, 0, 0 }, ChunkManager::chunkPosAt(plr->x, plr->y, plr->instanceID));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -655,16 +538,15 @@ void NPCManager::handleWarp(CNSocket* sock, int32_t warpId) {
|
||||
}
|
||||
else
|
||||
{
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC, resp); //Can only be used for exiting instances because it sets the instance flag to false
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC, resp); // Can only be used for exiting instances because it sets the instance flag to false
|
||||
resp.iX = Warps[warpId].x;
|
||||
resp.iY = Warps[warpId].y;
|
||||
resp.iZ = Warps[warpId].z;
|
||||
resp.iCandy = plr->money;
|
||||
resp.eIL = 4; // do not take away any items
|
||||
PlayerManager::removePlayerFromChunks(*plr->currentChunks, sock);
|
||||
plr->currentChunks->clear();
|
||||
plr->instanceID = INSTANCE_OVERWORLD;
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_WARP_USE_NPC_SUCC, sizeof(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC));
|
||||
PlayerManager::updatePlayerPosition(sock, resp.iX, resp.iY, resp.iZ, INSTANCE_OVERWORLD, plr->angle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -844,7 +726,9 @@ void NPCManager::eggStep(CNServer* serv, time_t currTime) {
|
||||
egg.second->dead = false;
|
||||
egg.second->deadUntil = 0;
|
||||
egg.second->appearanceData.iHP = 400;
|
||||
addNPC(egg.second->currentChunks, egg.first);
|
||||
|
||||
ChunkManager::addNPCToChunks(ChunkManager::getViewableChunks(ChunkManager::chunkPosAt(egg.second->appearanceData.iX, egg.second->appearanceData.iY, egg.second->instanceID)),
|
||||
egg.first);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1012,7 +896,8 @@ void NPCManager::eggPickup(CNSocket* sock, CNPacketData* data) {
|
||||
if (egg->summoned)
|
||||
destroyNPC(eggId);
|
||||
else {
|
||||
removeNPC(egg->currentChunks, eggId);
|
||||
ChunkManager::removeNPCFromChunks(ChunkManager::getViewableChunks(ChunkManager::chunkPosAt(egg->appearanceData.iX, egg->appearanceData.iY, egg->instanceID)),
|
||||
eggId);
|
||||
egg->dead = true;
|
||||
egg->deadUntil = getTime() + (time_t)type->regen * 1000;
|
||||
egg->appearanceData.iHP = 0;
|
||||
|
||||
Reference in New Issue
Block a user