1
0

Repaired Hoppers Treating Chests as two entities (#5202)

* Repaired Hoppers Treating Chests as two entities

* Style changes

* style fixes

* Fixed style issues, also condensed logic in MoveItemsFromChest

* Used m_Neighbour, fixed styling

* GetNeighbour not ReturnNeighbour

Co-authored-by: npresley <npresley@umich.edu>
This commit is contained in:
npresley0506 2021-04-23 08:51:59 -04:00 committed by GitHub
parent 59dbb37c9a
commit d117a6c5db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 71 additions and 74 deletions

View File

@ -52,6 +52,7 @@ morsmordere (Anzhelika Iugai)
mtilden
nesco
NiLSPACE (formerly STR_Warrior)
npresley0506
p-mcgowan
pokechu22
ProjectBM

View File

@ -144,6 +144,15 @@ bool cChestEntity::UsedBy(cPlayer * a_Player)
cChestEntity * cChestEntity::GetNeighbour()
{
return m_Neighbour;
}
void cChestEntity::ScanNeighbours()
{
// Callback for finding neighbouring chest.

View File

@ -46,6 +46,9 @@ public:
/** Search horizontally adjacent blocks for neighbouring chests of the same type and links them together. */
void ScanNeighbours();
/** Returns the value of m_Neighbour. */
cChestEntity * GetNeighbour();
/** Opens a new chest window where this is the primary chest and any neighbour is the secondary. */
void OpenNewWindow();

View File

@ -375,59 +375,50 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, const cTickTimeLong a_Current
bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
{
auto chestPos = GetPos().addedY(1);
auto mainChest = static_cast<cChestEntity *>(a_Chunk.GetBlockEntity(chestPos));
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__, chestPos);
FLOGWARNING("{0}: A chest entity was not found where expected, at {1}", __FUNCTION__, ChestPos);
return false;
}
if (MoveItemsFromGrid(*mainChest))
auto SideChest = MainChest->GetNeighbour();
if (SideChest == nullptr)
{
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 Vector3i neighborOfs[] =
{
{ 1, 1, 0},
{-1, 1, 0},
{ 0, 1, 1},
{ 0, 1, -1},
} ;
for (const auto & ofs: neighborOfs)
{
auto neighborRelCoord = ofs.addedXZ(m_RelX, m_RelZ);
auto neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(neighborRelCoord);
if (neighbor == nullptr)
{
continue;
}
BLOCKTYPE Block = neighbor->GetBlock(neighborRelCoord);
if (Block != mainChest->GetBlockType())
{
// Not the same kind of chest
continue;
}
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__, neighborAbsCoord);
}
else
{
if (MoveItemsFromGrid(*sideChest))
auto SideAbsCoords = SideChest->GetPos();
// the "primary" chest is the one with the higher z or x value
if (SideAbsCoords.z > ChestPos.z || SideAbsCoords.x > ChestPos.x)
{
// side is "primary" so pull from it first
if (MoveItemsFromGrid(*SideChest))
{
return true;
}
// main is secondary, pull from next
if (MoveItemsFromGrid(*MainChest))
{
return true;
}
}
else
{
if (MoveItemsFromGrid(*MainChest))
{
return true;
}
if (MoveItemsFromGrid(*SideChest))
{
return true;
}
}
return false;
}
// The chest was empty
return false;
}
@ -545,47 +536,40 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, Vector3i a_Coords)
FLOGWARNING("{0}: A chest entity was not found where expected, at {1}", __FUNCTION__, a_Coords);
return false;
}
auto SideChest = ConnectedChest->GetNeighbour();
if (SideChest == nullptr)
{
if (MoveItemsToGrid(*ConnectedChest))
{
// Chest block directly connected was not full
return true;
}
// 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 Vector3i neighborOfs [] =
{
{ 1, 0, 0},
{-1, 0, 0},
{ 0, 0, 1},
{ 0, 0, -1},
} ;
auto relCoord = cChunkDef::AbsoluteToRelative(a_Coords);
for (const auto & ofs: neighborOfs)
{
auto otherHalfRelCoord = relCoord + ofs;
auto neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(otherHalfRelCoord);
if (neighbor == nullptr)
{
continue;
}
auto Block = neighbor->GetBlock(otherHalfRelCoord);
if (Block != ConnectedChest->GetBlockType())
else
{
// Not the same kind of chest
continue;
}
auto chest = static_cast<cChestEntity *>(neighbor->GetBlockEntity(a_Coords + ofs));
if (chest == nullptr)
auto SideAbsCoords = SideChest->GetPos();
if (SideAbsCoords.z > a_Coords.z || SideAbsCoords.x > a_Coords.x)
{
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(*SideChest))
{
return true;
}
if (MoveItemsToGrid(*ConnectedChest))
{
return true;
}
}
else
{
if (MoveItemsToGrid(*ConnectedChest))
{
return true;
}
if (MoveItemsToGrid(*SideChest))
{
return true;
}
}
return MoveItemsToGrid(*chest);
}
// The chest was single and nothing could be moved
return false;
}