mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-26 15:00:06 +00:00
Implement instance copying
and make respawn points match the player instance
This commit is contained in:
parent
b87f20e2dc
commit
85530ef57f
@ -171,6 +171,21 @@ std::vector<Chunk*> ChunkManager::getDeltaChunks(std::vector<Chunk*> from, std::
|
|||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* inefficient algorithm to get all chunks from a specific instance
|
||||||
|
*/
|
||||||
|
std::vector<std::tuple<int, int, uint64_t>> ChunkManager::getChunksInMap(uint64_t mapNum) {
|
||||||
|
std::vector<std::tuple<int, int, uint64_t>> chnks;
|
||||||
|
|
||||||
|
for (auto it = ChunkManager::chunks.begin(); it != ChunkManager::chunks.end(); it++) {
|
||||||
|
if (std::get<2>(it->first) == mapNum) {
|
||||||
|
chnks.push_back(it->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return chnks;
|
||||||
|
}
|
||||||
|
|
||||||
bool ChunkManager::inPopulatedChunks(int posX, int posY, uint64_t instanceID) {
|
bool ChunkManager::inPopulatedChunks(int posX, int posY, uint64_t instanceID) {
|
||||||
auto chunk = ChunkManager::grabChunk(posX, posY, instanceID);
|
auto chunk = ChunkManager::grabChunk(posX, posY, instanceID);
|
||||||
auto nearbyChunks = ChunkManager::grabChunks(chunk);
|
auto nearbyChunks = ChunkManager::grabChunks(chunk);
|
||||||
@ -182,3 +197,33 @@ bool ChunkManager::inPopulatedChunks(int posX, int posY, uint64_t instanceID) {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChunkManager::createInstance(uint64_t instanceID) {
|
||||||
|
|
||||||
|
std::vector<std::tuple<int, int, uint64_t>> templateChunks = ChunkManager::getChunksInMap(instanceID & 0xffffffff); // base instance chunks
|
||||||
|
if (ChunkManager::getChunksInMap(instanceID).size() == 0) { // only instantiate if the instance doesn't exist already
|
||||||
|
std::cout << "Creating instance " << instanceID << std::endl;
|
||||||
|
for (std::tuple<int, int, uint64_t> &coords : templateChunks) {
|
||||||
|
for (int npcID : chunks[coords]->NPCs) {
|
||||||
|
// make a copy of each NPC in the template chunks and put them in the new instance
|
||||||
|
int newID = NPCManager::nextId++;
|
||||||
|
BaseNPC* newNPC = new BaseNPC();
|
||||||
|
memcpy(newNPC, NPCManager::NPCs[npcID], sizeof(BaseNPC));
|
||||||
|
newNPC->appearanceData.iNPC_ID = newID;
|
||||||
|
NPCManager::NPCs[newID] = newNPC;
|
||||||
|
NPCManager::updateNPCInstance(newID, instanceID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cout << "Instance " << instanceID << " already exists" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChunkManager::destroyInstance(uint64_t instanceID) {
|
||||||
|
std::cout << "Deleting instance " << instanceID << std::endl;
|
||||||
|
std::vector<std::tuple<int, int, uint64_t>> instanceChunks = ChunkManager::getChunksInMap(instanceID);
|
||||||
|
for (std::tuple<int, int, uint64_t>& coords : instanceChunks) {
|
||||||
|
destroyChunk(coords);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -16,8 +16,8 @@ public:
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
INSTANCE_OVERWORLD, // default instance every player starts in
|
INSTANCE_OVERWORLD, // default instance every player starts in
|
||||||
INSTANCE_IZ, // all infected zones share an instance
|
//INSTANCE_IZ, // all infected zones share an instance
|
||||||
INSTANCE_UNIQUE // fusion lairs are generated as requested (+ uid)
|
//INSTANCE_UNIQUE // fusion lairs are generated as requested (+ uid)
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace ChunkManager {
|
namespace ChunkManager {
|
||||||
@ -35,5 +35,9 @@ namespace ChunkManager {
|
|||||||
std::tuple<int, int, uint64_t> grabChunk(int posX, int posY, uint64_t instanceID);
|
std::tuple<int, int, uint64_t> grabChunk(int posX, int posY, uint64_t instanceID);
|
||||||
std::vector<Chunk*> grabChunks(std::tuple<int, int, uint64_t> chunkPos);
|
std::vector<Chunk*> grabChunks(std::tuple<int, int, uint64_t> chunkPos);
|
||||||
std::vector<Chunk*> getDeltaChunks(std::vector<Chunk*> from, std::vector<Chunk*> to);
|
std::vector<Chunk*> getDeltaChunks(std::vector<Chunk*> from, std::vector<Chunk*> to);
|
||||||
|
std::vector<std::tuple<int, int, uint64_t>> getChunksInMap(uint64_t mapNum);
|
||||||
bool inPopulatedChunks(int posX, int posY, uint64_t instanceID);
|
bool inPopulatedChunks(int posX, int posY, uint64_t instanceID);
|
||||||
|
|
||||||
|
void createInstance(uint64_t);
|
||||||
|
void destroyInstance(uint64_t);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include "MobManager.hpp"
|
#include "MobManager.hpp"
|
||||||
#include "MissionManager.hpp"
|
#include "MissionManager.hpp"
|
||||||
|
#include "ChunkManager.hpp"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -608,8 +609,9 @@ void NPCManager::handleWarp(CNSocket* sock, int32_t warpId) {
|
|||||||
if (Warps[warpId].isInstance)
|
if (Warps[warpId].isInstance)
|
||||||
{
|
{
|
||||||
uint64_t instanceID = Warps[warpId].instanceID;
|
uint64_t instanceID = Warps[warpId].instanceID;
|
||||||
if (false) { // TODO check if instance is unique and make a copy
|
if (Warps[warpId].limitTaskID != 0) { // if warp requires you to be on a mission, it's gotta be a unique instance
|
||||||
instanceID += ((uint64_t)plrv.plr->iIDGroup << 32); // upper 32 bits are leader ID
|
instanceID += ((uint64_t)plrv.plr->iIDGroup << 32); // upper 32 bits are leader ID
|
||||||
|
ChunkManager::createInstance(instanceID);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerManager::sendPlayerTo(sock, Warps[warpId].x, Warps[warpId].y, Warps[warpId].z, instanceID);
|
PlayerManager::sendPlayerTo(sock, Warps[warpId].x, Warps[warpId].y, Warps[warpId].z, instanceID);
|
||||||
|
@ -361,7 +361,7 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) {
|
|||||||
response.PCLoadData2CL.iFirstUseFlag2 = UINT64_MAX;
|
response.PCLoadData2CL.iFirstUseFlag2 = UINT64_MAX;
|
||||||
|
|
||||||
plr.SerialKey = enter->iEnterSerialKey;
|
plr.SerialKey = enter->iEnterSerialKey;
|
||||||
plr.instanceID = INSTANCE_OVERWORLD; // TODO: load this from the database (as long as it's not a unique instance)
|
plr.instanceID = INSTANCE_OVERWORLD; // the player should never be in an instance on enter
|
||||||
|
|
||||||
sock->setEKey(CNSocketEncryption::createNewKey(response.uiSvrTime, response.iID + 1, response.PCLoadData2CL.iFusionMatter + 1));
|
sock->setEKey(CNSocketEncryption::createNewKey(response.uiSvrTime, response.iID + 1, response.PCLoadData2CL.iFusionMatter + 1));
|
||||||
sock->setFEKey(plr.FEKey);
|
sock->setFEKey(plr.FEKey);
|
||||||
@ -929,7 +929,7 @@ WarpLocation PlayerManager::getRespawnPoint(Player *plr) {
|
|||||||
|
|
||||||
for (auto targ : NPCManager::RespawnPoints) {
|
for (auto targ : NPCManager::RespawnPoints) {
|
||||||
curDist = sqrt(pow(plr->x - targ.x, 2) + pow(plr->y - targ.y, 2));
|
curDist = sqrt(pow(plr->x - targ.x, 2) + pow(plr->y - targ.y, 2));
|
||||||
if (curDist < bestDist) {
|
if (curDist < bestDist && targ.instanceID == (plr->instanceID & 0xffffffff)) { // only mapNum needs to match
|
||||||
best = targ;
|
best = targ;
|
||||||
bestDist = curDist;
|
bestDist = curDist;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ void TableData::init() {
|
|||||||
inFile >> npcData;
|
inFile >> npcData;
|
||||||
for (nlohmann::json::iterator _npc = npcData.begin(); _npc != npcData.end(); _npc++) {
|
for (nlohmann::json::iterator _npc = npcData.begin(); _npc != npcData.end(); _npc++) {
|
||||||
auto npc = _npc.value();
|
auto npc = _npc.value();
|
||||||
uint64_t instanceID = npc.find("mapNum") == npc.end() ? INSTANCE_OVERWORLD : (int)npc["mapNum"];
|
int instanceID = npc.find("mapNum") == npc.end() ? INSTANCE_OVERWORLD : (int)npc["mapNum"];
|
||||||
BaseNPC *tmp = new BaseNPC(npc["x"], npc["y"], npc["z"], npc["angle"], instanceID, npc["id"], nextId);
|
BaseNPC *tmp = new BaseNPC(npc["x"], npc["y"], npc["z"], npc["angle"], instanceID, npc["id"], nextId);
|
||||||
|
|
||||||
NPCManager::NPCs[nextId] = tmp;
|
NPCManager::NPCs[nextId] = tmp;
|
||||||
@ -37,7 +37,7 @@ void TableData::init() {
|
|||||||
nextId++;
|
nextId++;
|
||||||
|
|
||||||
if (npc["id"] == 641 || npc["id"] == 642)
|
if (npc["id"] == 641 || npc["id"] == 642)
|
||||||
NPCManager::RespawnPoints.push_back({ npc["x"], npc["y"], ((int)npc["z"]) + RESURRECT_HEIGHT });
|
NPCManager::RespawnPoints.push_back({ npc["x"], npc["y"], ((int)npc["z"]) + RESURRECT_HEIGHT, instanceID });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception& err) {
|
catch (const std::exception& err) {
|
||||||
|
Loading…
Reference in New Issue
Block a user