mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-12-23 11:50:04 +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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
auto chunk = ChunkManager::grabChunk(posX, posY, instanceID);
|
||||
auto nearbyChunks = ChunkManager::grabChunks(chunk);
|
||||
@ -182,3 +197,33 @@ bool ChunkManager::inPopulatedChunks(int posX, int posY, uint64_t instanceID) {
|
||||
|
||||
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 {
|
||||
INSTANCE_OVERWORLD, // default instance every player starts in
|
||||
INSTANCE_IZ, // all infected zones share an instance
|
||||
INSTANCE_UNIQUE // fusion lairs are generated as requested (+ uid)
|
||||
//INSTANCE_IZ, // all infected zones share an instance
|
||||
//INSTANCE_UNIQUE // fusion lairs are generated as requested (+ uid)
|
||||
};
|
||||
|
||||
namespace ChunkManager {
|
||||
@ -35,5 +35,9 @@ namespace ChunkManager {
|
||||
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*> 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);
|
||||
|
||||
void createInstance(uint64_t);
|
||||
void destroyInstance(uint64_t);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "settings.hpp"
|
||||
#include "MobManager.hpp"
|
||||
#include "MissionManager.hpp"
|
||||
#include "ChunkManager.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
@ -608,8 +609,9 @@ void NPCManager::handleWarp(CNSocket* sock, int32_t warpId) {
|
||||
if (Warps[warpId].isInstance)
|
||||
{
|
||||
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
|
||||
ChunkManager::createInstance(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;
|
||||
|
||||
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->setFEKey(plr.FEKey);
|
||||
@ -929,7 +929,7 @@ WarpLocation PlayerManager::getRespawnPoint(Player *plr) {
|
||||
|
||||
for (auto targ : NPCManager::RespawnPoints) {
|
||||
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;
|
||||
bestDist = curDist;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ void TableData::init() {
|
||||
inFile >> npcData;
|
||||
for (nlohmann::json::iterator _npc = npcData.begin(); _npc != npcData.end(); _npc++) {
|
||||
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);
|
||||
|
||||
NPCManager::NPCs[nextId] = tmp;
|
||||
@ -37,7 +37,7 @@ void TableData::init() {
|
||||
nextId++;
|
||||
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user