diff options
author | Mattes D <github@xoft.cz> | 2019-10-16 10:06:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-16 10:06:34 +0200 |
commit | 221cc4ec5cb6301743e947eaabed3fecedba796f (patch) | |
tree | 4e44c8bb7523e5d1d04468fc906ae24674c10abc /src/Blocks/BlockHandler.cpp | |
parent | Fixed crash in hopper while pulling items from blockentity above itself (#4412) (diff) | |
download | cuberite-221cc4ec5cb6301743e947eaabed3fecedba796f.tar cuberite-221cc4ec5cb6301743e947eaabed3fecedba796f.tar.gz cuberite-221cc4ec5cb6301743e947eaabed3fecedba796f.tar.bz2 cuberite-221cc4ec5cb6301743e947eaabed3fecedba796f.tar.lz cuberite-221cc4ec5cb6301743e947eaabed3fecedba796f.tar.xz cuberite-221cc4ec5cb6301743e947eaabed3fecedba796f.tar.zst cuberite-221cc4ec5cb6301743e947eaabed3fecedba796f.zip |
Diffstat (limited to 'src/Blocks/BlockHandler.cpp')
-rw-r--r-- | src/Blocks/BlockHandler.cpp | 212 |
1 files changed, 56 insertions, 156 deletions
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 928fca1e9..58096f038 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -189,6 +189,7 @@ static cBlockHandler * CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_ACACIA_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType); case E_BLOCK_ACACIA_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_ACTIVATOR_RAIL: return new cBlockRailHandler (a_BlockType); + case E_BLOCK_AIR: return new cBlockWithNoDrops<> (a_BlockType); case E_BLOCK_ANVIL: return new cBlockAnvilHandler (a_BlockType); case E_BLOCK_BEACON: return new cBlockEntityHandler (a_BlockType); case E_BLOCK_BED: return new cBlockBedHandler (a_BlockType); @@ -401,185 +402,72 @@ void cBlockHandler::OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface void cBlockHandler::OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, const sSetBlock & a_BlockChange) { - OnPlaced(a_ChunkInterface, a_WorldInterface, a_BlockChange.GetX(), a_BlockChange.GetY(), a_BlockChange.GetZ(), a_BlockChange.m_BlockType, a_BlockChange.m_BlockMeta); + OnPlaced(a_ChunkInterface, a_WorldInterface, a_BlockChange.GetPos(), a_BlockChange.m_BlockType, a_BlockChange.m_BlockMeta); } -void cBlockHandler::OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) -{ -} - - - - - -void cBlockHandler::OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +void cBlockHandler::OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { // Notify the neighbors - NeighborChanged(a_ChunkInterface, a_BlockX - 1, a_BlockY, a_BlockZ, BLOCK_FACE_XP); - NeighborChanged(a_ChunkInterface, a_BlockX + 1, a_BlockY, a_BlockZ, BLOCK_FACE_XM); - NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_YP); - NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_YM); - NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ - 1, BLOCK_FACE_ZP); - NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ + 1, BLOCK_FACE_ZM); + NeighborChanged(a_ChunkInterface, a_BlockPos.addedX(-1), BLOCK_FACE_XP); + NeighborChanged(a_ChunkInterface, a_BlockPos.addedX( 1), BLOCK_FACE_XM); + NeighborChanged(a_ChunkInterface, a_BlockPos.addedY(-1), BLOCK_FACE_YP); + NeighborChanged(a_ChunkInterface, a_BlockPos.addedY( 1), BLOCK_FACE_YM); + NeighborChanged(a_ChunkInterface, a_BlockPos.addedZ(-1), BLOCK_FACE_ZP); + NeighborChanged(a_ChunkInterface, a_BlockPos.addedZ( 1), BLOCK_FACE_ZM); } -void cBlockHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) +void cBlockHandler::OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta) { // Notify the neighbors - NeighborChanged(a_ChunkInterface, a_BlockX - 1, a_BlockY, a_BlockZ, BLOCK_FACE_XP); - NeighborChanged(a_ChunkInterface, a_BlockX + 1, a_BlockY, a_BlockZ, BLOCK_FACE_XM); - NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_YP); - NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_YM); - NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ - 1, BLOCK_FACE_ZP); - NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ + 1, BLOCK_FACE_ZM); + NeighborChanged(a_ChunkInterface, a_BlockPos.addedX(-1), BLOCK_FACE_XP); + NeighborChanged(a_ChunkInterface, a_BlockPos.addedX( 1), BLOCK_FACE_XM); + NeighborChanged(a_ChunkInterface, a_BlockPos.addedY(-1), BLOCK_FACE_YP); + NeighborChanged(a_ChunkInterface, a_BlockPos.addedY( 1), BLOCK_FACE_YM); + NeighborChanged(a_ChunkInterface, a_BlockPos.addedZ(-1), BLOCK_FACE_ZP); + NeighborChanged(a_ChunkInterface, a_BlockPos.addedZ( 1), BLOCK_FACE_ZM); } -void cBlockHandler::NeighborChanged(cChunkInterface & a_ChunkInterface, int a_NeighborX, int a_NeighborY, int a_NeighborZ, eBlockFace a_WhichNeighbor) +void cBlockHandler::NeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_NeighborPos, eBlockFace a_WhichNeighbor) { - if ((a_NeighborY >= 0) && (a_NeighborY < cChunkDef::Height)) + if (!cChunkDef::IsValidHeight(a_NeighborPos.y)) { - cBlockInfo::GetHandler(a_ChunkInterface.GetBlock({a_NeighborX, a_NeighborY, a_NeighborZ}))->OnNeighborChanged(a_ChunkInterface, a_NeighborX, a_NeighborY, a_NeighborZ, a_WhichNeighbor); + return; } -} - - - - -void cBlockHandler::ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) -{ - // Setting the meta to a_BlockMeta keeps most textures. The few other blocks have to override this. - a_Pickups.push_back(cItem(m_BlockType, 1, a_BlockMeta)); + cBlockInfo::GetHandler(a_ChunkInterface.GetBlock(a_NeighborPos))->OnNeighborChanged(a_ChunkInterface, a_NeighborPos, a_WhichNeighbor); } -void cBlockHandler::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) +cItems cBlockHandler::ConvertToPickups( + NIBBLETYPE a_BlockMeta, + cBlockEntity * a_BlockEntity, + const cEntity * a_Digger, + const cItem * a_Tool +) { - cItems Pickups; - NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY, a_BlockZ}); - - if (a_CanDrop) - { - if ((a_Digger != nullptr) && (a_Digger->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0)) - { - switch (m_BlockType) - { - case E_BLOCK_ACACIA_DOOR: - case E_BLOCK_ACTIVE_COMPARATOR: - case E_BLOCK_BEETROOTS: - case E_BLOCK_BIRCH_DOOR: - case E_BLOCK_BREWING_STAND: - case E_BLOCK_CAKE: - case E_BLOCK_CARROTS: - case E_BLOCK_CAULDRON: - case E_BLOCK_COCOA_POD: - case E_BLOCK_CROPS: - case E_BLOCK_DARK_OAK_DOOR: - case E_BLOCK_DEAD_BUSH: - case E_BLOCK_DOUBLE_RED_SANDSTONE_SLAB: - case E_BLOCK_DOUBLE_STONE_SLAB: - case E_BLOCK_DOUBLE_WOODEN_SLAB: - case E_BLOCK_FIRE: - case E_BLOCK_FARMLAND: - case E_BLOCK_FLOWER_POT: - case E_BLOCK_HEAD: - case E_BLOCK_INACTIVE_COMPARATOR: - case E_BLOCK_INVERTED_DAYLIGHT_SENSOR: - case E_BLOCK_IRON_DOOR: - case E_BLOCK_JUNGLE_DOOR: - case E_BLOCK_MELON_STEM: - case E_BLOCK_MOB_SPAWNER: - case E_BLOCK_NETHER_WART: - case E_BLOCK_OAK_DOOR: - case E_BLOCK_PISTON_EXTENSION: - case E_BLOCK_POTATOES: - case E_BLOCK_PUMPKIN_STEM: - case E_BLOCK_PURPUR_DOUBLE_SLAB: - case E_BLOCK_REDSTONE_ORE_GLOWING: - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_REDSTONE_REPEATER_ON: - case E_BLOCK_REDSTONE_TORCH_OFF: - case E_BLOCK_REDSTONE_WIRE: - case E_BLOCK_SIGN_POST: - case E_BLOCK_SNOW: - case E_BLOCK_SPRUCE_DOOR: - case E_BLOCK_STANDING_BANNER: - case E_BLOCK_SUGARCANE: - case E_BLOCK_TALL_GRASS: - case E_BLOCK_TRIPWIRE: - case E_BLOCK_WALL_BANNER: - case E_BLOCK_WALLSIGN: - { - // Silktouch can't be used for these blocks - ConvertToPickups(Pickups, Meta); - break; - } - case E_BLOCK_BED: - { - // Need to access the bed entity to get the color for the item damage - ConvertToPickups(a_WorldInterface, Pickups, Meta, a_BlockX, a_BlockY, a_BlockZ); - break; - } - case E_BLOCK_ENDER_CHEST: - { - // Reset meta to 0 - Pickups.Add(m_BlockType, 1, 0); - break; - } - case E_BLOCK_LEAVES: - case E_BLOCK_NEW_LEAVES: - { - Pickups.Add(m_BlockType, 1, Meta & 0x03); - break; - } - default: Pickups.Add(m_BlockType, 1, Meta); break; - } - } - else if (m_BlockType == E_BLOCK_BED) - { - // Need to access the bed entity to get the color for the item damage - ConvertToPickups(a_WorldInterface, Pickups, Meta, a_BlockX, a_BlockY, a_BlockZ); - } - else - { - ConvertToPickups(Pickups, Meta); - } - } - - // Allow plugins to modify the pickups: - a_BlockPluginInterface.CallHookBlockToPickups(a_Digger, a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta, Pickups); - - if (!Pickups.empty()) - { - auto & r1 = GetRandomProvider(); - - // Mid-block position first - double MicroX, MicroY, MicroZ; - MicroX = a_BlockX + 0.5; - MicroY = a_BlockY + 0.5; - MicroZ = a_BlockZ + 0.5; - - // Add random offset second - MicroX += r1.RandReal<double>(-0.5, 0.5); - MicroZ += r1.RandReal<double>(-0.5, 0.5); - - a_WorldInterface.SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ); - } + UNUSED(a_BlockEntity); + UNUSED(a_Digger); + UNUSED(a_Tool); + + // Add self: + cItems res; + res.push_back(cItem(m_BlockType, 1, a_BlockMeta)); + return res; } @@ -655,25 +543,28 @@ cBoundingBox cBlockHandler::GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a -void cBlockHandler::Check(cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface, int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) +void cBlockHandler::Check( + cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface, + Vector3i a_RelPos, + cChunk & a_Chunk +) { - if (!CanBeAt(a_ChunkInterface, a_RelX, a_RelY, a_RelZ, a_Chunk)) + if (!CanBeAt(a_ChunkInterface, a_RelPos.x, a_RelPos.y, a_RelPos.z, a_Chunk)) { if (DoesDropOnUnsuitable()) { - int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; - int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; - DropBlock(a_ChunkInterface, *a_Chunk.GetWorld(), a_PluginInterface, nullptr, BlockX, a_RelY, BlockZ); + a_ChunkInterface.DropBlockAsPickups(a_Chunk.RelativeToAbsolute(a_RelPos)); + } + else + { + a_Chunk.SetBlock(a_RelPos, E_BLOCK_AIR, 0); } - - a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0); } else { // Wake up the simulators for this block: - int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; - int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; - a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp({BlockX, a_RelY, BlockZ}, &a_Chunk); + auto absPos = a_Chunk.RelativeToAbsolute(a_RelPos); + a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(absPos, &a_Chunk); } } @@ -691,6 +582,15 @@ ColourID cBlockHandler::GetMapBaseColourID(NIBBLETYPE a_Meta) +bool cBlockHandler::ToolHasSilkTouch(const cItem * a_Tool) +{ + return ((a_Tool != nullptr) && (a_Tool->m_Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0)); +} + + + + + cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE aBlockType) { return ::CreateBlockHandler(aBlockType); |