diff --git a/src/main/java/api/hbm/ntl/ISlotMonitorProvider.java b/src/main/java/api/hbm/ntl/ISlotMonitorProvider.java index 68e0e958b..8cbdf135b 100644 --- a/src/main/java/api/hbm/ntl/ISlotMonitorProvider.java +++ b/src/main/java/api/hbm/ntl/ISlotMonitorProvider.java @@ -15,7 +15,7 @@ public interface ISlotMonitorProvider { /** Returns an array of available slot monitors, which should ideally mirror the available slots of that container */ public SlotMonitor[] getMonitors(); - /** Returns the slot contents of that index, so that the monitors can detect changes */ + /** Returns the ORIGIANL ItemStack of that index, so that the monitors can detect changes */ public ItemStack getSlotAt(int index); /** Returns the amount of that slot at that index. Some storages may use int64 datatypes so we have to account for those too somehow, since ItemStacks cannot handle that. */ @@ -24,6 +24,12 @@ public interface ISlotMonitorProvider { /** Removes the given number of items from that slot, returns the amount left to remove if the stack was smaller than the supplied amount */ public long useUpItem(int index, long amount); + /** Adds the given number of items to that slot, returns the amount that couldn't be added due to stack limits */ + public long addItem(int index, long amount); + + /** Sets the slot contents, returns the number of items that couldn't be added */ + public long setupType(int index, ItemStack zeroStack, long amount); + /** Whether this storage unit is reachable by the access point */ public boolean isAvailableToCache(StackCache cache); diff --git a/src/main/java/api/hbm/ntl/StackCache.java b/src/main/java/api/hbm/ntl/StackCache.java index 1f853f4c7..11ffb61bc 100644 --- a/src/main/java/api/hbm/ntl/StackCache.java +++ b/src/main/java/api/hbm/ntl/StackCache.java @@ -57,11 +57,15 @@ public class StackCache { /** Uses up items and returns how many of the requested items could be removed, with no desyncs that number should always be equal to the supplied amount */ public long consumeItemsAndReturnQuantity(ItemStack stack, long amount) { - CacheSlot cache = getSlotFromStack(stack); + long stackIdentity = getStackIdentity(stack.getItem(), stack.getItemDamage(), stack.stackTagCompound); + CacheSlot cache = this.cacheSlots.get(stackIdentity); if(cache == null) return 0; long originalAmount = amount; for(SlotMonitor monitor : cache.monitors) { + ItemStack original = monitor.parent.getSlotAt(monitor.index); + long checkIdentity = getStackIdentity(original); + if(checkIdentity != stackIdentity) continue; amount = monitor.parent.useUpItem(monitor.index, amount); if(amount <= 0) break; } @@ -69,6 +73,33 @@ public class StackCache { return originalAmount - amount; } + /** Adds a stack to the system and returns the amount that did not fit */ + public long addItemsAndReturnQuantity(ItemStack stack, long amount) { + long stackIdentity = getStackIdentity(stack.getItem(), stack.getItemDamage(), stack.stackTagCompound); + CacheSlot cache = this.cacheSlots.get(stackIdentity); + + if(cache != null) for(SlotMonitor monitor : cache.monitors) { + ItemStack original = monitor.parent.getSlotAt(monitor.index); + long checkIdentity = getStackIdentity(original); + if(checkIdentity != stackIdentity) continue; + amount = monitor.parent.addItem(monitor.index, amount); + if(amount <= 0) break; + } + + if(amount > 0) { + CacheSlot nullCache = this.cacheSlots.get(getNullIdentity()); + if(nullCache != null) { // quite ironic, isn't it? + for(SlotMonitor monitor : nullCache.monitors) { + if(monitor.parent.getSlotAt(monitor.index) != null) continue; + amount = monitor.parent.setupType(monitor.index, stack, amount); + if(amount <= 0) break; + } + } + } + + return amount; + } + public void dissolveCache() { for(Entry cacheEntry : cacheSlots.entrySet()) { cacheEntry.getValue().destroy(); @@ -154,6 +185,15 @@ public class StackCache { } } + public static long getNullIdentity() { + return 0; //getStackIdentity(null, 0, null); + } + + public static long getStackIdentity(ItemStack stack) { + if(stack == null) return getNullIdentity(); + return getStackIdentity(stack.getItem(), stack.getItemDamage(), stack.stackTagCompound); + } + public static long getStackIdentity(Item item, int meta, NBTTagCompound nbt) { long identity = Item.getIdFromItem(item) * 27644437; identity += meta * 27644437; diff --git a/src/main/java/com/hbm/inventory/container/ContainerPneumoStorageAccess.java b/src/main/java/com/hbm/inventory/container/ContainerPneumoStorageAccess.java index 348e8617f..c4ebcd71c 100644 --- a/src/main/java/com/hbm/inventory/container/ContainerPneumoStorageAccess.java +++ b/src/main/java/com/hbm/inventory/container/ContainerPneumoStorageAccess.java @@ -98,41 +98,46 @@ public class ContainerPneumoStorageAccess extends Container implements ICustomPa @Override public ItemStack slotClick(int index, int button, int mode, EntityPlayer player) { + if(mode == 6) return null; + + boolean leftClick = button == 0 && mode == 0; + boolean rightClick = button == 1 && mode == 0; + boolean shiftClick = button == 0 && mode == 1; if(index >= 0 && index < GRID_SIZE) { boolean client = player.worldObj.isRemote; SlotPneumo slot = (SlotPneumo) this.getSlot(index); ItemStack held = player.inventory.getItemStack(); - - boolean standardClick = button == 0 && mode == 0; - boolean shiftClick = button == 0 && mode == 1; if(slot.getHasStack()) { // left click, can't hold an item and provides a full stack to the held item - if(standardClick && held == null) { + if(leftClick || rightClick) { ItemStack stack = slot.getStack().copy(); + + int alreadyHeld = held == null ? 0 : held.stackSize; + int capacity = stack.getMaxStackSize() - alreadyHeld; + if(rightClick && capacity > 1) capacity = 1; + int toGrab = (int) Math.min(capacity, slot.amount); - if(standardClick) { - int toGrab = (int) Math.min(stack.getMaxStackSize(), slot.amount); - + if(capacity > 0 && (held == null || StackCache.getStackIdentity(held) == StackCache.getStackIdentity(stack))) { if(client) { - stack.stackSize = toGrab; + stack.stackSize = toGrab + alreadyHeld; player.inventory.setItemStack(stack); - //slot.amount -= toGrab; - //if(slot.amount <= 0) slot.putStack(null); } else { - if(this.access.cache == null || this.access.cache.hasExpired) return stack; + if(this.access.cache == null || this.access.cache.hasExpired) return null; StackCache cache = this.access.cache; - stack.stackSize = (int) cache.consumeItemsAndReturnQuantity(stack, toGrab); // this can't work because the stack got altered with the description NBT..... + stack.stackSize = (int) cache.consumeItemsAndReturnQuantity(stack, toGrab) + alreadyHeld; player.inventory.setItemStack(stack); } + + return null; // for some reason we gotta terminate here and not below } // shift click, works even if there's a held stack, serverside only and the nwe just sync } else if(shiftClick && !client) { ItemStack stack = slot.getStack().copy(); - if(this.access.cache == null || this.access.cache.hasExpired) return stack; + if(this.access.cache == null || this.access.cache.hasExpired) return null; StackCache cache = this.access.cache; int originalStacksize = (int) Math.min(stack.getMaxStackSize(), slot.amount); stack.stackSize = originalStacksize; @@ -144,7 +149,37 @@ public class ContainerPneumoStorageAccess extends Container implements ICustomPa } } + if(held != null) { + int toDeposit = rightClick ? 1 : held.stackSize; + player.inventory.getItemStack().stackSize -= toDeposit; + if(player.inventory.getItemStack().stackSize <= 0) player.inventory.setItemStack(null); + if(this.access.cache == null || this.access.cache.hasExpired) return null; + StackCache cache = this.access.cache; + int remainder = (int) cache.addItemsAndReturnQuantity(held, toDeposit); + if(remainder > 0) { + ItemStack copy = held.copy(); + copy.stackSize = remainder; + InventoryUtil.tryAddItemToInventory(player.inventory.mainInventory, copy); + } + } + return slot.getHasStack() ? slot.getStack().copy() : null; + + // shift clicking an item from the player inv to the storage + } else if(index >= GRID_SIZE && index < this.inventorySlots.size()) { + + Slot slot = this.getSlot(index); + + if(shiftClick && slot.getHasStack()) { + ItemStack stack = slot.getStack().copy(); + if(this.access.cache == null || this.access.cache.hasExpired) return null; + StackCache cache = this.access.cache; + int remainder = (int) cache.addItemsAndReturnQuantity(stack, stack.stackSize); + slot.decrStackSize(stack.stackSize - remainder); + if(remainder <= 0) slot.putStack(null); + slot.onSlotChanged(); + detectAndSendChanges(); + } } return super.slotClick(index, button, mode, player); @@ -277,6 +312,11 @@ public class ContainerPneumoStorageAccess extends Container implements ICustomPa public SlotPneumo(IInventory inventory, int id, int x, int y) { super(inventory, id, x, y); } + + @Override + public boolean canTakeStack(EntityPlayer player) { + return true; + } } /** This inventory instance only exists to prepare the contents of a StackCache in such a way that we can use it in a container. */ diff --git a/src/main/java/com/hbm/inventory/gui/GUIPneumoStorageAccess.java b/src/main/java/com/hbm/inventory/gui/GUIPneumoStorageAccess.java index 10c5334cb..d0594da9f 100644 --- a/src/main/java/com/hbm/inventory/gui/GUIPneumoStorageAccess.java +++ b/src/main/java/com/hbm/inventory/gui/GUIPneumoStorageAccess.java @@ -3,6 +3,7 @@ package com.hbm.inventory.gui; import java.util.List; import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; import static com.hbm.inventory.gui.element.GUIElements.*; import com.hbm.inventory.container.ContainerPneumoStorageAccess; @@ -10,9 +11,11 @@ import com.hbm.inventory.container.ContainerPneumoStorageAccess.SlotPneumo; import com.hbm.inventory.gui.element.GUIElements; import com.hbm.lib.RefStrings; import com.hbm.tileentity.network.pneumatic.TileEntityPneumoStorageAccess; +import com.hbm.util.BobMathUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Slot; @@ -36,13 +39,6 @@ public class GUIPneumoStorageAccess extends GuiInfoContainer { @Override public void drawScreen(int x, int y, float interp) { super.drawScreen(x, y, interp); - - Slot slot = this.getSlotAtPosition(x, y); - - if(slot instanceof SlotPneumo) { - SlotPneumo pneumo = (SlotPneumo) slot; - if(pneumo.getHasStack()) this.drawInfo(new String[] {"x" + pneumo.amount}, x, y - 15); - } } @Override @@ -52,10 +48,31 @@ public class GUIPneumoStorageAccess extends GuiInfoContainer { @Override protected void drawGuiContainerForegroundLayer(int i, int j) { - String name = "container.pneumpStorageAccess"; + String name = "container.pneumoStorageAccess"; this.fontRendererObj.drawString(name, this.xSize / 2 - this.fontRendererObj.getStringWidth(name) / 2, 5, 4210752); this.fontRendererObj.drawString(I18n.format("container.inventory"), 8, this.ySize - 96 + 2, 4210752); + + GL11.glPushMatrix(); + RenderHelper.disableStandardItemLighting(); + GL11.glDisable(GL11.GL_DEPTH_TEST); + double scale = 0.5D; + GL11.glScaled(scale, scale, 1); + + for(Object o : this.inventorySlots.inventorySlots) { + if(!(o instanceof SlotPneumo)) continue; + SlotPneumo pneumoSlot = (SlotPneumo) o; + if(pneumoSlot.getHasStack()) { + String label = BobMathUtil.getShortNumber(pneumoSlot.amount); + int ix = (int) ((pneumoSlot.xDisplayPosition + 16) / scale) - this.fontRendererObj.getStringWidth(label); + int iy = (int) ((pneumoSlot.yDisplayPosition + 16) / scale) - this.fontRendererObj.FONT_HEIGHT; + this.fontRendererObj.drawStringWithShadow(label, ix, iy, -1); + } + } + GL11.glEnable(GL11.GL_DEPTH_TEST); + GL11.glPopMatrix(); + + RenderHelper.enableGUIStandardItemLighting(); } @Override diff --git a/src/main/java/com/hbm/tileentity/network/pneumatic/TileEntityPneumoStorageClutter.java b/src/main/java/com/hbm/tileentity/network/pneumatic/TileEntityPneumoStorageClutter.java index 5e5c96b84..9ee354b43 100644 --- a/src/main/java/com/hbm/tileentity/network/pneumatic/TileEntityPneumoStorageClutter.java +++ b/src/main/java/com/hbm/tileentity/network/pneumatic/TileEntityPneumoStorageClutter.java @@ -144,13 +144,33 @@ public class TileEntityPneumoStorageClutter extends TileEntityMachineBase implem @Override public long useUpItem(int index, long amount) { - - if(slots[index] != null) { - int toRemove = (int) Math.min(slots[index].stackSize, amount); + ItemStack stack = slots[index]; + if(stack != null) { + int toRemove = (int) Math.min(stack.stackSize, amount); this.decrStackSize(index, toRemove); return amount - toRemove; } - return amount; } + + @Override + public long addItem(int index, long amount) { + ItemStack stack = slots[index]; + if(stack != null) { + int capacity = Math.min(stack.getMaxStackSize(), this.getInventoryStackLimit()); + int toAdd = (int) Math.min(amount, capacity - stack.stackSize); + stack.stackSize += toAdd; + return amount - toAdd; + } + return amount; + } + + @Override + public long setupType(int index, ItemStack zeroStack, long amount) { + int capacity = Math.min(zeroStack.getMaxStackSize(), this.getInventoryStackLimit()); + int finalSize = (int) Math.min(amount, capacity); + slots[index] = zeroStack.copy(); + slots[index].stackSize = finalSize; + return amount - finalSize; + } } diff --git a/src/main/resources/assets/hbm/textures/blocks/brick_light.png b/src/main/resources/assets/hbm/textures/blocks/brick_light.png index 083fa23d5..2ef48619b 100644 Binary files a/src/main/resources/assets/hbm/textures/blocks/brick_light.png and b/src/main/resources/assets/hbm/textures/blocks/brick_light.png differ diff --git a/src/main/resources/assets/hbm/textures/blocks/pneumatic_storage_clutter.png b/src/main/resources/assets/hbm/textures/blocks/pneumatic_storage_clutter.png index 9f14c454d..8c501bb77 100644 Binary files a/src/main/resources/assets/hbm/textures/blocks/pneumatic_storage_clutter.png and b/src/main/resources/assets/hbm/textures/blocks/pneumatic_storage_clutter.png differ