Latest compatible version of Classicube from the original GitHub repository (https://github.com/ClassiCube/ClassiCube) that can be compiled on Classicube for PowerMac PPC running Mac OS X 10.4.

This commit is contained in:
Andrei Alexandru
2025-12-17 13:17:57 +02:00
commit c71492f846
1248 changed files with 422858 additions and 0 deletions

263
src/Entity.h Normal file
View File

@@ -0,0 +1,263 @@
#ifndef CC_ENTITY_H
#define CC_ENTITY_H
#include "EntityComponents.h"
#include "Physics.h"
#include "Constants.h"
#include "PackedCol.h"
#include "String.h"
CC_BEGIN_HEADER
/* Represents an in-game entity.
Copyright 2014-2025 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 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(int 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);
CC_END_HEADER
#endif