mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-25 22:40:16 +00:00
Implemented mob roaming.
Will likely need further tuning. Mobs in vacant chunks are skipped.
This commit is contained in:
parent
94ab5b8b64
commit
ac1fd1e5be
@ -104,3 +104,15 @@ std::vector<Chunk*> ChunkManager::getDeltaChunks(std::vector<Chunk*> from, std::
|
|||||||
|
|
||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChunkManager::inPopulatedChunks(int posX, int posY) {
|
||||||
|
auto chunk = ChunkManager::grabChunk(posX, posY);
|
||||||
|
auto nearbyChunks = ChunkManager::grabChunks(chunk);
|
||||||
|
|
||||||
|
for (Chunk *c: nearbyChunks) {
|
||||||
|
if (!c->players.empty())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@ -26,4 +26,5 @@ namespace ChunkManager {
|
|||||||
std::pair<int, int> grabChunk(int posX, int posY);
|
std::pair<int, int> grabChunk(int posX, int posY);
|
||||||
std::vector<Chunk*> grabChunks(std::pair<int, int> chunkPos);
|
std::vector<Chunk*> grabChunks(std::pair<int, int> 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);
|
||||||
|
bool inPopulatedChunks(int posX, int posY);
|
||||||
}
|
}
|
||||||
|
@ -179,9 +179,47 @@ void MobManager::deadStep(Mob *mob, time_t currTime) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MobManager::roamingStep(Mob *mob, time_t currTime) {
|
||||||
|
if (mob->nextMovement != 0 && currTime < mob->nextMovement)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int delay = (int)mob->data["m_iDelayTime"] * 1000;
|
||||||
|
mob->nextMovement = currTime + delay/2 + rand() % (delay/2);
|
||||||
|
|
||||||
|
INITSTRUCT(sP_FE2CL_NPC_MOVE, pkt);
|
||||||
|
int xStart = mob->spawnX - mob->idleRange/2;
|
||||||
|
int yStart = mob->spawnY - mob->idleRange/2;
|
||||||
|
|
||||||
|
pkt.iNPC_ID = mob->appearanceData.iNPC_ID;
|
||||||
|
pkt.iSpeed = mob->data["m_iWalkSpeed"];
|
||||||
|
pkt.iToX = mob->appearanceData.iX = xStart + rand() % mob->idleRange;
|
||||||
|
pkt.iToY = mob->appearanceData.iY = yStart + rand() % mob->idleRange;
|
||||||
|
pkt.iToZ = mob->appearanceData.iZ;
|
||||||
|
|
||||||
|
auto chunk = ChunkManager::grabChunk(mob->appearanceData.iX, mob->appearanceData.iY);
|
||||||
|
auto chunks = ChunkManager::grabChunks(chunk);
|
||||||
|
|
||||||
|
// notify all nearby players
|
||||||
|
for (Chunk *chunk : chunks) {
|
||||||
|
for (CNSocket *s : chunk->players) {
|
||||||
|
s->sendPacket(&pkt, P_FE2CL_NPC_MOVE, sizeof(sP_FE2CL_NPC_MOVE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MobManager::step(time_t currTime) {
|
void MobManager::step(time_t currTime) {
|
||||||
for (auto& pair : Mobs) {
|
for (auto& pair : Mobs) {
|
||||||
|
int x = pair.second->appearanceData.iX;
|
||||||
|
int y = pair.second->appearanceData.iY;
|
||||||
|
|
||||||
|
// skip chunks without players
|
||||||
|
if (!ChunkManager::inPopulatedChunks(x, y))
|
||||||
|
continue;
|
||||||
|
|
||||||
switch (pair.second->state) {
|
switch (pair.second->state) {
|
||||||
|
case MobState::ROAMING:
|
||||||
|
roamingStep(pair.second, currTime);
|
||||||
|
break;
|
||||||
case MobState::DEAD:
|
case MobState::DEAD:
|
||||||
deadStep(pair.second, currTime);
|
deadStep(pair.second, currTime);
|
||||||
break;
|
break;
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include "CNShardServer.hpp"
|
#include "CNShardServer.hpp"
|
||||||
#include "NPC.hpp"
|
#include "NPC.hpp"
|
||||||
|
|
||||||
|
#include "contrib/JSON.hpp"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
enum class MobState {
|
enum class MobState {
|
||||||
@ -22,14 +24,32 @@ struct Mob : public BaseNPC {
|
|||||||
const int regenTime;
|
const int regenTime;
|
||||||
bool despawned = false; // for the sake of death animations
|
bool despawned = false; // for the sake of death animations
|
||||||
|
|
||||||
Mob(int x, int y, int z, int type, int hp, int angle, int rt)
|
int spawnX;
|
||||||
: BaseNPC(x, y, z, type), maxHealth(hp), regenTime(rt) {
|
int spawnY;
|
||||||
|
int spawnZ;
|
||||||
|
|
||||||
|
const int idleRange;
|
||||||
|
time_t nextMovement = 0;
|
||||||
|
|
||||||
|
// temporary; until we're sure what's what
|
||||||
|
nlohmann::json data;
|
||||||
|
|
||||||
|
Mob(int x, int y, int z, int type, int hp, int angle, nlohmann::json d)
|
||||||
|
: BaseNPC(x, y, z, type), maxHealth(hp), regenTime(d["m_iRegenTime"]), idleRange(d["m_iIdleRange"]), data(d) {
|
||||||
state = MobState::ROAMING;
|
state = MobState::ROAMING;
|
||||||
|
|
||||||
|
spawnX = appearanceData.iX;
|
||||||
|
spawnY = appearanceData.iY;
|
||||||
|
spawnZ = appearanceData.iZ;
|
||||||
|
|
||||||
// NOTE: there appear to be discrepancies in the dump
|
// NOTE: there appear to be discrepancies in the dump
|
||||||
appearanceData.iHP = maxHealth;
|
appearanceData.iHP = maxHealth;
|
||||||
}
|
}
|
||||||
~Mob() {}
|
~Mob() {}
|
||||||
|
|
||||||
|
auto operator[](std::string s) {
|
||||||
|
return data[s];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace MobManager {
|
namespace MobManager {
|
||||||
@ -39,6 +59,7 @@ namespace MobManager {
|
|||||||
void step(time_t);
|
void step(time_t);
|
||||||
|
|
||||||
void deadStep(Mob*, time_t);
|
void deadStep(Mob*, time_t);
|
||||||
|
void roamingStep(Mob*, time_t);
|
||||||
|
|
||||||
void pcAttackNpcs(CNSocket *sock, CNPacketData *data);
|
void pcAttackNpcs(CNSocket *sock, CNPacketData *data);
|
||||||
void combatBegin(CNSocket *sock, CNPacketData *data);
|
void combatBegin(CNSocket *sock, CNPacketData *data);
|
||||||
|
@ -162,7 +162,7 @@ void TableData::init() {
|
|||||||
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();
|
||||||
auto td = npcTableData[(int)npc["iNPCType"]];
|
auto td = npcTableData[(int)npc["iNPCType"]];
|
||||||
Mob *tmp = new Mob(npc["iX"], npc["iY"], npc["iZ"], npc["iNPCType"], npc["iHP"], npc["iAngle"], td["m_iRegenTime"]);
|
Mob *tmp = new Mob(npc["iX"], npc["iY"], npc["iZ"], npc["iNPCType"], npc["iHP"], npc["iAngle"], td);
|
||||||
|
|
||||||
// Temporary fix, IDs will be pulled from json later
|
// Temporary fix, IDs will be pulled from json later
|
||||||
tmp->appearanceData.iNPC_ID = i;
|
tmp->appearanceData.iNPC_ID = i;
|
||||||
|
Loading…
Reference in New Issue
Block a user