1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
#ifndef CC_BLOCK_H
#define CC_BLOCK_H
#include "PackedCol.h"
#include "Vectors.h"
#include "Constants.h"
#include "BlockID.h"
/* Stores properties and data for blocks.
Also performs automatic rotation of directional blocks.
Copyright 2014-2023 ClassiCube | Licensed under BSD-3
*/
struct IGameComponent;
extern struct IGameComponent Blocks_Component;
enum SoundType {
SOUND_NONE, SOUND_WOOD, SOUND_GRAVEL, SOUND_GRASS,
SOUND_STONE, SOUND_METAL, SOUND_GLASS, SOUND_CLOTH,
SOUND_SAND, SOUND_SNOW, SOUND_COUNT
};
extern const char* const Sound_Names[SOUND_COUNT];
/* Describes how a block is rendered in the world. */
enum DrawType {
DRAW_OPAQUE, /* Completely covers blocks behind (e.g. dirt). */
DRAW_TRANSPARENT, /* Blocks behind show (e.g. glass). Pixels either fully visible or invisible. */
DRAW_TRANSPARENT_THICK, /* Same as Transparent, but all neighbour faces show. (e.g. leaves) */
DRAW_TRANSLUCENT, /* Blocks behind show (e.g. water). Pixels blend with other blocks behind. */
DRAW_GAS, /* Does not show (e.g. air). Can still be collided with. */
DRAW_SPRITE /* Block renders as an X (e.g. sapling). Pixels either fully visible or invisible. */
};
/* Describes the interaction a block has with a player when they collide with it. */
enum CollideType {
COLLIDE_NONE, /* No interaction when player collides. */
COLLIDE_LIQUID, /* 'swimming'/'bobbing' interaction when player collides. */
COLLIDE_SOLID, /* Block completely stops the player when they are moving. */
COLLIDE_ICE, /* Block is solid and partially slidable on. */
COLLIDE_SLIPPERY_ICE, /* Block is solid and fully slidable on. */
COLLIDE_WATER, /* Water style 'swimming'/'bobbing' interaction when player collides. */
COLLIDE_LAVA, /* Lava style 'swimming'/'bobbing' interaction when player collides. */
COLLIDE_CLIMB /* Rope/Ladder style climbing interaction when player collides. */
};
CC_VAR extern struct _BlockLists {
/* Whether this block is a liquid. (Like water/lava) */
cc_bool IsLiquid[BLOCK_COUNT];
/* Whether this block prevents lights from passing through it. */
cc_bool BlocksLight[BLOCK_COUNT];
/* Whether this block is fully bright/light emitting. (Like lava) */
cc_uint8 Brightness[BLOCK_COUNT];
/* Fog colour when player is inside this block. */
/* NOTE: Only applies if fog density is not 0. */
PackedCol FogCol[BLOCK_COUNT];
/* How thick fog is when player is inside this block. */
float FogDensity[BLOCK_COUNT];
/* Basic collision type of this block. (gas, liquid, or solid) */
cc_uint8 Collide[BLOCK_COUNT];
/* Extended collision type of this block, usually same as basic. */
/* NOTE: Not always the case. (e.g. ice, water, lava, rope differ) */
cc_uint8 ExtendedCollide[BLOCK_COUNT];
/* Speed multiplier when player is touching this block. */
/* Can be < 1 to slow player down, or > 1 to speed up. */
float SpeedMultiplier[BLOCK_COUNT];
/* Bit flags of which faces of this block uses light colour from neighbouring blocks. */
/* e.g. a block with Min.x of 0.0 uses light colour at X-1,Y,Z for XMIN face. */
/* e.g. a block with Min.x of 0.1 uses light colour at X,Y,Z for XMIN face. */
cc_uint8 LightOffset[BLOCK_COUNT];
/* Draw method used when rendering this block. See DrawType enum. */
cc_uint8 Draw[BLOCK_COUNT];
/* Sound played when the player manually destroys this block. See SoundType enum. */
cc_uint8 DigSounds[BLOCK_COUNT];
/* Sound played when the player walks on this block. See SoundType enum. */
cc_uint8 StepSounds[BLOCK_COUNT];
/* Whether fog colour is used to apply a tint effect to this block. */
cc_bool Tinted[BLOCK_COUNT];
/* Whether this block has an opaque draw type, min of (0,0,0), and max of (1,1,1) */
cc_bool FullOpaque[BLOCK_COUNT];
/* Offset/variation mode of this block. (only when drawn as a sprite) */
/* Some modes slightly randomly offset blocks to produce nicer looking clumps. */
cc_uint8 SpriteOffset[BLOCK_COUNT];
/* Coordinates of min corner of this block for collisions. */
Vec3 MinBB[BLOCK_COUNT];
/* Coordinates of max corner of this block for collisions. */
Vec3 MaxBB[BLOCK_COUNT];
/* Coordinates of min corner of this block for rendering. */
/* e.g. ice is very slightly offset horizontally. */
Vec3 RenderMinBB[BLOCK_COUNT];
/* Coordinates of max corner of this block for rendering. */
/* e.g. ice is very slightly offset horizontally. */
Vec3 RenderMaxBB[BLOCK_COUNT];
/* Texture ids of each face of blocks. */
TextureLoc Textures[BLOCK_COUNT * FACE_COUNT];
/* Whether this block is allowed to be placed. */
cc_bool CanPlace[BLOCK_COUNT];
/* Whether this block is allowed to be deleted. */
cc_bool CanDelete[BLOCK_COUNT];
/* Bit flags of faces hidden of two neighbouring blocks. */
cc_uint8 Hidden[BLOCK_COUNT * BLOCK_COUNT];
/* Bit flags of which faces of this block can stretch with greedy meshing. */
cc_uint8 CanStretch[BLOCK_COUNT];
/* Gravity of particles spawned when this block is broken */
float ParticleGravity[BLOCK_COUNT];
} Blocks;
#define Block_Tint(col, block)\
if (Blocks.Tinted[block]) col = PackedCol_Tint(col, Blocks.FogCol[block]);
/* Most blocks which 'stop' light actually stop the light starting at block below */
/* except for e.g. upside down slabs which 'stop' the light at same block level */
/* The difference can be seen by placing a lower and upper slab block on a wall, */
/* and comparing whether the block directly behind them is in shadow or not */
#define LIGHT_FLAG_SHADES_FROM_BELOW 6
cc_uint8 Block_ReadBrightness(cc_uint8 fullBright);
cc_uint8 Block_WriteFullBright(cc_uint8 brightness);
/* Returns whether the given block has been changed from default */
cc_bool Block_IsCustomDefined(BlockID block);
/* Updates state and raises event after the given block has been defined */
void Block_DefineCustom(BlockID block, cc_bool checkSprite);
/* Resets the given block to default */
void Block_UndefineCustom(BlockID block);
/* Resets all the properties of the given block to default */
void Block_ResetProps(BlockID block);
/* Gets the name of the given block */
/* NOTE: Name points directly within underlying buffer, you MUST NOT persist this string */
CC_API STRING_REF cc_string Block_UNSAFE_GetName( BlockID block);
typedef STRING_REF cc_string (*FP_Block_UNSAFE_GetName)(BlockID block);
/* Sets the name of the given block. */
void Block_SetName(BlockID block, const cc_string* name);
/* Finds the ID of the block whose name caselessly matches given name */
CC_API int Block_FindID(const cc_string* name);
/* Attempts to parse given name as a numerical block ID */
/* Falls back to Block_FindID if this fails */
CC_API int Block_Parse(const cc_string* name);
/* Sets the textures of the side faces of the given block */
void Block_SetSide(TextureLoc texLoc, BlockID blockId);
/* The texture for the given face of the given block */
#define Block_Tex(block, face) Blocks.Textures[(block) * FACE_COUNT + (face)]
/* Whether the given face of this block is occluded/hidden */
#define Block_IsFaceHidden(block, other, face) (Blocks.Hidden[((block) * BLOCK_COUNT) + (other)] & (1 << (face)))
/* Whether blocks can be automatically rotated */
extern cc_bool AutoRotate_Enabled;
/* Attempts to find the rotated block based on the user's orientation and offset on selected block */
/* If no rotated block is found, returns given block */
BlockID AutoRotate_RotateBlock(BlockID block);
/* Returns non 0 if both blocks belong to the same autorotate group */
cc_bool AutoRotate_BlocksShareGroup(BlockID block, BlockID blockOther);
#endif
|