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/World.h |
initial commit
Diffstat (limited to 'src/World.h')
-rw-r--r-- | src/World.h | 217 |
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 |