summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Server/Plugins/APIDump/APIDesc.lua4
-rw-r--r--src/BlockID.h2
-rw-r--r--src/Blocks/BlockBigFlower.h31
-rw-r--r--src/Blocks/BlockDeadBush.h2
-rw-r--r--src/Blocks/BlockFire.h2
-rw-r--r--src/Blocks/BlockFluid.h2
-rw-r--r--src/Blocks/BlockHandler.cpp2
-rw-r--r--src/Blocks/BlockHandler.h13
-rw-r--r--src/Blocks/BlockSnow.h4
-rw-r--r--src/Blocks/BlockTallGrass.h2
-rw-r--r--src/Blocks/BlockVine.h2
-rw-r--r--src/Chunk.cpp2
-rw-r--r--src/Generating/FinishGen.cpp4
-rw-r--r--src/Items/ItemBigFlower.h23
-rw-r--r--src/Items/ItemChest.h12
-rw-r--r--src/Items/ItemHandler.cpp12
-rw-r--r--src/Items/ItemSign.h3
-rw-r--r--tests/Generating/Stubs.cpp2
-rw-r--r--tests/LuaThreadStress/Stubs.cpp2
-rw-r--r--tests/SchematicFileSerializer/Stubs.cpp2
20 files changed, 78 insertions, 50 deletions
diff --git a/Server/Plugins/APIDump/APIDesc.lua b/Server/Plugins/APIDump/APIDesc.lua
index c3338b442..cdd724b14 100644
--- a/Server/Plugins/APIDump/APIDesc.lua
+++ b/Server/Plugins/APIDump/APIDesc.lua
@@ -15493,6 +15493,10 @@ end
{
Notes = "The player has swapped their held item with the item in their offhand slot (1.9)",
},
+ E_META_BIG_FLOWER_TOP =
+ {
+ Notes = "The metadata of a big flower block that indicates it is the top block.",
+ },
E_META_CONCRETE_BLACK =
{
Notes = "A flag in the metadata of concete that indicates that the concrete is black.",
diff --git a/src/BlockID.h b/src/BlockID.h
index 8454cd3da..96540bd6f 100644
--- a/src/BlockID.h
+++ b/src/BlockID.h
@@ -552,6 +552,8 @@ enum ENUM_BLOCK_META : NIBBLETYPE
E_META_BIG_FLOWER_LARGE_FERN = 3,
E_META_BIG_FLOWER_ROSE_BUSH = 4,
E_META_BIG_FLOWER_PEONY = 5,
+ // 0x8 is supposedly a bit flag but all vanilla plants have this value
+ E_META_BIG_FLOWER_TOP = 10,
// E_BLOCK_BREWING_STAND metas
E_META_BREWING_STAND_FILLED_SLOT_XP = 1,
diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h
index 3b3065f87..96139d656 100644
--- a/src/Blocks/BlockBigFlower.h
+++ b/src/Blocks/BlockBigFlower.h
@@ -18,19 +18,39 @@ public:
{
}
- virtual bool DoesIgnoreBuildCollision(cPlayer * a_Player, NIBBLETYPE a_Meta) override
+ virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override
{
- return (((a_Meta & E_META_BIG_FLOWER_DOUBLE_TALL_GRASS) != 0) || (a_Meta & E_META_BIG_FLOWER_LARGE_FERN) != 0);
+ if (IsMetaTopPart(a_Meta))
+ {
+ BLOCKTYPE BottomType;
+ if (
+ (a_Pos.y < 1) ||
+ !a_ChunkInterface.GetBlockTypeMeta(a_Pos.x, a_Pos.y - 1, a_Pos.z, BottomType, a_Meta) ||
+ (BottomType != E_BLOCK_BIG_FLOWER)
+ )
+ {
+ // Can't find the flower meta so assume grass
+ return true;
+ }
+ }
+
+ NIBBLETYPE FlowerMeta = a_Meta & 0x07;
+ return (
+ (FlowerMeta == E_META_BIG_FLOWER_DOUBLE_TALL_GRASS) ||
+ (FlowerMeta == E_META_BIG_FLOWER_LARGE_FERN)
+ );
}
virtual void DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_CanDrop) override
{
NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
int AlternateY = a_BlockY;
+ int BottomY = a_BlockY;
if (Meta & 0x8)
{
--AlternateY;
+ --BottomY;
}
else
{
@@ -39,13 +59,18 @@ public:
// also destroy the other block if it has a valid height and is a big flower
if (cChunkDef::IsValidHeight(AlternateY) && a_ChunkInterface.GetBlock(a_BlockX, AlternateY, a_BlockZ) == E_BLOCK_BIG_FLOWER)
{
- super::DropBlock(a_ChunkInterface, a_WorldInterface, a_BlockPluginInterface, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_CanDrop);
+ super::DropBlock(a_ChunkInterface, a_WorldInterface, a_BlockPluginInterface, a_Digger, a_BlockX, BottomY, a_BlockZ, a_CanDrop);
a_ChunkInterface.FastSetBlock(a_BlockX, AlternateY, a_BlockZ, E_BLOCK_AIR, 0);
}
}
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
+ if (IsMetaTopPart(a_BlockMeta))
+ {
+ return; // No way to tell flower type
+ }
+
NIBBLETYPE Meta = a_BlockMeta & 0x7;
if (Meta == E_META_BIG_FLOWER_DOUBLE_TALL_GRASS)
{
diff --git a/src/Blocks/BlockDeadBush.h b/src/Blocks/BlockDeadBush.h
index f9ce9a9ff..799d3a2f2 100644
--- a/src/Blocks/BlockDeadBush.h
+++ b/src/Blocks/BlockDeadBush.h
@@ -17,7 +17,7 @@ public:
{
}
- virtual bool DoesIgnoreBuildCollision(void) override
+ virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override
{
return true;
}
diff --git a/src/Blocks/BlockFire.h b/src/Blocks/BlockFire.h
index 346167a26..f16347558 100644
--- a/src/Blocks/BlockFire.h
+++ b/src/Blocks/BlockFire.h
@@ -232,7 +232,7 @@ public:
return (FoundFrameZP && FoundFrameZM);
}
- virtual bool DoesIgnoreBuildCollision(cPlayer * a_Player, NIBBLETYPE a_Meta) override
+ virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override
{
return true;
}
diff --git a/src/Blocks/BlockFluid.h b/src/Blocks/BlockFluid.h
index 0a8b34145..c33427739 100644
--- a/src/Blocks/BlockFluid.h
+++ b/src/Blocks/BlockFluid.h
@@ -24,7 +24,7 @@ public:
// No pickups
}
- virtual bool DoesIgnoreBuildCollision(void) override
+ virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override
{
return true;
}
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index 41e3561d1..40cc6b492 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -582,7 +582,7 @@ bool cBlockHandler::IsClickedThrough(void)
-bool cBlockHandler::DoesIgnoreBuildCollision(void)
+bool cBlockHandler::DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta)
{
return (m_BlockType == E_BLOCK_AIR);
}
diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h
index 625def7d8..302fdbc4b 100644
--- a/src/Blocks/BlockHandler.h
+++ b/src/Blocks/BlockHandler.h
@@ -114,16 +114,11 @@ public:
/** Checks if the player can build "inside" this block.
For example blocks placed "on" snow will be placed at the same position. So: Snow ignores Build collision
+ @param a_Pos Position of the block
+ @param a_Player Player trying to build on the block
+ @param a_Meta Meta value of the block currently at a_Pos
*/
- virtual bool DoesIgnoreBuildCollision(void);
-
- /** Similar to DoesIgnoreBuildCollision(void), but is used for cases where block's meta or
- player's item-in-hand is needed to determine collision (thin snow) */
- virtual bool DoesIgnoreBuildCollision(cPlayer *, NIBBLETYPE a_Meta)
- {
- UNUSED(a_Meta);
- return DoesIgnoreBuildCollision();
- }
+ virtual bool DoesIgnoreBuildCollision(cChunkInterface & ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta);
/** Returns if this block drops if it gets destroyed by an unsuitable situation.
Default: true */
diff --git a/src/Blocks/BlockSnow.h b/src/Blocks/BlockSnow.h
index d11c444b9..a502d82e4 100644
--- a/src/Blocks/BlockSnow.h
+++ b/src/Blocks/BlockSnow.h
@@ -41,9 +41,9 @@ public:
return true;
}
- virtual bool DoesIgnoreBuildCollision(cPlayer * a_Player, NIBBLETYPE a_Meta) override
+ virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override
{
- if ((a_Player->GetEquippedItem().m_ItemType == E_BLOCK_SNOW) && (a_Meta < 7))
+ if ((a_Player.GetEquippedItem().m_ItemType == E_BLOCK_SNOW) && (a_Meta < 7))
{
return true; // If a player is holding a (thin) snow block and it's size can be increased, return collision ignored
}
diff --git a/src/Blocks/BlockTallGrass.h b/src/Blocks/BlockTallGrass.h
index fb65bca65..8920bd7c9 100644
--- a/src/Blocks/BlockTallGrass.h
+++ b/src/Blocks/BlockTallGrass.h
@@ -18,7 +18,7 @@ public:
{
}
- virtual bool DoesIgnoreBuildCollision(void) override
+ virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override
{
return true;
}
diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h
index 755161b12..a015c8ab3 100644
--- a/src/Blocks/BlockVine.h
+++ b/src/Blocks/BlockVine.h
@@ -163,7 +163,7 @@ public:
}
}
- virtual bool DoesIgnoreBuildCollision(void) override
+ virtual bool DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta) override
{
return true;
}
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index 8a13fd20e..9ddee2343 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -1184,7 +1184,7 @@ bool cChunk::GrowTallGrass(int a_RelX, int a_RelY, int a_RelZ)
default: return false;
}
return UnboundedRelFastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_BIG_FLOWER, LargeFlowerMeta) &&
- UnboundedRelFastSetBlock(a_RelX, a_RelY + 1, a_RelZ, E_BLOCK_BIG_FLOWER, 0x8 | LargeFlowerMeta);
+ UnboundedRelFastSetBlock(a_RelX, a_RelY + 1, a_RelZ, E_BLOCK_BIG_FLOWER, E_META_BIG_FLOWER_TOP);
}
diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp
index df8d0929d..f6d6a2ff1 100644
--- a/src/Generating/FinishGen.cpp
+++ b/src/Generating/FinishGen.cpp
@@ -260,7 +260,7 @@ void cFinishGenClumpTopBlock::TryPlaceFoliageClump(cChunkDesc & a_ChunkDesc, int
a_ChunkDesc.SetBlockTypeMeta(x, Top + 1, z, a_BlockType, a_BlockMeta);
if (a_IsDoubleTall)
{
- a_ChunkDesc.SetBlockTypeMeta(x, Top + 2, z, E_BLOCK_BIG_FLOWER, 0x8 | a_BlockMeta);
+ a_ChunkDesc.SetBlockTypeMeta(x, Top + 2, z, E_BLOCK_BIG_FLOWER, E_META_BIG_FLOWER_TOP);
a_ChunkDesc.SetHeight(x, z, static_cast<HEIGHTTYPE>(Top + 2));
}
else
@@ -554,7 +554,7 @@ void cFinishGenTallGrass::GenFinish(cChunkDesc & a_ChunkDesc)
{
NIBBLETYPE Meta = (m_Noise.IntNoise2DInt(xx * 100, zz * 100) / 7 % 100) > 25 ? 2 : 3;
a_ChunkDesc.SetBlockTypeMeta(x, y, z, E_BLOCK_BIG_FLOWER, Meta);
- a_ChunkDesc.SetBlockTypeMeta(x, y + 1, z, E_BLOCK_BIG_FLOWER, 0x8 | Meta);
+ a_ChunkDesc.SetBlockTypeMeta(x, y + 1, z, E_BLOCK_BIG_FLOWER, E_META_BIG_FLOWER_TOP);
a_ChunkDesc.SetHeight(x, z, static_cast<HEIGHTTYPE>(y + 1));
}
}
diff --git a/src/Items/ItemBigFlower.h b/src/Items/ItemBigFlower.h
index f7171f2bc..81a1d54ce 100644
--- a/src/Items/ItemBigFlower.h
+++ b/src/Items/ItemBigFlower.h
@@ -34,17 +34,30 @@ public:
sSetBlockVector & a_BlocksToSet
) override
{
- // Can only be placed on the floor:
- if ((a_BlockY < 0) || (a_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) == E_BLOCK_AIR))
+ // Can only be placed on dirt:
+ if ((a_BlockY <= 0) || !IsBlockTypeOfDirt(a_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)))
{
return false;
}
- a_BlocksToSet.emplace_back(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_BIG_FLOWER, a_EquippedItem.m_ItemDamage & 0x07);
- if (a_BlockY < cChunkDef::Height - 1)
+ // Needs at least two free blocks to build in
+ if (a_BlockY >= cChunkDef::Height - 1)
{
- a_BlocksToSet.emplace_back(a_BlockX, a_BlockY + 1, a_BlockZ, E_BLOCK_BIG_FLOWER, (a_EquippedItem.m_ItemDamage & 0x07) | 0x08);
+ return false;
}
+
+ BLOCKTYPE TopType;
+ NIBBLETYPE TopMeta;
+ a_World.GetBlockTypeMeta(a_BlockX, a_BlockY + 1, a_BlockZ, TopType, TopMeta);
+ cChunkInterface ChunkInterface(a_World.GetChunkMap());
+
+ if (!BlockHandler(TopType)->DoesIgnoreBuildCollision(ChunkInterface, { a_BlockX, a_BlockY + 1, a_BlockZ }, a_Player, TopMeta))
+ {
+ return false;
+ }
+
+ a_BlocksToSet.emplace_back(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_BIG_FLOWER, a_EquippedItem.m_ItemDamage & 0x07);
+ a_BlocksToSet.emplace_back(a_BlockX, a_BlockY + 1, a_BlockZ, E_BLOCK_BIG_FLOWER, E_META_BIG_FLOWER_TOP);
return true;
}
};
diff --git a/src/Items/ItemChest.h b/src/Items/ItemChest.h
index d8cde2ae2..9f1a3f0d2 100644
--- a/src/Items/ItemChest.h
+++ b/src/Items/ItemChest.h
@@ -51,12 +51,9 @@ public:
BLOCKTYPE ClickedBlock;
NIBBLETYPE ClickedBlockMeta;
a_World.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedBlockMeta);
- if (
- BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision() ||
- BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision(&a_Player, ClickedBlockMeta)
- )
+ cChunkInterface ChunkInterface(a_World.GetChunkMap());
+ if (BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision(ChunkInterface, { a_BlockX, a_BlockY, a_BlockZ }, a_Player, ClickedBlockMeta))
{
- cChunkInterface ChunkInterface(a_World.GetChunkMap());
BlockHandler(ClickedBlock)->OnDestroyedByPlayer(ChunkInterface, a_World, &a_Player, a_BlockX, a_BlockY, a_BlockZ);
}
else
@@ -75,10 +72,7 @@ public:
// Clicked on side of block, make sure that placement won't be cancelled if there is a slab able to be double slabbed.
// No need to do combinability (dblslab) checks, client will do that here.
- if (
- !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision() &&
- !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision(&a_Player, PlaceMeta)
- )
+ if (BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision(ChunkInterface, { a_BlockX, a_BlockY, a_BlockZ }, a_Player, ClickedBlockMeta))
{
// Tried to place a block into another?
// Happens when you place a block aiming at side of block with a torch on it or stem beside it
diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp
index 8e3d79506..b430e83ef 100644
--- a/src/Items/ItemHandler.cpp
+++ b/src/Items/ItemHandler.cpp
@@ -357,14 +357,11 @@ bool cItemHandler::OnPlayerPlace(
NIBBLETYPE ClickedBlockMeta;
a_World.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedBlockMeta);
+ cChunkInterface ChunkInterface(a_World.GetChunkMap());
// Check if the block ignores build collision (water, grass etc.):
- if (
- BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision() ||
- BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision(&a_Player, ClickedBlockMeta)
- )
+ if (BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision(ChunkInterface, { a_BlockX, a_BlockY, a_BlockZ }, a_Player, ClickedBlockMeta))
{
- cChunkInterface ChunkInterface(a_World.GetChunkMap());
BlockHandler(ClickedBlock)->OnDestroyedByPlayer(ChunkInterface, a_World, &a_Player, a_BlockX, a_BlockY, a_BlockZ);
}
else
@@ -383,10 +380,7 @@ bool cItemHandler::OnPlayerPlace(
// Clicked on side of block, make sure that placement won't be cancelled if there is a slab able to be double slabbed.
// No need to do combinability (dblslab) checks, client will do that here.
- if (
- !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision() &&
- !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision(&a_Player, PlaceMeta)
- )
+ if (!BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision(ChunkInterface, { a_BlockX, a_BlockY, a_BlockZ }, a_Player, PlaceMeta))
{
// Tried to place a block into another?
// Happens when you place a block aiming at side of block with a torch on it or stem beside it
diff --git a/src/Items/ItemSign.h b/src/Items/ItemSign.h
index 4c417947d..37ad4967b 100644
--- a/src/Items/ItemSign.h
+++ b/src/Items/ItemSign.h
@@ -32,7 +32,8 @@ public:
BLOCKTYPE ClickedBlock;
NIBBLETYPE ClickedBlockMeta;
a_World.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedBlockMeta);
- bool isReplacingClickedBlock = BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision() || BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision(&a_Player, ClickedBlockMeta);
+ cChunkInterface ChunkInterface(a_World.GetChunkMap());
+ bool isReplacingClickedBlock = BlockHandler(ClickedBlock)->DoesIgnoreBuildCollision(ChunkInterface, { a_BlockX, a_BlockY, a_BlockZ }, a_Player, ClickedBlockMeta);
// If the regular placement doesn't work, do no further processing:
if (!super::OnPlayerPlace(a_World, a_Player, a_EquippedItem, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))
diff --git a/tests/Generating/Stubs.cpp b/tests/Generating/Stubs.cpp
index 0a9f431f4..aadb92d0b 100644
--- a/tests/Generating/Stubs.cpp
+++ b/tests/Generating/Stubs.cpp
@@ -222,7 +222,7 @@ bool cBlockHandler::IsClickedThrough(void)
-bool cBlockHandler::DoesIgnoreBuildCollision(void)
+bool cBlockHandler::DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta)
{
return (m_BlockType == E_BLOCK_AIR);
}
diff --git a/tests/LuaThreadStress/Stubs.cpp b/tests/LuaThreadStress/Stubs.cpp
index 0a9f431f4..aadb92d0b 100644
--- a/tests/LuaThreadStress/Stubs.cpp
+++ b/tests/LuaThreadStress/Stubs.cpp
@@ -222,7 +222,7 @@ bool cBlockHandler::IsClickedThrough(void)
-bool cBlockHandler::DoesIgnoreBuildCollision(void)
+bool cBlockHandler::DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta)
{
return (m_BlockType == E_BLOCK_AIR);
}
diff --git a/tests/SchematicFileSerializer/Stubs.cpp b/tests/SchematicFileSerializer/Stubs.cpp
index 74898fe50..7261d7a14 100644
--- a/tests/SchematicFileSerializer/Stubs.cpp
+++ b/tests/SchematicFileSerializer/Stubs.cpp
@@ -150,7 +150,7 @@ bool cBlockHandler::IsClickedThrough(void)
-bool cBlockHandler::DoesIgnoreBuildCollision(void)
+bool cBlockHandler::DoesIgnoreBuildCollision(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, cPlayer & a_Player, NIBBLETYPE a_Meta)
{
return (m_BlockType == E_BLOCK_AIR);
}