summary refs log tree commit diff
path: root/src/World.h
diff options
context:
space:
mode:
authorWlodekM <[email protected]>2024-06-16 10:35:45 +0300
committerWlodekM <[email protected]>2024-06-16 10:35:45 +0300
commitabef6da56913f1c55528103e60a50451a39628b1 (patch)
treeb3c8092471ecbb73e568cd0d336efa0e7871ee8d /src/World.h
initial commit
Diffstat (limited to 'src/World.h')
-rw-r--r--src/World.h217
1 files changed, 217 insertions, 0 deletions
diff --git a/src/World.h b/src/World.h
new file mode 100644
index 0000000..942eea7
--- /dev/null
+++ b/src/World.h
@@ -0,0 +1,217 @@
+#ifndef CC_WORLD_H
+#define CC_WORLD_H
+#include "Vectors.h"
+#include "PackedCol.h"
+/* 
+Represents a fixed size 3D array of blocks and associated metadata
+Copyright 2014-2023 ClassiCube | Licensed under BSD-3
+*/
+struct AABB;
+extern struct IGameComponent World_Component;
+
+/* Unpacka an index into x,y,z (slow!) */
+#define World_Unpack(idx, x, y, z) x = idx % World.Width; z = (idx / World.Width) % World.Length; y = (idx / World.Width) / World.Length;
+/* Packs an x,y,z into a single index */
+#define World_Pack(x, y, z) (((y) * World.Length + (z)) * World.Width + (x))
+#define WORLD_UUID_LEN 16
+
+#define World_ChunkPack(cx, cy, cz) (((cz) * World.ChunksY + (cy)) * World.ChunksX + (cx))
+/* TODO: Swap Y and Z? Make sure to update MapRenderer's ResetChunkCache and ClearChunkCache methods! */
+
+
+CC_VAR extern struct _WorldData {
+	/* The blocks in the world. */
+	BlockRaw* Blocks;
+#ifdef EXTENDED_BLOCKS
+	/* The upper 8 bit of blocks in the world. */
+	/* If only 8 bit blocks are used, equals World_Blocks. */
+	BlockRaw* Blocks2;
+#endif
+	/* Volume of the world. */
+	int Volume;
+
+	/* Dimensions of the world. */
+	int Width, Height, Length;
+	/* Maximum X/Y/Z coordinate in the world. */
+	/* (i.e. Width - 1, Height - 1, Length - 1) */
+	int MaxX, MaxY, MaxZ;
+	/* Adds one Y coordinate to a packed index. */
+	int OneY;
+	/* Unique identifier for this world. */
+	cc_uint8 Uuid[WORLD_UUID_LEN];
+
+#ifdef EXTENDED_BLOCKS
+	/* Masks access to World.Blocks/World.Blocks2 */
+	/* e.g. this will be 255 if only 8 bit blocks are used */
+	int IDMask;
+#endif
+	/* Whether the world has finished loading/generating. */
+	/* NOTE: Blocks may still be NULL. (e.g. error during loading) */
+	cc_bool Loaded;
+	/* Point in time the current world was last saved at */
+	double LastSave;
+	/* Default name of the world when saving */
+	cc_string Name;
+	/* Number of chunks on each axis the world is subdivided into */
+	int ChunksX, ChunksY, ChunksZ;
+	/* Number of chunks in the world, or ChunksX * ChunksY * ChunksZ */
+	int ChunksCount;
+	/* Seed world was generated with. May be 0 (unknown) */
+	int Seed;
+} World;
+
+/* Frees the blocks array, sets dimensions to 0, resets environment to default. */
+void World_Reset(void);
+/* Sets up state and raises WorldEvents.NewMap event */
+/* NOTE: This implicitly calls World_Reset. */
+CC_API void World_NewMap(void);
+/* Sets blocks array/dimensions of the map and raises WorldEvents.MapLoaded event */
+/* May also sets some environment settings like border/clouds height, if they are -1 */
+CC_API void World_SetNewMap(BlockRaw* blocks, int width, int height, int length);
+/* Sets the various dimension and max coordinate related variables. */
+/* NOTE: This is an internal API. Use World_SetNewMap instead. */
+CC_NOINLINE void World_SetDimensions(int width, int height, int length);
+void World_OutOfMemory(void);
+
+#ifdef EXTENDED_BLOCKS
+/* Sets World.Blocks2 and updates internal state for more than 256 blocks. */
+void World_SetMapUpper(BlockRaw* blocks);
+
+#define World_GetRawBlock(idx) ((World.Blocks[idx] | (World.Blocks2[idx] << 8)) & World.IDMask)
+
+/* Gets the block at the given coordinates. */
+/* NOTE: Does NOT check that the coordinates are inside the map. */
+static CC_INLINE BlockID World_GetBlock(int x, int y, int z) {
+	int i = World_Pack(x, y, z);
+	return (BlockID)World_GetRawBlock(i);
+}
+#else
+#define World_GetBlock(x, y, z) World.Blocks[World_Pack(x, y, z)]
+#define World_GetRawBlock(idx)  World.Blocks[idx]
+#endif
+
+/* If Y is above the map, returns BLOCK_AIR. */
+/* If coordinates are outside the map, returns BLOCK_AIR. */
+/* Otherwise returns the block at the given coordinates. */
+BlockID World_GetPhysicsBlock(int x, int y, int z);
+/* Sets the block at the given coordinates. */
+/* NOTE: Does NOT check that the coordinates are inside the map. */
+void World_SetBlock(int x, int y, int z, BlockID block);
+/* If coordinates are outside the map, returns BLOCK_AIR. */
+/* Otherwise returns the block at the given coordinates. */
+BlockID World_SafeGetBlock(int x, int y, int z);
+
+/* Whether the given coordinates lie inside the map. */
+static CC_INLINE cc_bool World_Contains(int x, int y, int z) {
+	return (unsigned)x < (unsigned)World.Width
+		&& (unsigned)y < (unsigned)World.Height
+		&& (unsigned)z < (unsigned)World.Length;
+}
+/* Whether the given coordinates lie horizontally inside the map. */
+static CC_INLINE cc_bool World_ContainsXZ(int x, int z) {
+	return (unsigned)x < (unsigned)World.Width 
+		&& (unsigned)z < (unsigned)World.Length;
+}
+
+enum EnvVar {
+	ENV_VAR_EDGE_BLOCK, ENV_VAR_SIDES_BLOCK, ENV_VAR_EDGE_HEIGHT, ENV_VAR_SIDES_OFFSET,
+	ENV_VAR_CLOUDS_HEIGHT, ENV_VAR_CLOUDS_SPEED, ENV_VAR_WEATHER_SPEED, ENV_VAR_WEATHER_FADE,
+	ENV_VAR_WEATHER, ENV_VAR_EXP_FOG, ENV_VAR_SKYBOX_HOR_SPEED, ENV_VAR_SKYBOX_VER_SPEED,
+	ENV_VAR_SKY_COLOR, ENV_VAR_CLOUDS_COLOR, ENV_VAR_FOG_COLOR, 
+	ENV_VAR_SUN_COLOR, ENV_VAR_SHADOW_COLOR, ENV_VAR_SKYBOX_COLOR,
+	ENV_VAR_LAVALIGHT_COLOR, ENV_VAR_LAMPLIGHT_COLOR
+};
+
+CC_VAR extern struct _EnvData {
+	BlockID EdgeBlock, SidesBlock;
+	int EdgeHeight, SidesOffset;
+	int CloudsHeight;
+	float CloudsSpeed;
+
+	float WeatherSpeed, WeatherFade;
+	int Weather, ExpFog;
+	float SkyboxHorSpeed, SkyboxVerSpeed;
+
+	PackedCol SkyCol, FogCol, CloudsCol, SkyboxCol;
+	PackedCol SunCol, SunXSide, SunZSide, SunYMin;
+	PackedCol ShadowCol, ShadowXSide, ShadowZSide, ShadowYMin;
+	PackedCol LavaLightCol, LampLightCol;
+} Env;
+#define Env_SidesHeight (Env.EdgeHeight + Env.SidesOffset)
+
+enum Weather_ { WEATHER_SUNNY, WEATHER_RAINY, WEATHER_SNOWY };
+extern const char* const Weather_Names[3];
+
+#define ENV_DEFAULT_SKY_COLOR       PackedCol_Make(0x99, 0xCC, 0xFF, 0xFF)
+#define ENV_DEFAULT_FOG_COLOR       PackedCol_Make(0xFF, 0xFF, 0xFF, 0xFF)
+#define ENV_DEFAULT_CLOUDS_COLOR    PackedCol_Make(0xFF, 0xFF, 0xFF, 0xFF)
+#define ENV_DEFAULT_SKYBOX_COLOR    PackedCol_Make(0xFF, 0xFF, 0xFF, 0xFF)
+#define ENV_DEFAULT_SUN_COLOR       PackedCol_Make(0xFF, 0xFF, 0xFF, 0xFF)
+#define ENV_DEFAULT_SHADOW_COLOR    PackedCol_Make(0x9B, 0x9B, 0x9B, 0xFF)
+#define ENV_DEFAULT_LAVALIGHT_COLOR PackedCol_Make(0xFF, 0xEB, 0xC6, 0xFF)
+#define ENV_DEFAULT_LAMPLIGHT_COLOR PackedCol_Make(0xFF, 0xFF, 0xFF, 0xFF)
+
+/* Resets all environment settings to default. */
+/* NOTE: Unlike Env_Set functions, DOES NOT raise EnvVarChanged event. */
+CC_API void Env_Reset(void);
+
+/* Sets the edge/horizon block. (default water) */
+CC_API void Env_SetEdgeBlock(BlockID block);
+/* Sets the sides/border block. (default bedrock) */
+CC_API void Env_SetSidesBlock(BlockID block);
+/* Sets the edge/horizon height. (default height/2) */
+CC_API void Env_SetEdgeHeight(int height);
+/* Sets offset of sides/border from horizon. (default -2) */
+CC_API void Env_SetSidesOffset(int offset);
+/* Sets clouds height. (default height+2)*/
+CC_API void Env_SetCloudsHeight(int height);
+/* Sets how fast clouds move. (default 1) */
+/* Negative speeds move in opposite direction. */
+CC_API void Env_SetCloudsSpeed(float speed);
+
+/* Sets how fast rain/snow falls. (default 1) */
+/* Negative speeds makes rain/snow fall upwards. */
+CC_API void Env_SetWeatherSpeed(float speed);
+/* Sets how quickly rain/snow fades over distance. (default 1) */
+CC_API void Env_SetWeatherFade(float rate);
+/* Sets the weather of the map. (default sun) */
+/* Can be sun/rain/snow, see WEATHER_ enum. */
+CC_API void Env_SetWeather(int weather);
+/* Sets whether exponential/smooth fog is used. (default false) */
+CC_API void Env_SetExpFog(cc_bool expFog);
+/* Sets how quickly skybox rotates/spins horizontally. (default 0) */
+/* speed is in rotations/second, so '2' completes two full spins per second. */
+CC_API void Env_SetSkyboxHorSpeed(float speed);
+/* Sets how quickly skybox rotates/spins vertically. (default 0) */
+/* speed is in rotations/second, so '2' completes two full spins per second. */
+CC_API void Env_SetSkyboxVerSpeed(float speed);
+
+/* Sets colour of the sky above clouds. (default #99CCFF) */
+CC_API void Env_SetSkyCol(PackedCol color);
+/* Sets base colour of the horizon fog. (default #FFFFFF) */
+/* Actual fog colour is blended between sky and fog colours, based on view distance. */
+CC_API void Env_SetFogCol(PackedCol color);
+/* Sets colour of clouds. (default #FFFFFF) */
+CC_API void Env_SetCloudsCol(PackedCol color);
+/* Sets colour of the skybox. (default #FFFFFF) */
+CC_API void Env_SetSkyboxCol(PackedCol color);
+/* Sets colour of sunlight. (default #FFFFFF) */
+/* This is the colour used for lighting when not underground. */
+CC_API void Env_SetSunCol(PackedCol color);
+/* Sets colour of shadow. (default #9B9B9B) */
+/* This is the colour used for lighting when underground. */
+CC_API void Env_SetShadowCol(PackedCol color);
+/* Sets colour that bright natural blocks cast with fancy lighting. (default #FFEBC6) */
+CC_API void Env_SetLavaLightCol(PackedCol color);
+/* Sets colour that bright artificial blocks cast with fancy lighting. (default #FFFFFF) */
+CC_API void Env_SetLampLightCol(PackedCol color);
+
+#define RESPAWN_NOT_FOUND -100000.0f
+/* Finds the highest Y coordinate of any solid block that intersects the given bounding box */
+/* So essentially, means max(Y + Block_MaxBB[block].y) over all solid blocks the AABB touches */
+/* Returns RESPAWN_NOT_FOUND when no intersecting solid blocks are found. */
+float Respawn_HighestSolidY(struct AABB* bb);
+/* Finds a suitable initial spawn position for the entity. */
+/* Works by iterating downwards from top of world until solid ground is found. */
+Vec3 Respawn_FindSpawnPosition(float x, float z, Vec3 modelSize);
+#endif