mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-12-23 03:40:05 +00:00
Bugfixes.
* Add newly created chunks to nearby players and NPCs. This fixes the slider/static path mob pop-in problem. * Update a player's chunks when resurrecting. This fixes a mob desync problem. * Use a private instance for the Time Lab * Spawn a slider for every stop * Fix mobs in private lairs using the template chunk mobs's current health for their max health * Don't call into the JSON lib in the loop in aggroCheck(). This is an optimization found after using gprof. * Don't print NPC deletions to console. This stops the spam when a private instance is deleted. * Changed default view distance to half the length of a map tile, so chunks are aligned to map tiles * Update tdata reference
This commit is contained in:
parent
49d8ed2e36
commit
c9f9b093f4
1
.gitignore
vendored
1
.gitignore
vendored
@ -13,3 +13,4 @@ build/
|
||||
*.db
|
||||
version.h
|
||||
infer-out
|
||||
gmon.out
|
||||
|
@ -21,7 +21,7 @@ port=8002
|
||||
ip=127.0.0.1
|
||||
# distance at which other players and NPCs become visible.
|
||||
# this value is used for calculating chunk size
|
||||
viewdistance=30000
|
||||
viewdistance=25600
|
||||
# time, in milliseconds, to wait before kicking a non-responsive client
|
||||
# default is 1 minute
|
||||
timeout=60000
|
||||
|
@ -8,15 +8,33 @@ std::map<std::tuple<int, int, uint64_t>, Chunk*> ChunkManager::chunks;
|
||||
|
||||
void ChunkManager::init() {} // stubbed
|
||||
|
||||
void ChunkManager::newChunk(std::tuple<int, int, uint64_t> pos) {
|
||||
Chunk *chunk = new Chunk();
|
||||
|
||||
chunk->players = std::set<CNSocket*>();
|
||||
chunk->NPCs = std::set<int32_t>();
|
||||
|
||||
// add the new chunk to every player and mob that's near it
|
||||
for (Chunk *c : grabChunks(pos)) {
|
||||
if (c == chunk)
|
||||
continue;
|
||||
|
||||
for (CNSocket *s : c->players)
|
||||
PlayerManager::players[s].currentChunks.push_back(chunk);
|
||||
|
||||
for (int32_t id : c->NPCs)
|
||||
NPCManager::NPCs[id]->currentChunks.push_back(chunk);
|
||||
}
|
||||
|
||||
chunks[pos] = chunk;
|
||||
}
|
||||
|
||||
void ChunkManager::addNPC(int posX, int posY, uint64_t instanceID, int32_t id) {
|
||||
std::tuple<int, int, uint64_t> pos = grabChunk(posX, posY, instanceID);
|
||||
|
||||
// make chunk if it doesn't exist!
|
||||
if (chunks.find(pos) == chunks.end()) {
|
||||
chunks[pos] = new Chunk();
|
||||
chunks[pos]->players = std::set<CNSocket*>();
|
||||
chunks[pos]->NPCs = std::set<int32_t>();
|
||||
}
|
||||
if (chunks.find(pos) == chunks.end())
|
||||
newChunk(pos);
|
||||
|
||||
Chunk* chunk = chunks[pos];
|
||||
|
||||
@ -27,11 +45,8 @@ void ChunkManager::addPlayer(int posX, int posY, uint64_t instanceID, CNSocket*
|
||||
std::tuple<int, int, uint64_t> pos = grabChunk(posX, posY, instanceID);
|
||||
|
||||
// make chunk if it doesn't exist!
|
||||
if (chunks.find(pos) == chunks.end()) {
|
||||
chunks[pos] = new Chunk();
|
||||
chunks[pos]->players = std::set<CNSocket*>();
|
||||
chunks[pos]->NPCs = std::set<int32_t>();
|
||||
}
|
||||
if (chunks.find(pos) == chunks.end())
|
||||
newChunk(pos);
|
||||
|
||||
Chunk* chunk = chunks[pos];
|
||||
|
||||
@ -212,7 +227,7 @@ void ChunkManager::createInstance(uint64_t instanceID) {
|
||||
BaseNPC* baseNPC = NPCManager::NPCs[npcID];
|
||||
if (baseNPC->npcClass == NPC_MOB) {
|
||||
Mob* newMob = new Mob(baseNPC->appearanceData.iX, baseNPC->appearanceData.iY, baseNPC->appearanceData.iZ, baseNPC->appearanceData.iAngle,
|
||||
instanceID, baseNPC->appearanceData.iNPCType, baseNPC->appearanceData.iHP, NPCManager::NPCData[baseNPC->appearanceData.iNPCType], newID);
|
||||
instanceID, baseNPC->appearanceData.iNPCType, ((Mob*)baseNPC)->maxHealth, NPCManager::NPCData[baseNPC->appearanceData.iNPCType], newID);
|
||||
NPCManager::NPCs[newID] = newMob;
|
||||
MobManager::Mobs[newID] = newMob;
|
||||
} else {
|
||||
|
@ -26,6 +26,7 @@ namespace ChunkManager {
|
||||
|
||||
extern std::map<std::tuple<int, int, uint64_t>, Chunk*> chunks;
|
||||
|
||||
void newChunk(std::tuple<int, int, uint64_t> pos);
|
||||
void addNPC(int posX, int posY, uint64_t instanceID, int32_t id);
|
||||
void addPlayer(int posX, int posY, uint64_t instanceID, CNSocket* sock);
|
||||
bool removePlayer(std::tuple<int, int, uint64_t> chunkPos, CNSocket* sock);
|
||||
|
@ -1046,7 +1046,7 @@ bool MobManager::aggroCheck(Mob *mob, time_t currTime) {
|
||||
if (plr->HP <= 0)
|
||||
continue;
|
||||
|
||||
int mobRange = mob->data["m_iSightRange"];
|
||||
int mobRange = mob->sightRange;
|
||||
|
||||
if (plr->iConditionBitFlag & CSB_BIT_UP_STEALTH)
|
||||
mobRange /= 3;
|
||||
|
@ -35,6 +35,7 @@ struct Mob : public BaseNPC {
|
||||
|
||||
// roaming
|
||||
int idleRange;
|
||||
const int sightRange;
|
||||
time_t nextMovement = 0;
|
||||
bool staticPath = false;
|
||||
|
||||
@ -50,7 +51,9 @@ struct Mob : public BaseNPC {
|
||||
nlohmann::json data;
|
||||
|
||||
Mob(int x, int y, int z, int angle, uint64_t iID, int type, int hp, nlohmann::json d, int32_t id)
|
||||
: BaseNPC(x, y, z, angle, iID, type, id), maxHealth(hp) {
|
||||
: BaseNPC(x, y, z, angle, iID, type, id),
|
||||
maxHealth(hp),
|
||||
sightRange(d["m_iSightRange"]) {
|
||||
state = MobState::ROAMING;
|
||||
|
||||
data = d;
|
||||
|
@ -107,7 +107,7 @@ void NPCManager::addNPC(std::vector<Chunk*> viewableChunks, int32_t id) {
|
||||
void NPCManager::destroyNPC(int32_t id) {
|
||||
// sanity check
|
||||
if (NPCs.find(id) == NPCs.end()) {
|
||||
std::cout << "npc not found : " << id << std::endl;
|
||||
std::cout << "npc not found: " << id << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -133,8 +133,6 @@ void NPCManager::destroyNPC(int32_t id) {
|
||||
// finally, remove it from the map and free it
|
||||
NPCs.erase(id);
|
||||
delete entity;
|
||||
|
||||
std::cout << "npc removed!" << std::endl;
|
||||
}
|
||||
|
||||
void NPCManager::updateNPCPosition(int32_t id, int X, int Y, int Z, int angle) {
|
||||
@ -601,7 +599,9 @@ void NPCManager::handleWarp(CNSocket* sock, int32_t warpId) {
|
||||
// std::cerr << "Warped to Map Num:" << Warps[warpId].instanceID << " NPC ID " << Warps[warpId].npcID << std::endl;
|
||||
if (Warps[warpId].isInstance) {
|
||||
uint64_t instanceID = Warps[warpId].instanceID;
|
||||
if (Warps[warpId].limitTaskID != 0) { // if warp requires you to be on a mission, it's gotta be a unique instance
|
||||
|
||||
// if warp requires you to be on a mission, it's gotta be a unique instance
|
||||
if (Warps[warpId].limitTaskID != 0 || instanceID == 14) { // 14 is a special case for the Time Lab
|
||||
instanceID += ((uint64_t)plrv.plr->iIDGroup << 32); // upper 32 bits are leader ID
|
||||
ChunkManager::createInstance(instanceID);
|
||||
}
|
||||
|
@ -793,9 +793,7 @@ void PlayerManager::revivePlayer(CNSocket* sock, CNPacketData* data) {
|
||||
NanoManager::nanoUnbuff(sock, CSB_BIT_PHOENIX, ECSB_PHOENIX, 0, false);
|
||||
plr->HP = PC_MAXHEALTH(plr->level);
|
||||
} else {
|
||||
plr->x = target.x;
|
||||
plr->y = target.y;
|
||||
plr->z = target.z;
|
||||
updatePlayerPosition(sock, target.x, target.y, target.z);
|
||||
|
||||
if (reviveData->iRegenType != 5)
|
||||
plr->HP = PC_MAXHEALTH(plr->level);
|
||||
|
@ -264,14 +264,13 @@ void TableData::loadPaths(int* nextId) {
|
||||
for (nlohmann::json::iterator _sliderPoint = pathDataSlider.begin(); _sliderPoint != pathDataSlider.end(); _sliderPoint++) {
|
||||
auto sliderPoint = _sliderPoint.value();
|
||||
if (sliderPoint["stop"]) { // check if this point in the circuit is a stop
|
||||
if (stops % 2 == 0) { // on;y put a slider down every other stop
|
||||
// spawn a slider
|
||||
BaseNPC* slider = new BaseNPC(sliderPoint["iX"], sliderPoint["iY"], sliderPoint["iZ"], 0, INSTANCE_OVERWORLD, 1, (*nextId)++, NPC_BUS);
|
||||
NPCManager::NPCs[slider->appearanceData.iNPC_ID] = slider;
|
||||
NPCManager::updateNPCPosition(slider->appearanceData.iNPC_ID, slider->appearanceData.iX, slider->appearanceData.iY, slider->appearanceData.iZ);
|
||||
// set slider path to a rotation of the circuit
|
||||
constructPathSlider(pathDataSlider, pos, slider->appearanceData.iNPC_ID);
|
||||
}
|
||||
BaseNPC* slider = new BaseNPC(sliderPoint["iX"], sliderPoint["iY"], sliderPoint["iZ"], 0, INSTANCE_OVERWORLD, 1, (*nextId)++, NPC_BUS);
|
||||
NPCManager::NPCs[slider->appearanceData.iNPC_ID] = slider;
|
||||
NPCManager::updateNPCPosition(slider->appearanceData.iNPC_ID, slider->appearanceData.iX, slider->appearanceData.iY, slider->appearanceData.iZ);
|
||||
// set slider path to a rotation of the circuit
|
||||
constructPathSlider(pathDataSlider, pos, slider->appearanceData.iNPC_ID);
|
||||
|
||||
stops++;
|
||||
}
|
||||
pos++;
|
||||
|
@ -12,7 +12,7 @@ int settings::DBSAVEINTERVAL = 240;
|
||||
int settings::SHARDPORT = 8002;
|
||||
std::string settings::SHARDSERVERIP = "127.0.0.1";
|
||||
time_t settings::TIMEOUT = 60000;
|
||||
int settings::VIEWDISTANCE = 40000;
|
||||
int settings::VIEWDISTANCE = 25600;
|
||||
bool settings::SIMULATEMOBS = true;
|
||||
|
||||
// default spawn point is Sector V (future)
|
||||
|
Loading…
Reference in New Issue
Block a user