diff options
author | WlodekM <[email protected]> | 2024-06-16 10:35:45 +0300 |
---|---|---|
committer | WlodekM <[email protected]> | 2024-06-16 10:35:45 +0300 |
commit | abef6da56913f1c55528103e60a50451a39628b1 (patch) | |
tree | b3c8092471ecbb73e568cd0d336efa0e7871ee8d /src/Entity.h |
initial commit
Diffstat (limited to 'src/Entity.h')
-rw-r--r-- | src/Entity.h | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/src/Entity.h b/src/Entity.h new file mode 100644 index 0000000..c3e2dc3 --- /dev/null +++ b/src/Entity.h @@ -0,0 +1,260 @@ +#ifndef CC_ENTITY_H +#define CC_ENTITY_H +#include "EntityComponents.h" +#include "Physics.h" +#include "Constants.h" +#include "PackedCol.h" +#include "String.h" +/* Represents an in-game entity. + Copyright 2014-2023 ClassiCube | Licensed under BSD-3 +*/ +struct Model; +struct IGameComponent; +struct ScheduledTask; +struct LocalPlayer; + +extern struct IGameComponent TabList_Component; +extern struct IGameComponent Entities_Component; + +#ifdef CC_BUILD_SPLITSCREEN +#define MAX_LOCAL_PLAYERS 4 +#else +#define MAX_LOCAL_PLAYERS 1 +#endif +#define MAX_NET_PLAYERS 255 + +/* Offset used to avoid floating point roundoff errors. */ +#define ENTITY_ADJUSTMENT 0.001f +#define ENTITIES_MAX_COUNT (MAX_NET_PLAYERS + MAX_LOCAL_PLAYERS) +#define ENTITIES_SELF_ID 255 + +enum NameMode { + NAME_MODE_NONE, NAME_MODE_HOVERED, NAME_MODE_ALL, NAME_MODE_ALL_HOVERED, NAME_MODE_ALL_UNSCALED, NAME_MODE_COUNT +}; +extern const char* const NameMode_Names[NAME_MODE_COUNT]; + +enum ShadowMode { + SHADOW_MODE_NONE, SHADOW_MODE_SNAP_TO_BLOCK, SHADOW_MODE_CIRCLE, SHADOW_MODE_CIRCLE_ALL, SHADOW_MODE_COUNT +}; +extern const char* const ShadowMode_Names[SHADOW_MODE_COUNT]; + +enum EntityType { ENTITY_TYPE_NONE, ENTITY_TYPE_PLAYER }; + +/* Which fields are included/valid in a LocationUpdate */ +#define LU_HAS_POS 0x01 +#define LU_HAS_PITCH 0x02 +#define LU_HAS_YAW 0x04 +#define LU_HAS_ROTX 0x08 +#define LU_HAS_ROTZ 0x10 + +/* 0-11-00000 How to move the entity when position field is included */ +#define LU_POS_MODEMASK 0x60 + +/* 0-00-00000 Entity is instantly teleported to update->pos */ +#define LU_POS_ABSOLUTE_INSTANT 0x00 +/* 0-01-00000 Entity is smoothly moved to update->pos */ +#define LU_POS_ABSOLUTE_SMOOTH 0x20 +/* 0-10-00000 Entity is smoothly moved to current position + update->pos */ +#define LU_POS_RELATIVE_SMOOTH 0x40 +/* 0-11-00000 Entity is offset/shifted by update->pos */ +#define LU_POS_RELATIVE_SHIFT 0x60 + +/* If set, then linearly interpolates between current and new angles */ +/* If not set, then current angles are immediately updated to new angles */ +#define LU_ORI_INTERPOLATE 0x80 + +/* Represents a location update for an entity. Can be a relative position, full position, and/or an orientation update. */ +struct LocationUpdate { + Vec3 pos; + float pitch, yaw, rotX, rotZ; + cc_uint8 flags; +}; + +/* Represents a position and orientation state */ +struct EntityLocation { Vec3 pos; float pitch, yaw, rotX, rotY, rotZ; }; + +struct Entity; +struct EntityVTABLE { + void (*Tick)(struct Entity* e, float delta); + void (*Despawn)(struct Entity* e); + void (*SetLocation)(struct Entity* e, struct LocationUpdate* update); + PackedCol (*GetCol)(struct Entity* e); + void (*RenderModel)(struct Entity* e, float delta, float t); + cc_bool (*ShouldRenderName)(struct Entity* e); +}; + +/* Skin is still being downloaded asynchronously */ +#define SKIN_FETCH_DOWNLOADING 1 +/* Skin was downloaded or copied from another entity with the same skin. */ +#define SKIN_FETCH_COMPLETED 2 + +/* true to restrict model scale (needed for local player, giant model collisions are too costly) */ +#define ENTITY_FLAG_MODEL_RESTRICTED_SCALE 0x01 +/* Whether the ModelVB field of this Entity instance refers to valid memory */ +/* This is just a hack to work around CEF plugin which declares Entity structs instances, */ +/* but those instances are declared using the older struct definition which lacked the ModelVB field */ +/* And therefore trying to access the ModelVB Field in entity struct instances created by the CEF plugin */ +/* results in attempting to read or write data from potentially invalid memory */ +#define ENTITY_FLAG_HAS_MODELVB 0x02 +/* Whether in classic mode, to slightly adjust this entity downwards when rendering it */ +/* to replicate the behaviour of the original vanilla classic client */ +#define ENTITY_FLAG_CLASSIC_ADJUST 0x04 + +/* Contains a model, along with position, velocity, and rotation. May also contain other fields and properties. */ +struct Entity { + const struct EntityVTABLE* VTABLE; + Vec3 Position; + /* NOTE: Do NOT change order of yaw/pitch, this will break models in plugins */ + float Pitch, Yaw, RotX, RotY, RotZ; + Vec3 Velocity; + + struct Model* Model; + BlockID ModelBlock; /* BlockID, if model name was originally a valid block. */ + cc_uint8 Flags; + cc_bool ShouldRender; + struct AABB ModelAABB; + Vec3 ModelScale, Size; + int _skinReqID; + + cc_uint8 SkinType; + cc_uint8 SkinFetchState; + cc_bool NoShade, OnGround; + GfxResourceID TextureId, MobTextureId; + float uScale, vScale; + struct Matrix Transform; + + struct AnimatedComp Anim; + char SkinRaw[STRING_SIZE]; + char NameRaw[STRING_SIZE]; + struct Texture NameTex; + + /* Previous and next intended location of the entity */ + /* Current state is linearly interpolated between prev and next */ + struct EntityLocation prev, next; + GfxResourceID ModelVB; +}; +typedef cc_bool (*Entity_TouchesCondition)(BlockID block); + +/* Initialises non-zero fields of the given entity. */ +void Entity_Init(struct Entity* e); +/* Gets the position of the eye of the given entity's model. */ +Vec3 Entity_GetEyePosition(struct Entity* e); +/* Returns the height of the eye of the given entity's model. */ +/* (i.e. distance to eye from feet/base of the model) */ +float Entity_GetEyeHeight(struct Entity* e); +/* Calculates the transformation matrix applied when rendering the given entity. */ +CC_API void Entity_GetTransform(struct Entity* e, Vec3 pos, Vec3 scale, struct Matrix* m); +void Entity_GetPickingBounds(struct Entity* e, struct AABB* bb); +/* Gets the current collision bounds of the given entity. */ +void Entity_GetBounds(struct Entity* e, struct AABB* bb); +/* Sets the model of the entity. (i.e its appearance) */ +CC_API void Entity_SetModel(struct Entity* e, const cc_string* model); +/* Updates cached Size and ModelAABB of the given entity. */ +/* NOTE: Only needed when manually changing Model or ModelScale. */ +/* Entity_SetModel already calls this method. */ +void Entity_UpdateModelBounds(struct Entity* e); + +/* Whether the given entity is touching any blocks meeting the given condition */ +CC_API cc_bool Entity_TouchesAny(struct AABB* bb, Entity_TouchesCondition cond); +cc_bool Entity_TouchesAnyRope(struct Entity* e); +cc_bool Entity_TouchesAnyLava(struct Entity* e); +cc_bool Entity_TouchesAnyWater(struct Entity* e); + +/* Sets the nametag above the given entity's head */ +void Entity_SetName(struct Entity* e, const cc_string* name); +/* Sets the skin name of the given entity. */ +void Entity_SetSkin(struct Entity* e, const cc_string* skin); +void Entity_LerpAngles(struct Entity* e, float t); + +/* Global data for all entities */ +/* (Actual entities may point to NetPlayers_List or elsewhere) */ +CC_VAR extern struct _EntitiesData { + struct Entity* List[ENTITIES_MAX_COUNT]; + cc_uint8 NamesMode, ShadowsMode; + struct LocalPlayer* CurPlayer; +} Entities; + +/* Ticks all entities */ +void Entities_Tick(struct ScheduledTask* task); +/* Renders all entities */ +void Entities_RenderModels(float delta, float t); +/* Removes the given entity, raising EntityEvents.Removed event */ +void Entities_Remove(EntityID id); +/* Gets the ID of the closest entity to the given entity */ +/* Returns -1 if there is no other entity nearby */ +int Entities_GetClosest(struct Entity* src); + +#define TABLIST_MAX_NAMES 256 +/* Data for all entries in tab list */ +CC_VAR extern struct _TabListData { + /* Buffer indices for player/list/group names */ + /* Use TabList_UNSAFE_GetPlayer/List/Group to get these names */ + /* NOTE: An Offset of 0 means the entry is unused */ + cc_uint16 NameOffsets[TABLIST_MAX_NAMES]; + /* Position/Order of this entry within the group */ + cc_uint8 GroupRanks[TABLIST_MAX_NAMES]; + struct StringsBuffer _buffer; + /* Whether the tablist entry is automatically removed */ + /* when the entity with the same ID is removed */ + cc_uint8 _entityLinked[TABLIST_MAX_NAMES >> 3]; +} TabList; + +/* Removes the tab list entry with the given ID, raising TabListEvents.Removed event */ +CC_API void TabList_Remove(EntityID id); +/* Sets the data for the tab list entry with the given id */ +/* Raises TabListEvents.Changed if replacing, TabListEvents.Added if a new entry */ +CC_API void TabList_Set(EntityID id, const cc_string* player, const cc_string* list, const cc_string* group, cc_uint8 rank); + +/* Raw unformatted name (for Tab name auto complete) */ +#define TabList_UNSAFE_GetPlayer(id) StringsBuffer_UNSAFE_Get(&TabList._buffer, TabList.NameOffsets[id] - 3) +/* Formatted name for display in tab list */ +#define TabList_UNSAFE_GetList(id) StringsBuffer_UNSAFE_Get(&TabList._buffer, TabList.NameOffsets[id] - 2) +/* Name of the group this entry is in (e.g. rank name, map name) */ +#define TabList_UNSAFE_GetGroup(id) StringsBuffer_UNSAFE_Get(&TabList._buffer, TabList.NameOffsets[id] - 1) + +#define TabList_EntityLinked_Get(id) (TabList._entityLinked[id >> 3] & (1 << (id & 0x7))) +#define TabList_EntityLinked_Set(id) (TabList._entityLinked[id >> 3] |= (cc_uint8)(1 << (id & 0x7))) +#define TabList_EntityLinked_Reset(id) (TabList._entityLinked[id >> 3] &= (cc_uint8)~(1 << (id & 0x7))) + + +/* Represents another entity in multiplayer */ +struct NetPlayer { + struct Entity Base; + struct NetInterpComp Interp; +}; +CC_API void NetPlayer_Init(struct NetPlayer* player); +extern struct NetPlayer NetPlayers_List[MAX_NET_PLAYERS]; + +struct LocalPlayerInput; +struct LocalPlayerInput { + void (*GetMovement)(struct LocalPlayer* p, float* xMoving, float* zMoving); + struct LocalPlayerInput* next; +}; +void LocalPlayerInput_Add(struct LocalPlayerInput* source); +void LocalPlayerInput_Remove(struct LocalPlayerInput* source); + +/* Represents the user/player's own entity. */ +struct LocalPlayer { + struct Entity Base; + Vec3 Spawn, OldVelocity; + float SpawnYaw, SpawnPitch, ReachDistance; + struct HacksComp Hacks; + struct TiltComp Tilt; + struct InterpComp Interp; + struct CollisionsComp Collisions; + struct PhysicsComp Physics; + cc_bool _warnedRespawn, _warnedFly, _warnedNoclip, _warnedZoom; + cc_uint8 index; +}; + +extern struct LocalPlayer LocalPlayer_Instances[MAX_LOCAL_PLAYERS]; +/* Returns how high (in blocks) the player can jump. */ +float LocalPlayer_JumpHeight(struct LocalPlayer* p); +/* Interpolates current position and orientation between Interp.Prev and Interp.Next */ +void LocalPlayer_SetInterpPosition(struct LocalPlayer* p, float t); +void LocalPlayer_ResetJumpVelocity(struct LocalPlayer* p); +cc_bool LocalPlayer_CheckCanZoom(struct LocalPlayer* p); +/* Moves local player back to spawn point. */ +void LocalPlayers_MoveToSpawn(struct LocationUpdate* update); +void LocalPlayer_CalcDefaultSpawn(struct LocalPlayer* p, struct LocationUpdate* update); +#endif |