BigFlower fixes (#3826)
* BigFlowers fixes * Correct upper part meta * Documented parameters to DoesIgnoreBuildCollision
This commit is contained in:
parent
885d828712
commit
bbf5bec817
@ -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.",
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user