[WIP] Convert all chunk-related logic to the new system's semantics

Replaced all references to chunk->players and chunk->NPCs with
chunk->entities and all instances of the old NPCClass enum with
EntityType.

The server compiles but will not yet run properly.
This commit is contained in:
dongresource 2021-03-21 03:54:24 +01:00
parent 224ffe05e7
commit 0c8e209360
13 changed files with 119 additions and 107 deletions

View File

@ -240,59 +240,67 @@ bool Chunking::inPopulatedChunks(std::set<Chunk*>* chnks) {
void Chunking::createInstance(uint64_t instanceID) { void Chunking::createInstance(uint64_t instanceID) {
std::vector<ChunkPos> templateChunks = getChunksInMap(MAPNUM(instanceID)); // base instance chunks std::vector<ChunkPos> templateChunks = getChunksInMap(MAPNUM(instanceID)); // base instance chunks
if (getChunksInMap(instanceID).size() == 0) { // only instantiate if the instance doesn't exist already
std::cout << "Creating instance " << instanceID << std::endl;
for (ChunkPos &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
BaseNPC* baseNPC = NPCManager::NPCs[npcID];
if (baseNPC->npcClass == NPC_MOB) {
if (((Mob*)baseNPC)->groupLeader != 0 && ((Mob*)baseNPC)->groupLeader != npcID)
continue; // follower; don't copy individually
Mob* newMob = new Mob(baseNPC->appearanceData.iX, baseNPC->appearanceData.iY, baseNPC->appearanceData.iZ, baseNPC->appearanceData.iAngle, // only instantiate if the instance doesn't exist already
instanceID, baseNPC->appearanceData.iNPCType, NPCManager::NPCData[baseNPC->appearanceData.iNPCType], NPCManager::nextId++); if (getChunksInMap(instanceID).size() != 0) {
NPCManager::NPCs[newMob->appearanceData.iNPC_ID] = newMob; std::cout << "Instance " << instanceID << " already exists" << std::endl;
MobAI::Mobs[newMob->appearanceData.iNPC_ID] = newMob; return;
}
// if in a group, copy over group members as well std::cout << "Creating instance " << instanceID << std::endl;
if (((Mob*)baseNPC)->groupLeader != 0) { for (ChunkPos &coords : templateChunks) {
newMob->groupLeader = newMob->appearanceData.iNPC_ID; // set leader ID for new leader for (const EntityRef& ref : chunks[coords]->entities) {
Mob* mobData = (Mob*)baseNPC; if (ref.type == EntityType::PLAYER)
for (int i = 0; i < 4; i++) { continue;
if (mobData->groupMember[i] != 0) {
int followerID = NPCManager::nextId++; // id for follower int npcID = ref.id;
BaseNPC* baseFollower = NPCManager::NPCs[mobData->groupMember[i]]; // follower from template BaseNPC* baseNPC = (BaseNPC*)ref.getEntity();
// new follower instance
Mob* newMobFollower = new Mob(baseFollower->appearanceData.iX, baseFollower->appearanceData.iY, baseFollower->appearanceData.iZ, baseFollower->appearanceData.iAngle, // make a copy of each NPC in the template chunks and put them in the new instance
instanceID, baseFollower->appearanceData.iNPCType, NPCManager::NPCData[baseFollower->appearanceData.iNPCType], followerID); if (baseNPC->type == EntityType::MOB) {
// add follower to NPC maps if (((Mob*)baseNPC)->groupLeader != 0 && ((Mob*)baseNPC)->groupLeader != npcID)
NPCManager::NPCs[followerID] = newMobFollower; continue; // follower; don't copy individually
MobAI::Mobs[followerID] = newMobFollower;
// set follower-specific properties Mob* newMob = new Mob(baseNPC->appearanceData.iX, baseNPC->appearanceData.iY, baseNPC->appearanceData.iZ, baseNPC->appearanceData.iAngle,
newMobFollower->groupLeader = newMob->appearanceData.iNPC_ID; instanceID, baseNPC->appearanceData.iNPCType, NPCManager::NPCData[baseNPC->appearanceData.iNPCType], NPCManager::nextId++);
newMobFollower->offsetX = ((Mob*)baseFollower)->offsetX; NPCManager::NPCs[newMob->appearanceData.iNPC_ID] = newMob;
newMobFollower->offsetY = ((Mob*)baseFollower)->offsetY; MobAI::Mobs[newMob->appearanceData.iNPC_ID] = newMob;
// add follower copy to leader copy
newMob->groupMember[i] = followerID; // if in a group, copy over group members as well
NPCManager::updateNPCPosition(followerID, baseFollower->appearanceData.iX, baseFollower->appearanceData.iY, baseFollower->appearanceData.iZ, if (((Mob*)baseNPC)->groupLeader != 0) {
instanceID, baseFollower->appearanceData.iAngle); newMob->groupLeader = newMob->appearanceData.iNPC_ID; // set leader ID for new leader
} Mob* mobData = (Mob*)baseNPC;
for (int i = 0; i < 4; i++) {
if (mobData->groupMember[i] != 0) {
int followerID = NPCManager::nextId++; // id for follower
BaseNPC* baseFollower = NPCManager::NPCs[mobData->groupMember[i]]; // follower from template
// new follower instance
Mob* newMobFollower = new Mob(baseFollower->appearanceData.iX, baseFollower->appearanceData.iY, baseFollower->appearanceData.iZ, baseFollower->appearanceData.iAngle,
instanceID, baseFollower->appearanceData.iNPCType, NPCManager::NPCData[baseFollower->appearanceData.iNPCType], followerID);
// add follower to NPC maps
NPCManager::NPCs[followerID] = newMobFollower;
MobAI::Mobs[followerID] = newMobFollower;
// set follower-specific properties
newMobFollower->groupLeader = newMob->appearanceData.iNPC_ID;
newMobFollower->offsetX = ((Mob*)baseFollower)->offsetX;
newMobFollower->offsetY = ((Mob*)baseFollower)->offsetY;
// add follower copy to leader copy
newMob->groupMember[i] = followerID;
NPCManager::updateNPCPosition(followerID, baseFollower->appearanceData.iX, baseFollower->appearanceData.iY, baseFollower->appearanceData.iZ,
instanceID, baseFollower->appearanceData.iAngle);
} }
} }
NPCManager::updateNPCPosition(newMob->appearanceData.iNPC_ID, baseNPC->appearanceData.iX, baseNPC->appearanceData.iY, baseNPC->appearanceData.iZ,
instanceID, baseNPC->appearanceData.iAngle);
} else {
BaseNPC* newNPC = new BaseNPC(baseNPC->appearanceData.iX, baseNPC->appearanceData.iY, baseNPC->appearanceData.iZ, baseNPC->appearanceData.iAngle,
instanceID, baseNPC->appearanceData.iNPCType, NPCManager::nextId++);
NPCManager::NPCs[newNPC->appearanceData.iNPC_ID] = newNPC;
NPCManager::updateNPCPosition(newNPC->appearanceData.iNPC_ID, baseNPC->appearanceData.iX, baseNPC->appearanceData.iY, baseNPC->appearanceData.iZ,
instanceID, baseNPC->appearanceData.iAngle);
} }
NPCManager::updateNPCPosition(newMob->appearanceData.iNPC_ID, baseNPC->appearanceData.iX, baseNPC->appearanceData.iY, baseNPC->appearanceData.iZ,
instanceID, baseNPC->appearanceData.iAngle);
} else {
BaseNPC* newNPC = new BaseNPC(baseNPC->appearanceData.iX, baseNPC->appearanceData.iY, baseNPC->appearanceData.iZ, baseNPC->appearanceData.iAngle,
instanceID, baseNPC->appearanceData.iNPCType, NPCManager::nextId++);
NPCManager::NPCs[newNPC->appearanceData.iNPC_ID] = newNPC;
NPCManager::updateNPCPosition(newNPC->appearanceData.iNPC_ID, baseNPC->appearanceData.iX, baseNPC->appearanceData.iY, baseNPC->appearanceData.iZ,
instanceID, baseNPC->appearanceData.iAngle);
} }
} }
} else {
std::cout << "Instance " << instanceID << " already exists" << std::endl;
} }
} }

View File

@ -11,8 +11,8 @@
class Chunk { class Chunk {
public: public:
std::set<CNSocket*> players; //std::set<CNSocket*> players;
std::set<int32_t> NPCs; //std::set<int32_t> NPCs;
std::set<EntityRef> entities; std::set<EntityRef> entities;
int nplayers = 0; int nplayers = 0;
}; };
@ -41,18 +41,4 @@ namespace Chunking {
bool inPopulatedChunks(std::set<Chunk*>* chnks); bool inPopulatedChunks(std::set<Chunk*>* chnks);
void createInstance(uint64_t); void createInstance(uint64_t);
void destroyInstanceIfEmpty(uint64_t); void destroyInstanceIfEmpty(uint64_t);
// death row below this point
//void updatePlayerChunk(CNSocket* sock, ChunkPos from, ChunkPos to);
//void updateNPCChunk(int32_t id, ChunkPos from, ChunkPos to);
//void trackPlayer(ChunkPos chunkPos, CNSocket* sock);
//void trackNPC(ChunkPos chunkPos, int32_t id);
//void untrackPlayer(ChunkPos chunkPos, CNSocket* sock);
//void untrackNPC(ChunkPos chunkPos, int32_t id);
//void addPlayerToChunks(std::set<Chunk*> chnks, CNSocket* sock);
//void addNPCToChunks(std::set<Chunk*> chnks, int32_t id);
//void removePlayerFromChunks(std::set<Chunk*> chnks, CNSocket* sock);
//void removeNPCFromChunks(std::set<Chunk*> chnks, int32_t id);
} }

View File

@ -662,7 +662,7 @@ static void whoisCommand(std::string full, std::vector<std::string>& args, CNSoc
Chat::sendServerMessage(sock, "[WHOIS] Type: " + std::to_string(npc->appearanceData.iNPCType)); Chat::sendServerMessage(sock, "[WHOIS] Type: " + std::to_string(npc->appearanceData.iNPCType));
Chat::sendServerMessage(sock, "[WHOIS] HP: " + std::to_string(npc->appearanceData.iHP)); Chat::sendServerMessage(sock, "[WHOIS] HP: " + std::to_string(npc->appearanceData.iHP));
Chat::sendServerMessage(sock, "[WHOIS] CBF: " + std::to_string(npc->appearanceData.iConditionBitFlag)); Chat::sendServerMessage(sock, "[WHOIS] CBF: " + std::to_string(npc->appearanceData.iConditionBitFlag));
Chat::sendServerMessage(sock, "[WHOIS] Class: " + std::to_string(npc->npcClass)); Chat::sendServerMessage(sock, "[WHOIS] EntityType: " + std::to_string((int)npc->type));
Chat::sendServerMessage(sock, "[WHOIS] X: " + std::to_string(npc->appearanceData.iX)); Chat::sendServerMessage(sock, "[WHOIS] X: " + std::to_string(npc->appearanceData.iX));
Chat::sendServerMessage(sock, "[WHOIS] Y: " + std::to_string(npc->appearanceData.iY)); Chat::sendServerMessage(sock, "[WHOIS] Y: " + std::to_string(npc->appearanceData.iY));
Chat::sendServerMessage(sock, "[WHOIS] Z: " + std::to_string(npc->appearanceData.iZ)); Chat::sendServerMessage(sock, "[WHOIS] Z: " + std::to_string(npc->appearanceData.iZ));
@ -682,7 +682,11 @@ static void lairUnlockCommand(std::string full, std::vector<std::string>& args,
int taskID = -1; int taskID = -1;
int missionID = -1; int missionID = -1;
int found = 0; int found = 0;
for (int32_t id : chnk->NPCs) { for (const EntityRef& ref : chnk->entities) {
if (ref.type == EntityType::PLAYER)
continue;
int32_t id = ref.id;
if (NPCManager::NPCs.find(id) == NPCManager::NPCs.end()) if (NPCManager::NPCs.find(id) == NPCManager::NPCs.end())
continue; continue;

View File

@ -9,6 +9,7 @@ enum class EntityType {
PLAYER, PLAYER,
SIMPLE_NPC, SIMPLE_NPC,
COMBAT_NPC, COMBAT_NPC,
MOB,
EGG, EGG,
BUS BUS
}; };
@ -68,34 +69,37 @@ struct EntityRef {
} }
}; };
/*
* Subclasses
*/
class BaseNPC : public Entity { class BaseNPC : public Entity {
public: public:
sNPCAppearanceData appearanceData; sNPCAppearanceData appearanceData;
NPCClass npcClass; //NPCClass npcClass;
int playersInView; int playersInView;
BaseNPC() {}; BaseNPC() {};
BaseNPC(int x, int y, int z, int angle, uint64_t iID, int type, int id) { // XXX BaseNPC(int x, int y, int z, int angle, uint64_t iID, int t, int id) { // XXX
appearanceData.iX = x; appearanceData.iX = x;
appearanceData.iY = y; appearanceData.iY = y;
appearanceData.iZ = z; appearanceData.iZ = z;
appearanceData.iNPCType = type; appearanceData.iNPCType = t;
appearanceData.iHP = 400; appearanceData.iHP = 400;
appearanceData.iAngle = angle; appearanceData.iAngle = angle;
appearanceData.iConditionBitFlag = 0; appearanceData.iConditionBitFlag = 0;
appearanceData.iBarkerType = 0; appearanceData.iBarkerType = 0;
appearanceData.iNPC_ID = id; appearanceData.iNPC_ID = id;
npcClass = NPCClass::NPC_BASE; type = EntityType::SIMPLE_NPC;
instanceID = iID; instanceID = iID;
chunkPos = std::make_tuple(0, 0, 0); chunkPos = std::make_tuple(0, 0, 0);
playersInView = 0; playersInView = 0;
}; };
BaseNPC(int x, int y, int z, int angle, uint64_t iID, int type, int id, NPCClass classType) : BaseNPC(x, y, z, angle, iID, type, id) { BaseNPC(int x, int y, int z, int angle, uint64_t iID, int t, int id, EntityType entityType) : BaseNPC(x, y, z, angle, iID, t, id) {
npcClass = classType; type = entityType;
} }
// XXX: move to CombatNPC, probably // XXX: move to CombatNPC, probably
@ -111,10 +115,10 @@ struct Egg : public BaseNPC {
bool dead = false; bool dead = false;
time_t deadUntil; time_t deadUntil;
Egg(int x, int y, int z, uint64_t iID, int type, int32_t id, bool summon) Egg(int x, int y, int z, uint64_t iID, int t, int32_t id, bool summon)
: BaseNPC(x, y, z, 0, iID, type, id) { : BaseNPC(x, y, z, 0, iID, t, id) {
summoned = summon; summoned = summon;
npcClass = NPCClass::NPC_EGG; type = EntityType::EGG;
} }
virtual bool isAlive() override { return !dead; } virtual bool isAlive() override { return !dead; }

View File

@ -121,7 +121,12 @@ bool MobAI::aggroCheck(Mob *mob, time_t currTime) {
for (auto it = mob->viewableChunks.begin(); it != mob->viewableChunks.end(); it++) { for (auto it = mob->viewableChunks.begin(); it != mob->viewableChunks.end(); it++) {
Chunk* chunk = *it; Chunk* chunk = *it;
for (CNSocket *s : chunk->players) { for (const EntityRef& ref : chunk->entities) {
// TODO: support targetting other CombatNPCs
if (ref.type != EntityType::PLAYER)
continue;
CNSocket *s = ref.sock;
Player *plr = PlayerManager::getPlayer(s); Player *plr = PlayerManager::getPlayer(s);
if (plr->HP <= 0) if (plr->HP <= 0)
@ -298,7 +303,12 @@ static void useAbilities(Mob *mob, time_t currTime) {
// find the players within range of eruption // find the players within range of eruption
for (auto it = mob->viewableChunks.begin(); it != mob->viewableChunks.end(); it++) { for (auto it = mob->viewableChunks.begin(); it != mob->viewableChunks.end(); it++) {
Chunk* chunk = *it; Chunk* chunk = *it;
for (CNSocket *s : chunk->players) { for (const EntityRef& ref : chunk->entities) {
// TODO: see aggroCheck()
if (ref.type != EntityType::PLAYER)
continue;
CNSocket *s= ref.sock;
Player *plr = PlayerManager::getPlayer(s); Player *plr = PlayerManager::getPlayer(s);
if (plr->HP <= 0) if (plr->HP <= 0)

View File

@ -53,8 +53,8 @@ struct Mob : public BaseNPC {
// temporary; until we're sure what's what // temporary; until we're sure what's what
nlohmann::json data; nlohmann::json data;
Mob(int x, int y, int z, int angle, uint64_t iID, int type, nlohmann::json d, int32_t id) Mob(int x, int y, int z, int angle, uint64_t iID, int t, nlohmann::json d, int32_t id)
: BaseNPC(x, y, z, angle, iID, type, id), : BaseNPC(x, y, z, angle, iID, t, id),
maxHealth(d["m_iHP"]), maxHealth(d["m_iHP"]),
sightRange(d["m_iSightRange"]) { sightRange(d["m_iSightRange"]) {
state = MobState::ROAMING; state = MobState::ROAMING;
@ -78,12 +78,12 @@ struct Mob : public BaseNPC {
// NOTE: there appear to be discrepancies in the dump // NOTE: there appear to be discrepancies in the dump
appearanceData.iHP = maxHealth; appearanceData.iHP = maxHealth;
npcClass = NPC_MOB; type = EntityType::MOB;
} }
// constructor for /summon // constructor for /summon
Mob(int x, int y, int z, uint64_t iID, int type, nlohmann::json d, int32_t id) Mob(int x, int y, int z, uint64_t iID, int t, nlohmann::json d, int32_t id)
: Mob(x, y, z, 0, iID, type, d, id) { : Mob(x, y, z, 0, iID, t, d, id) {
summoned = true; // will be despawned and deallocated when killed summoned = true; // will be despawned and deallocated when killed
} }

View File

@ -88,8 +88,9 @@ void NPCManager::updateNPCPosition(int32_t id, int X, int Y, int Z, uint64_t I,
void NPCManager::sendToViewable(BaseNPC *npc, void *buf, uint32_t type, size_t size) { void NPCManager::sendToViewable(BaseNPC *npc, void *buf, uint32_t type, size_t size) {
for (auto it = npc->viewableChunks.begin(); it != npc->viewableChunks.end(); it++) { for (auto it = npc->viewableChunks.begin(); it != npc->viewableChunks.end(); it++) {
Chunk* chunk = *it; Chunk* chunk = *it;
for (CNSocket *s : chunk->players) { for (const EntityRef& ref : chunk->entities) {
s->sendPacket(buf, type, size); if (ref.type == EntityType::PLAYER)
ref.sock->sendPacket(buf, type, size);
} }
} }
} }
@ -282,8 +283,11 @@ BaseNPC* NPCManager::getNearestNPC(std::set<Chunk*>* chunks, int X, int Y, int Z
int lastDist = INT_MAX; int lastDist = INT_MAX;
for (auto c = chunks->begin(); c != chunks->end(); c++) { // haha get it for (auto c = chunks->begin(); c != chunks->end(); c++) { // haha get it
Chunk* chunk = *c; Chunk* chunk = *c;
for (auto _npc = chunk->NPCs.begin(); _npc != chunk->NPCs.end(); _npc++) { for (auto ent = chunk->entities.begin(); ent != chunk->entities.end(); ent++) {
BaseNPC* npcTemp = NPCs[*_npc]; if (ent->type == EntityType::PLAYER)
continue;
BaseNPC* npcTemp = (BaseNPC*)ent->getEntity();
int distXY = std::hypot(X - npcTemp->appearanceData.iX, Y - npcTemp->appearanceData.iY); int distXY = std::hypot(X - npcTemp->appearanceData.iX, Y - npcTemp->appearanceData.iY);
int dist = std::hypot(distXY, Z - npcTemp->appearanceData.iZ); int dist = std::hypot(distXY, Z - npcTemp->appearanceData.iZ);
if (dist < lastDist) { if (dist < lastDist) {

View File

@ -93,6 +93,8 @@ struct Player : public Entity {
time_t lastShot; time_t lastShot;
std::vector<sItemBase> buyback; std::vector<sItemBase> buyback;
Player() { type = EntityType::PLAYER; }
virtual void enterIntoViewOf(CNSocket *sock) override; virtual void enterIntoViewOf(CNSocket *sock) override;
virtual void disappearFromViewOf(CNSocket *sock) override; virtual void disappearFromViewOf(CNSocket *sock) override;
}; };

View File

@ -331,11 +331,11 @@ void PlayerManager::sendToViewable(CNSocket* sock, void* buf, uint32_t type, siz
Player* plr = getPlayer(sock); Player* plr = getPlayer(sock);
for (auto it = plr->viewableChunks.begin(); it != plr->viewableChunks.end(); it++) { for (auto it = plr->viewableChunks.begin(); it != plr->viewableChunks.end(); it++) {
Chunk* chunk = *it; Chunk* chunk = *it;
for (CNSocket* otherSock : chunk->players) { for (const EntityRef& ref : chunk->entities) {
if (otherSock == sock) if (ref.type != EntityType::PLAYER || ref.sock == sock)
continue; continue;
otherSock->sendPacket(buf, type, size); ref.sock->sendPacket(buf, type, size);
} }
} }
} }

View File

@ -40,11 +40,11 @@ namespace PlayerManager {
Player* plr = getPlayer(sock); Player* plr = getPlayer(sock);
for (auto it = plr->viewableChunks.begin(); it != plr->viewableChunks.end(); it++) { for (auto it = plr->viewableChunks.begin(); it != plr->viewableChunks.end(); it++) {
Chunk* chunk = *it; Chunk* chunk = *it;
for (CNSocket* otherSock : chunk->players) { for (const EntityRef& ref : chunk->entities) {
if (otherSock == sock) if (ref.type != EntityType::PLAYER || ref.sock == sock)
continue; continue;
otherSock->sendPacket(pkt, type); ref.sock->sendPacket(pkt, type);
} }
} }
} }

View File

@ -139,7 +139,7 @@ static void loadPaths(int* nextId) {
if (passedDistance >= SLIDER_GAP_SIZE) { // space them out uniformaly if (passedDistance >= SLIDER_GAP_SIZE) { // space them out uniformaly
passedDistance -= SLIDER_GAP_SIZE; // step down passedDistance -= SLIDER_GAP_SIZE; // step down
// spawn a slider // spawn a slider
BaseNPC* slider = new BaseNPC(point.x, point.y, point.z, 0, INSTANCE_OVERWORLD, 1, (*nextId)++, NPC_BUS); BaseNPC* slider = new BaseNPC(point.x, point.y, point.z, 0, INSTANCE_OVERWORLD, 1, (*nextId)++, EntityType::BUS);
NPCManager::NPCs[slider->appearanceData.iNPC_ID] = slider; NPCManager::NPCs[slider->appearanceData.iNPC_ID] = slider;
NPCManager::updateNPCPosition(slider->appearanceData.iNPC_ID, slider->appearanceData.iX, slider->appearanceData.iY, slider->appearanceData.iZ, INSTANCE_OVERWORLD, 0); NPCManager::updateNPCPosition(slider->appearanceData.iNPC_ID, slider->appearanceData.iX, slider->appearanceData.iY, slider->appearanceData.iZ, INSTANCE_OVERWORLD, 0);
Transport::NPCQueues[slider->appearanceData.iNPC_ID] = route; Transport::NPCQueues[slider->appearanceData.iNPC_ID] = route;
@ -965,7 +965,7 @@ void TableData::flush() {
continue; continue;
int x, y, z; int x, y, z;
if (npc->npcClass == NPC_MOB) { if (npc->type == EntityType::MOB) {
Mob *m = (Mob*)npc; Mob *m = (Mob*)npc;
x = m->spawnX; x = m->spawnX;
y = m->spawnY; y = m->spawnY;
@ -998,7 +998,7 @@ void TableData::flush() {
int x, y, z; int x, y, z;
std::vector<Mob*> followers; std::vector<Mob*> followers;
if (npc->npcClass == NPC_MOB) { if (npc->type == EntityType::MOB) {
Mob* m = (Mob*)npc; Mob* m = (Mob*)npc;
x = m->spawnX; x = m->spawnX;
y = m->spawnY; y = m->spawnY;

View File

@ -256,13 +256,13 @@ static void stepNPCPathing() {
} }
// skip if not simulating mobs // skip if not simulating mobs
if (npc->npcClass == NPC_MOB && !MobAI::simulateMobs) { if (npc->type == EntityType::MOB && !MobAI::simulateMobs) {
it++; it++;
continue; continue;
} }
// do not roam if not roaming // do not roam if not roaming
if (npc->npcClass == NPC_MOB && ((Mob*)npc)->state != MobState::ROAMING) { if (npc->type == EntityType::MOB && ((Mob*)npc)->state != MobState::ROAMING) {
it++; it++;
continue; continue;
} }
@ -277,9 +277,11 @@ static void stepNPCPathing() {
// update NPC location to update viewables // update NPC location to update viewables
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, point.x, point.y, point.z, npc->instanceID, npc->appearanceData.iAngle); NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, point.x, point.y, point.z, npc->instanceID, npc->appearanceData.iAngle);
switch (npc->npcClass) { // TODO: move walking logic into Entity stack
case NPC_BUS: switch (npc->type) {
case EntityType::BUS:
INITSTRUCT(sP_FE2CL_TRANSPORTATION_MOVE, busMove); INITSTRUCT(sP_FE2CL_TRANSPORTATION_MOVE, busMove);
busMove.eTT = 3; busMove.eTT = 3;
busMove.iT_ID = npc->appearanceData.iNPC_ID; busMove.iT_ID = npc->appearanceData.iNPC_ID;
busMove.iMoveStyle = 0; // ??? busMove.iMoveStyle = 0; // ???
@ -290,7 +292,7 @@ static void stepNPCPathing() {
NPCManager::sendToViewable(npc, &busMove, P_FE2CL_TRANSPORTATION_MOVE, sizeof(sP_FE2CL_TRANSPORTATION_MOVE)); NPCManager::sendToViewable(npc, &busMove, P_FE2CL_TRANSPORTATION_MOVE, sizeof(sP_FE2CL_TRANSPORTATION_MOVE));
break; break;
case NPC_MOB: case EntityType::MOB:
MobAI::incNextMovement((Mob*)npc); MobAI::incNextMovement((Mob*)npc);
/* fallthrough */ /* fallthrough */
default: default:
@ -310,7 +312,7 @@ static void stepNPCPathing() {
* Move processed point to the back to maintain cycle, unless this is a * Move processed point to the back to maintain cycle, unless this is a
* dynamically calculated mob route. * dynamically calculated mob route.
*/ */
if (!(npc->npcClass == NPC_MOB && !((Mob*)npc)->staticPath)) if (!(npc->type == EntityType::MOB && !((Mob*)npc)->staticPath))
queue->push(point); queue->push(point);
it++; // go to next entry in map it++; // go to next entry in map

View File

@ -24,14 +24,6 @@ enum eCN_GM_TeleportType {
eCN_GM_TeleportMapType__Unstick eCN_GM_TeleportMapType__Unstick
}; };
// NPC classes
enum NPCClass {
NPC_BASE = 0,
NPC_MOB = 1,
NPC_BUS = 2,
NPC_EGG = 3
};
// nano powers // nano powers
enum { enum {
EST_NONE = 0, EST_NONE = 0,