1
0

Fixed crashes in HopperEntity.

Some of the coords were off and some functions were assuming too much.
Fixes the crash reported in http://forum.mc-server.org/showthread.php?tid=1497
This commit is contained in:
Mattes D 2014-06-24 09:46:04 +02:00
parent 4306092753
commit 742370497a

View File

@ -294,23 +294,24 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
return false; return false;
} }
int bx, by, bz; // 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); NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ);
if (!GetOutputBlockPos(Meta, bx, by, bz)) if (!GetOutputBlockPos(Meta, OutX, OutY, OutZ))
{ {
// Not attached to another container // Not attached to another container
return false; return false;
} }
if (by < 0) if (OutY < 0)
{ {
// Cannot output below the zero-th block level // Cannot output below the zero-th block level
return false; return false;
} }
// Convert coords to relative: // Convert coords to relative:
int rx = bx - a_Chunk.GetPosX() * cChunkDef::Width; int OutRelX = OutX - a_Chunk.GetPosX() * cChunkDef::Width;
int rz = bz - a_Chunk.GetPosZ() * cChunkDef::Width; int OutRelZ = OutZ - a_Chunk.GetPosZ() * cChunkDef::Width;
cChunk * DestChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(rx, rz); cChunk * DestChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(OutRelX, OutRelZ);
if (DestChunk == NULL) if (DestChunk == NULL)
{ {
// The destination chunk has been unloaded, don't tick // The destination chunk has been unloaded, don't tick
@ -319,26 +320,32 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
// Call proper moving function, based on the blocktype present at the coords: // Call proper moving function, based on the blocktype present at the coords:
bool res = false; bool res = false;
switch (DestChunk->GetBlock(rx, by, rz)) switch (DestChunk->GetBlock(OutRelX, OutY, OutRelZ))
{ {
case E_BLOCK_CHEST: case E_BLOCK_CHEST:
{ {
// Chests have special handling because of double-chests // Chests have special handling because of double-chests
res = MoveItemsToChest(*DestChunk, bx, by, bz); res = MoveItemsToChest(*DestChunk, OutX, OutY, OutZ);
break; break;
} }
case E_BLOCK_LIT_FURNACE: case E_BLOCK_LIT_FURNACE:
case E_BLOCK_FURNACE: case E_BLOCK_FURNACE:
{ {
// Furnaces have special handling because of the direction-to-slot relation // Furnaces have special handling because of the direction-to-slot relation
res = MoveItemsToFurnace(*DestChunk, bx, by, bz, Meta); res = MoveItemsToFurnace(*DestChunk, OutX, OutY, OutZ, Meta);
break; break;
} }
case E_BLOCK_DISPENSER: case E_BLOCK_DISPENSER:
case E_BLOCK_DROPPER: case E_BLOCK_DROPPER:
case E_BLOCK_HOPPER: case E_BLOCK_HOPPER:
{ {
res = MoveItemsToGrid(*(cBlockEntityWithItems *)DestChunk->GetBlockEntity(bx, by, bz)); cBlockEntityWithItems * BlockEntity = (cBlockEntityWithItems *)DestChunk->GetBlockEntity(OutX, OutY, OutZ);
if (BlockEntity == NULL)
{
LOGWARNING("%s: A block entity was not found where expected at {%d, %d, %d}", __FUNCTION__, OutX, OutY, OutZ);
return false;
}
res = MoveItemsToGrid(*BlockEntity);
break; break;
} }
} }
@ -359,7 +366,13 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
/// Moves items from a chest (dblchest) above the hopper into this hopper. Returns true if contents have changed. /// Moves items from a chest (dblchest) above the hopper into this hopper. Returns true if contents have changed.
bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk) bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
{ {
if (MoveItemsFromGrid(*(cChestEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ))) cChestEntity * Chest = (cChestEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ);
if (Chest == NULL)
{
LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX, m_PosY + 1, m_PosZ);
return false;
}
if (MoveItemsFromGrid(*Chest))
{ {
// Moved the item from the chest directly above the hopper // Moved the item from the chest directly above the hopper
return true; return true;
@ -389,10 +402,18 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
{ {
continue; continue;
} }
if (MoveItemsFromGrid(*(cChestEntity *)Neighbor->GetBlockEntity(x, m_PosY, z))) Chest = (cChestEntity *)Neighbor->GetBlockEntity(m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z);
if (Chest == NULL)
{
LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z);
}
else
{
if (MoveItemsFromGrid(*Chest))
{ {
return true; return true;
} }
}
return false; return false;
} }
@ -408,7 +429,11 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk) bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk)
{ {
cFurnaceEntity * Furnace = (cFurnaceEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ); cFurnaceEntity * Furnace = (cFurnaceEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ);
ASSERT(Furnace != NULL); if (Furnace == NULL)
{
LOGWARNING("%s: A furnace entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX, m_PosY + 1, m_PosZ);
return false;
}
// Try move from the output slot: // Try move from the output slot:
if (MoveItemsFromSlot(*Furnace, cFurnaceEntity::fsOutput, true)) if (MoveItemsFromSlot(*Furnace, cFurnaceEntity::fsOutput, true))
@ -517,7 +542,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, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
// Try the chest directly connected to the hopper: // Try the chest directly connected to the hopper:
if (MoveItemsToGrid(*(cChestEntity *)a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ))) cChestEntity * Chest = (cChestEntity *)a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ);
if (Chest == NULL)
{
LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, a_BlockX, a_BlockY, a_BlockZ);
return false;
}
if (MoveItemsToGrid(*Chest))
{ {
return true; return true;
} }
@ -534,19 +565,27 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_Block
{0, 1}, {0, 1},
{0, -1}, {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++) for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
{ {
int x = m_RelX + Coords[i].x; int x = RelX + Coords[i].x;
int z = m_RelZ + Coords[i].z; int z = RelZ + Coords[i].z;
cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z); cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z);
if ( if (
(Neighbor == NULL) || (Neighbor == NULL) ||
(Neighbor->GetBlock(x, m_PosY + 1, z) != E_BLOCK_CHEST) (Neighbor->GetBlock(x, a_BlockY, z) != E_BLOCK_CHEST)
) )
{ {
continue; continue;
} }
if (MoveItemsToGrid(*(cChestEntity *)Neighbor->GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ))) Chest = (cChestEntity *)Neighbor->GetBlockEntity(a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z);
if (Chest == NULL)
{
LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d} (%d, %d)", __FUNCTION__, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z, x, z);
continue;
}
if (MoveItemsToGrid(*Chest))
{ {
return true; return true;
} }