diff --git a/src/main/java/refinedstorage/tile/externalstorage/DeepStorageUnitStorage.java b/src/main/java/refinedstorage/tile/externalstorage/DeepStorageUnitStorage.java new file mode 100755 index 000000000..24f1159b7 --- /dev/null +++ b/src/main/java/refinedstorage/tile/externalstorage/DeepStorageUnitStorage.java @@ -0,0 +1,113 @@ +package refinedstorage.tile.externalstorage; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.items.ItemHandlerHelper; +import powercrystals.minefactoryreloaded.api.IDeepStorageUnit; +import refinedstorage.api.storage.CompareUtils; +import refinedstorage.tile.config.ModeFilter; + +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.List; + +public class DeepStorageUnitStorage extends ExternalStorage { + private TileExternalStorage externalStorage; + private IDeepStorageUnit unit; + + public DeepStorageUnitStorage(TileExternalStorage externalStorage, IDeepStorageUnit unit) { + this.externalStorage = externalStorage; + this.unit = unit; + } + + @Override + public int getCapacity() { + return unit.getMaxStoredCount(); + } + + @Override + public List getItems() { + if (unit.getStoredItemType() != null && unit.getStoredItemType().stackSize > 0) { + return Collections.singletonList(unit.getStoredItemType().copy()); + } + + return Collections.emptyList(); + } + + @Override + public ItemStack insertItem(@Nonnull ItemStack stack, int size, boolean simulate) { + if (ModeFilter.respectsMode(externalStorage.getFilters(), externalStorage, externalStorage.getCompare(), stack)) { + if (unit.getStoredItemType() != null) { + if (CompareUtils.compareStackNoQuantity(unit.getStoredItemType(), stack)) { + if (getStored() + size > unit.getMaxStoredCount()) { + int remainingSpace = getCapacity() - getStored(); + + if (remainingSpace <= 0) { + return ItemHandlerHelper.copyStackWithSize(stack, size); + } + + if (!simulate) { + unit.setStoredItemCount(unit.getStoredItemType().stackSize + remainingSpace); + } + + return ItemHandlerHelper.copyStackWithSize(stack, size - remainingSpace); + } else { + if (!simulate) { + unit.setStoredItemCount(unit.getStoredItemType().stackSize + size); + } + + return null; + } + } + } else { + if (getStored() + size > unit.getMaxStoredCount()) { + int remainingSpace = getCapacity() - getStored(); + + if (remainingSpace <= 0) { + return ItemHandlerHelper.copyStackWithSize(stack, size); + } + + if (!simulate) { + unit.setStoredItemType(stack.copy(), remainingSpace); + } + + return ItemHandlerHelper.copyStackWithSize(stack, size - remainingSpace); + } else { + if (!simulate) { + unit.setStoredItemType(stack.copy(), size); + } + + return null; + } + } + } + + return ItemHandlerHelper.copyStackWithSize(stack, size); + } + + @Override + public ItemStack extractItem(@Nonnull ItemStack stack, int size, int flags) { + if (CompareUtils.compareStack(stack, unit.getStoredItemType(), flags)) { + if (size > unit.getStoredItemType().stackSize) { + size = unit.getStoredItemType().stackSize; + } + + ItemStack stored = unit.getStoredItemType(); + + unit.setStoredItemCount(stored.stackSize - size); + + return ItemHandlerHelper.copyStackWithSize(stored, size); + } + + return null; + } + + @Override + public int getStored() { + return unit.getStoredItemType() != null ? unit.getStoredItemType().stackSize : 0; + } + + @Override + public int getPriority() { + return externalStorage.getPriority(); + } +} diff --git a/src/main/java/refinedstorage/tile/externalstorage/DrawerStorage.java b/src/main/java/refinedstorage/tile/externalstorage/DrawerStorage.java new file mode 100755 index 000000000..4b398d4d7 --- /dev/null +++ b/src/main/java/refinedstorage/tile/externalstorage/DrawerStorage.java @@ -0,0 +1,115 @@ +package refinedstorage.tile.externalstorage; + +import com.jaquadro.minecraft.storagedrawers.api.storage.IDrawer; +import com.jaquadro.minecraft.storagedrawers.api.storage.attribute.IVoidable; +import net.minecraft.item.ItemStack; +import net.minecraftforge.items.ItemHandlerHelper; +import refinedstorage.api.storage.CompareUtils; +import refinedstorage.tile.config.ModeFilter; + +import java.util.Collections; +import java.util.List; + +public class DrawerStorage extends ExternalStorage { + private TileExternalStorage externalStorage; + private IDrawer drawer; + + public DrawerStorage(TileExternalStorage externalStorage, IDrawer drawer) { + this.externalStorage = externalStorage; + this.drawer = drawer; + } + + @Override + public int getCapacity() { + return drawer.getMaxCapacity(); + } + + @Override + public List getItems() { + if (!drawer.isEmpty() && drawer.getStoredItemCount() > 0) { + return Collections.singletonList(drawer.getStoredItemCopy()); + } + + return Collections.emptyList(); + } + + public boolean isVoidable() { + return drawer instanceof IVoidable && ((IVoidable) drawer).isVoid(); + } + + @Override + public ItemStack insertItem(ItemStack stack, int size, boolean simulate) { + if (ModeFilter.respectsMode(externalStorage.getFilters(), externalStorage, externalStorage.getCompare(), stack) && drawer.canItemBeStored(stack)) { + if (!drawer.isEmpty()) { + if (getStored() + size > drawer.getMaxCapacity(stack)) { + int remainingSpace = getCapacity() - getStored(); + + if (remainingSpace <= 0) { + return isVoidable() ? null : ItemHandlerHelper.copyStackWithSize(stack, size); + } + + if (!simulate) { + drawer.setStoredItemCount(drawer.getStoredItemCount() + remainingSpace); + } + + return isVoidable() ? null : ItemHandlerHelper.copyStackWithSize(stack, size - remainingSpace); + } else { + if (!simulate) { + drawer.setStoredItemCount(drawer.getStoredItemCount() + size); + } + + return null; + } + } else { + if (getStored() + size > drawer.getMaxCapacity(stack)) { + int remainingSpace = getCapacity() - getStored(); + + if (remainingSpace <= 0) { + return isVoidable() ? null : ItemHandlerHelper.copyStackWithSize(stack, size); + } + + if (!simulate) { + drawer.setStoredItem(stack, remainingSpace); + } + + return isVoidable() ? null : ItemHandlerHelper.copyStackWithSize(stack, size - remainingSpace); + } else { + if (!simulate) { + drawer.setStoredItem(stack, size); + } + + return null; + } + } + } + + return ItemHandlerHelper.copyStackWithSize(stack, size); + } + + @Override + public ItemStack extractItem(ItemStack stack, int size, int flags) { + if (CompareUtils.compareStack(stack, drawer.getStoredItemPrototype(), flags) && drawer.canItemBeExtracted(stack)) { + if (size > drawer.getStoredItemCount()) { + size = drawer.getStoredItemCount(); + } + + ItemStack stored = drawer.getStoredItemPrototype(); + + drawer.setStoredItemCount(drawer.getStoredItemCount() - size); + + return ItemHandlerHelper.copyStackWithSize(stored, size); + } + + return null; + } + + @Override + public int getStored() { + return drawer.getStoredItemCount(); + } + + @Override + public int getPriority() { + return externalStorage.getPriority(); + } +} diff --git a/src/main/java/refinedstorage/tile/externalstorage/ExternalStorage.java b/src/main/java/refinedstorage/tile/externalstorage/ExternalStorage.java new file mode 100755 index 000000000..6ec709ebf --- /dev/null +++ b/src/main/java/refinedstorage/tile/externalstorage/ExternalStorage.java @@ -0,0 +1,39 @@ +package refinedstorage.tile.externalstorage; + +import net.minecraft.item.ItemStack; +import refinedstorage.api.storage.CompareUtils; +import refinedstorage.api.storage.IStorage; + +import java.util.List; + +public abstract class ExternalStorage implements IStorage { + private List cache; + + public abstract int getCapacity(); + + public boolean updateCache() { + List items = getItems(); + + if (cache == null) { + cache = items; + } else if (items.size() != cache.size()) { + cache = items; + + return true; + } else { + for (int i = 0; i < items.size(); ++i) { + if (!CompareUtils.compareStack(items.get(i), cache.get(i))) { + cache = items; + + return true; + } + } + } + + return false; + } + + public void updateCacheForcefully() { + cache = getItems(); + } +} diff --git a/src/main/java/refinedstorage/tile/externalstorage/ItemHandlerStorage.java b/src/main/java/refinedstorage/tile/externalstorage/ItemHandlerStorage.java new file mode 100755 index 000000000..716ae16f7 --- /dev/null +++ b/src/main/java/refinedstorage/tile/externalstorage/ItemHandlerStorage.java @@ -0,0 +1,84 @@ +package refinedstorage.tile.externalstorage; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.ItemHandlerHelper; +import refinedstorage.api.storage.CompareUtils; +import refinedstorage.tile.config.ModeFilter; + +import java.util.ArrayList; +import java.util.List; + +public class ItemHandlerStorage extends ExternalStorage { + private TileExternalStorage externalStorage; + private IItemHandler handler; + + public ItemHandlerStorage(TileExternalStorage externalStorage, IItemHandler handler) { + this.externalStorage = externalStorage; + this.handler = handler; + } + + @Override + public int getCapacity() { + return handler.getSlots() * 64; + } + + @Override + public List getItems() { + List items = new ArrayList(); + + for (int i = 0; i < handler.getSlots(); ++i) { + if (handler.getStackInSlot(i) != null && handler.getStackInSlot(i).getItem() != null) { + items.add(handler.getStackInSlot(i).copy()); + } + } + + return items; + } + + @Override + public ItemStack insertItem(ItemStack stack, int size, boolean simulate) { + if (ModeFilter.respectsMode(externalStorage.getFilters(), externalStorage, externalStorage.getCompare(), stack)) { + return ItemHandlerHelper.insertItem(handler, ItemHandlerHelper.copyStackWithSize(stack, size), simulate); + } + + return ItemHandlerHelper.copyStackWithSize(stack, size); + } + + @Override + public ItemStack extractItem(ItemStack stack, int size, int flags) { + for (int i = 0; i < handler.getSlots(); ++i) { + ItemStack slot = handler.getStackInSlot(i); + + if (slot != null && CompareUtils.compareStack(slot, stack, flags)) { + size = Math.min(size, slot.stackSize); + + ItemStack took = ItemHandlerHelper.copyStackWithSize(slot, size); + + handler.extractItem(i, size, false); + + return took; + } + } + + return null; + } + + @Override + public int getStored() { + int size = 0; + + for (int i = 0; i < handler.getSlots(); ++i) { + if (handler.getStackInSlot(i) != null) { + size += handler.getStackInSlot(i).stackSize; + } + } + + return size; + } + + @Override + public int getPriority() { + return externalStorage.getPriority(); + } +} diff --git a/src/main/java/refinedstorage/tile/externalstorage/TileExternalStorage.java b/src/main/java/refinedstorage/tile/externalstorage/TileExternalStorage.java new file mode 100755 index 000000000..e553528e0 --- /dev/null +++ b/src/main/java/refinedstorage/tile/externalstorage/TileExternalStorage.java @@ -0,0 +1,276 @@ +package refinedstorage.tile.externalstorage; + +import com.jaquadro.minecraft.storagedrawers.api.storage.IDrawer; +import com.jaquadro.minecraft.storagedrawers.api.storage.IDrawerGroup; +import io.netty.buffer.ByteBuf; +import net.minecraft.inventory.Container; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.items.IItemHandler; +import powercrystals.minefactoryreloaded.api.IDeepStorageUnit; +import refinedstorage.RefinedStorage; +import refinedstorage.api.network.INetworkMaster; +import refinedstorage.api.storage.IStorage; +import refinedstorage.api.storage.IStorageProvider; +import refinedstorage.container.ContainerStorage; +import refinedstorage.inventory.ItemHandlerBasic; +import refinedstorage.network.MessagePriorityUpdate; +import refinedstorage.tile.IStorageGui; +import refinedstorage.tile.TileNode; +import refinedstorage.tile.config.ICompareConfig; +import refinedstorage.tile.config.IModeConfig; +import refinedstorage.tile.config.IRedstoneModeConfig; +import refinedstorage.tile.config.ModeConstants; + +import java.util.ArrayList; +import java.util.List; + +public class TileExternalStorage extends TileNode implements IStorageProvider, IStorageGui, ICompareConfig, IModeConfig { + private static final String NBT_PRIORITY = "Priority"; + private static final String NBT_COMPARE = "Compare"; + private static final String NBT_MODE = "Mode"; + + private ItemHandlerBasic filters = new ItemHandlerBasic(9, this); + + private int priority = 0; + private int compare = 0; + private int mode = ModeConstants.WHITELIST; + + private int stored; + private int capacity; + + private List storages = new ArrayList(); + private int lastDrawerCount; + + @Override + public int getEnergyUsage() { + return RefinedStorage.INSTANCE.externalStorageUsage + (storages.size() * RefinedStorage.INSTANCE.externalStoragePerStorageUsage); + } + + @Override + public void updateNode() { + } + + @Override + public void onConnectionChange(INetworkMaster network, boolean state) { + super.onConnectionChange(network, state); + + updateStorage(network); + + network.getStorage().rebuild(); + } + + @Override + public void update() { + if (!worldObj.isRemote && network != null) { + if (ticks % (20 * 4) == 0) { + boolean shouldRebuild = false; + + for (ExternalStorage storage : storages) { + if (storage.updateCache()) { + shouldRebuild = true; + } + } + + if (shouldRebuild) { + network.getStorage().rebuild(); + } + } + + if (getFacingTile() instanceof IDrawerGroup && lastDrawerCount != ((IDrawerGroup) getFacingTile()).getDrawerCount()) { + lastDrawerCount = ((IDrawerGroup) getFacingTile()).getDrawerCount(); + + updateStorage(network); + } + } + + super.update(); + } + + @Override + public void writeContainerData(ByteBuf buf) { + super.writeContainerData(buf); + + buf.writeInt(priority); + buf.writeInt(getStored()); + buf.writeInt(getCapacity()); + buf.writeInt(compare); + buf.writeInt(mode); + } + + @Override + public void readContainerData(ByteBuf buf) { + super.readContainerData(buf); + + priority = buf.readInt(); + stored = buf.readInt(); + capacity = buf.readInt(); + compare = buf.readInt(); + mode = buf.readInt(); + } + + @Override + public Class getContainer() { + return ContainerStorage.class; + } + + @Override + public void read(NBTTagCompound tag) { + super.read(tag); + + readItems(filters, 0, tag); + + if (tag.hasKey(NBT_PRIORITY)) { + priority = tag.getInteger(NBT_PRIORITY); + } + + if (tag.hasKey(NBT_COMPARE)) { + compare = tag.getInteger(NBT_COMPARE); + } + + if (tag.hasKey(NBT_MODE)) { + mode = tag.getInteger(NBT_MODE); + } + } + + @Override + public NBTTagCompound write(NBTTagCompound tag) { + super.write(tag); + + writeItems(filters, 0, tag); + + tag.setInteger(NBT_PRIORITY, priority); + tag.setInteger(NBT_COMPARE, compare); + tag.setInteger(NBT_MODE, mode); + + return tag; + } + + @Override + public int getCompare() { + return compare; + } + + @Override + public void setCompare(int compare) { + this.compare = compare; + + markDirty(); + } + + @Override + public int getMode() { + return mode; + } + + @Override + public void setMode(int mode) { + this.mode = mode; + + markDirty(); + } + + @Override + public int getPriority() { + return priority; + } + + public void setPriority(int priority) { + this.priority = priority; + + markDirty(); + } + + public void updateStorage(INetworkMaster network) { + storages.clear(); + + TileEntity facing = getFacingTile(); + + if (facing instanceof IDrawerGroup) { + IDrawerGroup group = (IDrawerGroup) facing; + + for (int i = 0; i < group.getDrawerCount(); ++i) { + if (group.isDrawerEnabled(i)) { + storages.add(new DrawerStorage(this, group.getDrawer(i))); + } + } + } else if (facing instanceof IDrawer) { + storages.add(new DrawerStorage(this, (IDrawer) facing)); + } else if (facing instanceof IDeepStorageUnit) { + storages.add(new DeepStorageUnitStorage(this, (IDeepStorageUnit) facing)); + } else { + IItemHandler handler = getItemHandler(facing, getDirection().getOpposite()); + + if (handler != null) { + storages.add(new ItemHandlerStorage(this, handler)); + } + } + + network.getStorage().rebuild(); + } + + @Override + public void addStorages(List storages) { + storages.addAll(this.storages); + } + + @Override + public String getGuiTitle() { + return "gui.refinedstorage:external_storage"; + } + + @Override + public IRedstoneModeConfig getRedstoneModeConfig() { + return this; + } + + @Override + public ICompareConfig getCompareConfig() { + return this; + } + + @Override + public IModeConfig getModeConfig() { + return this; + } + + @Override + public int getStored() { + if (!worldObj.isRemote) { + int stored = 0; + + for (ExternalStorage storage : storages) { + stored += storage.getStored(); + } + + return stored; + } + + return stored; + } + + @Override + public int getCapacity() { + if (!worldObj.isRemote) { + int capacity = 0; + + for (ExternalStorage storage : storages) { + capacity += storage.getCapacity(); + } + + return capacity; + } + + return capacity; + } + + @Override + public void onPriorityChanged(int priority) { + RefinedStorage.INSTANCE.network.sendToServer(new MessagePriorityUpdate(pos, priority)); + } + + @Override + public IItemHandler getFilters() { + return filters; + } +}