Instance Stuff

custom instance commands
warping takes you into instances
npcs show up only in the instance they are supposed to be inside.
This commit is contained in:
Zenpock 2020-10-02 15:17:24 -05:00 committed by Gent
parent 5a80c53e79
commit bd34bb294c
6 changed files with 70 additions and 27 deletions

View File

@ -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,27 +583,30 @@ 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);
// 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
// force player & NPC reload
PlayerManager::removePlayerFromChunks(plrv.currentChunks, sock);
plrv.currentChunks.clear();
plrv.chunkPos = std::make_tuple(0, 0, plrv.plr->instanceID);
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));
}
}
/*
* Helper function to get NPC closest to coordinates in specified chunks

View File

@ -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);

View File

@ -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<Chunk*>();
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<int, int, int> 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;
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) {

View File

@ -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);

View File

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

View File

@ -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));