/// Moves one piece of the specified a_Entity's slot itemstack into this hopper. Returns true if contents have changed. Doesn't change the itemstack. bool cHopperEntity::MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_SlotNum, bool a_AllowNewStacks) { cItem One(a_Entity.GetSlot(a_SlotNum).CopyOne()); for (int i = 0; i < ContentsWidth * ContentsHeight; i++) { if (m_Contents.IsSlotEmpty(i)) { if (a_AllowNewStacks) { if (cPluginManager::Get()->CallHookHopperPullingItem(*m_World, *this, i, a_Entity, a_SlotNum)) { // Plugin disagrees with the move continue; } } m_Contents.SetSlot(i, One); return true; } else if (m_Contents.GetSlot(i).IsEqual(One)) { if (cPluginManager::Get()->CallHookHopperPullingItem(*m_World, *this, i, a_Entity, a_SlotNum)) { // Plugin disagrees with the move continue; } m_Contents.ChangeSlotCount(i, 1); return true; } } return false; }
bool cHopperEntity::MoveItemsFromGrid(cBlockEntityWithItems & a_Entity) { cItemGrid & Grid = a_Entity.GetContents(); int NumSlots = Grid.GetNumSlots(); // First try adding items of types already in the hopper: for (int i = 0; i < NumSlots; i++) { if (Grid.IsSlotEmpty(i)) { continue; } if (MoveItemsFromSlot(a_Entity, i, false)) { Grid.ChangeSlotCount(i, -1); return true; } } // No already existing stack can be topped up, try again with allowing new stacks: for (int i = 0; i < NumSlots; i++) { if (Grid.IsSlotEmpty(i)) { continue; } if (MoveItemsFromSlot(a_Entity, i, true)) { Grid.ChangeSlotCount(i, -1); return true; } } return false; }
bool cHopperEntity::MoveItemsToGrid(cBlockEntityWithItems & a_Entity) { // Iterate through our slots, try to move from each one: int NumSlots = a_Entity.GetContents().GetNumSlots(); for (int i = 0; i < NumSlots; i++) { if (MoveItemsToSlot(a_Entity, i)) { return true; } } return false; }
bool cHopperEntity::MoveItemsToSlot(cBlockEntityWithItems & a_Entity, int a_DstSlotNum) { cItemGrid & Grid = a_Entity.GetContents(); if (Grid.IsSlotEmpty(a_DstSlotNum)) { // The slot is empty, move the first non-empty slot from our contents: for (int i = 0; i < ContentsWidth * ContentsHeight; i++) { if (!m_Contents.IsSlotEmpty(i)) { if (cPluginManager::Get()->CallHookHopperPushingItem(*m_World, *this, i, a_Entity, a_DstSlotNum)) { // A plugin disagrees with the move continue; } Grid.SetSlot(a_DstSlotNum, m_Contents.GetSlot(i).CopyOne()); m_Contents.ChangeSlotCount(i, -1); return true; } } return false; } else { // The slot is taken, try to top it up: const cItem & DestSlot = Grid.GetSlot(a_DstSlotNum); if (DestSlot.IsFullStack()) { return false; } for (int i = 0; i < ContentsWidth * ContentsHeight; i++) { if (m_Contents.GetSlot(i).IsEqual(DestSlot)) { if (cPluginManager::Get()->CallHookHopperPushingItem(*m_World, *this, i, a_Entity, a_DstSlotNum)) { // A plugin disagrees with the move continue; } Grid.ChangeSlotCount(a_DstSlotNum, 1); m_Contents.ChangeSlotCount(i, -1); return true; } } return false; } }
bool cHopperEntity::MoveItemsFromGrid(cBlockEntityWithItems & a_Entity) { cItemGrid & Grid = a_Entity.GetContents(); int NumSlots = Grid.GetNumSlots(); for (int i = 0; i < NumSlots; i++) { if (Grid.IsSlotEmpty(i)) { continue; } if (MoveItemsFromSlot(a_Entity, i)) { Grid.ChangeSlotCount(i, -1); return true; } } return false; }
bool cHopperEntity::MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_SlotNum) { cItem One(a_Entity.GetSlot(a_SlotNum).CopyOne()); for (int i = 0; i < ContentsWidth * ContentsHeight; i++) { if (m_Contents.IsSlotEmpty(i)) { if (cPluginManager::Get()->CallHookHopperPullingItem(*m_World, *this, i, a_Entity, a_SlotNum)) { // Plugin disagrees with the move continue; } m_Contents.SetSlot(i, One); return true; } else if (m_Contents.GetSlot(i).IsEqual(One)) { if (cPluginManager::Get()->CallHookHopperPullingItem(*m_World, *this, i, a_Entity, a_SlotNum)) { // Plugin disagrees with the move continue; } auto PreviousCount = m_Contents.GetSlot(i).m_ItemCount; m_Contents.ChangeSlotCount(i, 1); if (PreviousCount + 1 == m_Contents.GetSlot(i).m_ItemCount) { // Successfully added a new item. (Failure condition consistutes: stack full) return true; } } } return false; }