diff options
author | Mattes D <github@xoft.cz> | 2019-09-29 14:59:24 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-29 14:59:24 +0200 |
commit | 365cbc6e1cea96741e26c9ce912b003f8fd2c62c (patch) | |
tree | f23682c47928597791c53f3a300b03494ffde417 /src/BlockEntities/HopperEntity.cpp | |
parent | Cactus can now grow and will be dropped if there is no place to grow. (diff) | |
download | cuberite-365cbc6e1cea96741e26c9ce912b003f8fd2c62c.tar cuberite-365cbc6e1cea96741e26c9ce912b003f8fd2c62c.tar.gz cuberite-365cbc6e1cea96741e26c9ce912b003f8fd2c62c.tar.bz2 cuberite-365cbc6e1cea96741e26c9ce912b003f8fd2c62c.tar.lz cuberite-365cbc6e1cea96741e26c9ce912b003f8fd2c62c.tar.xz cuberite-365cbc6e1cea96741e26c9ce912b003f8fd2c62c.tar.zst cuberite-365cbc6e1cea96741e26c9ce912b003f8fd2c62c.zip |
Diffstat (limited to 'src/BlockEntities/HopperEntity.cpp')
-rw-r--r-- | src/BlockEntities/HopperEntity.cpp | 181 |
1 files changed, 85 insertions, 96 deletions
diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp index 6eb5f961d..ea1e12008 100644 --- a/src/BlockEntities/HopperEntity.cpp +++ b/src/BlockEntities/HopperEntity.cpp @@ -17,8 +17,8 @@ -cHopperEntity::cHopperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): - Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World), +cHopperEntity::cHopperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World): + super(a_BlockType, a_BlockMeta, a_Pos, ContentsWidth, ContentsHeight, a_World), m_LastMoveItemsInTick(0), m_LastMoveItemsOutTick(0) { @@ -29,22 +29,20 @@ cHopperEntity::cHopperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int -bool cHopperEntity::GetOutputBlockPos(NIBBLETYPE a_BlockMeta, int & a_OutputX, int & a_OutputY, int & a_OutputZ) +std::pair<bool, Vector3i> cHopperEntity::GetOutputBlockPos(NIBBLETYPE a_BlockMeta) { - a_OutputX = m_PosX; - a_OutputY = m_PosY; - a_OutputZ = m_PosZ; + auto pos = GetPos(); switch (a_BlockMeta) { - case E_META_HOPPER_FACING_XM: a_OutputX--; return true; - case E_META_HOPPER_FACING_XP: a_OutputX++; return true; - case E_META_HOPPER_FACING_YM: a_OutputY--; return true; - case E_META_HOPPER_FACING_ZM: a_OutputZ--; return true; - case E_META_HOPPER_FACING_ZP: a_OutputZ++; return true; + case E_META_HOPPER_FACING_XM: return {true, pos.addedX(-1)}; + case E_META_HOPPER_FACING_XP: return {true, pos.addedX( 1)}; + case E_META_HOPPER_FACING_YM: return {true, pos.addedY(-1)}; + case E_META_HOPPER_FACING_ZM: return {true, pos.addedZ(-1)}; + case E_META_HOPPER_FACING_ZP: return {true, pos.addedZ( 1)}; default: { // Not attached - return false; + return {false, pos}; } } } @@ -55,7 +53,7 @@ bool cHopperEntity::GetOutputBlockPos(NIBBLETYPE a_BlockMeta, int & a_OutputX, i void cHopperEntity::CopyFrom(const cBlockEntity & a_Src) { - Super::CopyFrom(a_Src); + super::CopyFrom(a_Src); auto & src = static_cast<const cHopperEntity &>(a_Src); m_LastMoveItemsInTick = src.m_LastMoveItemsInTick; m_LastMoveItemsOutTick = src.m_LastMoveItemsOutTick; @@ -127,7 +125,7 @@ bool cHopperEntity::UsedBy(cPlayer * a_Player) void cHopperEntity::OpenNewWindow(void) { - OpenWindow(new cHopperWindow(m_PosX, m_PosY, m_PosZ, this)); + OpenWindow(new cHopperWindow(this)); } @@ -136,7 +134,7 @@ void cHopperEntity::OpenNewWindow(void) bool cHopperEntity::MoveItemsIn(cChunk & a_Chunk, Int64 a_CurrentTick) { - if (m_PosY >= cChunkDef::Height) + if (m_Pos.y >= cChunkDef::Height) { // This hopper is at the top of the world, no more blocks above return false; @@ -150,7 +148,7 @@ bool cHopperEntity::MoveItemsIn(cChunk & a_Chunk, Int64 a_CurrentTick) // Try moving an item in: bool res = false; - switch (a_Chunk.GetBlock(m_RelX, m_PosY + 1, m_RelZ)) + switch (a_Chunk.GetBlock(GetRelPos())) { case E_BLOCK_TRAPPED_CHEST: case E_BLOCK_CHEST: @@ -170,7 +168,7 @@ bool cHopperEntity::MoveItemsIn(cChunk & a_Chunk, Int64 a_CurrentTick) case E_BLOCK_DROPPER: case E_BLOCK_HOPPER: { - res = MoveItemsFromGrid(*static_cast<cBlockEntityWithItems *>(a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ))); + res = MoveItemsFromGrid(*static_cast<cBlockEntityWithItems *>(a_Chunk.GetBlockEntity(GetRelPos().addedY(1)))); break; } } @@ -286,24 +284,23 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick) } // Get the coords of the block where to output items: - int OutX, OutY, OutZ; - NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ); - if (!GetOutputBlockPos(Meta, OutX, OutY, OutZ)) + auto meta = a_Chunk.GetMeta(GetRelPos()); + auto out = GetOutputBlockPos(meta); + if (!out.first) { // Not attached to another container return false; } - if (OutY < 0) + if (out.second.y < 0) { // Cannot output below the zero-th block level return false; } // Convert coords to relative: - int OutRelX = OutX - a_Chunk.GetPosX() * cChunkDef::Width; - int OutRelZ = OutZ - a_Chunk.GetPosZ() * cChunkDef::Width; - cChunk * DestChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(OutRelX, OutRelZ); - if (DestChunk == nullptr) + auto relCoord = a_Chunk.AbsoluteToRelative(out.second); + auto destChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(relCoord.x, relCoord.z); + if (destChunk == nullptr) { // The destination chunk has been unloaded, don't tick return false; @@ -311,33 +308,34 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick) // Call proper moving function, based on the blocktype present at the coords: bool res = false; - switch (DestChunk->GetBlock(OutRelX, OutY, OutRelZ)) + auto absCoord = destChunk->RelativeToAbsolute(relCoord); + switch (destChunk->GetBlock(relCoord)) { case E_BLOCK_TRAPPED_CHEST: case E_BLOCK_CHEST: { // Chests have special handling because of double-chests - res = MoveItemsToChest(*DestChunk, OutX, OutY, OutZ); + res = MoveItemsToChest(*destChunk, absCoord); break; } case E_BLOCK_LIT_FURNACE: case E_BLOCK_FURNACE: { // Furnaces have special handling because of the direction-to-slot relation - res = MoveItemsToFurnace(*DestChunk, OutX, OutY, OutZ, Meta); + res = MoveItemsToFurnace(*destChunk, absCoord, meta); break; } case E_BLOCK_DISPENSER: case E_BLOCK_DROPPER: case E_BLOCK_HOPPER: { - cBlockEntityWithItems * BlockEntity = static_cast<cBlockEntityWithItems *>(DestChunk->GetBlockEntity(OutX, OutY, OutZ)); - if (BlockEntity == nullptr) + auto blockEntity = static_cast<cBlockEntityWithItems *>(destChunk->GetBlockEntity(absCoord)); + if (blockEntity == nullptr) { - FLOGWARNING("{0}: A block entity was not found where expected at {1}", __FUNCTION__, Vector3i{OutX, OutY, OutZ}); + FLOGWARNING("{0}: A block entity was not found where expected at {1}", __FUNCTION__, absCoord); return false; } - res = MoveItemsToGrid(*BlockEntity); + res = MoveItemsToGrid(*blockEntity); break; } } @@ -357,55 +355,52 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick) bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk) { - cChestEntity * MainChest = static_cast<cChestEntity *>(a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ)); - if (MainChest == nullptr) + auto chestPos = GetPos().addedY(1); + auto mainChest = static_cast<cChestEntity *>(a_Chunk.GetBlockEntity(chestPos)); + if (mainChest == nullptr) { - FLOGWARNING("{0}: A chest entity was not found where expected, at {1}", __FUNCTION__, GetPos() + Vector3i{0, 1, 0}); + FLOGWARNING("{0}: A chest entity was not found where expected, at {1}", __FUNCTION__, chestPos); return false; } - if (MoveItemsFromGrid(*MainChest)) + if (MoveItemsFromGrid(*mainChest)) { // Moved the item from the chest directly above the hopper return true; } // Check if the chest is a double-chest (chest directly above was empty), if so, try to move from there: - static const struct - { - int x, z; - } - Coords [] = + static const Vector3i neighborOfs[] = { - {1, 0}, - {-1, 0}, - {0, 1}, - {0, -1}, + { 1, 1, 0}, + {-1, 1, 0}, + { 0, 1, 1}, + { 0, 1, -1}, } ; - for (size_t i = 0; i < ARRAYCOUNT(Coords); i++) + for (const auto & ofs: neighborOfs) { - int x = m_RelX + Coords[i].x; - int z = m_RelZ + Coords[i].z; - cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z); - if (Neighbor == nullptr) + auto neighborRelCoord = ofs.addedXZ(m_RelX, m_RelZ); + auto neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(neighborRelCoord.x, neighborRelCoord.z); + if (neighbor == nullptr) { continue; } - BLOCKTYPE Block = Neighbor->GetBlock(x, m_PosY + 1, z); - if (Block != MainChest->GetBlockType()) + BLOCKTYPE Block = neighbor->GetBlock(neighborRelCoord); + if (Block != mainChest->GetBlockType()) { // Not the same kind of chest continue; } - cChestEntity * SideChest = static_cast<cChestEntity *>(Neighbor->GetBlockEntity(m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z)); - if (SideChest == nullptr) + auto neighborAbsCoord = neighbor->RelativeToAbsolute(neighborRelCoord); + auto sideChest = static_cast<cChestEntity *>(neighbor->GetBlockEntity(neighborAbsCoord)); + if (sideChest == nullptr) { - FLOGWARNING("{0}: A chest entity was not found where expected, at {1}", __FUNCTION__, GetPos() + Vector3i{Coords[i].x, 1, Coords[i].z}); + FLOGWARNING("{0}: A chest entity was not found where expected, at {1}", __FUNCTION__, neighborAbsCoord); } else { - if (MoveItemsFromGrid(*SideChest)) + if (MoveItemsFromGrid(*sideChest)) { return true; } @@ -413,7 +408,7 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk) return false; } - // The chest was single and nothing could be moved + // The chest was empty return false; } @@ -423,27 +418,27 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk) bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk) { - cFurnaceEntity * Furnace = static_cast<cFurnaceEntity *>(a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ)); - if (Furnace == nullptr) + auto furnace = static_cast<cFurnaceEntity *>(a_Chunk.GetBlockEntity(m_Pos.addedY(1))); + if (furnace == nullptr) { - FLOGWARNING("{0}: A furnace entity was not found where expected, at {1}", __FUNCTION__, GetPos() + Vector3i{0, 1, 0}); + FLOGWARNING("{0}: A furnace entity was not found where expected, at {1}", __FUNCTION__, m_Pos.addedY(1)); return false; } // Try move from the output slot: - if (MoveItemsFromSlot(*Furnace, cFurnaceEntity::fsOutput)) + if (MoveItemsFromSlot(*furnace, cFurnaceEntity::fsOutput)) { - cItem NewOutput(Furnace->GetOutputSlot()); - Furnace->SetOutputSlot(NewOutput.AddCount(-1)); + cItem NewOutput(furnace->GetOutputSlot()); + furnace->SetOutputSlot(NewOutput.AddCount(-1)); return true; } // No output moved, check if we can move an empty bucket out of the fuel slot: - if (Furnace->GetFuelSlot().m_ItemType == E_ITEM_BUCKET) + if (furnace->GetFuelSlot().m_ItemType == E_ITEM_BUCKET) { - if (MoveItemsFromSlot(*Furnace, cFurnaceEntity::fsFuel)) + if (MoveItemsFromSlot(*furnace, cFurnaceEntity::fsFuel)) { - Furnace->SetFuelSlot(cItem()); + furnace->SetFuelSlot(cItem()); return true; } } @@ -458,7 +453,7 @@ bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk) bool cHopperEntity::MoveItemsFromGrid(cBlockEntityWithItems & a_Entity) { - cItemGrid & Grid = a_Entity.GetContents(); + auto & Grid = a_Entity.GetContents(); int NumSlots = Grid.GetNumSlots(); for (int i = 0; i < NumSlots; i++) @@ -521,13 +516,13 @@ bool cHopperEntity::MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_Sl -bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ) +bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, Vector3i a_Coords) { // Try the chest directly connected to the hopper: - cChestEntity * ConnectedChest = static_cast<cChestEntity *>(a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ)); + auto ConnectedChest = static_cast<cChestEntity *>(a_Chunk.GetBlockEntity(a_Coords)); if (ConnectedChest == nullptr) { - FLOGWARNING("{0}: A chest entity was not found where expected, at {1}", __FUNCTION__, Vector3i{a_BlockX, a_BlockY, a_BlockZ}); + FLOGWARNING("{0}: A chest entity was not found where expected, at {1}", __FUNCTION__, a_Coords); return false; } if (MoveItemsToGrid(*ConnectedChest)) @@ -537,43 +532,37 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_Block } // Check if the chest is a double-chest (chest block directly connected was full), if so, try to move into the other half: - static const struct - { - int x, z; - } - Coords [] = + static const Vector3i neighborOfs [] = { - {1, 0}, - {-1, 0}, - {0, 1}, - {0, -1}, + { 1, 0, 0}, + {-1, 0, 0}, + { 0, 0, 1}, + { 0, 0, -1}, } ; - int RelX = a_BlockX - a_Chunk.GetPosX() * cChunkDef::Width; - int RelZ = a_BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width; - for (size_t i = 0; i < ARRAYCOUNT(Coords); i++) - { - int x = RelX + Coords[i].x; - int z = RelZ + Coords[i].z; - cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z); - if (Neighbor == nullptr) + auto relCoord = a_Chunk.AbsoluteToRelative(a_Coords); + for (const auto & ofs: neighborOfs) + { + auto otherHalfRelCoord = relCoord + ofs; + auto neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(otherHalfRelCoord.x, otherHalfRelCoord.z); + if (neighbor == nullptr) { continue; } - BLOCKTYPE Block = Neighbor->GetBlock(x, a_BlockY, z); + auto Block = neighbor->GetBlock(otherHalfRelCoord); if (Block != ConnectedChest->GetBlockType()) { // Not the same kind of chest continue; } - cChestEntity * Chest = static_cast<cChestEntity *>(Neighbor->GetBlockEntity(a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z)); - if (Chest == nullptr) + auto chest = static_cast<cChestEntity *>(neighbor->GetBlockEntity(a_Coords + ofs)); + if (chest == nullptr) { - FLOGWARNING("{0}: A chest entity was not found where expected, at {1} ({2}, {3}})", __FUNCTION__, Vector3i{a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z}, x, z); + FLOGWARNING("{0}: A chest entity was not found where expected, at {1} ({2}, {3}})", __FUNCTION__, a_Coords + ofs, ofs.x, ofs.z); continue; } - if (MoveItemsToGrid(*Chest)) + if (MoveItemsToGrid(*chest)) { return true; } @@ -588,18 +577,18 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_Block -bool cHopperEntity::MoveItemsToFurnace(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_HopperMeta) +bool cHopperEntity::MoveItemsToFurnace(cChunk & a_Chunk, Vector3i a_Coords, NIBBLETYPE a_HopperMeta) { - cFurnaceEntity * Furnace = static_cast<cFurnaceEntity *>(a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ)); + auto furnace = static_cast<cFurnaceEntity *>(a_Chunk.GetBlockEntity(a_Coords)); if (a_HopperMeta == E_META_HOPPER_FACING_YM) { // Feed the input slot of the furnace - return MoveItemsToSlot(*Furnace, cFurnaceEntity::fsInput); + return MoveItemsToSlot(*furnace, cFurnaceEntity::fsInput); } else { // Feed the fuel slot of the furnace - return MoveItemsToSlot(*Furnace, cFurnaceEntity::fsFuel); + return MoveItemsToSlot(*furnace, cFurnaceEntity::fsFuel); } } |