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:
parent
4306092753
commit
742370497a
@ -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,9 +402,17 @@ 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)
|
||||||
{
|
{
|
||||||
return true;
|
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 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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user