2020-08-27 20:16:52 +00:00
|
|
|
#pragma once
|
|
|
|
|
2021-03-17 19:07:40 +00:00
|
|
|
#include "core/Core.hpp"
|
2021-03-13 22:55:16 +00:00
|
|
|
#include "NPCManager.hpp"
|
2020-09-16 23:43:48 +00:00
|
|
|
|
|
|
|
enum class MobState {
|
|
|
|
INACTIVE,
|
|
|
|
ROAMING,
|
|
|
|
COMBAT,
|
|
|
|
RETREAT,
|
|
|
|
DEAD
|
|
|
|
};
|
|
|
|
|
2021-03-31 19:05:49 +00:00
|
|
|
namespace MobAI {
|
|
|
|
// needs to be declared before Mob's constructor
|
|
|
|
void step(CombatNPC*, time_t);
|
|
|
|
};
|
|
|
|
|
2021-03-21 18:29:17 +00:00
|
|
|
struct Mob : public CombatNPC {
|
2020-09-24 01:18:41 +00:00
|
|
|
// general
|
2021-03-21 18:29:17 +00:00
|
|
|
MobState state = MobState::INACTIVE;
|
2020-09-22 18:33:10 +00:00
|
|
|
|
2021-03-21 18:29:17 +00:00
|
|
|
std::unordered_map<int32_t,time_t> unbuffTimes = {};
|
2020-10-17 17:26:09 +00:00
|
|
|
|
2020-09-24 01:18:41 +00:00
|
|
|
// dead
|
|
|
|
time_t killedTime = 0;
|
2021-03-21 18:29:17 +00:00
|
|
|
time_t regenTime = 0;
|
2020-09-24 22:36:25 +00:00
|
|
|
bool summoned = false;
|
2020-09-24 01:18:41 +00:00
|
|
|
bool despawned = false; // for the sake of death animations
|
|
|
|
|
|
|
|
// roaming
|
2021-03-21 18:29:17 +00:00
|
|
|
int idleRange = 0;
|
|
|
|
const int sightRange = 0;
|
2020-09-22 18:33:10 +00:00
|
|
|
time_t nextMovement = 0;
|
2020-10-12 19:03:18 +00:00
|
|
|
bool staticPath = false;
|
2021-03-21 18:29:17 +00:00
|
|
|
int roamX = 0, roamY = 0, roamZ = 0;
|
2020-09-22 18:33:10 +00:00
|
|
|
|
2020-09-24 01:18:41 +00:00
|
|
|
// combat
|
|
|
|
CNSocket *target = nullptr;
|
|
|
|
time_t nextAttack = 0;
|
2020-10-28 21:05:01 +00:00
|
|
|
time_t lastDrainTime = 0;
|
2020-11-25 08:10:05 +00:00
|
|
|
int skillStyle = -1; // -1 for nothing, 0-2 for corruption, -2 for eruption
|
2021-03-21 18:29:17 +00:00
|
|
|
int hitX = 0, hitY = 0, hitZ = 0; // for use in ability targeting
|
2020-09-24 01:18:41 +00:00
|
|
|
|
2020-11-15 07:06:29 +00:00
|
|
|
// group
|
|
|
|
int groupLeader = 0;
|
2021-03-21 18:29:17 +00:00
|
|
|
int offsetX = 0, offsetY = 0;
|
|
|
|
int groupMember[4] = {};
|
2020-11-15 07:06:29 +00:00
|
|
|
|
2021-03-22 16:53:46 +00:00
|
|
|
// for optimizing away AI in empty chunks
|
|
|
|
int playersInView = 0;
|
|
|
|
|
2020-09-22 18:33:10 +00:00
|
|
|
// temporary; until we're sure what's what
|
2021-03-21 18:29:17 +00:00
|
|
|
nlohmann::json data = {};
|
2020-09-22 18:33:10 +00:00
|
|
|
|
2021-03-21 02:54:24 +00:00
|
|
|
Mob(int x, int y, int z, int angle, uint64_t iID, int t, nlohmann::json d, int32_t id)
|
2021-03-21 18:29:17 +00:00
|
|
|
: CombatNPC(x, y, z, angle, iID, t, id, d["m_iHP"]),
|
2020-10-20 22:55:58 +00:00
|
|
|
sightRange(d["m_iSightRange"]) {
|
2020-09-16 23:43:48 +00:00
|
|
|
state = MobState::ROAMING;
|
|
|
|
|
2020-09-24 01:18:41 +00:00
|
|
|
data = d;
|
|
|
|
|
2021-04-30 00:20:53 +00:00
|
|
|
speed = data["m_iRunSpeed"];
|
2020-09-24 01:18:41 +00:00
|
|
|
regenTime = data["m_iRegenTime"];
|
2020-12-17 00:59:55 +00:00
|
|
|
idleRange = (int)data["m_iIdleRange"];
|
functional crates (no more plungers) (#133)
* 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
2020-10-10 17:18:47 +00:00
|
|
|
level = data["m_iNpcLevel"];
|
2020-09-24 01:18:41 +00:00
|
|
|
|
2021-04-14 00:57:24 +00:00
|
|
|
roamX = spawnX = x;
|
|
|
|
roamY = spawnY = y;
|
|
|
|
roamZ = spawnZ = z;
|
2020-09-22 18:33:10 +00:00
|
|
|
|
2020-11-23 00:14:22 +00:00
|
|
|
offsetX = 0;
|
|
|
|
offsetY = 0;
|
|
|
|
|
2020-09-22 20:22:10 +00:00
|
|
|
appearanceData.iConditionBitFlag = 0;
|
|
|
|
|
2020-09-16 23:43:48 +00:00
|
|
|
// NOTE: there appear to be discrepancies in the dump
|
|
|
|
appearanceData.iHP = maxHealth;
|
2020-09-24 22:36:25 +00:00
|
|
|
|
2021-06-20 18:12:40 +00:00
|
|
|
kind = EntityType::MOB;
|
2021-03-31 19:05:49 +00:00
|
|
|
_stepAI = MobAI::step;
|
2020-09-24 22:36:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// constructor for /summon
|
2021-03-21 02:54:24 +00:00
|
|
|
Mob(int x, int y, int z, uint64_t iID, int t, nlohmann::json d, int32_t id)
|
|
|
|
: Mob(x, y, z, 0, iID, t, d, id) {
|
2020-09-24 22:36:25 +00:00
|
|
|
summoned = true; // will be despawned and deallocated when killed
|
2020-09-16 23:43:48 +00:00
|
|
|
}
|
2020-09-24 22:36:25 +00:00
|
|
|
|
2020-09-18 21:24:15 +00:00
|
|
|
~Mob() {}
|
2020-09-22 18:33:10 +00:00
|
|
|
|
|
|
|
auto operator[](std::string s) {
|
|
|
|
return data[s];
|
|
|
|
}
|
2020-09-16 23:43:48 +00:00
|
|
|
};
|
2020-08-27 20:16:52 +00:00
|
|
|
|
2021-03-13 22:55:16 +00:00
|
|
|
namespace MobAI {
|
2020-10-07 18:38:32 +00:00
|
|
|
extern bool simulateMobs;
|
2020-09-16 23:43:48 +00:00
|
|
|
|
2021-03-13 22:55:16 +00:00
|
|
|
// TODO: make this internal later
|
2020-10-12 19:03:18 +00:00
|
|
|
void incNextMovement(Mob *mob, time_t currTime=0);
|
2020-10-04 23:54:08 +00:00
|
|
|
bool aggroCheck(Mob *mob, time_t currTime);
|
2020-10-28 21:05:01 +00:00
|
|
|
void clearDebuff(Mob *mob);
|
2020-11-16 03:13:40 +00:00
|
|
|
void followToCombat(Mob *mob);
|
2020-12-30 22:07:10 +00:00
|
|
|
void groupRetreat(Mob *mob);
|
2021-01-09 13:16:29 +00:00
|
|
|
void enterCombat(CNSocket *sock, Mob *mob);
|
2020-08-27 20:16:52 +00:00
|
|
|
}
|