mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2025-07-14 13:30:08 +00:00

Storing certain things in appearance data and others in their own fields was gross. Now everything is stored on the same level and functions have been added to generate appearance data when it's needed by the client.
158 lines
3.4 KiB
C++
158 lines
3.4 KiB
C++
#pragma once
|
|
|
|
#include "core/Core.hpp"
|
|
#include "Chunking.hpp"
|
|
|
|
#include <stdint.h>
|
|
#include <set>
|
|
|
|
enum class EntityType : uint8_t {
|
|
INVALID,
|
|
PLAYER,
|
|
SIMPLE_NPC,
|
|
COMBAT_NPC,
|
|
MOB,
|
|
EGG,
|
|
BUS
|
|
};
|
|
|
|
struct Entity {
|
|
EntityType kind = EntityType::INVALID;
|
|
int x = 0, y = 0, z = 0;
|
|
uint64_t instanceID = 0;
|
|
ChunkPos chunkPos = {};
|
|
std::set<Chunk*> viewableChunks = {};
|
|
|
|
// destructor must be virtual, apparently
|
|
virtual ~Entity() {}
|
|
|
|
virtual bool isAlive() { return true; }
|
|
|
|
// stubs
|
|
virtual void enterIntoViewOf(CNSocket *sock) = 0;
|
|
virtual void disappearFromViewOf(CNSocket *sock) = 0;
|
|
};
|
|
|
|
struct EntityRef {
|
|
EntityType type;
|
|
union {
|
|
CNSocket *sock;
|
|
int32_t id;
|
|
};
|
|
|
|
EntityRef(CNSocket *s);
|
|
EntityRef(int32_t i);
|
|
|
|
bool isValid() const;
|
|
Entity *getEntity() const;
|
|
|
|
bool operator==(const EntityRef& other) const {
|
|
if (type != other.type)
|
|
return false;
|
|
|
|
if (type == EntityType::PLAYER)
|
|
return sock == other.sock;
|
|
|
|
return id == other.id;
|
|
}
|
|
|
|
// arbitrary ordering
|
|
bool operator<(const EntityRef& other) const {
|
|
if (type == other.type) {
|
|
if (type == EntityType::PLAYER)
|
|
return sock < other.sock;
|
|
else
|
|
return id < other.id;
|
|
}
|
|
|
|
return type < other.type;
|
|
}
|
|
};
|
|
|
|
/*
|
|
* Subclasses
|
|
*/
|
|
class BaseNPC : public Entity {
|
|
public:
|
|
int id;
|
|
int type;
|
|
int hp;
|
|
int angle;
|
|
int cbf;
|
|
int barkerType;
|
|
bool loopingPath = false;
|
|
|
|
BaseNPC(int _X, int _Y, int _Z, int _A, uint64_t iID, int t, int _id) { // XXX
|
|
x = _X;
|
|
y = _Y;
|
|
z = _Z;
|
|
type = t;
|
|
hp = 400;
|
|
angle = _A;
|
|
cbf = 0;
|
|
barkerType = 0;
|
|
id = _id;
|
|
instanceID = iID;
|
|
};
|
|
|
|
virtual void enterIntoViewOf(CNSocket *sock) override;
|
|
virtual void disappearFromViewOf(CNSocket *sock) override;
|
|
|
|
sNPCAppearanceData getAppearanceData();
|
|
};
|
|
|
|
struct CombatNPC : public BaseNPC {
|
|
int maxHealth = 0;
|
|
int spawnX = 0;
|
|
int spawnY = 0;
|
|
int spawnZ = 0;
|
|
int level = 0;
|
|
int speed = 300;
|
|
|
|
void (*_stepAI)(CombatNPC*, time_t) = nullptr;
|
|
|
|
// XXX
|
|
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),
|
|
maxHealth(maxHP) {}
|
|
|
|
virtual void stepAI(time_t currTime) {
|
|
if (_stepAI != nullptr)
|
|
_stepAI(this, currTime);
|
|
}
|
|
|
|
virtual bool isAlive() override { return hp > 0; }
|
|
};
|
|
|
|
// Mob is in MobAI.hpp, Player is in Player.hpp
|
|
|
|
// TODO: decouple from BaseNPC
|
|
struct Egg : public BaseNPC {
|
|
bool summoned = false;
|
|
bool dead = false;
|
|
time_t deadUntil;
|
|
|
|
Egg(int x, int y, int z, uint64_t iID, int t, int32_t id, bool summon)
|
|
: BaseNPC(x, y, z, 0, iID, t, id) {
|
|
summoned = summon;
|
|
kind = EntityType::EGG;
|
|
}
|
|
|
|
virtual bool isAlive() override { return !dead; }
|
|
|
|
virtual void enterIntoViewOf(CNSocket *sock) override;
|
|
virtual void disappearFromViewOf(CNSocket *sock) override;
|
|
};
|
|
|
|
// TODO: decouple from BaseNPC
|
|
struct Bus : public BaseNPC {
|
|
Bus(int x, int y, int z, int angle, uint64_t iID, int t, int id) :
|
|
BaseNPC(x, y, z, angle, iID, t, id) {
|
|
kind = EntityType::BUS;
|
|
loopingPath = true;
|
|
}
|
|
|
|
virtual void enterIntoViewOf(CNSocket *sock) override;
|
|
virtual void disappearFromViewOf(CNSocket *sock) override;
|
|
};
|