mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-25 06:20:14 +00:00
Generalize NPC AI stepping logic
The MobAI::Mobs map still needs to be removed.
This commit is contained in:
parent
3325397d17
commit
65462d01e3
@ -30,12 +30,8 @@ struct Entity {
|
|||||||
virtual bool isAlive() { return true; }
|
virtual bool isAlive() { return true; }
|
||||||
|
|
||||||
// stubs
|
// stubs
|
||||||
virtual void enterIntoViewOf(CNSocket *sock) {}
|
virtual void enterIntoViewOf(CNSocket *sock) = 0;
|
||||||
virtual void disappearFromViewOf(CNSocket *sock) {}
|
virtual void disappearFromViewOf(CNSocket *sock) = 0;
|
||||||
|
|
||||||
// we don't want objects of this base class to exist
|
|
||||||
protected:
|
|
||||||
Entity() {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EntityRef {
|
struct EntityRef {
|
||||||
@ -106,16 +102,16 @@ struct CombatNPC : public BaseNPC {
|
|||||||
int spawnZ = 0;
|
int spawnZ = 0;
|
||||||
int level = 0;
|
int level = 0;
|
||||||
|
|
||||||
void (*_stepAI)() = nullptr;
|
void (*_stepAI)(CombatNPC*, time_t) = nullptr;
|
||||||
|
|
||||||
// XXX
|
// XXX
|
||||||
CombatNPC(int x, int y, int z, int angle, uint64_t iID, int t, int id, int maxHP) :
|
CombatNPC(int x, int y, int z, int angle, uint64_t iID, int t, int id, int maxHP) :
|
||||||
BaseNPC(x, y, z, angle, iID, t, id),
|
BaseNPC(x, y, z, angle, iID, t, id),
|
||||||
maxHealth(maxHP) {}
|
maxHealth(maxHP) {}
|
||||||
|
|
||||||
virtual void stepAI() {
|
virtual void stepAI(time_t currTime) {
|
||||||
if (_stepAI != nullptr)
|
if (_stepAI != nullptr)
|
||||||
_stepAI();
|
_stepAI(this, currTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isAlive() override { return appearanceData.iHP > 0; }
|
virtual bool isAlive() override { return appearanceData.iHP > 0; }
|
||||||
|
@ -12,9 +12,8 @@
|
|||||||
using namespace MobAI;
|
using namespace MobAI;
|
||||||
|
|
||||||
std::map<int32_t, Mob*> MobAI::Mobs;
|
std::map<int32_t, Mob*> MobAI::Mobs;
|
||||||
static std::queue<int32_t> RemovalQueue;
|
|
||||||
|
|
||||||
bool MobAI::simulateMobs;
|
bool MobAI::simulateMobs = settings::SIMULATEMOBS;
|
||||||
|
|
||||||
static void roamingStep(Mob *mob, time_t currTime);
|
static void roamingStep(Mob *mob, time_t currTime);
|
||||||
|
|
||||||
@ -451,7 +450,7 @@ static void deadStep(Mob *mob, time_t currTime) {
|
|||||||
// if it was summoned, mark it for removal
|
// if it was summoned, mark it for removal
|
||||||
if (mob->summoned) {
|
if (mob->summoned) {
|
||||||
std::cout << "[INFO] Queueing killed summoned mob for removal" << std::endl;
|
std::cout << "[INFO] Queueing killed summoned mob for removal" << std::endl;
|
||||||
RemovalQueue.push(mob->appearanceData.iNPC_ID);
|
NPCManager::queueNPCRemoval(mob->appearanceData.iNPC_ID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -774,44 +773,33 @@ static void retreatStep(Mob *mob, time_t currTime) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void step(CNServer *serv, time_t currTime) {
|
void MobAI::step(CombatNPC *npc, time_t currTime) {
|
||||||
for (auto& pair : Mobs) {
|
assert(npc->type == EntityType::MOB);
|
||||||
if (pair.second->playersInView < 0)
|
auto mob = (Mob*)npc;
|
||||||
std::cout << "[WARN] Weird playerview value " << pair.second->playersInView << std::endl;
|
|
||||||
|
if (mob->playersInView < 0)
|
||||||
|
std::cout << "[WARN] Weird playerview value " << mob->playersInView << std::endl;
|
||||||
|
|
||||||
// skip mob movement and combat if disabled or not in view
|
// skip mob movement and combat if disabled or not in view
|
||||||
if ((!simulateMobs || pair.second->playersInView == 0) && pair.second->state != MobState::DEAD
|
if ((!simulateMobs || mob->playersInView == 0) && mob->state != MobState::DEAD
|
||||||
&& pair.second->state != MobState::RETREAT)
|
&& mob->state != MobState::RETREAT)
|
||||||
continue;
|
return;
|
||||||
|
|
||||||
switch (pair.second->state) {
|
switch (mob->state) {
|
||||||
case MobState::INACTIVE:
|
case MobState::INACTIVE:
|
||||||
// no-op
|
// no-op
|
||||||
break;
|
break;
|
||||||
case MobState::ROAMING:
|
case MobState::ROAMING:
|
||||||
roamingStep(pair.second, currTime);
|
roamingStep(mob, currTime);
|
||||||
break;
|
break;
|
||||||
case MobState::COMBAT:
|
case MobState::COMBAT:
|
||||||
combatStep(pair.second, currTime);
|
combatStep(mob, currTime);
|
||||||
break;
|
break;
|
||||||
case MobState::RETREAT:
|
case MobState::RETREAT:
|
||||||
retreatStep(pair.second, currTime);
|
retreatStep(mob, currTime);
|
||||||
break;
|
break;
|
||||||
case MobState::DEAD:
|
case MobState::DEAD:
|
||||||
deadStep(pair.second, currTime);
|
deadStep(mob, currTime);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// deallocate all NPCs queued for removal
|
|
||||||
while (RemovalQueue.size() > 0) {
|
|
||||||
NPCManager::destroyNPC(RemovalQueue.front());
|
|
||||||
RemovalQueue.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MobAI::init() {
|
|
||||||
REGISTER_SHARD_TIMER(step, 200);
|
|
||||||
|
|
||||||
simulateMobs = settings::SIMULATEMOBS;
|
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,11 @@ enum class MobState {
|
|||||||
DEAD
|
DEAD
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace MobAI {
|
||||||
|
// needs to be declared before Mob's constructor
|
||||||
|
void step(CombatNPC*, time_t);
|
||||||
|
};
|
||||||
|
|
||||||
struct Mob : public CombatNPC {
|
struct Mob : public CombatNPC {
|
||||||
// general
|
// general
|
||||||
MobState state = MobState::INACTIVE;
|
MobState state = MobState::INACTIVE;
|
||||||
@ -76,6 +81,7 @@ struct Mob : public CombatNPC {
|
|||||||
appearanceData.iHP = maxHealth;
|
appearanceData.iHP = maxHealth;
|
||||||
|
|
||||||
type = EntityType::MOB;
|
type = EntityType::MOB;
|
||||||
|
_stepAI = MobAI::step;
|
||||||
}
|
}
|
||||||
|
|
||||||
// constructor for /summon
|
// constructor for /summon
|
||||||
@ -98,8 +104,6 @@ namespace MobAI {
|
|||||||
extern bool simulateMobs;
|
extern bool simulateMobs;
|
||||||
extern std::map<int32_t, Mob*> Mobs;
|
extern std::map<int32_t, Mob*> Mobs;
|
||||||
|
|
||||||
void init();
|
|
||||||
|
|
||||||
// TODO: make this internal later
|
// TODO: make this internal later
|
||||||
void incNextMovement(Mob *mob, time_t currTime=0);
|
void incNextMovement(Mob *mob, time_t currTime=0);
|
||||||
bool aggroCheck(Mob *mob, time_t currTime);
|
bool aggroCheck(Mob *mob, time_t currTime);
|
||||||
|
@ -23,11 +23,13 @@
|
|||||||
|
|
||||||
using namespace NPCManager;
|
using namespace NPCManager;
|
||||||
|
|
||||||
std::map<int32_t, BaseNPC*> NPCManager::NPCs;
|
std::unordered_map<int32_t, BaseNPC*> NPCManager::NPCs;
|
||||||
std::map<int32_t, WarpLocation> NPCManager::Warps;
|
std::map<int32_t, WarpLocation> NPCManager::Warps;
|
||||||
std::vector<WarpLocation> NPCManager::RespawnPoints;
|
std::vector<WarpLocation> NPCManager::RespawnPoints;
|
||||||
nlohmann::json NPCManager::NPCData;
|
nlohmann::json NPCManager::NPCData;
|
||||||
|
|
||||||
|
static std::queue<int32_t> RemovalQueue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialized at the end of TableData::init().
|
* Initialized at the end of TableData::init().
|
||||||
* This allows us to summon and kill mobs in arbitrary order without
|
* This allows us to summon and kill mobs in arbitrary order without
|
||||||
@ -349,10 +351,32 @@ std::vector<NPCEvent> NPCManager::NPCEvents = {
|
|||||||
|
|
||||||
#pragma endregion NPCEvents
|
#pragma endregion NPCEvents
|
||||||
|
|
||||||
|
void NPCManager::queueNPCRemoval(int32_t id) {
|
||||||
|
RemovalQueue.push(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void step(CNServer *serv, time_t currTime) {
|
||||||
|
for (auto& pair : NPCs) {
|
||||||
|
if (pair.second->type != EntityType::COMBAT_NPC && pair.second->type != EntityType::MOB)
|
||||||
|
continue;
|
||||||
|
auto npc = (CombatNPC*)pair.second;
|
||||||
|
|
||||||
|
npc->stepAI(currTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// deallocate all NPCs queued for removal
|
||||||
|
while (RemovalQueue.size() > 0) {
|
||||||
|
NPCManager::destroyNPC(RemovalQueue.front());
|
||||||
|
RemovalQueue.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NPCManager::init() {
|
void NPCManager::init() {
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_WARP_USE_NPC, npcWarpHandler);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_WARP_USE_NPC, npcWarpHandler);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TIME_TO_GO_WARP, npcWarpTimeMachine);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TIME_TO_GO_WARP, npcWarpTimeMachine);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_NPC_SUMMON, npcSummonHandler);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_NPC_SUMMON, npcSummonHandler);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_NPC_UNSUMMON, npcUnsummonHandler);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_NPC_UNSUMMON, npcUnsummonHandler);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_BARKER, npcBarkHandler);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_BARKER, npcBarkHandler);
|
||||||
|
|
||||||
|
REGISTER_SHARD_TIMER(step, 200);
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ struct WarpLocation {
|
|||||||
};
|
};
|
||||||
|
|
||||||
namespace NPCManager {
|
namespace NPCManager {
|
||||||
extern std::map<int32_t, BaseNPC*> NPCs;
|
extern std::unordered_map<int32_t, BaseNPC*> NPCs;
|
||||||
extern std::map<int32_t, WarpLocation> Warps;
|
extern std::map<int32_t, WarpLocation> Warps;
|
||||||
extern std::vector<WarpLocation> RespawnPoints;
|
extern std::vector<WarpLocation> RespawnPoints;
|
||||||
extern std::vector<NPCEvent> NPCEvents;
|
extern std::vector<NPCEvent> NPCEvents;
|
||||||
@ -42,6 +42,7 @@ namespace NPCManager {
|
|||||||
extern int32_t nextId;
|
extern int32_t nextId;
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
void queueNPCRemoval(int32_t);
|
||||||
void destroyNPC(int32_t);
|
void destroyNPC(int32_t);
|
||||||
void updateNPCPosition(int32_t, int X, int Y, int Z, uint64_t I, int angle);
|
void updateNPCPosition(int32_t, int X, int Y, int Z, uint64_t I, int angle);
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "JSON.hpp"
|
|
||||||
#include "NPCManager.hpp"
|
#include "NPCManager.hpp"
|
||||||
|
|
||||||
namespace TableData {
|
namespace TableData {
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include "Buddies.hpp"
|
#include "Buddies.hpp"
|
||||||
#include "CustomCommands.hpp"
|
#include "CustomCommands.hpp"
|
||||||
#include "Combat.hpp"
|
#include "Combat.hpp"
|
||||||
#include "MobAI.hpp"
|
|
||||||
#include "Items.hpp"
|
#include "Items.hpp"
|
||||||
#include "Missions.hpp"
|
#include "Missions.hpp"
|
||||||
#include "Nanos.hpp"
|
#include "Nanos.hpp"
|
||||||
@ -107,7 +106,6 @@ int main() {
|
|||||||
CustomCommands::init();
|
CustomCommands::init();
|
||||||
Combat::init();
|
Combat::init();
|
||||||
Chat::init();
|
Chat::init();
|
||||||
MobAI::init();
|
|
||||||
Items::init();
|
Items::init();
|
||||||
Eggs::init();
|
Eggs::init();
|
||||||
Missions::init();
|
Missions::init();
|
||||||
|
Loading…
Reference in New Issue
Block a user