From d117a6c5db606a5624f3c910c257d90af5e7ec3b Mon Sep 17 00:00:00 2001 From: npresley0506 <82075033+npresley0506@users.noreply.github.com> Date: Fri, 23 Apr 2021 08:51:59 -0400 Subject: 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 --- CONTRIBUTORS | 1 + src/BlockEntities/ChestEntity.cpp | 9 +++ src/BlockEntities/ChestEntity.h | 3 + src/BlockEntities/HopperEntity.cpp | 126 ++++++++++++++++--------------------- 4 files changed, 68 insertions(+), 71 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 5c33c5585..d0f123003 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -52,6 +52,7 @@ morsmordere (Anzhelika Iugai) mtilden nesco NiLSPACE (formerly STR_Warrior) +npresley0506 p-mcgowan pokechu22 ProjectBM diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp index 9ede18759..3c80a7aa3 100644 --- a/src/BlockEntities/ChestEntity.cpp +++ b/src/BlockEntities/ChestEntity.cpp @@ -144,6 +144,15 @@ bool cChestEntity::UsedBy(cPlayer * a_Player) +cChestEntity * cChestEntity::GetNeighbour() +{ + return m_Neighbour; +} + + + + + void cChestEntity::ScanNeighbours() { // Callback for finding neighbouring chest. diff --git a/src/BlockEntities/ChestEntity.h b/src/BlockEntities/ChestEntity.h index ee59fa7b9..02b182481 100644 --- a/src/BlockEntities/ChestEntity.h +++ b/src/BlockEntities/ChestEntity.h @@ -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(); diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp index 58a5fd565..5b273b13c 100644 --- a/src/BlockEntities/HopperEntity.cpp +++ b/src/BlockEntities/HopperEntity.cpp @@ -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(a_Chunk.GetBlockEntity(chestPos)); - if (mainChest == nullptr) + auto ChestPos = GetPos().addedY(1); + auto MainChest = static_cast(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) { - // 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()) + if (MoveItemsFromGrid(*MainChest)) { - // Not the same kind of chest - continue; + return true; } - - auto neighborAbsCoord = neighbor->RelativeToAbsolute(neighborRelCoord); - auto sideChest = static_cast(neighbor->GetBlockEntity(neighborAbsCoord)); - if (sideChest == nullptr) + } + else + { + 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) { - FLOGWARNING("{0}: A chest entity was not found where expected, at {1}", __FUNCTION__, neighborAbsCoord); + // 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(*sideChest)) + 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; } - 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 SideChest = ConnectedChest->GetNeighbour(); + if (SideChest == nullptr) { - auto otherHalfRelCoord = relCoord + ofs; - auto neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(otherHalfRelCoord); - if (neighbor == nullptr) + if (MoveItemsToGrid(*ConnectedChest)) { - continue; + return true; } - - auto Block = neighbor->GetBlock(otherHalfRelCoord); - if (Block != ConnectedChest->GetBlockType()) + } + else + { + auto SideAbsCoords = SideChest->GetPos(); + if (SideAbsCoords.z > a_Coords.z || SideAbsCoords.x > a_Coords.x) { - // Not the same kind of chest - continue; + if (MoveItemsToGrid(*SideChest)) + { + return true; + } + if (MoveItemsToGrid(*ConnectedChest)) + { + return true; + } } - - auto chest = static_cast(neighbor->GetBlockEntity(a_Coords + ofs)); - if (chest == nullptr) + else { - 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(*ConnectedChest)) + { + return true; + } + if (MoveItemsToGrid(*SideChest)) + { + return true; + } } - return MoveItemsToGrid(*chest); } - - // The chest was single and nothing could be moved return false; } -- cgit v1.2.3