OpenFusion/src/MobManager.hpp

118 lines
3.0 KiB
C++
Raw Normal View History

#pragma once
#include "CNProtocol.hpp"
#include "CNShared.hpp"
#include "CNShardServer.hpp"
#include "NPC.hpp"
#include "contrib/JSON.hpp"
#include <map>
2020-10-01 14:36:16 +00:00
#include <queue>
enum class MobState {
INACTIVE,
ROAMING,
COMBAT,
RETREAT,
DEAD
};
struct Mob : public BaseNPC {
// general
MobState state;
int maxHealth;
int spawnX;
int spawnY;
int spawnZ;
// dead
time_t killedTime = 0;
time_t regenTime;
bool summoned = false;
bool despawned = false; // for the sake of death animations
// roaming
int idleRange;
time_t nextMovement = 0;
bool staticPath = false;
// combat
CNSocket *target = nullptr;
time_t nextAttack = 0;
// temporary; until we're sure what's what
nlohmann::json data;
2020-10-01 01:44:37 +00:00
Mob(int x, int y, int z, int iID, int type, int hp, int angle, nlohmann::json d, int32_t id)
: BaseNPC(x, y, z, iID, type, id), maxHealth(hp) {
state = MobState::ROAMING;
data = d;
regenTime = data["m_iRegenTime"];
idleRange = (int)data["m_iIdleRange"] * 2; // TODO: tuning?
// XXX: temporarily force respawns for Fusions until we implement instancing
if (regenTime >= 300000000)
regenTime = 1500;
spawnX = appearanceData.iX;
spawnY = appearanceData.iY;
spawnZ = appearanceData.iZ;
appearanceData.iConditionBitFlag = 0;
// NOTE: there appear to be discrepancies in the dump
appearanceData.iHP = maxHealth;
npcClass = NPC_MOB;
}
// constructor for /summon
2020-10-01 01:44:37 +00:00
Mob(int x, int y, int z, int iID, int type, nlohmann::json d, int32_t id)
: Mob(x, y, z, iID, type, 0, 0, d, id) {
summoned = true; // will be despawned and deallocated when killed
appearanceData.iHP = maxHealth = d["m_iHP"];
}
2020-09-18 21:24:15 +00:00
~Mob() {}
auto operator[](std::string s) {
return data[s];
}
};
namespace MobManager {
extern std::map<int32_t, Mob*> Mobs;
2020-10-01 14:36:16 +00:00
extern std::queue<int32_t> RemovalQueue;
extern bool simulateMobs;
void init();
void step(CNServer*, time_t);
void playerTick(CNServer*, time_t);
void deadStep(Mob*, time_t);
void combatStep(Mob*, time_t);
void retreatStep(Mob*, time_t);
void roamingStep(Mob*, time_t);
void pcAttackNpcs(CNSocket *sock, CNPacketData *data);
void combatBegin(CNSocket *sock, CNPacketData *data);
void combatEnd(CNSocket *sock, CNPacketData *data);
void dotDamageOnOff(CNSocket *sock, CNPacketData *data);
void dealGooDamage(CNSocket *sock, int amount);
void npcAttackPc(Mob *mob, time_t currTime);
int hitMob(CNSocket *sock, Mob *mob, int damage);
void killMob(CNSocket *sock, Mob *mob);
void giveReward(CNSocket *sock);
std::pair<int,int> lerp(int, int, int, int, int);
std::pair<int,int> getDamage(int, int, bool, bool, int, int, int);
void pcAttackChars(CNSocket *sock, CNPacketData *data);
void resendMobHP(Mob *mob);
void incNextMovement(Mob *mob, time_t currTime=0);
bool aggroCheck(Mob *mob, time_t currTime);
}