mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-05 06:50:04 +00:00
172 lines
4.3 KiB
C++
172 lines
4.3 KiB
C++
#pragma once
|
|
|
|
#include "CNProtocol.hpp"
|
|
#include "CNShared.hpp"
|
|
#include "CNShardServer.hpp"
|
|
#include "NPC.hpp"
|
|
|
|
#include "contrib/JSON.hpp"
|
|
|
|
#include <map>
|
|
#include <unordered_map>
|
|
#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;
|
|
int level;
|
|
|
|
std::unordered_map<int32_t,time_t> unbuffTimes;
|
|
|
|
// dead
|
|
time_t killedTime = 0;
|
|
time_t regenTime;
|
|
bool summoned = false;
|
|
bool despawned = false; // for the sake of death animations
|
|
|
|
// roaming
|
|
int idleRange;
|
|
const int sightRange;
|
|
time_t nextMovement = 0;
|
|
bool staticPath = false;
|
|
int roamX, roamY, roamZ;
|
|
|
|
// combat
|
|
CNSocket *target = nullptr;
|
|
time_t nextAttack = 0;
|
|
time_t lastDrainTime = 0;
|
|
|
|
// drop
|
|
int dropType;
|
|
|
|
// group
|
|
int groupLeader = 0;
|
|
int offsetX, offsetY;
|
|
int groupMember[4] = {0, 0, 0, 0};
|
|
|
|
// temporary; until we're sure what's what
|
|
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),
|
|
sightRange(d["m_iSightRange"]) {
|
|
state = MobState::ROAMING;
|
|
|
|
data = d;
|
|
|
|
regenTime = data["m_iRegenTime"];
|
|
idleRange = (int)data["m_iIdleRange"] * 2; // TODO: tuning?
|
|
dropType = data["m_iDropType"];
|
|
level = data["m_iNpcLevel"];
|
|
|
|
roamX = spawnX = appearanceData.iX;
|
|
roamY = spawnY = appearanceData.iY;
|
|
roamZ = spawnZ = appearanceData.iZ;
|
|
|
|
offsetX = 0;
|
|
offsetY = 0;
|
|
|
|
appearanceData.iConditionBitFlag = 0;
|
|
|
|
// NOTE: there appear to be discrepancies in the dump
|
|
appearanceData.iHP = maxHealth;
|
|
|
|
npcClass = NPC_MOB;
|
|
}
|
|
|
|
// constructor for /summon
|
|
Mob(int x, int y, int z, uint64_t iID, int type, nlohmann::json d, int32_t id)
|
|
: Mob(x, y, z, 0, iID, type, 0, d, id) {
|
|
summoned = true; // will be despawned and deallocated when killed
|
|
appearanceData.iHP = maxHealth = d["m_iHP"];
|
|
}
|
|
|
|
~Mob() {}
|
|
|
|
auto operator[](std::string s) {
|
|
return data[s];
|
|
}
|
|
};
|
|
|
|
struct MobDropChance {
|
|
int dropChance;
|
|
std::vector<int> cratesRatio;
|
|
};
|
|
|
|
struct MobDrop {
|
|
std::vector<int> crateIDs;
|
|
int dropChanceType;
|
|
int taros;
|
|
int fm;
|
|
int boosts;
|
|
};
|
|
|
|
struct Bullet {
|
|
int pointDamage;
|
|
int groupDamage;
|
|
bool weaponBoost;
|
|
int bulletType;
|
|
};
|
|
|
|
namespace MobManager {
|
|
extern std::map<int32_t, Mob*> Mobs;
|
|
extern std::queue<int32_t> RemovalQueue;
|
|
extern std::map<int32_t, MobDropChance> MobDropChances;
|
|
extern std::map<int32_t, MobDrop> MobDrops;
|
|
extern std::map<int32_t, std::map<int8_t, Bullet>> Bullets;
|
|
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, Mob *mob);
|
|
void getReward(sItemBase *reward, MobDrop *drop, MobDropChance *chance);
|
|
void giveEventReward(CNSocket* sock, Player* player);
|
|
|
|
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 drainMobHP(Mob *mob, int amount);
|
|
void incNextMovement(Mob *mob, time_t currTime=0);
|
|
bool aggroCheck(Mob *mob, time_t currTime);
|
|
void clearDebuff(Mob *mob);
|
|
|
|
void grenadeFire(CNSocket* sock, CNPacketData* data);
|
|
void rocketFire(CNSocket* sock, CNPacketData* data);
|
|
void projectileHit(CNSocket* sock, CNPacketData* data);
|
|
/// returns bullet id
|
|
int8_t addBullet(Player* plr, bool isGrenade);
|
|
|
|
void followToCombat(Mob *mob);
|
|
|
|
}
|