mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-05 06:50:04 +00:00
dd54668697
* FM, Taros and Boosts awards from killing mobs should be pretty accurate now. A temporary formula for adjusting player/mob level gap is implemented, but it will probably need to be adjusted in the future * Mobs now drop correct crates * Crates can be opened and give you correct items This includes regular mob crates, world boss crates, mission crates, IZ race crates, E.G.G.E.R.s, golden Eggs, and Event Crates. Keep in mind that neither IZ races or golden Eggs are implemented, but if you spawn such a crate it can be opened. * All data is read from a json file, for which I'm going to release a tool soon so it's easily adjustable * There is a new setting for enabling events, which enables dropping extra event crates These are Knishmas, Halloween and Easter
143 lines
3.6 KiB
C++
143 lines
3.6 KiB
C++
#pragma once
|
|
|
|
#include "CNProtocol.hpp"
|
|
#include "CNShared.hpp"
|
|
#include "CNShardServer.hpp"
|
|
#include "NPC.hpp"
|
|
|
|
#include "contrib/JSON.hpp"
|
|
|
|
#include <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;
|
|
|
|
// 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;
|
|
int roamX, roamY, roamZ;
|
|
|
|
//drop
|
|
int dropType;
|
|
|
|
// 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) {
|
|
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"];
|
|
|
|
// XXX: temporarily force respawns for Fusions until we implement instancing
|
|
//if (regenTime >= 300000000)
|
|
// regenTime = 1500;
|
|
|
|
roamX = spawnX = appearanceData.iX;
|
|
roamY = spawnY = appearanceData.iY;
|
|
roamZ = spawnZ = appearanceData.iZ;
|
|
|
|
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;
|
|
};
|
|
|
|
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 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);
|
|
sItemBase getReward(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 resendMobHP(Mob *mob);
|
|
void incNextMovement(Mob *mob, time_t currTime=0);
|
|
bool aggroCheck(Mob *mob, time_t currTime);
|
|
}
|