summaryrefslogtreecommitdiffstats
path: root/src/BlockEntities/HopperEntity.cpp
diff options
context:
space:
mode:
authorMattes D <github@xoft.cz>2019-09-29 14:59:24 +0200
committerGitHub <noreply@github.com>2019-09-29 14:59:24 +0200
commit365cbc6e1cea96741e26c9ce912b003f8fd2c62c (patch)
treef23682c47928597791c53f3a300b03494ffde417 /src/BlockEntities/HopperEntity.cpp
parentCactus can now grow and will be dropped if there is no place to grow. (diff)
downloadcuberite-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.cpp181
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);
}
}