diff --git a/src/NPCManager.cpp b/src/NPCManager.cpp index 71b6b18..4dfeac3 100644 --- a/src/NPCManager.cpp +++ b/src/NPCManager.cpp @@ -177,6 +177,12 @@ void NPCManager::updateNPCPosition(int32_t id, int X, int Y, int Z) { npc->currentChunks = allChunks; } +void NPCManager::updateNPCInstance(int32_t npcID, int instanceID) { + BaseNPC* npc = NPCs[npcID]; + npc->instanceID = instanceID; + updateNPCPosition(npcID, npc->appearanceData.iX, npc->appearanceData.iY, npc->appearanceData.iZ); +} + void NPCManager::sendToViewable(BaseNPC *npc, void *buf, uint32_t type, size_t size) { for (Chunk *chunk : npc->currentChunks) { for (CNSocket *s : chunk->players) { @@ -577,26 +583,29 @@ void NPCManager::npcWarpTimeMachine(CNSocket* sock, CNPacketData* data) { } void NPCManager::handleWarp(CNSocket* sock, int32_t warpId) { + PlayerView& plrv = PlayerManager::players[sock]; // sanity check if (Warps.find(warpId) == Warps.end()) return; - PlayerView& plrv = PlayerManager::players[sock]; - - // send to client - INITSTRUCT(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC, resp); - resp.iX = Warps[warpId].x; - resp.iY = Warps[warpId].y; - resp.iZ = Warps[warpId].z; - resp.iCandy = plrv.plr->money; - resp.eIL = 4; // do not take away any items - - // force player & NPC reload - PlayerManager::removePlayerFromChunks(plrv.currentChunks, sock); - plrv.currentChunks.clear(); - plrv.chunkPos = std::make_tuple(0, 0, plrv.plr->instanceID); - - sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_WARP_USE_NPC_SUCC, sizeof(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC)); + // std::cerr << "Warped to Map Num:" << Warps[warpId].instanceID << " NPC ID " << Warps[warpId].npcID << std::endl; + if (Warps[warpId].isInstance) + { + PlayerManager::sendPlayerTo(sock, Warps[warpId].x, Warps[warpId].y, Warps[warpId].z, Warps[warpId].instanceID); + } + 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 + resp.iX = Warps[warpId].x; + resp.iY = Warps[warpId].y; + resp.iZ = Warps[warpId].z; + resp.iCandy = plrv.plr->money; + resp.eIL = 4; // do not take away any items + PlayerManager::removePlayerFromChunks(plrv.currentChunks, sock); + plrv.currentChunks.clear(); + plrv.plr->instanceID = 0; + sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_WARP_USE_NPC_SUCC, sizeof(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC)); + } } /* diff --git a/src/NPCManager.hpp b/src/NPCManager.hpp index 20ef45f..571b0fc 100644 --- a/src/NPCManager.hpp +++ b/src/NPCManager.hpp @@ -13,7 +13,7 @@ // this should really be called vec3 or something... struct WarpLocation { - int x, y, z; + int x, y, z, instanceID, isInstance, limitTaskID, npcID; }; namespace NPCManager { @@ -29,6 +29,7 @@ namespace NPCManager { void destroyNPC(int32_t); void updateNPCPosition(int32_t, int X, int Y, int Z, int angle); void updateNPCPosition(int32_t, int X, int Y, int Z); + void updateNPCInstance(int32_t, int instanceID); void sendToViewable(BaseNPC* npc, void* buf, uint32_t type, size_t size); diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index 2b3746e..a20e2f6 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -50,7 +50,7 @@ void PlayerManager::addPlayer(CNSocket* key, Player plr) { memcpy(p, &plr, sizeof(Player)); players[key] = PlayerView(); - players[key].chunkPos = std::make_tuple(0, 0, p->instanceID); + players[key].chunkPos = std::make_tuple(0, 0, 0); players[key].currentChunks = std::vector(); players[key].plr = p; players[key].lastHeartbeat = 0; @@ -191,10 +191,10 @@ void PlayerManager::updatePlayerPosition(CNSocket* sock, int X, int Y, int Z) { view.plr->x = X; view.plr->y = Y; view.plr->z = Z; - updatePlayerChunk(sock, X, Y); + updatePlayerChunk(sock, X, Y, view.plr->instanceID); } -void PlayerManager::updatePlayerChunk(CNSocket* sock, int X, int Y) { +void PlayerManager::updatePlayerChunk(CNSocket* sock, int X, int Y,int mapNum) { PlayerView& view = players[sock]; std::tuple newPos = ChunkManager::grabChunk(X, Y, view.plr->instanceID); @@ -223,8 +223,27 @@ void PlayerManager::updatePlayerChunk(CNSocket* sock, int X, int Y) { } void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z, int I) { - getPlayer(sock)->instanceID = I; - sendPlayerTo(sock, X, Y, Z); + PlayerView& plrv = PlayerManager::players[sock]; + Player* plr = plrv.plr; + plr->instanceID = I; + if (I != INSTANCE_OVERWORLD) { + INITSTRUCT(sP_FE2CL_INSTANCE_MAP_INFO, pkt); + pkt.iInstanceMapNum = I; + sock->sendPacket((void*)&pkt, P_FE2CL_INSTANCE_MAP_INFO, sizeof(sP_FE2CL_INSTANCE_MAP_INFO)); + sendPlayerTo(sock, X, Y, Z); + } else { + // annoying but necessary to set the flag back + INITSTRUCT(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC, resp); + resp.iX = X; + resp.iY = Y; + resp.iZ = Z; + resp.iCandy = plrv.plr->money; + resp.eIL = 4; // do not take away any items + PlayerManager::removePlayerFromChunks(plrv.currentChunks, sock); + plrv.currentChunks.clear(); + sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_WARP_USE_NPC_SUCC, sizeof(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC)); + } + } void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z) { diff --git a/src/PlayerManager.hpp b/src/PlayerManager.hpp index 38ce6ae..f30449c 100644 --- a/src/PlayerManager.hpp +++ b/src/PlayerManager.hpp @@ -32,7 +32,7 @@ namespace PlayerManager { void updatePlayerPosition(CNSocket* sock, int X, int Y, int Z); void updatePlayerPosition(CNSocket* sock, int X, int Y, int Z, int angle); - void updatePlayerChunk(CNSocket* sock, int X, int Y); + void updatePlayerChunk(CNSocket* sock, int X, int Y, int instanceID); void sendPlayerTo(CNSocket* sock, int X, int Y, int Z, int I); void sendPlayerTo(CNSocket* sock, int X, int Y, int Z); diff --git a/src/TableData.cpp b/src/TableData.cpp index 5181fc0..e83e5b0 100644 --- a/src/TableData.cpp +++ b/src/TableData.cpp @@ -23,11 +23,19 @@ void TableData::init() { try { std::ifstream inFile(settings::NPCJSON); nlohmann::json npcData; + nlohmann::json nullExample; // read file into json inFile >> npcData; - + int null = 0; for (nlohmann::json::iterator _npc = npcData.begin(); _npc != npcData.end(); _npc++) { + if (npcData[_npc.key()]["mapNum"] == nullExample) + { + npcData[_npc.key()]["mapNum"] = 0; + _npc.value()["mapNum"] = 0; + null = 1; + //return; + } auto npc = _npc.value(); BaseNPC *tmp = new BaseNPC(npc["x"], npc["y"], npc["z"], npc["angle"], INSTANCE_OVERWORLD, npc["id"], nextId); @@ -38,7 +46,13 @@ void TableData::init() { if (npc["id"] == 641 || npc["id"] == 642) NPCManager::RespawnPoints.push_back({ npc["x"], npc["y"], ((int)npc["z"]) + RESURRECT_HEIGHT }); } - + if (null == 1) + { + std::cout << "Updated Json to include Map Num" << std::endl; + std::ofstream outFile(settings::NPCJSON); + outFile << npcData << std::endl; + outFile.close(); + } } catch (const std::exception& err) { std::cerr << "[WARN] Malformed NPCs.json file! Reason:" << err.what() << std::endl; @@ -61,7 +75,7 @@ void TableData::init() { for (nlohmann::json::iterator _warp = warpData.begin(); _warp != warpData.end(); _warp++) { auto warp = _warp.value(); - WarpLocation warpLoc = { warp["m_iToX"], warp["m_iToY"], warp["m_iToZ"] }; + WarpLocation warpLoc = { warp["m_iToX"], warp["m_iToY"], warp["m_iToZ"],warp["m_iToMapNum"],warp["m_iIsInstance"],warp["m_iLimit_TaskID"],warp["m_iNpcNumber"] }; int warpID = warp["m_iWarpNumber"]; NPCManager::Warps[warpID] = warpLoc; } diff --git a/src/TransportManager.cpp b/src/TransportManager.cpp index 69c6290..9b398f9 100644 --- a/src/TransportManager.cpp +++ b/src/TransportManager.cpp @@ -255,7 +255,7 @@ void TransportManager::stepSkywaySystem() { bmstk.iToZ = point.z; it->first->sendPacket((void*)&bmstk, P_FE2CL_PC_BROOMSTICK_MOVE, sizeof(sP_FE2CL_PC_BROOMSTICK_MOVE)); // set player location to point to update viewables - PlayerManager::updatePlayerChunk(it->first, point.x, point.y); + PlayerManager::updatePlayerChunk(it->first, point.x, point.y, plr->instanceID); // send packet to players in view PlayerManager::sendToViewable(it->first, (void*)&bmstk, P_FE2CL_PC_BROOMSTICK_MOVE, sizeof(sP_FE2CL_PC_BROOMSTICK_MOVE));