make world available to plugins

This commit is contained in:
UnknownShadow200 2019-01-19 09:14:22 +11:00
parent de58e0b0ed
commit 26c4681ebe
21 changed files with 287 additions and 283 deletions

View File

@ -106,12 +106,12 @@ static void Physics_OnNewMapLoaded(void* obj) {
TickQueue_Clear(&physics_lavaQ);
TickQueue_Clear(&physics_waterQ);
physics_maxWaterX = World_MaxX - 2;
physics_maxWaterY = World_MaxY - 2;
physics_maxWaterZ = World_MaxZ - 2;
physics_maxWaterX = World.MaxX - 2;
physics_maxWaterY = World.MaxY - 2;
physics_maxWaterZ = World.MaxZ - 2;
Tree_Width = World_Width; Tree_Height = World_Height; Tree_Length = World_Length;
Tree_Blocks = World_Blocks;
Tree_Width = World.Width; Tree_Height = World.Height; Tree_Length = World.Length;
Tree_Blocks = World.Blocks;
Random_InitFromCurrentTime(&physics_rnd);
Tree_Rnd = &physics_rnd;
}
@ -122,25 +122,25 @@ void Physics_SetEnabled(bool enabled) {
}
static void Physics_Activate(int index) {
BlockID block = World_Blocks[index];
BlockID block = World.Blocks[index];
PhysicsHandler activate = Physics_OnActivate[block];
if (activate) activate(index, block);
}
static void Physics_ActivateNeighbours(int x, int y, int z, int index) {
if (x > 0) Physics_Activate(index - 1);
if (x < World_MaxX) Physics_Activate(index + 1);
if (z > 0) Physics_Activate(index - World_Width);
if (z < World_MaxZ) Physics_Activate(index + World_Width);
if (y > 0) Physics_Activate(index - World_OneY);
if (y < World_MaxY) Physics_Activate(index + World_OneY);
if (x < World.MaxX) Physics_Activate(index + 1);
if (z > 0) Physics_Activate(index - World.Width);
if (z < World.MaxZ) Physics_Activate(index + World.Width);
if (y > 0) Physics_Activate(index - World.OneY);
if (y < World.MaxY) Physics_Activate(index + World.OneY);
}
static bool Physics_IsEdgeWater(int x, int y, int z) {
return
(Env_EdgeBlock == BLOCK_WATER || Env_EdgeBlock == BLOCK_STILL_WATER)
&& (y >= Env_SidesHeight && y < Env_EdgeHeight)
&& (x == 0 || z == 0 || x == World_MaxX || z == World_MaxZ);
&& (x == 0 || z == 0 || x == World.MaxX || z == World.MaxZ);
}
@ -171,29 +171,29 @@ static void Physics_TickRandomBlocks(void) {
PhysicsHandler tick;
int x, y, z, x2, y2, z2;
for (y = 0; y < World_Height; y += CHUNK_SIZE) {
y2 = min(y + CHUNK_MAX, World_MaxY);
for (z = 0; z < World_Length; z += CHUNK_SIZE) {
z2 = min(z + CHUNK_MAX, World_MaxZ);
for (x = 0; x < World_Width; x += CHUNK_SIZE) {
x2 = min(x + CHUNK_MAX, World_MaxX);
for (y = 0; y < World.Height; y += CHUNK_SIZE) {
y2 = min(y + CHUNK_MAX, World.MaxY);
for (z = 0; z < World.Length; z += CHUNK_SIZE) {
z2 = min(z + CHUNK_MAX, World.MaxZ);
for (x = 0; x < World.Width; x += CHUNK_SIZE) {
x2 = min(x + CHUNK_MAX, World.MaxX);
/* Inlined 3 random ticks for this chunk */
lo = World_Pack( x, y, z);
hi = World_Pack(x2, y2, z2);
index = Random_Range(&physics_rnd, lo, hi);
block = World_Blocks[index];
block = World.Blocks[index];
tick = Physics_OnRandomTick[block];
if (tick) tick(index, block);
index = Random_Range(&physics_rnd, lo, hi);
block = World_Blocks[index];
block = World.Blocks[index];
tick = Physics_OnRandomTick[block];
if (tick) tick(index, block);
index = Random_Range(&physics_rnd, lo, hi);
block = World_Blocks[index];
block = World.Blocks[index];
tick = Physics_OnRandomTick[block];
if (tick) tick(index, block);
}
@ -208,9 +208,9 @@ static void Physics_DoFalling(int index, BlockID block) {
int x, y, z;
/* Find lowest block can fall into */
while (index >= World_OneY) {
index -= World_OneY;
other = World_Blocks[index];
while (index >= World.OneY) {
index -= World.OneY;
other = World.Blocks[index];
if (other == BLOCK_AIR || (other >= BLOCK_WATER && other <= BLOCK_STILL_LAVA))
found = index;
@ -250,7 +250,7 @@ static void Physics_HandleSapling(int index, BlockID block) {
World_Unpack(index, x, y, z);
below = BLOCK_AIR;
if (y > 0) below = World_Blocks[index - World_OneY];
if (y > 0) below = World.Blocks[index - World.OneY];
if (below != BLOCK_GRASS) return;
height = 5 + Random_Next(&physics_rnd, 3);
@ -297,7 +297,7 @@ static void Physics_HandleFlower(int index, BlockID block) {
}
below = BLOCK_DIRT;
if (y > 0) below = World_Blocks[index - World_OneY];
if (y > 0) below = World.Blocks[index - World.OneY];
if (!(below == BLOCK_DIRT || below == BLOCK_GRASS)) {
Game_UpdateBlock(x, y, z, BLOCK_AIR);
Physics_ActivateNeighbours(x, y, z, index);
@ -316,7 +316,7 @@ static void Physics_HandleMushroom(int index, BlockID block) {
}
below = BLOCK_STONE;
if (y > 0) below = World_Blocks[index - World_OneY];
if (y > 0) below = World.Blocks[index - World.OneY];
if (!(below == BLOCK_STONE || below == BLOCK_COBBLE)) {
Game_UpdateBlock(x, y, z, BLOCK_AIR);
Physics_ActivateNeighbours(x, y, z, index);
@ -329,7 +329,7 @@ static void Physics_PlaceLava(int index, BlockID block) {
}
static void Physics_PropagateLava(int posIndex, int x, int y, int z) {
BlockID block = World_Blocks[posIndex];
BlockID block = World.Blocks[posIndex];
if (block == BLOCK_WATER || block == BLOCK_STILL_WATER) {
Game_UpdateBlock(x, y, z, BLOCK_STONE);
} else if (Blocks.Collide[block] == COLLIDE_GAS) {
@ -343,10 +343,10 @@ static void Physics_ActivateLava(int index, BlockID block) {
World_Unpack(index, x, y, z);
if (x > 0) Physics_PropagateLava(index - 1, x - 1, y, z);
if (x < World_MaxX) Physics_PropagateLava(index + 1, x + 1, y, z);
if (z > 0) Physics_PropagateLava(index - World_Width, x, y, z - 1);
if (z < World_MaxZ) Physics_PropagateLava(index + World_Width, x, y, z + 1);
if (y > 0) Physics_PropagateLava(index - World_OneY, x, y - 1, z);
if (x < World.MaxX) Physics_PropagateLava(index + 1, x + 1, y, z);
if (z > 0) Physics_PropagateLava(index - World.Width, x, y, z - 1);
if (z < World.MaxZ) Physics_PropagateLava(index + World.Width, x, y, z + 1);
if (y > 0) Physics_PropagateLava(index - World.OneY, x, y - 1, z);
}
static void Physics_TickLava(void) {
@ -354,7 +354,7 @@ static void Physics_TickLava(void) {
for (i = 0; i < count; i++) {
int index;
if (Physics_CheckItem(&physics_lavaQ, &index)) {
BlockID block = World_Blocks[index];
BlockID block = World.Blocks[index];
if (!(block == BLOCK_LAVA || block == BLOCK_STILL_LAVA)) continue;
Physics_ActivateLava(index, block);
}
@ -367,16 +367,16 @@ static void Physics_PlaceWater(int index, BlockID block) {
}
static void Physics_PropagateWater(int posIndex, int x, int y, int z) {
BlockID block = World_Blocks[posIndex];
BlockID block = World.Blocks[posIndex];
int xx, yy, zz;
if (block == BLOCK_LAVA || block == BLOCK_STILL_LAVA) {
Game_UpdateBlock(x, y, z, BLOCK_STONE);
} else if (Blocks.Collide[block] == COLLIDE_GAS && block != BLOCK_ROPE) {
/* Sponge check */
for (yy = (y < 2 ? 0 : y - 2); yy <= (y > physics_maxWaterY ? World_MaxY : y + 2); yy++) {
for (zz = (z < 2 ? 0 : z - 2); zz <= (z > physics_maxWaterZ ? World_MaxZ : z + 2); zz++) {
for (xx = (x < 2 ? 0 : x - 2); xx <= (x > physics_maxWaterX ? World_MaxX : x + 2); xx++) {
for (yy = (y < 2 ? 0 : y - 2); yy <= (y > physics_maxWaterY ? World.MaxY : y + 2); yy++) {
for (zz = (z < 2 ? 0 : z - 2); zz <= (z > physics_maxWaterZ ? World.MaxZ : z + 2); zz++) {
for (xx = (x < 2 ? 0 : x - 2); xx <= (x > physics_maxWaterX ? World.MaxX : x + 2); xx++) {
block = World_GetBlock(xx, yy, zz);
if (block == BLOCK_SPONGE) return;
}
@ -393,10 +393,10 @@ static void Physics_ActivateWater(int index, BlockID block) {
World_Unpack(index, x, y, z);
if (x > 0) Physics_PropagateWater(index - 1, x - 1, y, z);
if (x < World_MaxX) Physics_PropagateWater(index + 1, x + 1, y, z);
if (z > 0) Physics_PropagateWater(index - World_Width, x, y, z - 1);
if (z < World_MaxZ) Physics_PropagateWater(index + World_Width, x, y, z + 1);
if (y > 0) Physics_PropagateWater(index - World_OneY, x, y - 1, z);
if (x < World.MaxX) Physics_PropagateWater(index + 1, x + 1, y, z);
if (z > 0) Physics_PropagateWater(index - World.Width, x, y, z - 1);
if (z < World.MaxZ) Physics_PropagateWater(index + World.Width, x, y, z + 1);
if (y > 0) Physics_PropagateWater(index - World.OneY, x, y - 1, z);
}
static void Physics_TickWater(void) {
@ -404,7 +404,7 @@ static void Physics_TickWater(void) {
for (i = 0; i < count; i++) {
int index;
if (Physics_CheckItem(&physics_waterQ, &index)) {
BlockID block = World_Blocks[index];
BlockID block = World.Blocks[index];
if (!(block == BLOCK_WATER || block == BLOCK_STILL_WATER)) continue;
Physics_ActivateWater(index, block);
}
@ -441,7 +441,7 @@ static void Physics_DeleteSponge(int index, BlockID block) {
if (!World_IsValidPos(xx, yy, zz)) continue;
index = World_Pack(xx, yy, zz);
block = World_Blocks[index];
block = World.Blocks[index];
if (block == BLOCK_WATER || block == BLOCK_STILL_WATER) {
TickQueue_Enqueue(&physics_waterQ, index | PHYSICS_ONE_DELAY);
}
@ -455,9 +455,9 @@ static void Physics_DeleteSponge(int index, BlockID block) {
static void Physics_HandleSlab(int index, BlockID block) {
int x, y, z;
World_Unpack(index, x, y, z);
if (index < World_OneY) return;
if (index < World.OneY) return;
if (World_Blocks[index - World_OneY] != BLOCK_SLAB) return;
if (World.Blocks[index - World.OneY] != BLOCK_SLAB) return;
Game_UpdateBlock(x, y, z, BLOCK_AIR);
Game_UpdateBlock(x, y - 1, z, BLOCK_DOUBLE_SLAB);
}
@ -465,9 +465,9 @@ static void Physics_HandleSlab(int index, BlockID block) {
static void Physics_HandleCobblestoneSlab(int index, BlockID block) {
int x, y, z;
World_Unpack(index, x, y, z);
if (index < World_OneY) return;
if (index < World.OneY) return;
if (World_Blocks[index - World_OneY] != BLOCK_COBBLE_SLAB) return;
if (World.Blocks[index - World.OneY] != BLOCK_COBBLE_SLAB) return;
Game_UpdateBlock(x, y, z, BLOCK_AIR);
Game_UpdateBlock(x, y - 1, z, BLOCK_COBBLE);
}
@ -497,7 +497,7 @@ static void Physics_Explode(int x, int y, int z, int power) {
if (!World_IsValidPos(xx, yy, zz)) continue;
index = World_Pack(xx, yy, zz);
block = World_Blocks[index];
block = World.Blocks[index];
if (block < BLOCK_CPE_COUNT && physics_blocksTnt[block]) continue;
Game_UpdateBlock(xx, yy, zz, BLOCK_AIR);
@ -561,7 +561,7 @@ void Physics_Free(void) {
}
void Physics_Tick(void) {
if (!Physics_Enabled || !World_Blocks) return;
if (!Physics_Enabled || !World.Blocks) return;
/*if ((tickCount % 5) == 0) {*/
Physics_TickLava();

View File

@ -121,9 +121,9 @@ static void Builder_SetPartInfo(struct Builder1DPart* part, int* offset, struct
static void Builder_Stretch(int x1, int y1, int z1) {
int xMax = min(World_Width, x1 + CHUNK_SIZE);
int yMax = min(World_Height, y1 + CHUNK_SIZE);
int zMax = min(World_Length, z1 + CHUNK_SIZE);
int xMax = min(World.Width, x1 + CHUNK_SIZE);
int yMax = min(World.Height, y1 + CHUNK_SIZE);
int zMax = min(World.Length, z1 + CHUNK_SIZE);
int cIndex, index, tileIdx, count;
BlockID b;
@ -181,8 +181,8 @@ static void Builder_Stretch(int x1, int y1, int z1) {
index++;
if (Builder_Counts[index] == 0 ||
(x == World_MaxX && (y < Builder_SidesLevel || (b >= BLOCK_WATER && b <= BLOCK_STILL_LAVA && y < Builder_EdgeLevel))) ||
(x != World_MaxX && (Blocks.Hidden[tileIdx + Builder_Chunk[cIndex + 1]] & (1 << FACE_XMAX)) != 0)) {
(x == World.MaxX && (y < Builder_SidesLevel || (b >= BLOCK_WATER && b <= BLOCK_STILL_LAVA && y < Builder_EdgeLevel))) ||
(x != World.MaxX && (Blocks.Hidden[tileIdx + Builder_Chunk[cIndex + 1]] & (1 << FACE_XMAX)) != 0)) {
Builder_Counts[index] = 0;
} else {
count = Builder_StretchZ(index, x, y, z, cIndex, b, FACE_XMAX);
@ -203,8 +203,8 @@ static void Builder_Stretch(int x1, int y1, int z1) {
index++;
if (Builder_Counts[index] == 0 ||
(z == World_MaxZ && (y < Builder_SidesLevel || (b >= BLOCK_WATER && b <= BLOCK_STILL_LAVA && y < Builder_EdgeLevel))) ||
(z != World_MaxZ && (Blocks.Hidden[tileIdx + Builder_Chunk[cIndex + EXTCHUNK_SIZE]] & (1 << FACE_ZMAX)) != 0)) {
(z == World.MaxZ && (y < Builder_SidesLevel || (b >= BLOCK_WATER && b <= BLOCK_STILL_LAVA && y < Builder_EdgeLevel))) ||
(z != World.MaxZ && (Blocks.Hidden[tileIdx + Builder_Chunk[cIndex + EXTCHUNK_SIZE]] & (1 << FACE_ZMAX)) != 0)) {
Builder_Counts[index] = 0;
} else {
count = Builder_StretchX(index, x, y, z, cIndex, b, FACE_ZMAX);
@ -244,12 +244,12 @@ static void Builder_Stretch(int x1, int y1, int z1) {
for (yy = -1; yy < 17; ++yy) {\
y = yy + y1;\
if (y < 0) continue;\
if (y >= World_Height) break;\
if (y >= World.Height) break;\
\
for (zz = -1; zz < 17; ++zz) {\
z = zz + z1;\
if (z < 0) continue;\
if (z >= World_Length) break;\
if (z >= World.Length) break;\
\
index = World_Pack(x1 - 1, y, z);\
cIndex = Builder_PackChunk(-1, yy, zz);\
@ -257,7 +257,7 @@ for (yy = -1; yy < 17; ++yy) {\
for (xx = -1; xx < 17; ++xx, ++index, ++cIndex) {\
x = xx + x1;\
if (x < 0) continue;\
if (x >= World_Width) break;\
if (x >= World.Width) break;\
\
block = get_block;\
allAir = allAir && Blocks.Draw[block] == DRAW_GAS;\
@ -274,12 +274,12 @@ static void Builder_ReadChunkData(int x1, int y1, int z1, bool* outAllAir, bool*
int xx, yy, zz, x, y, z;
#ifndef EXTENDED_BLOCKS
Builder_ReadChunkBody(World_Blocks[index]);
Builder_ReadChunkBody(World.Blocks[index]);
#else
if (Block_UsedCount <= 256) {
Builder_ReadChunkBody(World_Blocks[index]);
Builder_ReadChunkBody(World.Blocks[index]);
} else {
Builder_ReadChunkBody(World_Blocks[index] | (World_Blocks2[index] << 8));
Builder_ReadChunkBody(World.Blocks[index] | (World.Blocks2[index] << 8));
}
#endif
@ -305,16 +305,16 @@ static bool Builder_BuildChunk(int x1, int y1, int z1, bool* allAir) {
Mem_Set(chunk, BLOCK_AIR, EXTCHUNK_SIZE_3 * sizeof(BlockID));
Builder_ReadChunkData(x1, y1, z1, allAir, &allSolid);
if (x1 == 0 || y1 == 0 || z1 == 0 || x1 + CHUNK_SIZE >= World_Width ||
y1 + CHUNK_SIZE >= World_Height || z1 + CHUNK_SIZE >= World_Length) allSolid = false;
if (x1 == 0 || y1 == 0 || z1 == 0 || x1 + CHUNK_SIZE >= World.Width ||
y1 + CHUNK_SIZE >= World.Height || z1 + CHUNK_SIZE >= World.Length) allSolid = false;
if (*allAir || allSolid) return false;
Lighting_LightHint(x1 - 1, z1 - 1);
Mem_Set(counts, 1, CHUNK_SIZE_3 * FACE_COUNT);
xMax = min(World_Width, x1 + CHUNK_SIZE);
yMax = min(World_Height, y1 + CHUNK_SIZE);
zMax = min(World_Length, z1 + CHUNK_SIZE);
xMax = min(World.Width, x1 + CHUNK_SIZE);
yMax = min(World.Height, y1 + CHUNK_SIZE);
zMax = min(World.Length, z1 + CHUNK_SIZE);
Builder_ChunkEndX = xMax; Builder_ChunkEndZ = zMax;
Builder_Stretch(x1, y1, z1);
@ -498,15 +498,15 @@ static PackedCol Normal_LightCol(int x, int y, int z, Face face, BlockID block)
case FACE_XMIN:
return x < offset ? Env_SunXSide : Lighting_Col_XSide_Fast(x - offset, y, z);
case FACE_XMAX:
return x > (World_MaxX - offset) ? Env_SunXSide : Lighting_Col_XSide_Fast(x + offset, y, z);
return x > (World.MaxX - offset) ? Env_SunXSide : Lighting_Col_XSide_Fast(x + offset, y, z);
case FACE_ZMIN:
return z < offset ? Env_SunZSide : Lighting_Col_ZSide_Fast(x, y, z - offset);
case FACE_ZMAX:
return z > (World_MaxZ - offset) ? Env_SunZSide : Lighting_Col_ZSide_Fast(x, y, z + offset);
return z > (World.MaxZ - offset) ? Env_SunZSide : Lighting_Col_ZSide_Fast(x, y, z + offset);
case FACE_YMIN:
return y <= 0 ? Env_SunYMin : Lighting_Col_YMin_Fast(x, y - offset, z);
case FACE_YMAX:
return y >= World_MaxY ? Env_SunCol : Lighting_Col_YMax_Fast(x, (y + 1) - offset, z);
return y >= World.MaxY ? Env_SunCol : Lighting_Col_YMax_Fast(x, (y + 1) - offset, z);
}
return invalid; /* should never happen */
}
@ -643,7 +643,7 @@ static void NormalBuilder_RenderBlock(int index) {
part = &Builder_Parts[baseOffset + Atlas1D_Index(loc)];
col = fullBright ? white :
Builder_X <= (World_MaxX - offset) ? Lighting_Col_XSide_Fast(Builder_X + offset, Builder_Y, Builder_Z) : Env_SunXSide;
Builder_X <= (World.MaxX - offset) ? Lighting_Col_XSide_Fast(Builder_X + offset, Builder_Y, Builder_Z) : Env_SunXSide;
Drawer_XMax(count_XMax, col, loc, &part->fVertices[FACE_XMAX]);
}
@ -663,7 +663,7 @@ static void NormalBuilder_RenderBlock(int index) {
part = &Builder_Parts[baseOffset + Atlas1D_Index(loc)];
col = fullBright ? white :
Builder_Z <= (World_MaxZ - offset) ? Lighting_Col_ZSide_Fast(Builder_X, Builder_Y, Builder_Z + offset) : Env_SunZSide;
Builder_Z <= (World.MaxZ - offset) ? Lighting_Col_ZSide_Fast(Builder_X, Builder_Y, Builder_Z + offset) : Env_SunZSide;
Drawer_ZMax(count_ZMax, col, loc, &part->fVertices[FACE_ZMAX]);
}
@ -733,10 +733,10 @@ enum ADV_MASK {
static int Adv_Lit(int x, int y, int z, int cIndex) {
int flags, offset, lightHeight;
BlockID block;
if (y < 0 || y >= World_Height) return 7; /* all faces lit */
if (y < 0 || y >= World.Height) return 7; /* all faces lit */
/* TODO: check sides height (if sides > edges), check if edge block casts a shadow */
if (x < 0 || z < 0 || x >= World_Width || z >= World_Length) {
if (x < 0 || z < 0 || x >= World.Width || z >= World.Length) {
return y >= Builder_EdgeLevel ? 7 : y == (Builder_EdgeLevel - 1) ? 6 : 0;
}

View File

@ -171,9 +171,9 @@ bool Entity_TouchesAny(struct AABB* bounds, Entity_TouchesCondition condition) {
Vector3I_Floor(&bbMin, &bounds->Min);
Vector3I_Floor(&bbMax, &bounds->Max);
bbMin.X = max(bbMin.X, 0); bbMax.X = min(bbMax.X, World_MaxX);
bbMin.Y = max(bbMin.Y, 0); bbMax.Y = min(bbMax.Y, World_MaxY);
bbMin.Z = max(bbMin.Z, 0); bbMax.Z = min(bbMax.Z, World_MaxZ);
bbMin.X = max(bbMin.X, 0); bbMax.X = min(bbMax.X, World.MaxX);
bbMin.Y = max(bbMin.Y, 0); bbMax.Y = min(bbMax.Y, World.MaxY);
bbMin.Z = max(bbMin.Z, 0); bbMax.Z = min(bbMax.Z, World.MaxZ);
for (y = bbMin.Y; y <= bbMax.Y; y++) { v.Y = (float)y;
for (z = bbMin.Z; z <= bbMax.Z; z++) { v.Z = (float)z;
@ -844,7 +844,7 @@ static void LocalPlayer_Tick(struct Entity* e, double delta) {
bool wasOnGround;
Vector3 headingVelocity;
if (!World_Blocks) return;
if (!World.Blocks) return;
e->StepSize = hacks->FullBlockStep && hacks->Enabled && hacks->CanAnyHacks && hacks->CanSpeed ? 1.0f : 0.5f;
p->OldVelocity = e->Velocity;
wasOnGround = e->OnGround;
@ -953,14 +953,14 @@ static void LocalPlayer_DoRespawn(void) {
float height, spawnY;
int y;
if (!World_Blocks) return;
if (!World.Blocks) return;
Vector3I_Floor(&pos, &spawn);
/* Spawn player at highest solid position to match vanilla Minecraft classic */
/* Only when player can noclip, since this can let you 'clip' to above solid blocks */
if (p->Hacks.CanNoclip && World_IsValidPos_3I(pos)) {
AABB_Make(&bb, &spawn, &p->Base.Size);
for (y = pos.Y; y <= World_Height; y++) {
for (y = pos.Y; y <= World.Height; y++) {
spawnY = Respawn_HighestSolidY(&bb);
if (spawnY == RESPAWN_NOT_FOUND) {

View File

@ -105,7 +105,7 @@ void Entity_GetBounds(struct Entity* e, struct AABB* bb);
CC_API void Entity_SetModel(struct Entity* e, const String* model);
/* Updates cached Size and ModelAABB of the given entity. */
/* NOTE: Only needed when manually changing Model or ModelScale. */
/* Entity_SetModel implicitly call this method. */
/* Entity_SetModel already calls this method. */
void Entity_UpdateModelBounds(struct Entity* e);
/* Whether the given entity is touching any blocks meeting the given condition .*/

View File

@ -565,7 +565,7 @@ static bool ShadowComponent_GetBlocks(struct Entity* e, int x, int y, int z, str
for (i = 0; i < 4; i++) { data[i] = zeroData; }
cur = data;
posY = e->Position.Y;
outside = x < 0 || z < 0 || x >= World_Width || z >= World_Length;
outside = x < 0 || z < 0 || x >= World.Width || z >= World.Length;
for (i = 0; y >= 0 && i < 4; y--) {
if (!outside) {
@ -635,7 +635,7 @@ void ShadowComponent_Draw(struct Entity* e) {
pos = e->Position;
if (pos.Y < 0.0f) return;
y = min((int)pos.Y, World_MaxY);
y = min((int)pos.Y, World.MaxY);
radius = 7.0f * min(e->ModelScale.Y, 1.0f) * e->Model->ShadowScale;
shadow_radius = radius / 16.0f;
@ -1072,9 +1072,9 @@ static float PhysicsComp_LowestModifier(struct PhysicsComp* comp, struct AABB* b
Vector3I_Floor(&bbMin, &bounds->Min);
Vector3I_Floor(&bbMax, &bounds->Max);
bbMin.X = max(bbMin.X, 0); bbMax.X = min(bbMax.X, World_MaxX);
bbMin.Y = max(bbMin.Y, 0); bbMax.Y = min(bbMax.Y, World_MaxY);
bbMin.Z = max(bbMin.Z, 0); bbMax.Z = min(bbMax.Z, World_MaxZ);
bbMin.X = max(bbMin.X, 0); bbMax.X = min(bbMax.X, World.MaxX);
bbMin.Y = max(bbMin.Y, 0); bbMax.Y = min(bbMax.Y, World.MaxY);
bbMin.Z = max(bbMin.Z, 0); bbMax.Z = min(bbMax.Z, World.MaxZ);
for (y = bbMin.Y; y <= bbMax.Y; y++) { v.Y = (float)y;
for (z = bbMin.Z; z <= bbMax.Z; z++) { v.Z = (float)z;

View File

@ -112,7 +112,7 @@ void EnvRenderer_UpdateFog(void) {
EnvRenderer_CalcFog(&fogDensity, &fogCol);
Gfx_ClearCol(fogCol);
if (!World_Blocks) return;
if (!World.Blocks) return;
if (EnvRenderer_Minimal) {
EnvRenderer_UpdateFogMinimal(fogDensity);
} else {
@ -182,13 +182,13 @@ static void EnvRenderer_UpdateClouds(void) {
int extent;
int x1, z1, x2, z2;
if (!World_Blocks || Gfx_LostContext) return;
if (!World.Blocks || Gfx_LostContext) return;
Gfx_DeleteVb(&clouds_vb);
if (EnvRenderer_Minimal) return;
extent = Utils_AdjViewDist(Game_ViewDistance);
x1 = -extent; x2 = World_Width + extent;
z1 = -extent; z2 = World_Length + extent;
x1 = -extent; x2 = World.Width + extent;
z1 = -extent; z2 = World.Length + extent;
clouds_vertices = EnvRenderer_Vertices(x2 - x1, z2 - z1);
ptr = v;
@ -214,7 +214,7 @@ void EnvRenderer_RenderSky(double deltaTime) {
float skyY, normY, dy;
if (!sky_vb || EnvRenderer_ShouldRenderSkybox()) return;
normY = (float)World_Height + 8.0f;
normY = (float)World.Height + 8.0f;
skyY = max(Camera.CurrentPos.Y + 8.0f, normY);
Gfx_SetVertexFormat(VERTEX_FORMAT_P3FC4B);
Gfx_BindVb(sky_vb);
@ -261,13 +261,13 @@ static void EnvRenderer_UpdateSky(void) {
int extent, height;
int x1, z1, x2, z2;
if (!World_Blocks || Gfx_LostContext) return;
if (!World.Blocks || Gfx_LostContext) return;
Gfx_DeleteVb(&sky_vb);
if (EnvRenderer_Minimal) return;
extent = Utils_AdjViewDist(Game_ViewDistance);
x1 = -extent; x2 = World_Width + extent;
z1 = -extent; z2 = World_Length + extent;
x1 = -extent; x2 = World.Width + extent;
z1 = -extent; z2 = World.Length + extent;
sky_vertices = EnvRenderer_Vertices(x2 - x1, z2 - z1);
ptr = v;
@ -275,7 +275,7 @@ static void EnvRenderer_UpdateSky(void) {
ptr = Mem_Alloc(sky_vertices, sizeof(VertexP3fC4b), "temp sky vertices");
}
height = max((World_Height + 2), Env_CloudsHeight) + 6;
height = max((World.Height + 2), Env_CloudsHeight) + 6;
EnvRenderer_DrawSkyY(x1, z1, x2, z2, height, ptr);
sky_vb = Gfx_CreateVb(ptr, VERTEX_FORMAT_P3FC4B, sky_vertices);
@ -363,19 +363,19 @@ static Vector3I weather_lastPos;
#define WEATHER_EXTENT 4
#define WEATHER_VERTS_COUNT 8 * (WEATHER_EXTENT * 2 + 1) * (WEATHER_EXTENT * 2 + 1)
#define Weather_Pack(x, z) ((x) * World_Length + (z))
#define Weather_Pack(x, z) ((x) * World.Length + (z))
static void EnvRenderer_InitWeatherHeightmap(void) {
int i;
Weather_Heightmap = Mem_Alloc(World_Width * World_Length, 2, "weather heightmap");
Weather_Heightmap = Mem_Alloc(World.Width * World.Length, 2, "weather heightmap");
for (i = 0; i < World_Width * World_Length; i++) {
for (i = 0; i < World.Width * World.Length; i++) {
Weather_Heightmap[i] = Int16_MaxValue;
}
}
#define EnvRenderer_RainCalcBody(get_block)\
for (y = maxY; y >= 0; y--, i -= World_OneY) {\
for (y = maxY; y >= 0; y--, i -= World.OneY) {\
draw = Blocks.Draw[get_block];\
\
if (!(draw == DRAW_GAS || draw == DRAW_SPRITE)) {\
@ -389,12 +389,12 @@ static int EnvRenderer_CalcRainHeightAt(int x, int maxY, int z, int hIndex) {
uint8_t draw;
#ifndef EXTENDED_BLOCKS
EnvRenderer_RainCalcBody(World_Blocks[i]);
EnvRenderer_RainCalcBody(World.Blocks[i]);
#else
if (Block_UsedCount <= 256) {
EnvRenderer_RainCalcBody(World_Blocks[i]);
EnvRenderer_RainCalcBody(World.Blocks[i]);
} else {
EnvRenderer_RainCalcBody(World_Blocks[i] | (World_Blocks2[i] << 8));
EnvRenderer_RainCalcBody(World.Blocks[i] | (World.Blocks2[i] << 8));
}
#endif
@ -405,12 +405,12 @@ static int EnvRenderer_CalcRainHeightAt(int x, int maxY, int z, int hIndex) {
static float EnvRenderer_RainHeight(int x, int z) {
int hIndex, height;
int y;
if (x < 0 || z < 0 || x >= World_Width || z >= World_Length) return (float)Env_EdgeHeight;
if (x < 0 || z < 0 || x >= World.Width || z >= World.Length) return (float)Env_EdgeHeight;
hIndex = Weather_Pack(x, z);
height = Weather_Heightmap[hIndex];
y = height == Int16_MaxValue ? EnvRenderer_CalcRainHeightAt(x, World_MaxY, z, hIndex) : height;
y = height == Int16_MaxValue ? EnvRenderer_CalcRainHeightAt(x, World.MaxY, z, hIndex) : height;
return y == -1 ? 0 : y + Blocks.MaxBB[World_GetBlock(x, y, z)].Y;
}
@ -467,7 +467,7 @@ void EnvRenderer_RenderWeather(double deltaTime) {
/* Rain should extend up by 64 blocks, or to the top of the world. */
pos.Y += 64;
pos.Y = max(World_Height, pos.Y);
pos.Y = max(World.Height, pos.Y);
speed = (weather == WEATHER_RAINY ? 1.0f : 0.2f) * Env_WeatherSpeed;
vOffset = (float)Game.Time * speed;
@ -589,11 +589,11 @@ static Rect2D EnvRenderer_Rect(int x, int y, int width, int height) {
static void EnvRenderer_CalcBorderRects(Rect2D* rects) {
int extent = Utils_AdjViewDist(Game_ViewDistance);
rects[0] = EnvRenderer_Rect(-extent, -extent, extent + World_Width + extent, extent);
rects[1] = EnvRenderer_Rect(-extent, World_Length, extent + World_Width + extent, extent);
rects[0] = EnvRenderer_Rect(-extent, -extent, extent + World.Width + extent, extent);
rects[1] = EnvRenderer_Rect(-extent, World.Length, extent + World.Width + extent, extent);
rects[2] = EnvRenderer_Rect(-extent, 0, extent, World_Length);
rects[3] = EnvRenderer_Rect(World_Width, 0, extent, World_Length);
rects[2] = EnvRenderer_Rect(-extent, 0, extent, World.Length);
rects[3] = EnvRenderer_Rect(World.Width, 0, extent, World.Length);
}
static void EnvRenderer_UpdateBorderTextures(void) {
@ -693,7 +693,7 @@ static void EnvRenderer_UpdateMapSides(void) {
VertexP3fT2fC4b* ptr;
VertexP3fT2fC4b* cur;
if (!World_Blocks || Gfx_LostContext) return;
if (!World.Blocks || Gfx_LostContext) return;
Gfx_DeleteVb(&sides_vb);
block = Env_SidesBlock;
@ -707,9 +707,9 @@ static void EnvRenderer_UpdateMapSides(void) {
}
y = Env_SidesHeight;
sides_vertices += EnvRenderer_Vertices(World_Width, World_Length); /* YQuads beneath map */
sides_vertices += 2 * EnvRenderer_Vertices(World_Width, Math_AbsI(y)); /* ZQuads */
sides_vertices += 2 * EnvRenderer_Vertices(World_Length, Math_AbsI(y)); /* XQuads */
sides_vertices += EnvRenderer_Vertices(World.Width, World.Length); /* YQuads beneath map */
sides_vertices += 2 * EnvRenderer_Vertices(World.Width, Math_AbsI(y)); /* ZQuads */
sides_vertices += 2 * EnvRenderer_Vertices(World.Length, Math_AbsI(y)); /* XQuads */
ptr = v;
if (sides_vertices > ENV_SMALL_VERTICES) {
@ -731,11 +731,11 @@ static void EnvRenderer_UpdateMapSides(void) {
y1 = 0; y2 = y;
if (y < 0) { y1 = y; y2 = 0; }
EnvRenderer_DrawBorderY(0, 0, World_Width, World_Length, 0, col, 0, 0, &cur);
EnvRenderer_DrawBorderZ(0, 0, World_Width, y1, y2, col, &cur);
EnvRenderer_DrawBorderZ(World_Length, 0, World_Width, y1, y2, col, &cur);
EnvRenderer_DrawBorderX(0, 0, World_Length, y1, y2, col, &cur);
EnvRenderer_DrawBorderX(World_Width, 0, World_Length, y1, y2, col, &cur);
EnvRenderer_DrawBorderY(0, 0, World.Width, World.Length, 0, col, 0, 0, &cur);
EnvRenderer_DrawBorderZ(0, 0, World.Width, y1, y2, col, &cur);
EnvRenderer_DrawBorderZ(World.Length, 0, World.Width, y1, y2, col, &cur);
EnvRenderer_DrawBorderX(0, 0, World.Length, y1, y2, col, &cur);
EnvRenderer_DrawBorderX(World.Width, 0, World.Length, y1, y2, col, &cur);
sides_vb = Gfx_CreateVb(ptr, VERTEX_FORMAT_P3FT2FC4B, sides_vertices);
if (sides_vertices > ENV_SMALL_VERTICES) Mem_Free(ptr);
@ -752,7 +752,7 @@ static void EnvRenderer_UpdateMapEdges(void) {
VertexP3fT2fC4b* ptr;
VertexP3fT2fC4b* cur;
if (!World_Blocks || Gfx_LostContext) return;
if (!World.Blocks || Gfx_LostContext) return;
Gfx_DeleteVb(&edges_vb);
block = Env_EdgeBlock;

View File

@ -21,12 +21,12 @@
*--------------------------------------------------------General----------------------------------------------------------*
*#########################################################################################################################*/
static ReturnCode Map_ReadBlocks(struct Stream* stream) {
World_BlocksSize = World_Width * World_Length * World_Height;
World_Blocks = Mem_Alloc(World_BlocksSize, 1, "map blocks");
World.BlocksSize = World.Width * World.Length * World.Height;
World.Blocks = Mem_Alloc(World.BlocksSize, 1, "map blocks");
#ifdef EXTENDED_BLOCKS
World_Blocks2 = World_Blocks;
World.Blocks2 = World.Blocks;
#endif
return Stream_Read(stream, World_Blocks, World_BlocksSize);
return Stream_Read(stream, World.Blocks, World.BlocksSize);
}
static ReturnCode Map_SkipGZipHeader(struct Stream* stream) {
@ -75,7 +75,7 @@ void Map_LoadFrom(const String* path) {
res = stream.Close(&stream);
if (res) { Logger_Warn2(res, "closing", path); }
World_SetNewMap(World_Blocks, World_BlocksSize, World_Width, World_Height, World_Length);
World_SetNewMap(World.Blocks, World.BlocksSize, World.Width, World.Height, World.Length);
Event_RaiseVoid(&WorldEvents.MapLoaded);
LocationUpdate_MakePosAndOri(&update, p->Spawn, p->SpawnRotY, p->SpawnHeadX, false);
@ -115,13 +115,13 @@ static ReturnCode Lvl_ReadCustomBlocks(struct Stream* stream) {
int x, y, z, i;
/* skip bounds checks when we know chunk is entirely inside map */
int adjWidth = World_Width & ~0x0F;
int adjHeight = World_Height & ~0x0F;
int adjLength = World_Length & ~0x0F;
int adjWidth = World.Width & ~0x0F;
int adjHeight = World.Height & ~0x0F;
int adjLength = World.Length & ~0x0F;
for (y = 0; y < World_Height; y += LVL_CHUNKSIZE) {
for (z = 0; z < World_Length; z += LVL_CHUNKSIZE) {
for (x = 0; x < World_Width; x += LVL_CHUNKSIZE) {
for (y = 0; y < World.Height; y += LVL_CHUNKSIZE) {
for (z = 0; z < World.Length; z += LVL_CHUNKSIZE) {
for (x = 0; x < World.Width; x += LVL_CHUNKSIZE) {
if ((res = stream->ReadU8(stream, &hasCustom))) return res;
if (hasCustom != 1) continue;
@ -133,15 +133,15 @@ static ReturnCode Lvl_ReadCustomBlocks(struct Stream* stream) {
xx = i & 0xF; yy = (i >> 8) & 0xF; zz = (i >> 4) & 0xF;
index = baseIndex + World_Pack(xx, yy, zz);
World_Blocks[index] = World_Blocks[index] == LVL_CUSTOMTILE ? chunk[i] : World_Blocks[index];
World.Blocks[index] = World.Blocks[index] == LVL_CUSTOMTILE ? chunk[i] : World.Blocks[index];
}
} else {
for (i = 0; i < sizeof(chunk); i++) {
xx = i & 0xF; yy = (i >> 8) & 0xF; zz = (i >> 4) & 0xF;
if ((x + xx) >= World_Width || (y + yy) >= World_Height || (z + zz) >= World_Length) continue;
if ((x + xx) >= World.Width || (y + yy) >= World.Height || (z + zz) >= World.Length) continue;
index = baseIndex + World_Pack(xx, yy, zz);
World_Blocks[index] = World_Blocks[index] == LVL_CUSTOMTILE ? chunk[i] : World_Blocks[index];
World.Blocks[index] = World.Blocks[index] == LVL_CUSTOMTILE ? chunk[i] : World.Blocks[index];
}
}
}
@ -166,9 +166,9 @@ ReturnCode Lvl_Load(struct Stream* stream) {
if ((res = Stream_Read(&compStream, header, sizeof(header)))) return res;
if (Stream_GetU16_LE(&header[0]) != 1874) return LVL_ERR_VERSION;
World_Width = Stream_GetU16_LE(&header[2]);
World_Length = Stream_GetU16_LE(&header[4]);
World_Height = Stream_GetU16_LE(&header[6]);
World.Width = Stream_GetU16_LE(&header[2]);
World.Length = Stream_GetU16_LE(&header[4]);
World.Height = Stream_GetU16_LE(&header[6]);
p->Spawn.X = Stream_GetU16_LE(&header[8]);
p->Spawn.Z = Stream_GetU16_LE(&header[10]);
@ -178,15 +178,15 @@ ReturnCode Lvl_Load(struct Stream* stream) {
/* (2) pervisit, perbuild permissions */
if ((res = Map_ReadBlocks(&compStream))) return res;
blocks = World_Blocks;
blocks = World.Blocks;
/* Bulk convert 4 blocks at once */
for (i = 0; i < (World_BlocksSize & ~3); i += 4) {
for (i = 0; i < (World.BlocksSize & ~3); i += 4) {
*blocks = Lvl_table[*blocks]; blocks++;
*blocks = Lvl_table[*blocks]; blocks++;
*blocks = Lvl_table[*blocks]; blocks++;
*blocks = Lvl_table[*blocks]; blocks++;
}
for (; i < World_BlocksSize; i++) {
for (; i < World.BlocksSize; i++) {
*blocks = Lvl_table[*blocks]; blocks++;
}
@ -227,9 +227,9 @@ ReturnCode Fcm_Load(struct Stream* stream) {
if (Stream_GetU32_LE(&header[0]) != 0x0FC2AF40UL) return FCM_ERR_IDENTIFIER;
if (header[4] != 13) return FCM_ERR_REVISION;
World_Width = Stream_GetU16_LE(&header[5]);
World_Height = Stream_GetU16_LE(&header[7]);
World_Length = Stream_GetU16_LE(&header[9]);
World.Width = Stream_GetU16_LE(&header[5]);
World.Height = Stream_GetU16_LE(&header[7]);
World.Length = Stream_GetU16_LE(&header[9]);
p->Spawn.X = ((int)Stream_GetU32_LE(&header[11])) / 32.0f;
p->Spawn.Y = ((int)Stream_GetU32_LE(&header[15])) / 32.0f;
@ -239,7 +239,7 @@ ReturnCode Fcm_Load(struct Stream* stream) {
/* header[25] (4) date modified */
/* header[29] (4) date created */
Mem_Copy(&World_Uuid, &header[33], sizeof(World_Uuid));
Mem_Copy(&World.Uuid, &header[33], sizeof(World.Uuid));
/* header[49] (26) layer index */
count = (int)Stream_GetU32_LE(&header[75]);
@ -422,27 +422,27 @@ static ReturnCode Nbt_ReadTag(uint8_t typeId, bool readTagName, struct Stream* s
*--------------------------------------------------ClassicWorld format----------------------------------------------------*
*#########################################################################################################################*/
static void Cw_Callback_1(struct NbtTag* tag) {
if (IsTag(tag, "X")) { World_Width = NbtTag_U16(tag); return; }
if (IsTag(tag, "Y")) { World_Height = NbtTag_U16(tag); return; }
if (IsTag(tag, "Z")) { World_Length = NbtTag_U16(tag); return; }
if (IsTag(tag, "X")) { World.Width = NbtTag_U16(tag); return; }
if (IsTag(tag, "Y")) { World.Height = NbtTag_U16(tag); return; }
if (IsTag(tag, "Z")) { World.Length = NbtTag_U16(tag); return; }
if (IsTag(tag, "UUID")) {
if (tag->DataSize != sizeof(World_Uuid)) Logger_Abort("Map UUID must be 16 bytes");
Mem_Copy(World_Uuid, tag->Value.Small, sizeof(World_Uuid));
if (tag->DataSize != sizeof(World.Uuid)) Logger_Abort("Map UUID must be 16 bytes");
Mem_Copy(World.Uuid, tag->Value.Small, sizeof(World.Uuid));
return;
}
if (IsTag(tag, "BlockArray")) {
World_BlocksSize = tag->DataSize;
World.BlocksSize = tag->DataSize;
if (NbtTag_IsSmall(tag)) {
World_Blocks = Mem_Alloc(World_BlocksSize, 1, ".cw map blocks");
Mem_Copy(World_Blocks, tag->Value.Small, tag->DataSize);
World.Blocks = Mem_Alloc(World.BlocksSize, 1, ".cw map blocks");
Mem_Copy(World.Blocks, tag->Value.Small, tag->DataSize);
} else {
World_Blocks = tag->Value.Big;
tag->Value.Big = NULL; /* So Nbt_ReadTag doesn't call Mem_Free on World_Blocks */
World.Blocks = tag->Value.Big;
tag->Value.Big = NULL; /* So Nbt_ReadTag doesn't call Mem_Free on World.Blocks */
}
#ifdef EXTENDED_BLOCKS
World_Blocks2 = World_Blocks;
World.Blocks2 = World.Blocks;
#endif
}
}
@ -828,18 +828,18 @@ ReturnCode Dat_Load(struct Stream* stream) {
fieldName = String_FromRawArray(field->FieldName);
if (String_CaselessEqualsConst(&fieldName, "width")) {
World_Width = Dat_I32(field);
World.Width = Dat_I32(field);
} else if (String_CaselessEqualsConst(&fieldName, "height")) {
World_Length = Dat_I32(field);
World.Length = Dat_I32(field);
} else if (String_CaselessEqualsConst(&fieldName, "depth")) {
World_Height = Dat_I32(field);
World.Height = Dat_I32(field);
} else if (String_CaselessEqualsConst(&fieldName, "blocks")) {
if (field->Type != JFIELD_ARRAY) Logger_Abort("Blocks field must be Array");
World_Blocks = field->Value.Array.Ptr;
World.Blocks = field->Value.Array.Ptr;
#ifdef EXTENDED_BLOCKS
World_Blocks2 = World_Blocks;
World.Blocks2 = World.Blocks;
#endif
World_BlocksSize = field->Value.Array.Size;
World.BlocksSize = field->Value.Array.Size;
} else if (String_CaselessEqualsConst(&fieldName, "xSpawn")) {
p->Spawn.X = (float)Dat_I32(field);
} else if (String_CaselessEqualsConst(&fieldName, "ySpawn")) {
@ -1005,11 +1005,11 @@ ReturnCode Cw_Save(struct Stream* stream) {
Mem_Copy(tmp, cw_begin, sizeof(cw_begin));
{
Mem_Copy(&tmp[43], World_Uuid, sizeof(World_Uuid));
Stream_SetU16_BE(&tmp[63], World_Width);
Stream_SetU16_BE(&tmp[69], World_Height);
Stream_SetU16_BE(&tmp[75], World_Length);
Stream_SetU32_BE(&tmp[127], World_BlocksSize);
Mem_Copy(&tmp[43], World.Uuid, sizeof(World.Uuid));
Stream_SetU16_BE(&tmp[63], World.Width);
Stream_SetU16_BE(&tmp[69], World.Height);
Stream_SetU16_BE(&tmp[75], World.Length);
Stream_SetU32_BE(&tmp[127], World.BlocksSize);
/* TODO: Maybe keep real spawn too? */
Stream_SetU16_BE(&tmp[89], (uint16_t)p->Base.Position.X);
@ -1019,7 +1019,7 @@ ReturnCode Cw_Save(struct Stream* stream) {
tmp[112] = Math_Deg2Packed(p->SpawnHeadX);
}
if ((res = Stream_Write(stream, tmp, sizeof(cw_begin)))) return res;
if ((res = Stream_Write(stream, World_Blocks, World_BlocksSize))) return res;
if ((res = Stream_Write(stream, World.Blocks, World.BlocksSize))) return res;
Mem_Copy(tmp, cw_meta_cpe, sizeof(cw_meta_cpe));
{
@ -1076,22 +1076,22 @@ ReturnCode Schematic_Save(struct Stream* stream) {
Mem_Copy(tmp, sc_begin, sizeof(sc_begin));
{
Stream_SetU16_BE(&tmp[41], World_Width);
Stream_SetU16_BE(&tmp[52], World_Height);
Stream_SetU16_BE(&tmp[63], World_Length);
Stream_SetU32_BE(&tmp[74], World_BlocksSize);
Stream_SetU16_BE(&tmp[41], World.Width);
Stream_SetU16_BE(&tmp[52], World.Height);
Stream_SetU16_BE(&tmp[63], World.Length);
Stream_SetU32_BE(&tmp[74], World.BlocksSize);
}
if ((res = Stream_Write(stream, tmp, sizeof(sc_begin)))) return res;
if ((res = Stream_Write(stream, World_Blocks, World_BlocksSize))) return res;
if ((res = Stream_Write(stream, World.Blocks, World.BlocksSize))) return res;
Mem_Copy(tmp, sc_data, sizeof(sc_data));
{
Stream_SetU32_BE(&tmp[7], World_BlocksSize);
Stream_SetU32_BE(&tmp[7], World.BlocksSize);
}
if ((res = Stream_Write(stream, tmp, sizeof(sc_data)))) return res;
for (i = 0; i < World_BlocksSize; i += sizeof(chunk)) {
int count = World_BlocksSize - i; count = min(count, sizeof(chunk));
for (i = 0; i < World.BlocksSize; i += sizeof(chunk)) {
int count = World.BlocksSize - i; count = min(count, sizeof(chunk));
if ((res = Stream_Write(stream, chunk, count))) return res;
}
return Stream_Write(stream, sc_end, sizeof(sc_end));

View File

@ -559,7 +559,7 @@ static void Game_Render3D(double delta, float t) {
/* Render water over translucent blocks when underwater for proper alpha blending */
pos = LocalPlayer_Instance.Base.Position;
if (Camera.CurrentPos.Y < Env_EdgeHeight && (pos.X < 0 || pos.Z < 0 || pos.X > World_Width || pos.Z > World_Length)) {
if (Camera.CurrentPos.Y < Env_EdgeHeight && (pos.X < 0 || pos.Z < 0 || pos.X > World.Width || pos.Z > World.Length)) {
MapRenderer_RenderTranslucent(delta);
EnvRenderer_RenderMapEdges(delta);
} else {
@ -664,7 +664,7 @@ static void Game_RenderFrame(double delta) {
Game_UpdateViewMatrix();
visible = !Gui_Active || !Gui_Active->BlocksWorld;
if (visible && World_Blocks) {
if (visible && World.Blocks) {
Game_Render3D(delta, t);
} else {
PickedPos_SetAsInvalid(&Game_SelectedPos);

View File

@ -246,7 +246,7 @@ static bool InputHandler_PushbackPlace(struct AABB* blockBB) {
/* Being vertically above the map is acceptable though */
insideMap =
pos.X > 0.0f && pos.Y >= 0.0f && pos.Z > 0.0f &&
pos.X < World_Width && pos.Z < World_Length;
pos.X < World.Width && pos.Z < World.Length;
if (!insideMap) return false;
AABB_Make(&playerBB, &pos, &p->Size);

View File

@ -12,7 +12,7 @@ int16_t* Lighting_Heightmap;
#define HEIGHT_UNCALCULATED Int16_MaxValue
#define Lighting_CalcBody(get_block)\
for (y = maxY; y >= 0; y--, i -= World_OneY) {\
for (y = maxY; y >= 0; y--, i -= World.OneY) {\
block = get_block;\
\
if (Blocks.BlocksLight[block]) {\
@ -28,12 +28,12 @@ static int Lighting_CalcHeightAt(int x, int maxY, int z, int hIndex) {
int y, offset;
#ifndef EXTENDED_BLOCKS
Lighting_CalcBody(World_Blocks[i]);
Lighting_CalcBody(World.Blocks[i]);
#else
if (Block_UsedCount <= 256) {
Lighting_CalcBody(World_Blocks[i]);
Lighting_CalcBody(World.Blocks[i]);
} else {
Lighting_CalcBody(World_Blocks[i] | (World_Blocks2[i] << 8));
Lighting_CalcBody(World.Blocks[i] | (World.Blocks2[i] << 8));
}
#endif
@ -44,7 +44,7 @@ static int Lighting_CalcHeightAt(int x, int maxY, int z, int hIndex) {
static int Lighting_GetLightHeight(int x, int z) {
int hIndex = Lighting_Pack(x, z);
int lightH = Lighting_Heightmap[hIndex];
return lightH == HEIGHT_UNCALCULATED ? Lighting_CalcHeightAt(x, World_Height - 1, z, hIndex) : lightH;
return lightH == HEIGHT_UNCALCULATED ? Lighting_CalcHeightAt(x, World.Height - 1, z, hIndex) : lightH;
}
/* Outside colour is same as sunlight colour, so we reuse when possible */
@ -82,7 +82,7 @@ PackedCol Lighting_Col_ZSide_Fast(int x, int y, int z) {
void Lighting_Refresh(void) {
int i;
for (i = 0; i < World_Width * World_Length; i++) {
for (i = 0; i < World.Width * World.Length; i++) {
Lighting_Heightmap[i] = HEIGHT_UNCALCULATED;
}
}
@ -115,7 +115,7 @@ static void Lighting_UpdateLighting(int x, int y, int z, BlockID oldBlock, Block
} else if (y == lightH && oldOffset == 0) {
/* For a solid block on top of an upside down slab, they will both have the same light height. */
/* So we need to account for this particular case. */
above = y == (World_Height - 1) ? BLOCK_AIR : World_GetBlock(x, y + 1, z);
above = y == (World.Height - 1) ? BLOCK_AIR : World_GetBlock(x, y + 1, z);
if (Blocks.BlocksLight[above]) return;
if (nowBlocks) {
@ -132,7 +132,7 @@ static bool Lighting_Needs(BlockID block, BlockID other) {
#define Lighting_NeedsNeighourBody(get_block)\
/* Update if any blocks in the chunk are affected by light change. */ \
for (; y >= minY; y--, i -= World_OneY) {\
for (; y >= minY; y--, i -= World.OneY) {\
other = get_block;\
affected = y == nY ? Lighting_Needs(block, other) : Blocks.Draw[other] != DRAW_GAS;\
if (affected) return true;\
@ -143,12 +143,12 @@ static bool Lighting_NeedsNeighour(BlockID block, int i, int minY, int y, int nY
bool affected;
#ifndef EXTENDED_BLOCKS
Lighting_NeedsNeighourBody(World_Blocks[i]);
Lighting_NeedsNeighourBody(World.Blocks[i]);
#else
if (Block_UsedCount <= 256) {
Lighting_NeedsNeighourBody(World_Blocks[i]);
Lighting_NeedsNeighourBody(World.Blocks[i]);
} else {
Lighting_NeedsNeighourBody(World_Blocks[i] | (World_Blocks2[i] << 8));
Lighting_NeedsNeighourBody(World.Blocks[i] | (World.Blocks2[i] << 8));
}
#endif
return false;
@ -167,7 +167,7 @@ static void Lighting_ResetNeighbour(int x, int y, int z, BlockID block, int cx,
for (cy = maxCy; cy >= minCy; cy--) {
minY = (cy << CHUNK_SHIFT);
maxY = (cy << CHUNK_SHIFT) + CHUNK_MAX;
if (maxY > World_MaxY) maxY = World_MaxY;
if (maxY > World.MaxY) maxY = World.MaxY;
if (Lighting_NeedsNeighour(block, World_Pack(x, maxY, z), minY, maxY, y)) {
MapRenderer_RefreshChunk(cx, cy, cz);
@ -261,7 +261,7 @@ static int Lighting_InitialHeightmapCoverage(int x1, int z1, int xCount, int zCo
}
#define Lighting_CalculateBody(get_block)\
for (y = World_Height - 1; y >= 0; y--) {\
for (y = World.Height - 1; y >= 0; y--) {\
if (elemsLeft <= 0) { return true; } \
mapIndex = World_Pack(x1, y, z1);\
hIndex = Lighting_Pack(x1, z1);\
@ -298,8 +298,8 @@ for (y = World_Height - 1; y >= 0; y--) {\
x++; mapIndex++; index++; \
}\
prevRunCount = 0;\
hIndex += World_Width;\
mapIndex = baseIndex + World_Width; /* advance one Z */ \
hIndex += World.Width;\
mapIndex = baseIndex + World.Width; /* advance one Z */ \
}\
}
@ -310,12 +310,12 @@ static bool Lighting_CalculateHeightmapCoverage(int x1, int z1, int xCount, int
int x, y, z;
#ifndef EXTENDED_BLOCKS
Lighting_CalculateBody(World_Blocks[mapIndex]);
Lighting_CalculateBody(World.Blocks[mapIndex]);
#else
if (Block_UsedCount <= 256) {
Lighting_CalculateBody(World_Blocks[mapIndex]);
Lighting_CalculateBody(World.Blocks[mapIndex]);
} else {
Lighting_CalculateBody(World_Blocks[mapIndex] | (World_Blocks2[mapIndex] << 8));
Lighting_CalculateBody(World.Blocks[mapIndex] | (World.Blocks2[mapIndex] << 8));
}
#endif
return false;
@ -337,8 +337,8 @@ static void Lighting_FinishHeightmapCoverage(int x1, int z1, int xCount, int zCo
}
void Lighting_LightHint(int startX, int startZ) {
int x1 = max(startX, 0), x2 = min(World_Width, startX + EXTCHUNK_SIZE);
int z1 = max(startZ, 0), z2 = min(World_Length, startZ + EXTCHUNK_SIZE);
int x1 = max(startX, 0), x2 = min(World.Width, startX + EXTCHUNK_SIZE);
int z1 = max(startZ, 0), z2 = min(World.Length, startZ + EXTCHUNK_SIZE);
int xCount = x2 - x1, zCount = z2 - z1;
int32_t skip[EXTCHUNK_SIZE * EXTCHUNK_SIZE];
@ -358,7 +358,7 @@ static void Lighting_Reset(void) {
}
static void Lighting_OnNewMapLoaded(void) {
Lighting_Heightmap = Mem_Alloc(World_Width * World_Length, 2, "lighting heightmap");
Lighting_Heightmap = Mem_Alloc(World.Width * World.Length, 2, "lighting heightmap");
Lighting_Refresh();
}

View File

@ -8,7 +8,7 @@ BasicLighting: Uses a simple heightmap, where each block is either in sun or sha
struct IGameComponent;
extern struct IGameComponent Lighting_Component;
#define Lighting_Pack(x, z) ((x) + World_Width * (z))
#define Lighting_Pack(x, z) ((x) + World.Width * (z))
extern int16_t* Lighting_Heightmap;
/* Equivalent to (but far more optimised form of)

View File

@ -89,7 +89,7 @@ static void MapRenderer_CheckWeather(double delta) {
Vector3I_Floor(&pos, &Camera.CurrentPos);
block = World_SafeGetBlock_3I(pos);
outside = pos.X < 0 || pos.Y < 0 || pos.Z < 0 || pos.X >= World_Width || pos.Z >= World_Length;
outside = pos.X < 0 || pos.Y < 0 || pos.Z < 0 || pos.X >= World.Width || pos.Z >= World.Length;
inTranslucent = Blocks.Draw[block] == DRAW_TRANSLUCENT || (pos.Y < Env_EdgeHeight && outside);
/* If we are under water, render weather before to blend properly */
@ -353,9 +353,9 @@ static void MapRenderer_ResetPartCounts(void) {
static void MapRenderer_InitChunks(void) {
int x, y, z, index = 0;
for (z = 0; z < World_Length; z += CHUNK_SIZE) {
for (y = 0; y < World_Height; y += CHUNK_SIZE) {
for (x = 0; x < World_Width; x += CHUNK_SIZE) {
for (z = 0; z < World.Length; z += CHUNK_SIZE) {
for (y = 0; y < World.Height; y += CHUNK_SIZE) {
for (x = 0; x < World.Width; x += CHUNK_SIZE) {
ChunkInfo_Reset(&mapChunks[index], x, y, z);
sortedChunks[index] = &mapChunks[index];
renderChunks[index] = &mapChunks[index];
@ -368,9 +368,9 @@ static void MapRenderer_InitChunks(void) {
static void MapRenderer_ResetChunks(void) {
int x, y, z, index = 0;
for (z = 0; z < World_Length; z += CHUNK_SIZE) {
for (y = 0; y < World_Height; y += CHUNK_SIZE) {
for (x = 0; x < World_Width; x += CHUNK_SIZE) {
for (z = 0; z < World.Length; z += CHUNK_SIZE) {
for (y = 0; y < World.Height; y += CHUNK_SIZE) {
for (x = 0; x < World.Width; x += CHUNK_SIZE) {
ChunkInfo_Reset(&mapChunks[index], x, y, z);
index++;
}
@ -392,7 +392,7 @@ void MapRenderer_Refresh(void) {
int oldCount;
chunkPos = Vector3I_MaxValue();
if (mapChunks && World_Blocks) {
if (mapChunks && World.Blocks) {
MapRenderer_DeleteChunks();
MapRenderer_ResetChunks();
@ -412,7 +412,7 @@ void MapRenderer_RefreshBorders(int maxHeight) {
bool onBorder;
chunkPos = Vector3I_MaxValue();
if (!mapChunks || !World_Blocks) return;
if (!mapChunks || !World.Blocks) return;
for (cz = 0; cz < MapRenderer_ChunksZ; cz++) {
for (cy = 0; cy < MapRenderer_ChunksY; cy++) {
@ -731,9 +731,9 @@ static void MapRenderer_OnNewMap(void) {
static void MapRenderer_OnNewMapLoaded(void) {
int count;
MapRenderer_ChunksX = (World_Width + CHUNK_MAX) >> CHUNK_SHIFT;
MapRenderer_ChunksY = (World_Height + CHUNK_MAX) >> CHUNK_SHIFT;
MapRenderer_ChunksZ = (World_Length + CHUNK_MAX) >> CHUNK_SHIFT;
MapRenderer_ChunksX = (World.Width + CHUNK_MAX) >> CHUNK_SHIFT;
MapRenderer_ChunksY = (World.Height + CHUNK_MAX) >> CHUNK_SHIFT;
MapRenderer_ChunksZ = (World.Length + CHUNK_MAX) >> CHUNK_SHIFT;
count = MapRenderer_ChunksX * MapRenderer_ChunksY * MapRenderer_ChunksZ;
/* TODO: Only perform reallocation when map volume has changed */

View File

@ -1111,11 +1111,11 @@ static void GenLevelScreen_ContextRecreated(void* screen) {
struct GenLevelScreen* s = screen;
String_InitArray(tmp, tmpBuffer);
String_AppendInt(&tmp, World_Width);
String_AppendInt(&tmp, World.Width);
GenLevelScreen_Input(s, 0, -80, false, &tmp);
String_AppendInt(&tmp, World_Height);
String_AppendInt(&tmp, World.Height);
GenLevelScreen_Input(s, 1, -40, false, &tmp);
String_AppendInt(&tmp, World_Length);
String_AppendInt(&tmp, World.Length);
GenLevelScreen_Input(s, 2, 0, false, &tmp);
GenLevelScreen_Input(s, 3, 40, true, &tmp);
@ -2341,9 +2341,9 @@ struct Screen* EnvSettingsScreen_MakeInstance(void) {
String cloudHeight, edgeHeight;
cloudHeight = String_ClearedArray(cloudHeightBuffer);
String_AppendInt(&cloudHeight, World_Height + 2);
String_AppendInt(&cloudHeight, World.Height + 2);
edgeHeight = String_ClearedArray(edgeHeightBuffer);
String_AppendInt(&edgeHeight, World_Height / 2);
String_AppendInt(&edgeHeight, World.Height / 2);
validators[0] = MenuInputValidator_Hex();
defaultValues[0] = ENV_DEFAULT_CLOUDSCOL_HEX;

View File

@ -62,19 +62,19 @@ struct Model {
/* NOTE: These bounds are not transformed. (i.e. no rotation, centered around 0,0,0) */
void (*GetPickingBounds)(struct Entity* entity);
/* Count of assigned vertices within the raw vertices array */
/* The rest of the fields are set in Model_Init() */
int index;
uint8_t armX, armY; /* these translate arm model part back to (0, 0) */
bool initalised;
/* Whether the model should be slightly bobbed up and down when rendering */
/* Whether the model should be slightly bobbed up and down when rendering. */
/* e.g. for HumanoidModel, when legs are at the peak of their swing, whole model is moved slightly down */
bool Bobbing;
bool UsesSkin, CalcHumanAnims, UsesHumanSkin, Pushes;
float Gravity; Vector3 Drag, GroundFriction;
/* Returns the transformation matrix applied to the model when rendering */
/* Returns the transformation matrix applied to the model when rendering. */
/* NOTE: Most models just use Entity_GetTransform (except SittingModel) */
void (*GetTransform)(struct Entity* entity, Vector3 pos, struct Matrix* m);
void (*DrawArm)(struct Entity* entity);

View File

@ -508,7 +508,7 @@ static void Classic_LevelFinalise(uint8_t* data) {
#ifdef EXTENDED_BLOCKS
if (cpe_extBlocks) {
/* defer allocation of scond map array if possible */
World_Blocks2 = map2_blocks ? map2_blocks : map_blocks;
World.Blocks2 = map2_blocks ? map2_blocks : map_blocks;
Block_SetUsedCount(map2_blocks ? 768 : 256);
}
#endif
@ -1185,7 +1185,7 @@ static void CPE_BulkBlockUpdate(uint8_t* data) {
for (i = 0; i < count; i++) {
index = indices[i];
if (index < 0 || index >= World_BlocksSize) continue;
if (index < 0 || index >= World.BlocksSize) continue;
World_Unpack(index, x, y, z);
if (World_IsValidPos(x, y, z)) {
@ -1373,7 +1373,7 @@ static void CPE_Tick(void) {
*------------------------------------------------------Custom blocks------------------------------------------------------*
*#########################################################################################################################*/
static void BlockDefs_OnBlockUpdated(BlockID block, bool didBlockLight) {
if (!World_Blocks) return;
if (!World.Blocks) return;
/* Need to refresh lighting when a block's light blocking state changes */
if (Blocks.BlocksLight[block] != didBlockLight) { Lighting_Refresh(); }
}

View File

@ -119,8 +119,8 @@ static BlockID Picking_GetInside(int x, int y, int z) {
bool sides;
int height;
if (x >= 0 && z >= 0 && x < World_Width && z < World_Length) {
if (y >= World_Height) return BLOCK_AIR;
if (x >= 0 && z >= 0 && x < World.Width && z < World.Length) {
if (y >= World.Height) return BLOCK_AIR;
if (y >= 0) return World_GetBlock(x, y, z);
}
@ -134,19 +134,19 @@ static BlockID Picking_GetOutside(int x, int y, int z, Vector3I origin) {
bool sides;
int height;
if (x < 0 || z < 0 || x >= World_Width || z >= World_Length) return BLOCK_AIR;
if (x < 0 || z < 0 || x >= World.Width || z >= World.Length) return BLOCK_AIR;
sides = Env_SidesBlock != BLOCK_AIR;
/* handling of blocks inside the map, above, and on borders */
if (y >= World_Height) return BLOCK_AIR;
if (y >= World.Height) return BLOCK_AIR;
if (sides && y == -1 && origin.Y > 0) return PICKING_BORDER;
if (sides && y == 0 && origin.Y < 0) return PICKING_BORDER;
height = Env_SidesHeight; if (height < 1) height = 1;
if (sides && x == 0 && y >= 0 && y < height && origin.X < 0) return PICKING_BORDER;
if (sides && z == 0 && y >= 0 && y < height && origin.Z < 0) return PICKING_BORDER;
if (sides && x == World_MaxX && y >= 0 && y < height && origin.X >= World_Width) return PICKING_BORDER;
if (sides && z == World_MaxZ && y >= 0 && y < height && origin.Z >= World_Length) return PICKING_BORDER;
if (sides && x == World.MaxX && y >= 0 && y < height && origin.X >= World.Width) return PICKING_BORDER;
if (sides && z == World.MaxZ && y >= 0 && y < height && origin.Z >= World.Length) return PICKING_BORDER;
if (y >= 0) return World_GetBlock(x, y, z);
return BLOCK_AIR;
}

View File

@ -1084,7 +1084,7 @@ int Platform_TextWidth(struct DrawTextArgs* args) {
/* need to calculate glyph width */
if (charWidth == UInt16_MaxValue) {
cp = Convert_CP437ToUnicode(text.buffer[i]);
res = FT_Load_Char(face, cp, 0); /* TODO: Check error */
res = FT_Load_Char(face, cp, 0);
if (res) {
Platform_Log2("Error %i measuring width of %r", &res, &text.buffer[i]);

View File

@ -654,11 +654,11 @@ static void GeneratingScreen_EndGeneration(void) {
Chat_AddRaw("&cFailed to generate the map."); return;
}
World_BlocksSize = Gen_Width * Gen_Height * Gen_Length;
World_SetNewMap(Gen_Blocks, World_BlocksSize, Gen_Width, Gen_Height, Gen_Length);
World.BlocksSize = Gen_Width * Gen_Height * Gen_Length;
World_SetNewMap(Gen_Blocks, World.BlocksSize, Gen_Width, Gen_Height, Gen_Length);
Gen_Blocks = NULL;
x = (World_Width / 2) + 0.5f; z = (World_Length / 2) + 0.5f;
x = (World.Width / 2) + 0.5f; z = (World.Length / 2) + 0.5f;
p->Spawn = Respawn_FindSpawnPosition(x, z, p->Base.Size);
LocationUpdate_MakePosAndOri(&update, p->Spawn, 0.0f, 0.0f, false);

View File

@ -46,6 +46,7 @@ uint32_t Utils_CRC32(const uint8_t* data, uint32_t length);
extern const uint32_t Utils_Crc32Table[256];
CC_NOINLINE void* Utils_Resize(void* buffer, uint32_t* maxElems, uint32_t elemSize, uint32_t defElems, uint32_t expandElems);
CC_NOINLINE bool Utils_ParseIP(const String* ip, uint8_t* data);
/* Converts blocks of 3 bytes into 4 ASCII characters. (pads if needed) */
/* Returns the number of ASCII characters written. */
/* NOTE: You MUST ensure that dst is appropriately sized. */

View File

@ -9,17 +9,7 @@
#include "Physics.h"
#include "Game.h"
BlockRaw* World_Blocks;
#ifdef EXTENDED_BLOCKS
BlockRaw* World_Blocks2;
#endif
int World_BlocksSize;
int World_Width, World_Height, World_Length;
int World_MaxX, World_MaxY, World_MaxZ;
int World_OneY;
uint8_t World_Uuid[16];
struct _WorldData World;
/*########################################################################################################################*
*----------------------------------------------------------World----------------------------------------------------------*
*#########################################################################################################################*/
@ -34,48 +24,48 @@ static void World_NewUuid(void) {
}
for (i = 0; i < 16; i++) {
World_Uuid[i] = Random_Next(&rnd, 256);
World.Uuid[i] = Random_Next(&rnd, 256);
}
/* Set version and variant bits */
World_Uuid[6] &= 0x0F;
World_Uuid[6] |= 0x40; /* version 4*/
World_Uuid[8] &= 0x3F;
World_Uuid[8] |= 0x80; /* variant 2*/
World.Uuid[6] &= 0x0F;
World.Uuid[6] |= 0x40; /* version 4*/
World.Uuid[8] &= 0x3F;
World.Uuid[8] |= 0x80; /* variant 2*/
}
void World_Reset(void) {
#ifdef EXTENDED_BLOCKS
if (World_Blocks != World_Blocks2) Mem_Free(World_Blocks2);
if (World.Blocks != World.Blocks2) Mem_Free(World.Blocks2);
#endif
Mem_Free(World_Blocks);
World_Width = 0; World_Height = 0; World_Length = 0;
World_MaxX = 0; World_MaxY = 0; World_MaxZ = 0;
Mem_Free(World.Blocks);
World.Width = 0; World.Height = 0; World.Length = 0;
World.MaxX = 0; World.MaxY = 0; World.MaxZ = 0;
#ifdef EXTENDED_BLOCKS
World_Blocks2 = NULL;
World.Blocks2 = NULL;
#endif
World_Blocks = NULL; World_BlocksSize = 0;
World.Blocks = NULL; World.BlocksSize = 0;
Env_Reset();
World_NewUuid();
}
void World_SetNewMap(BlockRaw* blocks, int blocksSize, int width, int height, int length) {
World_Width = width; World_Height = height; World_Length = length;
World_Blocks = blocks; World_BlocksSize = blocksSize;
if (!World_BlocksSize) World_Blocks = NULL;
World.Width = width; World.Height = height; World.Length = length;
World.Blocks = blocks; World.BlocksSize = blocksSize;
if (!World.BlocksSize) World.Blocks = NULL;
if (blocksSize != (width * height * length)) {
Logger_Abort("Blocks array size does not match volume of map");
}
#ifdef EXTENDED_BLOCKS
World_Blocks2 = World_Blocks;
World.Blocks2 = World.Blocks;
#endif
World_OneY = width * length;
World_MaxX = width - 1;
World_MaxY = height - 1;
World_MaxZ = length - 1;
World.OneY = width * length;
World.MaxX = width - 1;
World.MaxY = height - 1;
World.MaxZ = length - 1;
if (Env_EdgeHeight == -1) {
Env_EdgeHeight = height / 2;
@ -89,25 +79,25 @@ void World_SetNewMap(BlockRaw* blocks, int blocksSize, int width, int height, in
#ifdef EXTENDED_BLOCKS
void World_SetBlock(int x, int y, int z, BlockID block) {
int i = World_Pack(x, y, z);
World_Blocks[i] = (BlockRaw)block;
World.Blocks[i] = (BlockRaw)block;
/* defer allocation of second map array if possible */
if (World_Blocks == World_Blocks2) {
if (World.Blocks == World.Blocks2) {
if (block < 256) return;
World_Blocks2 = Mem_AllocCleared(World_BlocksSize, 1, "blocks array upper");
World.Blocks2 = Mem_AllocCleared(World.BlocksSize, 1, "blocks array upper");
Block_SetUsedCount(768);
}
World_Blocks2[i] = (BlockRaw)(block >> 8);
World.Blocks2[i] = (BlockRaw)(block >> 8);
}
#else
void World_SetBlock(int x, int y, int z, BlockID block) {
World_Blocks[World_Pack(x, y, z)] = block;
World.Blocks[World_Pack(x, y, z)] = block;
}
#endif
BlockID World_GetPhysicsBlock(int x, int y, int z) {
if (x < 0 || x >= World_Width || z < 0 || z >= World_Length || y < 0) return BLOCK_BEDROCK;
if (y >= World_Height) return BLOCK_AIR;
if (x < 0 || x >= World.Width || z < 0 || z >= World.Length || y < 0) return BLOCK_BEDROCK;
if (y >= World.Height) return BLOCK_AIR;
return World_GetBlock(x, y, z);
}
@ -118,12 +108,12 @@ BlockID World_SafeGetBlock_3I(Vector3I p) {
bool World_IsValidPos(int x, int y, int z) {
return x >= 0 && y >= 0 && z >= 0 &&
x < World_Width && y < World_Height && z < World_Length;
x < World.Width && y < World.Height && z < World.Length;
}
bool World_IsValidPos_3I(Vector3I p) {
return p.X >= 0 && p.Y >= 0 && p.Z >= 0 &&
p.X < World_Width && p.Y < World_Height && p.Z < World_Length;
p.X < World.Width && p.Y < World.Height && p.Z < World.Length;
}
@ -287,11 +277,11 @@ Vector3 Respawn_FindSpawnPosition(float x, float z, Vector3 modelSize) {
float highestY;
int y;
spawn.Y = World_Height + ENTITY_ADJUSTMENT;
spawn.Y = World.Height + ENTITY_ADJUSTMENT;
AABB_Make(&bb, &spawn, &modelSize);
spawn.Y = 0.0f;
for (y = World_Height; y >= 0; y--) {
for (y = World.Height; y >= 0; y--) {
highestY = Respawn_HighestSolidY(&bb);
if (highestY != RESPAWN_NOT_FOUND) {
spawn.Y = highestY; break;

View File

@ -8,19 +8,32 @@
*/
struct AABB;
#define World_Unpack(idx, x, y, z) x = idx % World_Width; z = (idx / World_Width) % World_Length; y = (idx / World_Width) / World_Length;
#define World_Pack(x, y, z) (((y) * World_Length + (z)) * World_Width + (x))
/* 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))
extern BlockRaw* World_Blocks;
CC_VAR extern struct _WorldData {
/* The blocks in the world. */
BlockRaw* Blocks;
#ifdef EXTENDED_BLOCKS
extern BlockRaw* World_Blocks2;
/* The upper 8 bit of blocks in the world. */
/* If only 8 bit blocks are used, equals World_Blocks. */
BlockRaw* Blocks2;
#endif
extern int World_BlocksSize;
/* Volume of the world. */
int BlocksSize;
extern int World_Width, World_Height, World_Length;
extern int World_MaxX, World_MaxY, World_MaxZ;
extern int World_OneY;
extern uint8_t World_Uuid[16];
/* 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. */
uint8_t Uuid[16];
} World;
extern String World_TextureUrl;
/* Frees the blocks array, sets dimensions to 0, resets environment to default. */
@ -34,7 +47,7 @@ CC_API void World_SetNewMap(BlockRaw* blocks, int blocksSize, int width, int hei
extern int Block_IDMask;
static CC_INLINE BlockID World_GetBlock(int x, int y, int z) {
int i = World_Pack(x, y, z);
return (BlockID)((World_Blocks[i] | (World_Blocks2[i] << 8)) & Block_IDMask);
return (BlockID)((World.Blocks[i] | (World.Blocks2[i] << 8)) & Block_IDMask);
}
#else
#define World_GetBlock(x, y, z) World_Blocks[World_Pack(x, y, z)]