Added External Storage API (#1460). Fixed bug where External Storage could only handle 1 fluid inventory per block (#1034).
This commit is contained in:
@@ -21,6 +21,7 @@ NOTE: Worlds that used Refined Storage 1.5.x are fully compatible with Refined S
|
|||||||
- Fixed bug where storage disks in Portable Grids could be moved into themselves (raoulvdberge)
|
- Fixed bug where storage disks in Portable Grids could be moved into themselves (raoulvdberge)
|
||||||
- Fixed the Crafter crashing when opening it while connected to a Primal Tech Grill or Kiln (raoulvdberge)
|
- Fixed the Crafter crashing when opening it while connected to a Primal Tech Grill or Kiln (raoulvdberge)
|
||||||
- Fixed bug where Crafting Upgrade on Interface kept too many items in stock (raoulvdberge)
|
- Fixed bug where Crafting Upgrade on Interface kept too many items in stock (raoulvdberge)
|
||||||
|
- Fixed bug where External Storage could only handle 1 fluid inventory per block (raoulvdberge)
|
||||||
- Prevent accidental Grid scrollbar click after clicking JEI recipe transfer button (raoulvdberge)
|
- Prevent accidental Grid scrollbar click after clicking JEI recipe transfer button (raoulvdberge)
|
||||||
- Added a missing config option for Crafter Manager energy usage (raoulvdberge)
|
- Added a missing config option for Crafter Manager energy usage (raoulvdberge)
|
||||||
- If an Interface is configured to expose the entire network storage (by configuring no export slots), it will no longer expose the entire RS storage, due to performance issues (raoulvdberge)
|
- If an Interface is configured to expose the entire network storage (by configuring no export slots), it will no longer expose the entire RS storage, due to performance issues (raoulvdberge)
|
||||||
|
@@ -14,10 +14,12 @@ import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeRegistry;
|
|||||||
import com.raoulvdberge.refinedstorage.api.network.readerwriter.IReaderWriterChannel;
|
import com.raoulvdberge.refinedstorage.api.network.readerwriter.IReaderWriterChannel;
|
||||||
import com.raoulvdberge.refinedstorage.api.network.readerwriter.IReaderWriterHandlerRegistry;
|
import com.raoulvdberge.refinedstorage.api.network.readerwriter.IReaderWriterHandlerRegistry;
|
||||||
import com.raoulvdberge.refinedstorage.api.solderer.ISoldererRegistry;
|
import com.raoulvdberge.refinedstorage.api.solderer.ISoldererRegistry;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.StorageType;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskManager;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskManager;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskRegistry;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskRegistry;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskSync;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskSync;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IExternalStorageProvider;
|
||||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||||
import com.raoulvdberge.refinedstorage.api.util.IOneSixMigrationHelper;
|
import com.raoulvdberge.refinedstorage.api.util.IOneSixMigrationHelper;
|
||||||
import com.raoulvdberge.refinedstorage.api.util.IQuantityFormatter;
|
import com.raoulvdberge.refinedstorage.api.util.IQuantityFormatter;
|
||||||
@@ -146,6 +148,20 @@ public interface IRSAPI {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
IStorageDiskSync getStorageDiskSync();
|
IStorageDiskSync getStorageDiskSync();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an external storage provider for the given storage type.
|
||||||
|
*
|
||||||
|
* @param type the storage type
|
||||||
|
* @param provider the external storage provider
|
||||||
|
*/
|
||||||
|
void addExternalStorageProvider(StorageType type, IExternalStorageProvider provider);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param type the type
|
||||||
|
* @return a list of external storage providers
|
||||||
|
*/
|
||||||
|
List<IExternalStorageProvider> getExternalStorageProviders(StorageType type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param world the world
|
* @param world the world
|
||||||
* @param capacity the capacity
|
* @param capacity the capacity
|
||||||
|
@@ -0,0 +1,9 @@
|
|||||||
|
package com.raoulvdberge.refinedstorage.api.storage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The storage type.
|
||||||
|
*/
|
||||||
|
public enum StorageType {
|
||||||
|
ITEM,
|
||||||
|
FLUID
|
||||||
|
}
|
@@ -1,5 +1,6 @@
|
|||||||
package com.raoulvdberge.refinedstorage.api.storage.disk;
|
package com.raoulvdberge.refinedstorage.api.storage.disk;
|
||||||
|
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.StorageType;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -36,5 +37,5 @@ public interface IStorageDiskProvider {
|
|||||||
/**
|
/**
|
||||||
* @return the storage type
|
* @return the storage type
|
||||||
*/
|
*/
|
||||||
StorageDiskType getType();
|
StorageType getType();
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +0,0 @@
|
|||||||
package com.raoulvdberge.refinedstorage.api.storage.disk;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The storage disk type.
|
|
||||||
*/
|
|
||||||
public enum StorageDiskType {
|
|
||||||
ITEM,
|
|
||||||
FLUID
|
|
||||||
}
|
|
@@ -0,0 +1,32 @@
|
|||||||
|
package com.raoulvdberge.refinedstorage.api.storage.externalstorage;
|
||||||
|
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides information about an external storage.
|
||||||
|
*/
|
||||||
|
public interface IExternalStorageContext {
|
||||||
|
/**
|
||||||
|
* @return the priority of the external storage
|
||||||
|
*/
|
||||||
|
int getPriority();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the access type of the external storage
|
||||||
|
*/
|
||||||
|
AccessType getAccessType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param stack the stack to test
|
||||||
|
* @return true if the external storage accepts the item, false otherwise
|
||||||
|
*/
|
||||||
|
boolean acceptsItem(ItemStack stack);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param stack the stack to test
|
||||||
|
* @return true if the external storage accepts the fluid, false otherwise
|
||||||
|
*/
|
||||||
|
boolean acceptsFluid(FluidStack stack);
|
||||||
|
}
|
@@ -0,0 +1,30 @@
|
|||||||
|
package com.raoulvdberge.refinedstorage.api.storage.externalstorage;
|
||||||
|
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides an external storage handler to the external storage block.
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
public interface IExternalStorageProvider<T> {
|
||||||
|
/**
|
||||||
|
* @param tile the tile
|
||||||
|
* @param direction the direction of the external storage
|
||||||
|
* @return true if the provider can provide, false otherwise
|
||||||
|
*/
|
||||||
|
boolean canProvide(TileEntity tile, EnumFacing direction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context the context of the external storage
|
||||||
|
* @param tile the tile supplier
|
||||||
|
* @param direction the direction of the external storage
|
||||||
|
* @return the external storage handler
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
IStorageExternal<T> provide(IExternalStorageContext context, Supplier<TileEntity> tile, EnumFacing direction);
|
||||||
|
}
|
@@ -0,0 +1,27 @@
|
|||||||
|
package com.raoulvdberge.refinedstorage.api.storage.externalstorage;
|
||||||
|
|
||||||
|
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.IStorage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An external storage handler.
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
public interface IStorageExternal<T> extends IStorage<T> {
|
||||||
|
/**
|
||||||
|
* For storage disks and blocks, the network detects changes and updates the {@link com.raoulvdberge.refinedstorage.api.storage.IStorageCache} accordingly.
|
||||||
|
* However, for blocks connected to an external storage the external storage itself is responsible for bookkeeping the changes
|
||||||
|
* and submitting them to the {@link com.raoulvdberge.refinedstorage.api.storage.IStorageCache}. That bookkeeping is supposed to happen in this method.
|
||||||
|
* <p>
|
||||||
|
* It's called every external storage tick.
|
||||||
|
*
|
||||||
|
* @param network the network
|
||||||
|
*/
|
||||||
|
void update(INetwork network);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the capacity of the connected storage
|
||||||
|
*/
|
||||||
|
int getCapacity();
|
||||||
|
}
|
@@ -18,10 +18,12 @@ import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeRegistry;
|
|||||||
import com.raoulvdberge.refinedstorage.api.network.readerwriter.IReaderWriterChannel;
|
import com.raoulvdberge.refinedstorage.api.network.readerwriter.IReaderWriterChannel;
|
||||||
import com.raoulvdberge.refinedstorage.api.network.readerwriter.IReaderWriterHandlerRegistry;
|
import com.raoulvdberge.refinedstorage.api.network.readerwriter.IReaderWriterHandlerRegistry;
|
||||||
import com.raoulvdberge.refinedstorage.api.solderer.ISoldererRegistry;
|
import com.raoulvdberge.refinedstorage.api.solderer.ISoldererRegistry;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.StorageType;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskManager;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskManager;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskRegistry;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskRegistry;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskSync;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskSync;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IExternalStorageProvider;
|
||||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||||
import com.raoulvdberge.refinedstorage.api.util.IOneSixMigrationHelper;
|
import com.raoulvdberge.refinedstorage.api.util.IOneSixMigrationHelper;
|
||||||
import com.raoulvdberge.refinedstorage.api.util.IQuantityFormatter;
|
import com.raoulvdberge.refinedstorage.api.util.IQuantityFormatter;
|
||||||
@@ -55,9 +57,7 @@ import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.LinkedList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class API implements IRSAPI {
|
public class API implements IRSAPI {
|
||||||
private static final IRSAPI INSTANCE = new API();
|
private static final IRSAPI INSTANCE = new API();
|
||||||
@@ -74,6 +74,7 @@ public class API implements IRSAPI {
|
|||||||
private IStorageDiskRegistry storageDiskRegistry = new StorageDiskRegistry();
|
private IStorageDiskRegistry storageDiskRegistry = new StorageDiskRegistry();
|
||||||
private IStorageDiskSync storageDiskSync = new StorageDiskSync();
|
private IStorageDiskSync storageDiskSync = new StorageDiskSync();
|
||||||
private IOneSixMigrationHelper oneSixMigrationHelper = new OneSixMigrationHelper();
|
private IOneSixMigrationHelper oneSixMigrationHelper = new OneSixMigrationHelper();
|
||||||
|
private Map<StorageType, List<IExternalStorageProvider>> externalStorageProviders = new HashMap<>();
|
||||||
private List<ICraftingPatternRenderHandler> patternRenderHandlers = new LinkedList<>();
|
private List<ICraftingPatternRenderHandler> patternRenderHandlers = new LinkedList<>();
|
||||||
|
|
||||||
public static IRSAPI instance() {
|
public static IRSAPI instance() {
|
||||||
@@ -230,6 +231,18 @@ public class API implements IRSAPI {
|
|||||||
return storageDiskSync;
|
return storageDiskSync;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addExternalStorageProvider(StorageType type, IExternalStorageProvider provider) {
|
||||||
|
externalStorageProviders.computeIfAbsent(type, k -> new ArrayList<>()).add(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IExternalStorageProvider> getExternalStorageProviders(StorageType type) {
|
||||||
|
List<IExternalStorageProvider> providers = externalStorageProviders.get(type);
|
||||||
|
|
||||||
|
return providers == null ? Collections.emptyList() : providers;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public IStorageDisk<ItemStack> createDefaultItemDisk(World world, int capacity) {
|
public IStorageDisk<ItemStack> createDefaultItemDisk(World world, int capacity) {
|
||||||
|
@@ -92,7 +92,7 @@ public class NetworkNodeDestructor extends NetworkNode implements IComparable, I
|
|||||||
if (entity instanceof EntityItem) {
|
if (entity instanceof EntityItem) {
|
||||||
ItemStack droppedItem = ((EntityItem) entity).getItem();
|
ItemStack droppedItem = ((EntityItem) entity).getItem();
|
||||||
|
|
||||||
if (IFilterable.canTake(itemFilters, mode, compare, droppedItem) && network.insertItem(droppedItem, droppedItem.getCount(), true) == null) {
|
if (IFilterable.acceptsItem(itemFilters, mode, compare, droppedItem) && network.insertItem(droppedItem, droppedItem.getCount(), true) == null) {
|
||||||
network.insertItemTracked(droppedItem.copy(), droppedItem.getCount());
|
network.insertItemTracked(droppedItem.copy(), droppedItem.getCount());
|
||||||
|
|
||||||
world.removeEntity(entity);
|
world.removeEntity(entity);
|
||||||
@@ -114,7 +114,7 @@ public class NetworkNodeDestructor extends NetworkNode implements IComparable, I
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!frontStack.isEmpty()) {
|
if (!frontStack.isEmpty()) {
|
||||||
if (IFilterable.canTake(itemFilters, mode, compare, frontStack) && frontBlockState.getBlockHardness(world, front) != -1.0) {
|
if (IFilterable.acceptsItem(itemFilters, mode, compare, frontStack) && frontBlockState.getBlockHardness(world, front) != -1.0) {
|
||||||
NonNullList<ItemStack> drops = NonNullList.create();
|
NonNullList<ItemStack> drops = NonNullList.create();
|
||||||
|
|
||||||
if (frontBlock instanceof BlockShulkerBox) {
|
if (frontBlock instanceof BlockShulkerBox) {
|
||||||
@@ -171,7 +171,7 @@ public class NetworkNodeDestructor extends NetworkNode implements IComparable, I
|
|||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
FluidStack stack = handler.drain(Fluid.BUCKET_VOLUME, false);
|
FluidStack stack = handler.drain(Fluid.BUCKET_VOLUME, false);
|
||||||
|
|
||||||
if (stack != null && IFilterable.canTakeFluids(fluidFilters, mode, compare, stack) && network.insertFluid(stack, stack.amount, true) == null) {
|
if (stack != null && IFilterable.acceptsFluid(fluidFilters, mode, compare, stack) && network.insertFluid(stack, stack.amount, true) == null) {
|
||||||
FluidStack drained = handler.drain(Fluid.BUCKET_VOLUME, true);
|
FluidStack drained = handler.drain(Fluid.BUCKET_VOLUME, true);
|
||||||
|
|
||||||
network.insertFluid(drained, drained.amount, false);
|
network.insertFluid(drained, drained.amount, false);
|
||||||
|
@@ -1,17 +1,19 @@
|
|||||||
package com.raoulvdberge.refinedstorage.apiimpl.network.node.externalstorage;
|
package com.raoulvdberge.refinedstorage.apiimpl.network.node;
|
||||||
|
|
||||||
import com.raoulvdberge.refinedstorage.RS;
|
import com.raoulvdberge.refinedstorage.RS;
|
||||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
|
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.IStorage;
|
import com.raoulvdberge.refinedstorage.api.storage.IStorage;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.IStorageProvider;
|
import com.raoulvdberge.refinedstorage.api.storage.IStorageProvider;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.StorageType;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IExternalStorageContext;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IExternalStorageProvider;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IStorageExternal;
|
||||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.IGuiStorage;
|
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNode;
|
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheFluid;
|
import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheFluid;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheItem;
|
import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheItem;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.util.OneSixMigrationHelper;
|
import com.raoulvdberge.refinedstorage.apiimpl.util.OneSixMigrationHelper;
|
||||||
import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy;
|
|
||||||
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase;
|
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase;
|
||||||
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerFluid;
|
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerFluid;
|
||||||
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerListenerNetworkNode;
|
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerListenerNetworkNode;
|
||||||
@@ -20,20 +22,18 @@ import com.raoulvdberge.refinedstorage.tile.config.*;
|
|||||||
import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter;
|
import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter;
|
||||||
import com.raoulvdberge.refinedstorage.util.AccessTypeUtils;
|
import com.raoulvdberge.refinedstorage.util.AccessTypeUtils;
|
||||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||||
import com.raoulvdberge.refinedstorage.util.WorldUtils;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
public class NetworkNodeExternalStorage extends NetworkNode implements IStorageProvider, IGuiStorage, IComparable, IFilterable, IPrioritizable, IType, IAccessType {
|
public class NetworkNodeExternalStorage extends NetworkNode implements IStorageProvider, IGuiStorage, IComparable, IFilterable, IPrioritizable, IType, IAccessType, IExternalStorageContext {
|
||||||
public static final String ID = "external_storage";
|
public static final String ID = "external_storage";
|
||||||
|
|
||||||
private static final String NBT_PRIORITY = "Priority";
|
private static final String NBT_PRIORITY = "Priority";
|
||||||
@@ -51,8 +51,8 @@ public class NetworkNodeExternalStorage extends NetworkNode implements IStorageP
|
|||||||
private AccessType accessType = AccessType.INSERT_EXTRACT;
|
private AccessType accessType = AccessType.INSERT_EXTRACT;
|
||||||
private int networkTicks;
|
private int networkTicks;
|
||||||
|
|
||||||
private List<StorageItemExternal> itemStorages = new CopyOnWriteArrayList<>();
|
private List<IStorageExternal<ItemStack>> itemStorages = new CopyOnWriteArrayList<>();
|
||||||
private List<StorageFluidExternal> fluidStorages = new CopyOnWriteArrayList<>();
|
private List<IStorageExternal<FluidStack>> fluidStorages = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
public NetworkNodeExternalStorage(World world, BlockPos pos) {
|
public NetworkNodeExternalStorage(World world, BlockPos pos) {
|
||||||
super(world, pos);
|
super(world, pos);
|
||||||
@@ -81,20 +81,12 @@ public class NetworkNodeExternalStorage extends NetworkNode implements IStorageP
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (StorageItemExternal storage : itemStorages) {
|
for (IStorageExternal<ItemStack> storage : itemStorages) {
|
||||||
storage.detectChanges(network);
|
storage.update(network);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean fluidChangeDetected = false;
|
for (IStorageExternal<FluidStack> storage : fluidStorages) {
|
||||||
|
storage.update(network);
|
||||||
for (StorageFluidExternal storage : fluidStorages) {
|
|
||||||
if (storage.updateCache()) {
|
|
||||||
fluidChangeDetected = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fluidChangeDetected) {
|
|
||||||
network.getFluidStorageCache().invalidate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,7 +137,7 @@ public class NetworkNodeExternalStorage extends NetworkNode implements IStorageP
|
|||||||
}
|
}
|
||||||
|
|
||||||
accessType = AccessTypeUtils.readAccessType(tag);
|
accessType = AccessTypeUtils.readAccessType(tag);
|
||||||
|
|
||||||
OneSixMigrationHelper.migrateEmptyWhitelistToEmptyBlacklist(version, this, itemFilters, fluidFilters);
|
OneSixMigrationHelper.migrateEmptyWhitelistToEmptyBlacklist(version, this, itemFilters, fluidFilters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,19 +188,19 @@ public class NetworkNodeExternalStorage extends NetworkNode implements IStorageP
|
|||||||
|
|
||||||
TileEntity facing = getFacingTile();
|
TileEntity facing = getFacingTile();
|
||||||
|
|
||||||
if (type == IType.ITEMS) {
|
if (facing != null) {
|
||||||
if (facing != null && !(facing.hasCapability(CapabilityNetworkNodeProxy.NETWORK_NODE_PROXY_CAPABILITY, getDirection().getOpposite()) && facing.getCapability(CapabilityNetworkNodeProxy.NETWORK_NODE_PROXY_CAPABILITY, getDirection().getOpposite()).getNode() instanceof IStorageProvider)) {
|
if (type == IType.ITEMS) {
|
||||||
IItemHandler itemHandler = WorldUtils.getItemHandler(facing, getDirection().getOpposite());
|
for (IExternalStorageProvider provider : API.instance().getExternalStorageProviders(StorageType.ITEM)) {
|
||||||
|
if (provider.canProvide(facing, getDirection())) {
|
||||||
if (itemHandler != null) {
|
itemStorages.add(provider.provide(this, () -> getFacingTile(), getDirection()));
|
||||||
itemStorages.add(new StorageItemItemHandler(this, () -> WorldUtils.getItemHandler(getFacingTile(), getDirection().getOpposite())));
|
}
|
||||||
|
}
|
||||||
|
} else if (type == IType.FLUIDS) {
|
||||||
|
for (IExternalStorageProvider provider : API.instance().getExternalStorageProviders(StorageType.FLUID)) {
|
||||||
|
if (provider.canProvide(facing, getDirection())) {
|
||||||
|
fluidStorages.add(provider.provide(this, () -> getFacingTile(), getDirection()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if (type == IType.FLUIDS) {
|
|
||||||
IFluidHandler fluidHandler = WorldUtils.getFluidHandler(facing, getDirection().getOpposite());
|
|
||||||
|
|
||||||
if (fluidHandler != null) {
|
|
||||||
fluidStorages.add(new StorageFluidExternal(this, () -> WorldUtils.getFluidHandler(getFacingTile(), getDirection().getOpposite())));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,6 +263,16 @@ public class NetworkNodeExternalStorage extends NetworkNode implements IStorageP
|
|||||||
return accessType;
|
return accessType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean acceptsItem(ItemStack stack) {
|
||||||
|
return IFilterable.acceptsItem(itemFilters, mode, compare, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean acceptsFluid(FluidStack stack) {
|
||||||
|
return IFilterable.acceptsFluid(fluidFilters, mode, compare, stack);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAccessType(AccessType type) {
|
public void setAccessType(AccessType type) {
|
||||||
this.accessType = type;
|
this.accessType = type;
|
||||||
@@ -309,19 +311,11 @@ public class NetworkNodeExternalStorage extends NetworkNode implements IStorageP
|
|||||||
return getType() == IType.ITEMS ? itemFilters : fluidFilters;
|
return getType() == IType.ITEMS ? itemFilters : fluidFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemHandlerBase getItemFilters() {
|
public List<IStorageExternal<ItemStack>> getItemStorages() {
|
||||||
return itemFilters;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemHandlerFluid getFluidFilters() {
|
|
||||||
return fluidFilters;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<StorageItemExternal> getItemStorages() {
|
|
||||||
return itemStorages;
|
return itemStorages;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<StorageFluidExternal> getFluidStorages() {
|
public List<IStorageExternal<FluidStack>> getFluidStorages() {
|
||||||
return fluidStorages;
|
return fluidStorages;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -79,7 +79,7 @@ public class NetworkNodeImporter extends NetworkNode implements IComparable, IFi
|
|||||||
|
|
||||||
ItemStack stack = handler.getStackInSlot(currentSlot);
|
ItemStack stack = handler.getStackInSlot(currentSlot);
|
||||||
|
|
||||||
if (!IFilterable.canTake(itemFilters, mode, compare, stack)) {
|
if (!IFilterable.acceptsItem(itemFilters, mode, compare, stack)) {
|
||||||
currentSlot++;
|
currentSlot++;
|
||||||
} else if (ticks % upgrades.getSpeed() == 0) {
|
} else if (ticks % upgrades.getSpeed() == 0) {
|
||||||
ItemStack result = handler.extractItem(currentSlot, upgrades.getItemInteractCount(), true);
|
ItemStack result = handler.extractItem(currentSlot, upgrades.getItemInteractCount(), true);
|
||||||
@@ -101,7 +101,7 @@ public class NetworkNodeImporter extends NetworkNode implements IComparable, IFi
|
|||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
FluidStack stack = handler.drain(Fluid.BUCKET_VOLUME, false);
|
FluidStack stack = handler.drain(Fluid.BUCKET_VOLUME, false);
|
||||||
|
|
||||||
if (stack != null && IFilterable.canTakeFluids(fluidFilters, mode, compare, stack) && network.insertFluid(stack, stack.amount, true) == null) {
|
if (stack != null && IFilterable.acceptsFluid(fluidFilters, mode, compare, stack) && network.insertFluid(stack, stack.amount, true) == null) {
|
||||||
FluidStack toDrain = handler.drain(Fluid.BUCKET_VOLUME * upgrades.getItemInteractCount(), false);
|
FluidStack toDrain = handler.drain(Fluid.BUCKET_VOLUME * upgrades.getItemInteractCount(), false);
|
||||||
|
|
||||||
if (toDrain != null) {
|
if (toDrain != null) {
|
||||||
|
@@ -4,7 +4,7 @@ import com.raoulvdberge.refinedstorage.RS;
|
|||||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.CraftingRequester;
|
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.CraftingRequester;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.externalstorage.StorageItemItemHandler;
|
import com.raoulvdberge.refinedstorage.apiimpl.storage.externalstorage.StorageExternalItem;
|
||||||
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase;
|
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase;
|
||||||
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerListenerNetworkNode;
|
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerListenerNetworkNode;
|
||||||
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerProxy;
|
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerProxy;
|
||||||
@@ -93,7 +93,7 @@ public class NetworkNodeInterface extends NetworkNode implements IComparable {
|
|||||||
int delta = got.isEmpty() ? wanted.getCount() : (wanted.getCount() - got.getCount());
|
int delta = got.isEmpty() ? wanted.getCount() : (wanted.getCount() - got.getCount());
|
||||||
|
|
||||||
if (delta > 0) {
|
if (delta > 0) {
|
||||||
ItemStack result = network.extractItem(wanted, delta, compare, false, s -> !(s instanceof StorageItemItemHandler) || !((StorageItemItemHandler) s).isConnectedToInterface());
|
ItemStack result = network.extractItem(wanted, delta, compare, false, s -> !(s instanceof StorageExternalItem) || !((StorageExternalItem) s).isConnectedToInterface());
|
||||||
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
if (exportItems.getStackInSlot(i).isEmpty()) {
|
if (exportItems.getStackInSlot(i).isEmpty()) {
|
||||||
|
@@ -56,7 +56,7 @@ public class StorageDiskFluidDriveWrapper implements IStorageDisk<FluidStack> {
|
|||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public FluidStack insert(@Nonnull FluidStack stack, int size, boolean simulate) {
|
public FluidStack insert(@Nonnull FluidStack stack, int size, boolean simulate) {
|
||||||
if (!IFilterable.canTakeFluids(diskDrive.getFluidFilters(), diskDrive.getMode(), diskDrive.getCompare(), stack)) {
|
if (!IFilterable.acceptsFluid(diskDrive.getFluidFilters(), diskDrive.getMode(), diskDrive.getCompare(), stack)) {
|
||||||
return StackUtils.copy(stack, size);
|
return StackUtils.copy(stack, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -56,7 +56,7 @@ public class StorageDiskItemDriveWrapper implements IStorageDisk<ItemStack> {
|
|||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public ItemStack insert(@Nonnull ItemStack stack, int size, boolean simulate) {
|
public ItemStack insert(@Nonnull ItemStack stack, int size, boolean simulate) {
|
||||||
if (!IFilterable.canTake(diskDrive.getItemFilters(), diskDrive.getMode(), diskDrive.getCompare(), stack)) {
|
if (!IFilterable.acceptsItem(diskDrive.getItemFilters(), diskDrive.getMode(), diskDrive.getCompare(), stack)) {
|
||||||
return ItemHandlerHelper.copyStackWithSize(stack, size);
|
return ItemHandlerHelper.copyStackWithSize(stack, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -66,7 +66,7 @@ public class StorageDiskFluidManipulatorWrapper implements IStorageDisk<FluidSta
|
|||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public FluidStack insert(@Nonnull FluidStack stack, int size, boolean simulate) {
|
public FluidStack insert(@Nonnull FluidStack stack, int size, boolean simulate) {
|
||||||
if (!IFilterable.canTakeFluids(diskManipulator.getFluidFilters(), diskManipulator.getMode(), diskManipulator.getCompare(), stack)) {
|
if (!IFilterable.acceptsFluid(diskManipulator.getFluidFilters(), diskManipulator.getMode(), diskManipulator.getCompare(), stack)) {
|
||||||
return StackUtils.copy(stack, size);
|
return StackUtils.copy(stack, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ public class StorageDiskFluidManipulatorWrapper implements IStorageDisk<FluidSta
|
|||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public FluidStack extract(@Nonnull FluidStack stack, int size, int flags, boolean simulate) {
|
public FluidStack extract(@Nonnull FluidStack stack, int size, int flags, boolean simulate) {
|
||||||
if (!IFilterable.canTakeFluids(diskManipulator.getFluidFilters(), diskManipulator.getMode(), diskManipulator.getCompare(), stack)) {
|
if (!IFilterable.acceptsFluid(diskManipulator.getFluidFilters(), diskManipulator.getMode(), diskManipulator.getCompare(), stack)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -61,7 +61,7 @@ public class StorageDiskItemManipulatorWrapper implements IStorageDisk<ItemStack
|
|||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public ItemStack insert(@Nonnull ItemStack stack, int size, boolean simulate) {
|
public ItemStack insert(@Nonnull ItemStack stack, int size, boolean simulate) {
|
||||||
if (!IFilterable.canTake(diskManipulator.getItemFilters(), diskManipulator.getMode(), diskManipulator.getCompare(), stack)) {
|
if (!IFilterable.acceptsItem(diskManipulator.getItemFilters(), diskManipulator.getMode(), diskManipulator.getCompare(), stack)) {
|
||||||
return ItemHandlerHelper.copyStackWithSize(stack, size);
|
return ItemHandlerHelper.copyStackWithSize(stack, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ public class StorageDiskItemManipulatorWrapper implements IStorageDisk<ItemStack
|
|||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public ItemStack extract(@Nonnull ItemStack stack, int size, int flags, boolean simulate) {
|
public ItemStack extract(@Nonnull ItemStack stack, int size, int flags, boolean simulate) {
|
||||||
if (!IFilterable.canTake(diskManipulator.getItemFilters(), diskManipulator.getMode(), diskManipulator.getCompare(), stack)) {
|
if (!IFilterable.acceptsItem(diskManipulator.getItemFilters(), diskManipulator.getMode(), diskManipulator.getCompare(), stack)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,123 +0,0 @@
|
|||||||
package com.raoulvdberge.refinedstorage.apiimpl.network.node.externalstorage;
|
|
||||||
|
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
|
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.IStorage;
|
|
||||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
|
||||||
import com.raoulvdberge.refinedstorage.tile.config.IFilterable;
|
|
||||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
|
||||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
|
||||||
import net.minecraftforge.fluids.capability.IFluidTankProperties;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public class StorageFluidExternal implements IStorage<FluidStack> {
|
|
||||||
private FluidStack cache;
|
|
||||||
|
|
||||||
private NetworkNodeExternalStorage externalStorage;
|
|
||||||
private Supplier<IFluidHandler> handlerSupplier;
|
|
||||||
|
|
||||||
public StorageFluidExternal(NetworkNodeExternalStorage externalStorage, Supplier<IFluidHandler> handlerSupplier) {
|
|
||||||
this.externalStorage = externalStorage;
|
|
||||||
this.handlerSupplier = handlerSupplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IFluidTankProperties getProperties() {
|
|
||||||
IFluidHandler handler = handlerSupplier.get();
|
|
||||||
|
|
||||||
return (handler != null && handler.getTankProperties() != null && handler.getTankProperties().length != 0) ? handler.getTankProperties()[0] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private FluidStack getContents() {
|
|
||||||
return getProperties() == null ? null : getProperties().getContents();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<FluidStack> getStacks() {
|
|
||||||
return getContents() == null ? Collections.emptyList() : Collections.singletonList(getContents().copy());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public FluidStack insert(@Nonnull FluidStack stack, int size, boolean simulate) {
|
|
||||||
if (getProperties() != null && IFilterable.canTakeFluids(externalStorage.getFluidFilters(), externalStorage.getMode(), externalStorage.getCompare(), stack) && getProperties().canFillFluidType(stack)) {
|
|
||||||
int filled = handlerSupplier.get().fill(StackUtils.copy(stack, size), !simulate);
|
|
||||||
|
|
||||||
if (filled == size) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return StackUtils.copy(stack, size - filled);
|
|
||||||
}
|
|
||||||
|
|
||||||
return StackUtils.copy(stack, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public FluidStack extract(@Nonnull FluidStack stack, int size, int flags, boolean simulate) {
|
|
||||||
IFluidHandler handler = handlerSupplier.get();
|
|
||||||
|
|
||||||
if (handler == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
FluidStack toDrain = StackUtils.copy(stack, size);
|
|
||||||
|
|
||||||
if (API.instance().getComparer().isEqual(getContents(), toDrain, flags)) {
|
|
||||||
return handler.drain(toDrain, !simulate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getStored() {
|
|
||||||
return getContents() != null ? getContents().amount : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCapacity() {
|
|
||||||
return getProperties() != null ? getProperties().getCapacity() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPriority() {
|
|
||||||
return externalStorage.getPriority();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccessType getAccessType() {
|
|
||||||
return externalStorage.getAccessType();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCacheDelta(int storedPreInsertion, int size, @Nullable FluidStack remainder) {
|
|
||||||
if (getAccessType() == AccessType.INSERT) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return remainder == null ? size : (size - remainder.amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean updateCache() {
|
|
||||||
FluidStack stack = getContents();
|
|
||||||
|
|
||||||
if (cache == null) {
|
|
||||||
cache = StackUtils.copy(stack);
|
|
||||||
} else if (!API.instance().getComparer().isEqual(stack, cache, IComparer.COMPARE_NBT | IComparer.COMPARE_QUANTITY)) {
|
|
||||||
cache = StackUtils.copy(stack);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateCacheForcefully() {
|
|
||||||
cache = StackUtils.copy(getContents());
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,94 +0,0 @@
|
|||||||
package com.raoulvdberge.refinedstorage.apiimpl.network.node.externalstorage;
|
|
||||||
|
|
||||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
|
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.IStorage;
|
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public abstract class StorageItemExternal implements IStorage<ItemStack> {
|
|
||||||
private List<ItemStack> cache;
|
|
||||||
|
|
||||||
public abstract int getCapacity();
|
|
||||||
|
|
||||||
public void detectChanges(INetwork network) {
|
|
||||||
// If we are insert only, we don't care about sending changes
|
|
||||||
if (getAccessType() == AccessType.INSERT) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cache == null) {
|
|
||||||
cache = new ArrayList<>(getStacks());
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ItemStack> newStacks = new ArrayList<>(getStacks());
|
|
||||||
|
|
||||||
for (int i = 0; i < newStacks.size(); ++i) {
|
|
||||||
ItemStack actual = newStacks.get(i);
|
|
||||||
|
|
||||||
// If we exceed the cache size, than that means this item is added
|
|
||||||
if (i >= cache.size()) {
|
|
||||||
if (!actual.isEmpty()) {
|
|
||||||
network.getItemStorageCache().add(actual, actual.getCount(), false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ItemStack cached = cache.get(i);
|
|
||||||
|
|
||||||
if (!cached.isEmpty() && actual.isEmpty()) {
|
|
||||||
// If the cached is not empty but the actual is, we remove this item
|
|
||||||
network.getItemStorageCache().remove(cached, cached.getCount(), true);
|
|
||||||
} else if (cached.isEmpty() && !actual.isEmpty()) {
|
|
||||||
// If the cached is empty and the actual isn't, we added this item
|
|
||||||
network.getItemStorageCache().add(actual, actual.getCount(), false, true);
|
|
||||||
|
|
||||||
network.getCraftingManager().track(actual, actual.getCount());
|
|
||||||
} else if (cached.isEmpty() && actual.isEmpty()) {
|
|
||||||
// If they're both empty, nothing happens
|
|
||||||
} else if (!API.instance().getComparer().isEqualNoQuantity(cached, actual)) {
|
|
||||||
// If both items mismatch, remove the old and add the new
|
|
||||||
network.getItemStorageCache().remove(cached, cached.getCount(), true);
|
|
||||||
network.getItemStorageCache().add(actual, actual.getCount(), false, true);
|
|
||||||
|
|
||||||
network.getCraftingManager().track(actual, actual.getCount());
|
|
||||||
} else if (cached.getCount() != actual.getCount()) {
|
|
||||||
int delta = actual.getCount() - cached.getCount();
|
|
||||||
|
|
||||||
if (delta > 0) {
|
|
||||||
network.getItemStorageCache().add(actual, delta, false, true);
|
|
||||||
|
|
||||||
network.getCraftingManager().track(actual, delta);
|
|
||||||
} else {
|
|
||||||
network.getItemStorageCache().remove(actual, Math.abs(delta), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the cache size is somehow bigger than the actual stacks, that means the inventory shrunk
|
|
||||||
// In that case, we remove the items that have been removed due to the shrinkage
|
|
||||||
if (cache.size() > newStacks.size()) {
|
|
||||||
for (int i = newStacks.size(); i < cache.size(); ++i) {
|
|
||||||
if (cache.get(i) != ItemStack.EMPTY) {
|
|
||||||
network.getItemStorageCache().remove(cache.get(i), cache.get(i).getCount(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.cache = newStacks;
|
|
||||||
|
|
||||||
network.getItemStorageCache().flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCacheDelta(int storedPreInsertion, int size, @Nullable ItemStack remainder) {
|
|
||||||
return remainder == null ? size : (size - remainder.getCount());
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,142 +0,0 @@
|
|||||||
package com.raoulvdberge.refinedstorage.apiimpl.network.node.externalstorage;
|
|
||||||
|
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
|
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
|
||||||
import com.raoulvdberge.refinedstorage.tile.TileInterface;
|
|
||||||
import com.raoulvdberge.refinedstorage.tile.config.IFilterable;
|
|
||||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraftforge.items.IItemHandler;
|
|
||||||
import net.minecraftforge.items.ItemHandlerHelper;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public class StorageItemItemHandler extends StorageItemExternal {
|
|
||||||
private NetworkNodeExternalStorage externalStorage;
|
|
||||||
private Supplier<IItemHandler> handlerSupplier;
|
|
||||||
private boolean connectedToInterface;
|
|
||||||
|
|
||||||
public StorageItemItemHandler(NetworkNodeExternalStorage externalStorage, Supplier<IItemHandler> handlerSupplier) {
|
|
||||||
this.externalStorage = externalStorage;
|
|
||||||
this.handlerSupplier = handlerSupplier;
|
|
||||||
this.connectedToInterface = externalStorage.getFacingTile() instanceof TileInterface;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isConnectedToInterface() {
|
|
||||||
return connectedToInterface;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCapacity() {
|
|
||||||
IItemHandler handler = handlerSupplier.get();
|
|
||||||
|
|
||||||
if (handler == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int capacity = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < handler.getSlots(); ++i) {
|
|
||||||
capacity += Math.min(handler.getSlotLimit(i), handler.getStackInSlot(i).getMaxStackSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
return capacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<ItemStack> getStacks() {
|
|
||||||
IItemHandler handler = handlerSupplier.get();
|
|
||||||
|
|
||||||
if (handler == null) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ItemStack> stacks = new ArrayList<>();
|
|
||||||
|
|
||||||
for (int i = 0; i < handler.getSlots(); ++i) {
|
|
||||||
stacks.add(handler.getStackInSlot(i).copy());
|
|
||||||
}
|
|
||||||
|
|
||||||
return stacks;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack insert(@Nonnull ItemStack stack, int size, boolean simulate) {
|
|
||||||
IItemHandler handler = handlerSupplier.get();
|
|
||||||
|
|
||||||
if (handler != null && IFilterable.canTake(externalStorage.getItemFilters(), externalStorage.getMode(), externalStorage.getCompare(), stack)) {
|
|
||||||
return StackUtils.emptyToNull(ItemHandlerHelper.insertItem(handler, ItemHandlerHelper.copyStackWithSize(stack, size), simulate));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ItemHandlerHelper.copyStackWithSize(stack, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack extract(@Nonnull ItemStack stack, int size, int flags, boolean simulate) {
|
|
||||||
int remaining = size;
|
|
||||||
|
|
||||||
ItemStack received = null;
|
|
||||||
|
|
||||||
IItemHandler handler = handlerSupplier.get();
|
|
||||||
|
|
||||||
if (handler == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < handler.getSlots(); ++i) {
|
|
||||||
ItemStack slot = handler.getStackInSlot(i);
|
|
||||||
|
|
||||||
if (!slot.isEmpty() && API.instance().getComparer().isEqual(slot, stack, flags)) {
|
|
||||||
ItemStack got = handler.extractItem(i, remaining, simulate);
|
|
||||||
|
|
||||||
if (!got.isEmpty()) {
|
|
||||||
if (received == null) {
|
|
||||||
received = got.copy();
|
|
||||||
} else {
|
|
||||||
received.grow(got.getCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
remaining -= got.getCount();
|
|
||||||
|
|
||||||
if (remaining == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return received;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getStored() {
|
|
||||||
IItemHandler handler = handlerSupplier.get();
|
|
||||||
|
|
||||||
if (handler == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int size = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < handler.getSlots(); ++i) {
|
|
||||||
size += handler.getStackInSlot(i).getCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPriority() {
|
|
||||||
return externalStorage.getPriority();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AccessType getAccessType() {
|
|
||||||
return externalStorage.getAccessType();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -41,7 +41,7 @@ public class StorageDiskFluidStorageWrapper implements IStorageDisk<FluidStack>
|
|||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public FluidStack insert(@Nonnull FluidStack stack, int size, boolean simulate) {
|
public FluidStack insert(@Nonnull FluidStack stack, int size, boolean simulate) {
|
||||||
if (!IFilterable.canTakeFluids(storage.getFilters(), storage.getMode(), storage.getCompare(), stack)) {
|
if (!IFilterable.acceptsFluid(storage.getFilters(), storage.getMode(), storage.getCompare(), stack)) {
|
||||||
return StackUtils.copy(stack, size);
|
return StackUtils.copy(stack, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -41,7 +41,7 @@ public class StorageDiskItemStorageWrapper implements IStorageDisk<ItemStack> {
|
|||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public ItemStack insert(@Nonnull ItemStack stack, int size, boolean simulate) {
|
public ItemStack insert(@Nonnull ItemStack stack, int size, boolean simulate) {
|
||||||
if (!IFilterable.canTake(storage.getFilters(), storage.getMode(), storage.getCompare(), stack)) {
|
if (!IFilterable.acceptsItem(storage.getFilters(), storage.getMode(), storage.getCompare(), stack)) {
|
||||||
return ItemHandlerHelper.copyStackWithSize(stack, size);
|
return ItemHandlerHelper.copyStackWithSize(stack, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,8 +5,10 @@ import com.raoulvdberge.refinedstorage.api.storage.*;
|
|||||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
@@ -19,6 +21,7 @@ public class StorageCacheFluid implements IStorageCache<FluidStack> {
|
|||||||
private CopyOnWriteArrayList<IStorage<FluidStack>> storages = new CopyOnWriteArrayList<>();
|
private CopyOnWriteArrayList<IStorage<FluidStack>> storages = new CopyOnWriteArrayList<>();
|
||||||
private IStackList<FluidStack> list = API.instance().createFluidStackList();
|
private IStackList<FluidStack> list = API.instance().createFluidStackList();
|
||||||
private List<IStorageCacheListener<FluidStack>> listeners = new LinkedList<>();
|
private List<IStorageCacheListener<FluidStack>> listeners = new LinkedList<>();
|
||||||
|
private List<Pair<FluidStack, Integer>> batchedChanges = new ArrayList<>();
|
||||||
|
|
||||||
public StorageCacheFluid(INetwork network) {
|
public StorageCacheFluid(INetwork network) {
|
||||||
this.network = network;
|
this.network = network;
|
||||||
@@ -54,20 +57,31 @@ public class StorageCacheFluid implements IStorageCache<FluidStack> {
|
|||||||
list.add(stack, size);
|
list.add(stack, size);
|
||||||
|
|
||||||
if (!rebuilding) {
|
if (!rebuilding) {
|
||||||
listeners.forEach(l -> l.onChanged(stack, size));
|
if (!batched) {
|
||||||
|
listeners.forEach(l -> l.onChanged(stack, size));
|
||||||
|
} else {
|
||||||
|
batchedChanges.add(Pair.of(stack, size));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void remove(@Nonnull FluidStack stack, int size, boolean batched) {
|
public synchronized void remove(@Nonnull FluidStack stack, int size, boolean batched) {
|
||||||
if (list.remove(stack, size)) {
|
if (list.remove(stack, size)) {
|
||||||
listeners.forEach(l -> l.onChanged(stack, -size));
|
if (!batched) {
|
||||||
|
listeners.forEach(l -> l.onChanged(stack, -size));
|
||||||
|
} else {
|
||||||
|
batchedChanges.add(Pair.of(stack, -size));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
throw new UnsupportedOperationException("Cannot flush fluid storage cache");
|
if (!batchedChanges.isEmpty()) {
|
||||||
|
batchedChanges.forEach(c -> listeners.forEach(l -> l.onChanged(c.getKey(), c.getValue())));
|
||||||
|
batchedChanges.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -0,0 +1,25 @@
|
|||||||
|
package com.raoulvdberge.refinedstorage.apiimpl.storage.externalstorage;
|
||||||
|
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IExternalStorageContext;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IExternalStorageProvider;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IStorageExternal;
|
||||||
|
import com.raoulvdberge.refinedstorage.util.WorldUtils;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class ExternalStorageProviderFluid implements IExternalStorageProvider<FluidStack> {
|
||||||
|
@Override
|
||||||
|
public boolean canProvide(TileEntity tile, EnumFacing direction) {
|
||||||
|
return WorldUtils.getFluidHandler(tile, direction.getOpposite()) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public IStorageExternal<FluidStack> provide(IExternalStorageContext context, Supplier<TileEntity> tile, EnumFacing direction) {
|
||||||
|
return new StorageExternalFluid(context, () -> WorldUtils.getFluidHandler(tile.get(), direction.getOpposite()));
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,36 @@
|
|||||||
|
package com.raoulvdberge.refinedstorage.apiimpl.storage.externalstorage;
|
||||||
|
|
||||||
|
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.IStorageProvider;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IExternalStorageContext;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IExternalStorageProvider;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IStorageExternal;
|
||||||
|
import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy;
|
||||||
|
import com.raoulvdberge.refinedstorage.tile.TileInterface;
|
||||||
|
import com.raoulvdberge.refinedstorage.util.WorldUtils;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class ExternalStorageProviderItem implements IExternalStorageProvider<ItemStack> {
|
||||||
|
@Override
|
||||||
|
public boolean canProvide(TileEntity tile, EnumFacing direction) {
|
||||||
|
boolean isNode = tile.hasCapability(CapabilityNetworkNodeProxy.NETWORK_NODE_PROXY_CAPABILITY, direction.getOpposite());
|
||||||
|
INetworkNodeProxy nodeProxy = tile.getCapability(CapabilityNetworkNodeProxy.NETWORK_NODE_PROXY_CAPABILITY, direction.getOpposite());
|
||||||
|
|
||||||
|
if (!(isNode && nodeProxy.getNode() instanceof IStorageProvider)) {
|
||||||
|
return WorldUtils.getItemHandler(tile, direction.getOpposite()) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public IStorageExternal<ItemStack> provide(IExternalStorageContext context, Supplier<TileEntity> tile, EnumFacing direction) {
|
||||||
|
return new StorageExternalItem(context, () -> WorldUtils.getItemHandler(tile.get(), direction.getOpposite()), tile.get() instanceof TileInterface);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,224 @@
|
|||||||
|
package com.raoulvdberge.refinedstorage.apiimpl.storage.externalstorage;
|
||||||
|
|
||||||
|
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IExternalStorageContext;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IStorageExternal;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||||
|
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||||
|
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||||
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||||
|
import net.minecraftforge.fluids.capability.IFluidTankProperties;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class StorageExternalFluid implements IStorageExternal<FluidStack> {
|
||||||
|
private IExternalStorageContext context;
|
||||||
|
private Supplier<IFluidHandler> handlerSupplier;
|
||||||
|
private List<FluidStack> cache;
|
||||||
|
|
||||||
|
public StorageExternalFluid(IExternalStorageContext context, Supplier<IFluidHandler> handlerSupplier) {
|
||||||
|
this.context = context;
|
||||||
|
this.handlerSupplier = handlerSupplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private IFluidTankProperties[] getProperties() {
|
||||||
|
IFluidHandler handler = handlerSupplier.get();
|
||||||
|
|
||||||
|
return (handler != null && handler.getTankProperties() != null && handler.getTankProperties().length != 0) ? handler.getTankProperties() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(INetwork network) {
|
||||||
|
// If we are insert only, we don't care about sending changes
|
||||||
|
if (getAccessType() == AccessType.INSERT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache == null) {
|
||||||
|
cache = new ArrayList<>(getStacksWithNulls());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<FluidStack> newStacks = new ArrayList<>(getStacksWithNulls());
|
||||||
|
|
||||||
|
for (int i = 0; i < newStacks.size(); ++i) {
|
||||||
|
FluidStack actual = newStacks.get(i);
|
||||||
|
|
||||||
|
// If we exceed the cache size, than that means this item is added
|
||||||
|
if (i >= cache.size()) {
|
||||||
|
if (actual != null) {
|
||||||
|
network.getFluidStorageCache().add(actual, actual.amount, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FluidStack cached = cache.get(i);
|
||||||
|
|
||||||
|
if (actual == null && cached == null) {
|
||||||
|
// NO OP
|
||||||
|
} else if (actual == null && cached != null) {
|
||||||
|
network.getFluidStorageCache().remove(cached, cached.amount, true);
|
||||||
|
} else if (actual != null && cached == null) {
|
||||||
|
network.getFluidStorageCache().add(actual, actual.amount, false, true);
|
||||||
|
} else if (!API.instance().getComparer().isEqual(actual, cached, IComparer.COMPARE_NBT)) {
|
||||||
|
network.getFluidStorageCache().remove(cached, cached.amount, true);
|
||||||
|
network.getFluidStorageCache().add(actual, actual.amount, false, true);
|
||||||
|
} else if (actual.amount > cached.amount) {
|
||||||
|
network.getFluidStorageCache().add(actual, actual.amount - cached.amount, false, true);
|
||||||
|
} else if (actual.amount < cached.amount) {
|
||||||
|
network.getFluidStorageCache().remove(actual, cached.amount - actual.amount, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache.size() > newStacks.size()) {
|
||||||
|
for (int i = newStacks.size(); i < cache.size(); ++i) {
|
||||||
|
if (cache.get(i) != null) {
|
||||||
|
network.getFluidStorageCache().remove(cache.get(i), cache.get(i).amount, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cache = newStacks;
|
||||||
|
|
||||||
|
network.getFluidStorageCache().flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCapacity() {
|
||||||
|
IFluidTankProperties[] props = getProperties();
|
||||||
|
|
||||||
|
if (props != null) {
|
||||||
|
int cap = 0;
|
||||||
|
|
||||||
|
for (IFluidTankProperties properties : props) {
|
||||||
|
cap += properties.getCapacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
return cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<FluidStack> getStacks() {
|
||||||
|
IFluidTankProperties[] props = getProperties();
|
||||||
|
|
||||||
|
if (props != null) {
|
||||||
|
List<FluidStack> fluids = new ArrayList<>();
|
||||||
|
|
||||||
|
for (IFluidTankProperties properties : props) {
|
||||||
|
FluidStack stack = properties.getContents();
|
||||||
|
|
||||||
|
if (stack != null) {
|
||||||
|
fluids.add(stack.copy());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fluids;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<FluidStack> getStacksWithNulls() {
|
||||||
|
IFluidTankProperties[] props = getProperties();
|
||||||
|
|
||||||
|
if (props != null) {
|
||||||
|
List<FluidStack> fluids = new ArrayList<>();
|
||||||
|
|
||||||
|
for (IFluidTankProperties properties : props) {
|
||||||
|
FluidStack stack = properties.getContents();
|
||||||
|
|
||||||
|
if (stack != null) {
|
||||||
|
fluids.add(stack.copy());
|
||||||
|
} else {
|
||||||
|
fluids.add(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fluids;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public FluidStack insert(@Nonnull FluidStack stack, int size, boolean simulate) {
|
||||||
|
if (context.acceptsFluid(stack)) {
|
||||||
|
int filled = handlerSupplier.get().fill(StackUtils.copy(stack, size), !simulate);
|
||||||
|
|
||||||
|
if (filled == size) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StackUtils.copy(stack, size - filled);
|
||||||
|
}
|
||||||
|
|
||||||
|
return StackUtils.copy(stack, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public FluidStack extract(@Nonnull FluidStack stack, int size, int flags, boolean simulate) {
|
||||||
|
IFluidHandler handler = handlerSupplier.get();
|
||||||
|
|
||||||
|
if (handler == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler.drain(StackUtils.copy(stack, size), !simulate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getStored() {
|
||||||
|
IFluidTankProperties[] props = getProperties();
|
||||||
|
|
||||||
|
if (props != null) {
|
||||||
|
int stored = 0;
|
||||||
|
|
||||||
|
for (IFluidTankProperties properties : props) {
|
||||||
|
FluidStack contents = properties.getContents();
|
||||||
|
|
||||||
|
if (contents != null) {
|
||||||
|
stored += contents.amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stored;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPriority() {
|
||||||
|
return context.getPriority();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessType getAccessType() {
|
||||||
|
return context.getAccessType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCacheDelta(int storedPreInsertion, int size, @Nullable FluidStack remainder) {
|
||||||
|
if (getAccessType() == AccessType.INSERT) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return remainder == null ? size : (size - remainder.amount);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,229 @@
|
|||||||
|
package com.raoulvdberge.refinedstorage.apiimpl.storage.externalstorage;
|
||||||
|
|
||||||
|
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IExternalStorageContext;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IStorageExternal;
|
||||||
|
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||||
|
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class StorageExternalItem implements IStorageExternal<ItemStack> {
|
||||||
|
private IExternalStorageContext context;
|
||||||
|
private Supplier<IItemHandler> handlerSupplier;
|
||||||
|
private List<ItemStack> cache;
|
||||||
|
private boolean connectedToInterface;
|
||||||
|
|
||||||
|
public StorageExternalItem(IExternalStorageContext context, Supplier<IItemHandler> handlerSupplier, boolean connectedToInterface) {
|
||||||
|
this.context = context;
|
||||||
|
this.handlerSupplier = handlerSupplier;
|
||||||
|
this.connectedToInterface = connectedToInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConnectedToInterface() {
|
||||||
|
return connectedToInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(INetwork network) {
|
||||||
|
// If we are insert only, we don't care about sending changes
|
||||||
|
if (getAccessType() == AccessType.INSERT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache == null) {
|
||||||
|
cache = new ArrayList<>(getStacks());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ItemStack> newStacks = new ArrayList<>(getStacks());
|
||||||
|
|
||||||
|
for (int i = 0; i < newStacks.size(); ++i) {
|
||||||
|
ItemStack actual = newStacks.get(i);
|
||||||
|
|
||||||
|
// If we exceed the cache size, than that means this item is added
|
||||||
|
if (i >= cache.size()) {
|
||||||
|
if (!actual.isEmpty()) {
|
||||||
|
network.getItemStorageCache().add(actual, actual.getCount(), false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack cached = cache.get(i);
|
||||||
|
|
||||||
|
if (!cached.isEmpty() && actual.isEmpty()) {
|
||||||
|
// If the cached is not empty but the actual is, we remove this item
|
||||||
|
network.getItemStorageCache().remove(cached, cached.getCount(), true);
|
||||||
|
} else if (cached.isEmpty() && !actual.isEmpty()) {
|
||||||
|
// If the cached is empty and the actual isn't, we added this item
|
||||||
|
network.getItemStorageCache().add(actual, actual.getCount(), false, true);
|
||||||
|
|
||||||
|
network.getCraftingManager().track(actual, actual.getCount());
|
||||||
|
} else if (cached.isEmpty() && actual.isEmpty()) {
|
||||||
|
// If they're both empty, nothing happens
|
||||||
|
} else if (!API.instance().getComparer().isEqualNoQuantity(cached, actual)) {
|
||||||
|
// If both items mismatch, remove the old and add the new
|
||||||
|
network.getItemStorageCache().remove(cached, cached.getCount(), true);
|
||||||
|
network.getItemStorageCache().add(actual, actual.getCount(), false, true);
|
||||||
|
|
||||||
|
network.getCraftingManager().track(actual, actual.getCount());
|
||||||
|
} else if (cached.getCount() != actual.getCount()) {
|
||||||
|
int delta = actual.getCount() - cached.getCount();
|
||||||
|
|
||||||
|
if (delta > 0) {
|
||||||
|
network.getItemStorageCache().add(actual, delta, false, true);
|
||||||
|
|
||||||
|
network.getCraftingManager().track(actual, delta);
|
||||||
|
} else {
|
||||||
|
network.getItemStorageCache().remove(actual, Math.abs(delta), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the cache size is somehow bigger than the actual stacks, that means the inventory shrunk
|
||||||
|
// In that case, we remove the items that have been removed due to the shrinkage
|
||||||
|
if (cache.size() > newStacks.size()) {
|
||||||
|
for (int i = newStacks.size(); i < cache.size(); ++i) {
|
||||||
|
if (cache.get(i) != ItemStack.EMPTY) {
|
||||||
|
network.getItemStorageCache().remove(cache.get(i), cache.get(i).getCount(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cache = newStacks;
|
||||||
|
|
||||||
|
network.getItemStorageCache().flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCapacity() {
|
||||||
|
IItemHandler handler = handlerSupplier.get();
|
||||||
|
|
||||||
|
if (handler == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int capacity = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < handler.getSlots(); ++i) {
|
||||||
|
capacity += Math.min(handler.getSlotLimit(i), handler.getStackInSlot(i).getMaxStackSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
return capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<ItemStack> getStacks() {
|
||||||
|
IItemHandler handler = handlerSupplier.get();
|
||||||
|
|
||||||
|
if (handler == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ItemStack> stacks = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < handler.getSlots(); ++i) {
|
||||||
|
stacks.add(handler.getStackInSlot(i).copy());
|
||||||
|
}
|
||||||
|
|
||||||
|
return stacks;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public ItemStack insert(@Nonnull ItemStack stack, int size, boolean simulate) {
|
||||||
|
IItemHandler handler = handlerSupplier.get();
|
||||||
|
|
||||||
|
if (handler != null && context.acceptsItem(stack)) {
|
||||||
|
return StackUtils.emptyToNull(ItemHandlerHelper.insertItem(handler, ItemHandlerHelper.copyStackWithSize(stack, size), simulate));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ItemHandlerHelper.copyStackWithSize(stack, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public ItemStack extract(@Nonnull ItemStack stack, int size, int flags, boolean simulate) {
|
||||||
|
int remaining = size;
|
||||||
|
|
||||||
|
ItemStack received = null;
|
||||||
|
|
||||||
|
IItemHandler handler = handlerSupplier.get();
|
||||||
|
|
||||||
|
if (handler == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < handler.getSlots(); ++i) {
|
||||||
|
ItemStack slot = handler.getStackInSlot(i);
|
||||||
|
|
||||||
|
if (!slot.isEmpty() && API.instance().getComparer().isEqual(slot, stack, flags)) {
|
||||||
|
ItemStack got = handler.extractItem(i, remaining, simulate);
|
||||||
|
|
||||||
|
if (!got.isEmpty()) {
|
||||||
|
if (received == null) {
|
||||||
|
received = got.copy();
|
||||||
|
} else {
|
||||||
|
received.grow(got.getCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
remaining -= got.getCount();
|
||||||
|
|
||||||
|
if (remaining == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return received;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getStored() {
|
||||||
|
IItemHandler handler = handlerSupplier.get();
|
||||||
|
|
||||||
|
if (handler == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < handler.getSlots(); ++i) {
|
||||||
|
size += handler.getStackInSlot(i).getCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPriority() {
|
||||||
|
return context.getPriority();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessType getAccessType() {
|
||||||
|
return context.getAccessType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCacheDelta(int storedPreInsertion, int size, @Nullable ItemStack remainder) {
|
||||||
|
if (getAccessType() == AccessType.INSERT) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return remainder == null ? size : (size - remainder.getCount());
|
||||||
|
}
|
||||||
|
}
|
@@ -1,7 +1,7 @@
|
|||||||
package com.raoulvdberge.refinedstorage.block;
|
package com.raoulvdberge.refinedstorage.block;
|
||||||
|
|
||||||
import com.raoulvdberge.refinedstorage.RSGui;
|
import com.raoulvdberge.refinedstorage.RSGui;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.externalstorage.NetworkNodeExternalStorage;
|
import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNodeExternalStorage;
|
||||||
import com.raoulvdberge.refinedstorage.tile.TileExternalStorage;
|
import com.raoulvdberge.refinedstorage.tile.TileExternalStorage;
|
||||||
import com.raoulvdberge.refinedstorage.util.RenderUtils;
|
import com.raoulvdberge.refinedstorage.util.RenderUtils;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
package com.raoulvdberge.refinedstorage.item;
|
package com.raoulvdberge.refinedstorage.item;
|
||||||
|
|
||||||
import com.raoulvdberge.refinedstorage.RSItems;
|
import com.raoulvdberge.refinedstorage.RSItems;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.StorageType;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskProvider;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskProvider;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskSyncData;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskSyncData;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.StorageDiskType;
|
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||||
import com.raoulvdberge.refinedstorage.block.FluidStorageType;
|
import com.raoulvdberge.refinedstorage.block.FluidStorageType;
|
||||||
import net.minecraft.client.resources.I18n;
|
import net.minecraft.client.resources.I18n;
|
||||||
@@ -148,7 +148,7 @@ public class ItemFluidStorageDisk extends ItemBase implements IStorageDiskProvid
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StorageDiskType getType() {
|
public StorageType getType() {
|
||||||
return StorageDiskType.FLUID;
|
return StorageType.FLUID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
package com.raoulvdberge.refinedstorage.item;
|
package com.raoulvdberge.refinedstorage.item;
|
||||||
|
|
||||||
import com.raoulvdberge.refinedstorage.RSItems;
|
import com.raoulvdberge.refinedstorage.RSItems;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.StorageType;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskProvider;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskProvider;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskSyncData;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskSyncData;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.StorageDiskType;
|
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||||
import com.raoulvdberge.refinedstorage.block.ItemStorageType;
|
import com.raoulvdberge.refinedstorage.block.ItemStorageType;
|
||||||
import net.minecraft.client.resources.I18n;
|
import net.minecraft.client.resources.I18n;
|
||||||
@@ -148,7 +148,7 @@ public class ItemStorageDisk extends ItemBase implements IStorageDiskProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StorageDiskType getType() {
|
public StorageType getType() {
|
||||||
return StorageDiskType.ITEM;
|
return StorageType.ITEM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@ import com.google.gson.JsonSyntaxException;
|
|||||||
import com.raoulvdberge.refinedstorage.RS;
|
import com.raoulvdberge.refinedstorage.RS;
|
||||||
import com.raoulvdberge.refinedstorage.RSBlocks;
|
import com.raoulvdberge.refinedstorage.RSBlocks;
|
||||||
import com.raoulvdberge.refinedstorage.RSItems;
|
import com.raoulvdberge.refinedstorage.RSItems;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.StorageType;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementColor;
|
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementColor;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementFluidRender;
|
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementFluidRender;
|
||||||
@@ -25,6 +26,8 @@ import com.raoulvdberge.refinedstorage.apiimpl.network.readerwriter.ReaderWriter
|
|||||||
import com.raoulvdberge.refinedstorage.apiimpl.solderer.SoldererRecipeLoader;
|
import com.raoulvdberge.refinedstorage.apiimpl.solderer.SoldererRecipeLoader;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.disk.StorageDiskFactoryFluid;
|
import com.raoulvdberge.refinedstorage.apiimpl.storage.disk.StorageDiskFactoryFluid;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.disk.StorageDiskFactoryItem;
|
import com.raoulvdberge.refinedstorage.apiimpl.storage.disk.StorageDiskFactoryItem;
|
||||||
|
import com.raoulvdberge.refinedstorage.apiimpl.storage.externalstorage.ExternalStorageProviderFluid;
|
||||||
|
import com.raoulvdberge.refinedstorage.apiimpl.storage.externalstorage.ExternalStorageProviderItem;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.util.OneSixMigrationHelper;
|
import com.raoulvdberge.refinedstorage.apiimpl.util.OneSixMigrationHelper;
|
||||||
import com.raoulvdberge.refinedstorage.block.BlockBase;
|
import com.raoulvdberge.refinedstorage.block.BlockBase;
|
||||||
import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy;
|
import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy;
|
||||||
@@ -147,6 +150,9 @@ public class ProxyCommon {
|
|||||||
API.instance().getStorageDiskRegistry().add(StorageDiskFactoryItem.ID, new StorageDiskFactoryItem());
|
API.instance().getStorageDiskRegistry().add(StorageDiskFactoryItem.ID, new StorageDiskFactoryItem());
|
||||||
API.instance().getStorageDiskRegistry().add(StorageDiskFactoryFluid.ID, new StorageDiskFactoryFluid());
|
API.instance().getStorageDiskRegistry().add(StorageDiskFactoryFluid.ID, new StorageDiskFactoryFluid());
|
||||||
|
|
||||||
|
API.instance().addExternalStorageProvider(StorageType.ITEM, new ExternalStorageProviderItem());
|
||||||
|
API.instance().addExternalStorageProvider(StorageType.FLUID, new ExternalStorageProviderFluid());
|
||||||
|
|
||||||
int id = 0;
|
int id = 0;
|
||||||
|
|
||||||
RS.INSTANCE.network.registerMessage(MessageTileDataParameter.class, MessageTileDataParameter.class, id++, Side.CLIENT);
|
RS.INSTANCE.network.registerMessage(MessageTileDataParameter.class, MessageTileDataParameter.class, id++, Side.CLIENT);
|
||||||
|
@@ -20,14 +20,13 @@ import com.raoulvdberge.refinedstorage.api.storage.AccessType;
|
|||||||
import com.raoulvdberge.refinedstorage.api.storage.IStorage;
|
import com.raoulvdberge.refinedstorage.api.storage.IStorage;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.IStorageCache;
|
import com.raoulvdberge.refinedstorage.api.storage.IStorageCache;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.IStorageTracker;
|
import com.raoulvdberge.refinedstorage.api.storage.IStorageTracker;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IStorageExternal;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.CraftingManager;
|
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.CraftingManager;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.energy.Energy;
|
import com.raoulvdberge.refinedstorage.apiimpl.energy.Energy;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.NetworkNodeGraph;
|
import com.raoulvdberge.refinedstorage.apiimpl.network.NetworkNodeGraph;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.FluidGridHandler;
|
import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.FluidGridHandler;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.ItemGridHandler;
|
import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.ItemGridHandler;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.item.NetworkItemHandler;
|
import com.raoulvdberge.refinedstorage.apiimpl.network.item.NetworkItemHandler;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.externalstorage.StorageFluidExternal;
|
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.externalstorage.StorageItemExternal;
|
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.readerwriter.ReaderWriterManager;
|
import com.raoulvdberge.refinedstorage.apiimpl.network.readerwriter.ReaderWriterManager;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.security.SecurityManager;
|
import com.raoulvdberge.refinedstorage.apiimpl.network.security.SecurityManager;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheFluid;
|
import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheFluid;
|
||||||
@@ -319,8 +318,8 @@ public class TileController extends TileBase implements ITickable, INetwork, IRe
|
|||||||
|
|
||||||
if (remainder == null) {
|
if (remainder == null) {
|
||||||
// The external storage is responsible for sending changes, we don't need to anymore
|
// The external storage is responsible for sending changes, we don't need to anymore
|
||||||
if (storage instanceof StorageItemExternal && !simulate) {
|
if (storage instanceof IStorageExternal && !simulate) {
|
||||||
((StorageItemExternal) storage).detectChanges(this);
|
((IStorageExternal) storage).update(this);
|
||||||
|
|
||||||
insertedExternally += size;
|
insertedExternally += size;
|
||||||
}
|
}
|
||||||
@@ -328,8 +327,8 @@ public class TileController extends TileBase implements ITickable, INetwork, IRe
|
|||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// The external storage is responsible for sending changes, we don't need to anymore
|
// The external storage is responsible for sending changes, we don't need to anymore
|
||||||
if (size != remainder.getCount() && storage instanceof StorageItemExternal && !simulate) {
|
if (size != remainder.getCount() && storage instanceof IStorageExternal && !simulate) {
|
||||||
((StorageItemExternal) storage).detectChanges(this);
|
((IStorageExternal) storage).update(this);
|
||||||
|
|
||||||
insertedExternally += size - remainder.getCount();
|
insertedExternally += size - remainder.getCount();
|
||||||
}
|
}
|
||||||
@@ -363,8 +362,8 @@ public class TileController extends TileBase implements ITickable, INetwork, IRe
|
|||||||
|
|
||||||
if (took != null) {
|
if (took != null) {
|
||||||
// The external storage is responsible for sending changes, we don't need to anymore
|
// The external storage is responsible for sending changes, we don't need to anymore
|
||||||
if (storage instanceof StorageItemExternal && !simulate) {
|
if (storage instanceof IStorageExternal && !simulate) {
|
||||||
((StorageItemExternal) storage).detectChanges(this);
|
((IStorageExternal) storage).update(this);
|
||||||
|
|
||||||
extractedExternally += took.getCount();
|
extractedExternally += took.getCount();
|
||||||
}
|
}
|
||||||
@@ -390,16 +389,17 @@ public class TileController extends TileBase implements ITickable, INetwork, IRe
|
|||||||
return newStack;
|
return newStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public FluidStack insertFluid(@Nonnull FluidStack stack, int size, boolean simulate) {
|
public FluidStack insertFluid(@Nonnull FluidStack stack, int size, boolean simulate) {
|
||||||
if (fluidStorage.getStorages().isEmpty()) {
|
if (stack == null || fluidStorage.getStorages().isEmpty()) {
|
||||||
return StackUtils.copy(stack, size);
|
return StackUtils.copy(stack, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
FluidStack remainder = stack;
|
FluidStack remainder = stack;
|
||||||
|
|
||||||
int inserted = 0;
|
int inserted = 0;
|
||||||
|
int insertedExternally = 0;
|
||||||
|
|
||||||
for (IStorage<FluidStack> storage : this.fluidStorage.getStorages()) {
|
for (IStorage<FluidStack> storage : this.fluidStorage.getStorages()) {
|
||||||
if (storage.getAccessType() == AccessType.EXTRACT) {
|
if (storage.getAccessType() == AccessType.EXTRACT) {
|
||||||
@@ -414,30 +414,41 @@ public class TileController extends TileBase implements ITickable, INetwork, IRe
|
|||||||
inserted += storage.getCacheDelta(storedPre, size, remainder);
|
inserted += storage.getCacheDelta(storedPre, size, remainder);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (storage instanceof StorageFluidExternal && !simulate) {
|
|
||||||
((StorageFluidExternal) storage).updateCacheForcefully();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remainder == null) {
|
if (remainder == null) {
|
||||||
|
// The external storage is responsible for sending changes, we don't need to anymore
|
||||||
|
if (storage instanceof IStorageExternal && !simulate) {
|
||||||
|
((IStorageExternal) storage).update(this);
|
||||||
|
|
||||||
|
insertedExternally += size;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
// The external storage is responsible for sending changes, we don't need to anymore
|
||||||
|
if (size != remainder.amount && storage instanceof IStorageExternal && !simulate) {
|
||||||
|
((IStorageExternal) storage).update(this);
|
||||||
|
|
||||||
|
insertedExternally += size - remainder.amount;
|
||||||
|
}
|
||||||
|
|
||||||
size = remainder.amount;
|
size = remainder.amount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inserted > 0) {
|
if (!simulate && inserted - insertedExternally > 0) {
|
||||||
fluidStorage.add(stack, inserted, false, false);
|
fluidStorage.add(stack, inserted - insertedExternally, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return remainder;
|
return remainder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public FluidStack extractFluid(@Nonnull FluidStack stack, int size, int flags, boolean simulate) {
|
public FluidStack extractFluid(@Nonnull FluidStack stack, int size, int flags, boolean simulate) {
|
||||||
int requested = size;
|
int requested = size;
|
||||||
int received = 0;
|
int received = 0;
|
||||||
|
|
||||||
|
int extractedExternally = 0;
|
||||||
|
|
||||||
FluidStack newStack = null;
|
FluidStack newStack = null;
|
||||||
|
|
||||||
for (IStorage<FluidStack> storage : this.fluidStorage.getStorages()) {
|
for (IStorage<FluidStack> storage : this.fluidStorage.getStorages()) {
|
||||||
@@ -448,8 +459,11 @@ public class TileController extends TileBase implements ITickable, INetwork, IRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (took != null) {
|
if (took != null) {
|
||||||
if (storage instanceof StorageFluidExternal && !simulate) {
|
// The external storage is responsible for sending changes, we don't need to anymore
|
||||||
((StorageFluidExternal) storage).updateCacheForcefully();
|
if (storage instanceof IStorageExternal && !simulate) {
|
||||||
|
((IStorageExternal) storage).update(this);
|
||||||
|
|
||||||
|
extractedExternally += took.amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newStack == null) {
|
if (newStack == null) {
|
||||||
@@ -466,8 +480,8 @@ public class TileController extends TileBase implements ITickable, INetwork, IRe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newStack != null && !simulate) {
|
if (newStack != null && newStack.amount - extractedExternally > 0 && !simulate) {
|
||||||
fluidStorage.remove(newStack, newStack.amount, false);
|
fluidStorage.remove(newStack, newStack.amount - extractedExternally, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newStack;
|
return newStack;
|
||||||
|
@@ -1,14 +1,15 @@
|
|||||||
package com.raoulvdberge.refinedstorage.tile;
|
package com.raoulvdberge.refinedstorage.tile;
|
||||||
|
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
|
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.externalstorage.NetworkNodeExternalStorage;
|
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IStorageExternal;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.externalstorage.StorageFluidExternal;
|
import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNodeExternalStorage;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.externalstorage.StorageItemExternal;
|
|
||||||
import com.raoulvdberge.refinedstorage.tile.config.*;
|
import com.raoulvdberge.refinedstorage.tile.config.*;
|
||||||
import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter;
|
import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.network.datasync.DataSerializers;
|
import net.minecraft.network.datasync.DataSerializers;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
@@ -21,11 +22,11 @@ public class TileExternalStorage extends TileNode<NetworkNodeExternalStorage> {
|
|||||||
public static final TileDataParameter<Integer, TileExternalStorage> STORED = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> {
|
public static final TileDataParameter<Integer, TileExternalStorage> STORED = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> {
|
||||||
int stored = 0;
|
int stored = 0;
|
||||||
|
|
||||||
for (StorageItemExternal storage : t.getNode().getItemStorages()) {
|
for (IStorageExternal<ItemStack> storage : t.getNode().getItemStorages()) {
|
||||||
stored += storage.getStored();
|
stored += storage.getStored();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (StorageFluidExternal storage : t.getNode().getFluidStorages()) {
|
for (IStorageExternal<FluidStack> storage : t.getNode().getFluidStorages()) {
|
||||||
stored += storage.getStored();
|
stored += storage.getStored();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,11 +35,11 @@ public class TileExternalStorage extends TileNode<NetworkNodeExternalStorage> {
|
|||||||
public static final TileDataParameter<Integer, TileExternalStorage> CAPACITY = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> {
|
public static final TileDataParameter<Integer, TileExternalStorage> CAPACITY = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> {
|
||||||
int capacity = 0;
|
int capacity = 0;
|
||||||
|
|
||||||
for (StorageItemExternal storage : t.getNode().getItemStorages()) {
|
for (IStorageExternal<ItemStack> storage : t.getNode().getItemStorages()) {
|
||||||
capacity += storage.getCapacity();
|
capacity += storage.getCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (StorageFluidExternal storage : t.getNode().getFluidStorages()) {
|
for (IStorageExternal<FluidStack> storage : t.getNode().getFluidStorages()) {
|
||||||
capacity += storage.getCapacity();
|
capacity += storage.getCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,7 +24,7 @@ public interface IFilterable {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean canTake(IItemHandler filters, int mode, int compare, ItemStack stack) {
|
static boolean acceptsItem(IItemHandler filters, int mode, int compare, ItemStack stack) {
|
||||||
if (mode == WHITELIST) {
|
if (mode == WHITELIST) {
|
||||||
for (int i = 0; i < filters.getSlots(); ++i) {
|
for (int i = 0; i < filters.getSlots(); ++i) {
|
||||||
ItemStack slot = filters.getStackInSlot(i);
|
ItemStack slot = filters.getStackInSlot(i);
|
||||||
@@ -50,7 +50,7 @@ public interface IFilterable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean canTakeFluids(ItemHandlerFluid filters, int mode, int compare, FluidStack stack) {
|
static boolean acceptsFluid(ItemHandlerFluid filters, int mode, int compare, FluidStack stack) {
|
||||||
if (mode == WHITELIST) {
|
if (mode == WHITELIST) {
|
||||||
for (int i = 0; i < filters.getSlots(); ++i) {
|
for (int i = 0; i < filters.getSlots(); ++i) {
|
||||||
FluidStack slot = filters.getFluidStackInSlot(i);
|
FluidStack slot = filters.getFluidStackInSlot(i);
|
||||||
|
@@ -10,10 +10,10 @@ import com.raoulvdberge.refinedstorage.api.network.grid.handler.IItemGridHandler
|
|||||||
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
|
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.IStorageCache;
|
import com.raoulvdberge.refinedstorage.api.storage.IStorageCache;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.IStorageCacheListener;
|
import com.raoulvdberge.refinedstorage.api.storage.IStorageCacheListener;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.storage.StorageType;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskContainerContext;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskContainerContext;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskProvider;
|
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskProvider;
|
||||||
import com.raoulvdberge.refinedstorage.api.storage.disk.StorageDiskType;
|
|
||||||
import com.raoulvdberge.refinedstorage.api.util.IFilter;
|
import com.raoulvdberge.refinedstorage.api.util.IFilter;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.ItemGridHandlerPortable;
|
import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.ItemGridHandlerPortable;
|
||||||
@@ -123,7 +123,7 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid,
|
|||||||
private List<IFilter> filters = new ArrayList<>();
|
private List<IFilter> filters = new ArrayList<>();
|
||||||
private List<IGridTab> tabs = new ArrayList<>();
|
private List<IGridTab> tabs = new ArrayList<>();
|
||||||
private ItemHandlerFilter filter = new ItemHandlerFilter(filters, tabs, new ItemHandlerListenerTile(this));
|
private ItemHandlerFilter filter = new ItemHandlerFilter(filters, tabs, new ItemHandlerListenerTile(this));
|
||||||
private ItemHandlerBase disk = new ItemHandlerBase(1, new ItemHandlerListenerTile(this), s -> NetworkNodeDiskDrive.VALIDATOR_STORAGE_DISK.test(s) && ((IStorageDiskProvider) s.getItem()).getType() == StorageDiskType.ITEM) {
|
private ItemHandlerBase disk = new ItemHandlerBase(1, new ItemHandlerListenerTile(this), s -> NetworkNodeDiskDrive.VALIDATOR_STORAGE_DISK.test(s) && ((IStorageDiskProvider) s.getItem()).getType() == StorageType.ITEM) {
|
||||||
@Override
|
@Override
|
||||||
protected void onContentsChanged(int slot) {
|
protected void onContentsChanged(int slot) {
|
||||||
super.onContentsChanged(slot);
|
super.onContentsChanged(slot);
|
||||||
|
Reference in New Issue
Block a user