From 3f6d823aa41f1a7641fb686cf24561b0aca95798 Mon Sep 17 00:00:00 2001 From: Tommy Santerre Date: Sat, 14 Feb 2015 17:11:38 -0500 Subject: [PATCH] Correct world height validations. Unify the way we test block above the current one (Height - 1 instead of a_RelY + 1). Allow generation of world of flat height = 255 --- src/BlockEntities/ChestEntity.cpp | 4 ++-- src/Blocks/BlockBigFlower.h | 2 +- src/Blocks/BlockDirt.h | 2 +- src/Blocks/BlockFarmland.h | 2 +- src/Blocks/BlockFluid.h | 4 ++-- src/Blocks/BlockPortal.h | 2 +- src/Chunk.cpp | 6 +++--- src/ClientHandle.cpp | 6 ++++++ src/Entities/Boat.cpp | 2 +- src/Entities/FallingBlock.cpp | 5 ++++- src/Generating/FinishGen.cpp | 2 +- src/Generating/ShapeGen.cpp | 2 +- src/Items/ItemDoor.h | 2 +- src/MobSpawner.cpp | 2 +- src/Mobs/Monster.cpp | 2 +- src/Mobs/Sheep.cpp | 2 +- src/Simulator/FireSimulator.cpp | 2 +- src/Simulator/IncrementalRedstoneSimulator.cpp | 4 ++-- 18 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp index 3821f9aab..1c186310c 100644 --- a/src/BlockEntities/ChestEntity.cpp +++ b/src/BlockEntities/ChestEntity.cpp @@ -80,7 +80,7 @@ void cChestEntity::UsedBy(cPlayer * a_Player) void cChestEntity::OpenNewWindow(void) { // TODO: cats are an obstruction - if ((GetPosY() + 1 < cChunkDef::Height) && cBlockInfo::IsSolid(GetWorld()->GetBlock(GetPosX(), GetPosY() + 1, GetPosZ()))) + if ((GetPosY() < cChunkDef::Height - 1) && cBlockInfo::IsSolid(GetWorld()->GetBlock(GetPosX(), GetPosY() + 1, GetPosZ()))) { // Obstruction, don't open return; @@ -99,7 +99,7 @@ void cChestEntity::OpenNewWindow(void) virtual bool Item(cChestEntity * a_Chest) override { - if ((a_Chest->GetPosY() + 1 < cChunkDef::Height) && cBlockInfo::IsSolid(a_Chest->GetWorld()->GetBlock(a_Chest->GetPosX(), a_Chest->GetPosY() + 1, a_Chest->GetPosZ()))) + if ((a_Chest->GetPosY() < cChunkDef::Height - 1) && cBlockInfo::IsSolid(a_Chest->GetWorld()->GetBlock(a_Chest->GetPosX(), a_Chest->GetPosY() + 1, a_Chest->GetPosZ()))) { // Obstruction, don't open return false; diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h index 5240ddf53..6c5cc6b68 100644 --- a/src/Blocks/BlockBigFlower.h +++ b/src/Blocks/BlockBigFlower.h @@ -81,7 +81,7 @@ public: virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR) && (a_RelY < cChunkDef::Height) && ((a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ) == E_BLOCK_AIR) || (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ) == E_BLOCK_BIG_FLOWER))); + return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR) && (a_RelY < cChunkDef::Height - 1) && ((a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ) == E_BLOCK_AIR) || (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ) == E_BLOCK_BIG_FLOWER))); } diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index cc0d845e4..32512a2ef 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -59,7 +59,7 @@ public: a_Chunk.GetWorld()->QueueLightChunk(a_Chunk.GetPosX(), a_Chunk.GetPosZ()); return; } - else if (std::max(a_Chunk.GetBlockLight(a_RelX, a_RelY + 1, a_RelZ), a_Chunk.GetTimeAlteredLight(a_Chunk.GetSkyLight(a_RelX, a_RelY + 1, a_RelZ))) < 9) + else if ((a_RelY < cChunkDef::Height - 1) && std::max(a_Chunk.GetBlockLight(a_RelX, a_RelY + 1, a_RelZ), a_Chunk.GetTimeAlteredLight(a_Chunk.GetSkyLight(a_RelX, a_RelY + 1, a_RelZ))) < 9) { // Source block is not bright enough to spread return; diff --git a/src/Blocks/BlockFarmland.h b/src/Blocks/BlockFarmland.h index 02a48a4af..23a7392da 100644 --- a/src/Blocks/BlockFarmland.h +++ b/src/Blocks/BlockFarmland.h @@ -45,7 +45,7 @@ public: } // Farmland too dry. If nothing is growing on top, turn back to dirt: - BLOCKTYPE UpperBlock = (a_RelY >= cChunkDef::Height) ? E_BLOCK_AIR : a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ); + BLOCKTYPE UpperBlock = (a_RelY >= cChunkDef::Height - 1) ? E_BLOCK_AIR : a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ); switch (UpperBlock) { case E_BLOCK_CROPS: diff --git a/src/Blocks/BlockFluid.h b/src/Blocks/BlockFluid.h index 8c0aae041..2823baedc 100644 --- a/src/Blocks/BlockFluid.h +++ b/src/Blocks/BlockFluid.h @@ -99,7 +99,7 @@ public: // Check if it's fuel: BLOCKTYPE BlockType; if ( - ((a_RelY + y < 0) || (a_RelY + y > cChunkDef::Height)) || + ((a_RelY + y < 0) || (a_RelY + y >= cChunkDef::Height)) || !a_Chunk.UnboundedRelGetBlockType(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType) || !cFireSimulator::IsFuel(BlockType) ) @@ -126,7 +126,7 @@ public: for (size_t i = 0; i < ARRAYCOUNT(CrossCoords); i++) { if ( - ((RelY + CrossCoords[i].y >= 0) && (RelY + CrossCoords[i].y <= cChunkDef::Height)) && + ((RelY + CrossCoords[i].y >= 0) && (RelY + CrossCoords[i].y < cChunkDef::Height)) && a_Chunk.UnboundedRelGetBlockType(RelX + CrossCoords[i].x, RelY + CrossCoords[i].y, RelZ + CrossCoords[i].z, BlockType) && (BlockType == E_BLOCK_AIR) ) diff --git a/src/Blocks/BlockPortal.h b/src/Blocks/BlockPortal.h index 97ba26ee3..581a29447 100644 --- a/src/Blocks/BlockPortal.h +++ b/src/Blocks/BlockPortal.h @@ -55,7 +55,7 @@ public: virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - if ((a_RelY <= 0) || (a_RelY >= cChunkDef::Height)) + if ((a_RelY <= 0) || (a_RelY >= cChunkDef::Height - 1)) { return false; // In case someone places a portal with meta 1 or 2 at boundaries, and server tries to get invalid coords at Y - 1 or Y + 1 } diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 00ac1fdb1..1e5481826 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -931,7 +931,7 @@ void cChunk::ApplyWeatherToTop() FastSetBlock(X, Height, Z, E_BLOCK_SNOW, TopMeta - 1); } } - else if (cBlockInfo::IsSnowable(TopBlock) && (Height + 1 < cChunkDef::Height)) + else if (cBlockInfo::IsSnowable(TopBlock) && (Height < cChunkDef::Height - 1)) { SetBlock(X, Height + 1, Z, E_BLOCK_SNOW, 0); } @@ -1253,7 +1253,7 @@ bool cChunk::UnboundedRelGetBlockLights(int a_RelX, int a_RelY, int a_RelZ, NIBB bool cChunk::UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { - if ((a_RelY < 0) || (a_RelY > cChunkDef::Height)) + if ((a_RelY < 0) || (a_RelY >= cChunkDef::Height)) { LOGWARNING("UnboundedRelSetBlock(): requesting a block with a_RelY out of range: %d", a_RelY); return false; @@ -1274,7 +1274,7 @@ bool cChunk::UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE bool cChunk::UnboundedRelFastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { - if ((a_RelY < 0) || (a_RelY > cChunkDef::Height)) + if ((a_RelY < 0) || (a_RelY >= cChunkDef::Height)) { LOGWARNING("UnboundedRelFastSetBlock(): requesting a block with a_RelY out of range: %d", a_RelY); return false; diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index ec10ac521..6351ab2e3 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1006,6 +1006,12 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB int BlockY = a_BlockY; int BlockZ = a_BlockZ; AddFaceDirection(BlockX, BlockY, BlockZ, a_BlockFace); + + if ((BlockY < 0) || (BlockY >= cChunkDef::Height)) + { + return; + } + if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(BlockX, BlockY, BlockZ))->IsClickedThrough()) { a_BlockX = BlockX; diff --git a/src/Entities/Boat.cpp b/src/Entities/Boat.cpp index 6d8b4ef31..6177eb32f 100644 --- a/src/Entities/Boat.cpp +++ b/src/Entities/Boat.cpp @@ -98,7 +98,7 @@ void cBoat::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) SetSpeed(GetSpeed() * 0.97); // Slowly decrease the speed - if ((POSY_TOINT < 0) || (POSY_TOINT > cChunkDef::Height)) + if ((POSY_TOINT < 0) || (POSY_TOINT >= cChunkDef::Height)) { return; } diff --git a/src/Entities/FallingBlock.cpp b/src/Entities/FallingBlock.cpp index 75105a0cd..7301a3c9d 100644 --- a/src/Entities/FallingBlock.cpp +++ b/src/Entities/FallingBlock.cpp @@ -77,7 +77,10 @@ void cFallingBlock::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) ); */ - cSandSimulator::FinishFalling(m_World, BlockX, BlockY + 1, BlockZ, m_BlockType, m_BlockMeta); + if (BlockY < cChunkDef::Height - 1) + { + cSandSimulator::FinishFalling(m_World, BlockX, BlockY + 1, BlockZ, m_BlockType, m_BlockMeta); + } Destroy(true); return; } diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 260253d62..5839a4ccc 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -571,7 +571,7 @@ void cFinishGenSnow::GenFinish(cChunkDesc & a_ChunkDesc) continue; } - if (!cBlockInfo::IsSnowable(a_ChunkDesc.GetBlockType(x, Height, z)) && (Height < cChunkDef::Height - 1)) + if (!cBlockInfo::IsSnowable(a_ChunkDesc.GetBlockType(x, Height, z)) || (Height >= cChunkDef::Height - 1)) { // The top block can't be snown over. continue; diff --git a/src/Generating/ShapeGen.cpp b/src/Generating/ShapeGen.cpp index 45a9c3b93..43601ee20 100644 --- a/src/Generating/ShapeGen.cpp +++ b/src/Generating/ShapeGen.cpp @@ -41,7 +41,7 @@ public: { for (int x = 0; x < cChunkDef::Width; x++) { - HEIGHTTYPE height = cChunkDef::GetHeight(heightMap, x, z) + 1; + int height = cChunkDef::GetHeight(heightMap, x, z) + 1; Byte * shapeColumn = &(a_Shape[(x + 16 * z) * 256]); for (int y = 0; y < height; y++) { diff --git a/src/Items/ItemDoor.h b/src/Items/ItemDoor.h index 71143d5a8..524c49a5c 100644 --- a/src/Items/ItemDoor.h +++ b/src/Items/ItemDoor.h @@ -34,7 +34,7 @@ public: AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); // Door (bottom block) can be placed in Y range of [1, 254]: - if ((a_BlockY < 1) || (a_BlockY + 2 >= cChunkDef::Height)) + if ((a_BlockY < 1) || (a_BlockY >= cChunkDef::Height - 2)) { return false; } diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index 7a5238fd8..dfeab1461 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -132,7 +132,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R BLOCKTYPE TargetBlock = E_BLOCK_AIR; if (a_Chunk->UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, TargetBlock)) { - if ((a_RelY + 1 > cChunkDef::Height) || (a_RelY - 1 < 0)) + if ((a_RelY >= cChunkDef::Height - 1) || (a_RelY <= 0)) { return false; } diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 6e07bfbb6..a86497753 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -135,7 +135,7 @@ void cMonster::TickPathFinding() { 0, -1}, } ; - if ((PosY - 1 < 0) || (PosY + 2 > cChunkDef::Height) /* PosY + 1 will never be true if PosY + 2 is not */) + if ((PosY - 1 < 0) || (PosY + 2 >= cChunkDef::Height) /* PosY + 1 will never be true if PosY + 2 is not */) { // Too low/high, can't really do anything FinishPathFinding(); diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index e4d1760e0..c0cdec035 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -91,7 +91,7 @@ void cSheep::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) int PosY = POSY_TOINT - 1; int PosZ = POSZ_TOINT; - if ((PosY <= 0) || (PosY > cChunkDef::Height)) + if ((PosY <= 0) || (PosY >= cChunkDef::Height)) { return; } diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 8456ed11d..0ee33a3bc 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -377,7 +377,7 @@ void cFireSimulator::RemoveFuelNeighbors(cChunk * a_Chunk, int a_RelX, int a_Rel if (BlockType == E_BLOCK_TNT) { m_World.SpawnPrimedTNT(AbsX, Y, AbsZ, 0); - Neighbour->SetBlock(X, a_RelY + Y, Z, E_BLOCK_AIR, 0); + Neighbour->SetBlock(X, Y, Z, E_BLOCK_AIR, 0); return; } diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 1cc5340dd..40be9c582 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -31,7 +31,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY, { return; } - else if ((a_BlockY < 0) || (a_BlockY > cChunkDef::Height)) + else if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) { return; } @@ -556,7 +556,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_RelBlockX, int a_Re if ((i >= 4) && (i <= 7)) // If we are currently checking for wire surrounding ourself one block above... { BLOCKTYPE Type = 0; - if (a_RelBlockY + 1 >= cChunkDef::Height) + if (a_RelBlockY >= cChunkDef::Height - 1) { continue; }