(Fluid) interfaces now expose entire storage again + add subnetting.
This commit is contained in:
@@ -5,6 +5,10 @@
|
||||
- Added Crafting Upgrade support for fluids on the Exporter, Constructor and Fluid Interface (raoulvdberge)
|
||||
- Added support for JEI ghost slot dragging (raoulvdberge)
|
||||
- Added config option to hide covers in the creative mode tabs and JEI (raoulvdberge)
|
||||
- Added the ability to connect the External Storage to (Fluid) Interfaces of other networks, allowing subnetting (raoulvdberge)
|
||||
- The External Storage no longer lets a network connection through through its front face, to allow for subnetting (raoulvdberge)
|
||||
- An empty Interface now exposes the entire item storage again (raoulvdberge)
|
||||
- An empty Fluid Interface now exposes the entire fluid storage (raoulvdberge)
|
||||
- Removed "emit signal when item is being autocrafted" option in the Detector (raoulvdberge)
|
||||
- The Crafting Card no longer schedules requests when there are items or fluids missing (raoulvdberge)
|
||||
- You can now keep fluids in stock by attaching a External Storage in fluid mode to a Fluid Interface with a Crafting Upgrade (raoulvdberge)
|
||||
|
@@ -25,7 +25,7 @@ public interface IStorageCache<T> {
|
||||
* Adds a stack to the cache.
|
||||
* <p>
|
||||
* Note that this doesn't modify any of the connected storages, but just modifies the cache.
|
||||
* Use {@link IStorage#insert(T, int, boolean)} to add a stack to an actual storage.
|
||||
* Use {@link IStorage#insert(T, int, com.raoulvdberge.refinedstorage.api.util.Action)} to add a stack to an actual storage.
|
||||
* <p>
|
||||
* Will merge it with another stack if it already exists.
|
||||
*
|
||||
@@ -40,7 +40,7 @@ public interface IStorageCache<T> {
|
||||
* Removes a stack from the cache.
|
||||
* <p>
|
||||
* Note that this doesn't modify any of the connected storages, but just modifies the cache.
|
||||
* Use {@link IStorage#extract(T, int, int, boolean)} to remove a stack from an actual storage.
|
||||
* Use {@link IStorage#extract(T, int, int, com.raoulvdberge.refinedstorage.api.util.Action)} to remove a stack from an actual storage.
|
||||
*
|
||||
* @param stack the stack to remove, do NOT modify
|
||||
* @param size the size to remove
|
||||
|
@@ -2,7 +2,7 @@ package com.raoulvdberge.refinedstorage.api.util;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A stack list.
|
||||
@@ -21,9 +21,7 @@ public interface IStackList<T> {
|
||||
*
|
||||
* @param stack the stack
|
||||
*/
|
||||
default void add(@Nonnull T stack) {
|
||||
add(stack, getSizeFromStack(stack));
|
||||
}
|
||||
void add(@Nonnull T stack);
|
||||
|
||||
/**
|
||||
* Decrements the count of that stack in the list.
|
||||
@@ -40,9 +38,7 @@ public interface IStackList<T> {
|
||||
* @param stack the stack
|
||||
* @return true if the remove was successful for the full amount, false otherwise
|
||||
*/
|
||||
default boolean remove(@Nonnull T stack) {
|
||||
return remove(stack, getSizeFromStack(stack));
|
||||
}
|
||||
boolean remove(@Nonnull T stack);
|
||||
|
||||
/**
|
||||
* Returns a stack.
|
||||
@@ -85,16 +81,10 @@ public interface IStackList<T> {
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* @param stack the stack
|
||||
* @return the size of the stack
|
||||
*/
|
||||
int getSizeFromStack(T stack);
|
||||
|
||||
/**
|
||||
* @return a collection of stacks in this list
|
||||
* @return a list of stacks in this list
|
||||
*/
|
||||
@Nonnull
|
||||
Collection<T> getStacks();
|
||||
List<T> getStacks();
|
||||
|
||||
/**
|
||||
* @return a new copy of this list, with the stacks in it copied as well
|
||||
|
@@ -214,7 +214,20 @@ public abstract class NetworkNode implements INetworkNode, INetworkNodeVisitor {
|
||||
return world;
|
||||
}
|
||||
|
||||
public boolean canConductThroughFace() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean canConduct(@Nullable EnumFacing direction) {
|
||||
if (direction == getDirection() && !canConductThroughFace()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
INetworkNode faceNode = API.instance().getNetworkNodeManager(world).getNode(pos.offset(direction));
|
||||
if (faceNode instanceof NetworkNode && !((NetworkNode) faceNode).canConductThroughFace() && direction == ((NetworkNode) faceNode).getDirection().getOpposite()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -39,7 +39,7 @@ public class NetworkNodeCable extends NetworkNode implements ICoverable {
|
||||
|
||||
@Override
|
||||
public boolean canConduct(@Nullable EnumFacing direction) {
|
||||
return coverManager.canConduct(direction);
|
||||
return coverManager.canConduct(direction) && super.canConduct(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -354,7 +354,7 @@ public class NetworkNodeConstructor extends NetworkNode implements IComparable,
|
||||
|
||||
@Override
|
||||
public boolean canConduct(@Nullable EnumFacing direction) {
|
||||
return coverManager.canConduct(direction);
|
||||
return coverManager.canConduct(direction) && super.canConduct(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -330,7 +330,7 @@ public class NetworkNodeDestructor extends NetworkNode implements IComparable, I
|
||||
|
||||
@Override
|
||||
public boolean canConduct(@Nullable EnumFacing direction) {
|
||||
return coverManager.canConduct(direction);
|
||||
return coverManager.canConduct(direction) && super.canConduct(direction);
|
||||
}
|
||||
|
||||
public boolean isPickupItem() {
|
||||
|
@@ -258,7 +258,7 @@ public class NetworkNodeExporter extends NetworkNode implements IComparable, ITy
|
||||
|
||||
@Override
|
||||
public boolean canConduct(@Nullable EnumFacing direction) {
|
||||
return coverManager.canConduct(direction);
|
||||
return coverManager.canConduct(direction) && super.canConduct(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -366,7 +366,12 @@ public class NetworkNodeExternalStorage extends NetworkNode implements IStorageP
|
||||
|
||||
@Override
|
||||
public boolean canConduct(@Nullable EnumFacing direction) {
|
||||
return coverManager.canConduct(direction);
|
||||
return coverManager.canConduct(direction) && super.canConduct(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canConductThroughFace() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@@ -7,6 +7,7 @@ import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.externalstorage.StorageExternalFluid;
|
||||
import com.raoulvdberge.refinedstorage.inventory.fluid.FluidHandlerFluidInterface;
|
||||
import com.raoulvdberge.refinedstorage.inventory.fluid.FluidHandlerProxy;
|
||||
import com.raoulvdberge.refinedstorage.inventory.fluid.FluidInventory;
|
||||
import com.raoulvdberge.refinedstorage.inventory.item.ItemHandlerBase;
|
||||
import com.raoulvdberge.refinedstorage.inventory.item.ItemHandlerUpgrade;
|
||||
@@ -23,6 +24,7 @@ import net.minecraft.world.World;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.FluidTank;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
@@ -50,7 +52,8 @@ public class NetworkNodeFluidInterface extends NetworkNode {
|
||||
};
|
||||
private FluidTank tankOut = new FluidTank(TANK_CAPACITY);
|
||||
|
||||
private FluidHandlerFluidInterface tank = new FluidHandlerFluidInterface(tankIn, tankOut);
|
||||
private FluidHandlerProxy tank = new FluidHandlerProxy(tankIn, tankOut);
|
||||
private FluidHandlerFluidInterface fluids = new FluidHandlerFluidInterface(this);
|
||||
|
||||
private ItemHandlerBase in = new ItemHandlerBase(1, new ListenerNetworkNode(this), stack -> StackUtils.getFluid(stack, true).getRight() != null);
|
||||
private FluidInventory out = new FluidInventory(1, TANK_CAPACITY, new ListenerNetworkNode(this));
|
||||
@@ -245,8 +248,8 @@ public class NetworkNodeFluidInterface extends NetworkNode {
|
||||
return out;
|
||||
}
|
||||
|
||||
public FluidHandlerFluidInterface getTank() {
|
||||
return tank;
|
||||
public IFluidHandler getTank() {
|
||||
return out.getFluid(0) == null ? fluids : tank;
|
||||
}
|
||||
|
||||
public FluidTank getTankIn() {
|
||||
|
@@ -231,7 +231,7 @@ public class NetworkNodeImporter extends NetworkNode implements IComparable, IFi
|
||||
|
||||
@Override
|
||||
public boolean canConduct(@Nullable EnumFacing direction) {
|
||||
return coverManager.canConduct(direction);
|
||||
return coverManager.canConduct(direction) && super.canConduct(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -7,6 +7,7 @@ import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.externalstorage.StorageExternalItem;
|
||||
import com.raoulvdberge.refinedstorage.inventory.item.ItemHandlerBase;
|
||||
import com.raoulvdberge.refinedstorage.inventory.item.ItemHandlerInterface;
|
||||
import com.raoulvdberge.refinedstorage.inventory.item.ItemHandlerProxy;
|
||||
import com.raoulvdberge.refinedstorage.inventory.item.ItemHandlerUpgrade;
|
||||
import com.raoulvdberge.refinedstorage.inventory.listener.ListenerNetworkNode;
|
||||
@@ -34,6 +35,8 @@ public class NetworkNodeInterface extends NetworkNode implements IComparable {
|
||||
|
||||
private IItemHandler items = new ItemHandlerProxy(importItems, exportItems);
|
||||
|
||||
private ItemHandlerInterface networkItems = new ItemHandlerInterface(this);
|
||||
|
||||
private ItemHandlerUpgrade upgrades = new ItemHandlerUpgrade(4, new ListenerNetworkNode(this), ItemUpgrade.TYPE_SPEED, ItemUpgrade.TYPE_STACK, ItemUpgrade.TYPE_CRAFTING);
|
||||
|
||||
private int compare = IComparer.COMPARE_NBT | IComparer.COMPARE_DAMAGE;
|
||||
@@ -221,7 +224,7 @@ public class NetworkNodeInterface extends NetworkNode implements IComparable {
|
||||
}
|
||||
|
||||
public IItemHandler getItems() {
|
||||
return items;
|
||||
return exportFilterItems.isEmpty() ? networkItems : items;
|
||||
}
|
||||
|
||||
public IItemHandler getUpgrades() {
|
||||
|
@@ -98,7 +98,7 @@ public class NetworkNodeReader extends NetworkNode implements IReader, IGuiReade
|
||||
|
||||
@Override
|
||||
public boolean canConduct(@Nullable EnumFacing direction) {
|
||||
return coverManager.canConduct(direction);
|
||||
return coverManager.canConduct(direction) && super.canConduct(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -39,7 +39,7 @@ public class NetworkNodeRelay extends NetworkNode {
|
||||
|
||||
@Override
|
||||
public boolean canConduct(@Nullable EnumFacing direction) {
|
||||
return canUpdate();
|
||||
return canUpdate() && super.canConduct(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -130,7 +130,7 @@ public class NetworkNodeWriter extends NetworkNode implements IWriter, IGuiReade
|
||||
|
||||
@Override
|
||||
public boolean canConduct(@Nullable EnumFacing direction) {
|
||||
return coverManager.canConduct(direction);
|
||||
return coverManager.canConduct(direction) && super.canConduct(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -232,7 +232,7 @@ public class NetworkNodeDiskManipulator extends NetworkNode implements IComparab
|
||||
ItemStack extracted = null;
|
||||
int i = 0;
|
||||
|
||||
if (IFilterable.isEmpty(itemFilters)) {
|
||||
if (itemFilters.isEmpty()) {
|
||||
ItemStack toExtract = null;
|
||||
ArrayList<ItemStack> networkItems = new ArrayList<>(network.getItemStorageCache().getList().getStacks());
|
||||
|
||||
@@ -331,7 +331,7 @@ public class NetworkNodeDiskManipulator extends NetworkNode implements IComparab
|
||||
FluidStack extracted = null;
|
||||
int i = 0;
|
||||
|
||||
if (IFilterable.isEmpty(itemFilters)) {
|
||||
if (fluidFilters.isEmpty()) {
|
||||
FluidStack toExtract = null;
|
||||
ArrayList<FluidStack> networkFluids = new ArrayList<>(network.getFluidStorageCache().getList().getStacks());
|
||||
|
||||
|
@@ -10,6 +10,7 @@ import com.raoulvdberge.refinedstorage.apiimpl.network.node.storage.NetworkNodeF
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.storage.NetworkNodeStorage;
|
||||
import com.raoulvdberge.refinedstorage.block.enums.FluidStorageType;
|
||||
import com.raoulvdberge.refinedstorage.block.enums.ItemStorageType;
|
||||
import com.raoulvdberge.refinedstorage.inventory.item.ItemHandlerBase;
|
||||
import com.raoulvdberge.refinedstorage.item.ItemPattern;
|
||||
import com.raoulvdberge.refinedstorage.tile.config.IFilterable;
|
||||
import net.minecraft.item.Item;
|
||||
@@ -205,10 +206,10 @@ public class OneSixMigrationHelper implements IOneSixMigrationHelper {
|
||||
public static void removalHook() {
|
||||
}
|
||||
|
||||
public static void migrateEmptyWhitelistToEmptyBlacklist(String version, IFilterable filterable, @Nullable IItemHandler itemFilterInv) {
|
||||
public static void migrateEmptyWhitelistToEmptyBlacklist(String version, IFilterable filterable, @Nullable ItemHandlerBase itemFilterInv) {
|
||||
// Only migrate if we come from a version where the RS version tag stuff in NetworkNode wasn't added yet.
|
||||
// Otherwise, we would constantly migrate empty whitelists to empty blacklists...
|
||||
if (version == null && filterable.getMode() == IFilterable.WHITELIST && IFilterable.isEmpty(itemFilterInv)) {
|
||||
if (version == null && filterable.getMode() == IFilterable.WHITELIST && (itemFilterInv == null || itemFilterInv.isEmpty())) {
|
||||
filterable.setMode(IFilter.MODE_BLACKLIST);
|
||||
}
|
||||
}
|
||||
|
@@ -1,24 +1,24 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.util;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.util.MultiMap;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class StackListFluid implements IStackList<FluidStack> {
|
||||
private ArrayListMultimap<Fluid, FluidStack> stacks = ArrayListMultimap.create();
|
||||
private MultiMap<Fluid, FluidStack> stacks = new MultiMap<>();
|
||||
|
||||
@Override
|
||||
public void add(@Nonnull FluidStack stack, int size) {
|
||||
if (stack == null || size < 0) {
|
||||
throw new IllegalArgumentException("Cannot accept empty stack");
|
||||
}
|
||||
|
||||
|
||||
for (FluidStack otherStack : stacks.get(stack.getFluid())) {
|
||||
if (stack.isFluidEqual(otherStack)) {
|
||||
if ((long) otherStack.amount + (long) size > Integer.MAX_VALUE) {
|
||||
@@ -36,6 +36,11 @@ public class StackListFluid implements IStackList<FluidStack> {
|
||||
stacks.put(stack.getFluid(), newStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(@Nonnull FluidStack stack) {
|
||||
add(stack, stack.amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(@Nonnull FluidStack stack, int size) {
|
||||
for (FluidStack otherStack : stacks.get(stack.getFluid())) {
|
||||
@@ -55,6 +60,11 @@ public class StackListFluid implements IStackList<FluidStack> {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(@Nonnull FluidStack stack) {
|
||||
return remove(stack, stack.amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public FluidStack get(@Nonnull FluidStack stack, int flags) {
|
||||
@@ -89,14 +99,9 @@ public class StackListFluid implements IStackList<FluidStack> {
|
||||
return stacks.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSizeFromStack(FluidStack stack) {
|
||||
return stack.amount;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Collection<FluidStack> getStacks() {
|
||||
public List<FluidStack> getStacks() {
|
||||
return stacks.values();
|
||||
}
|
||||
|
||||
|
@@ -1,18 +1,18 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.util;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.util.MultiMap;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class StackListItem implements IStackList<ItemStack> {
|
||||
private ArrayListMultimap<Item, ItemStack> stacks = ArrayListMultimap.create();
|
||||
private MultiMap<Item, ItemStack> stacks = new MultiMap<>();
|
||||
|
||||
@Override
|
||||
public void add(@Nonnull ItemStack stack, int size) {
|
||||
@@ -35,6 +35,11 @@ public class StackListItem implements IStackList<ItemStack> {
|
||||
stacks.put(stack.getItem(), ItemHandlerHelper.copyStackWithSize(stack, size));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(@Nonnull ItemStack stack) {
|
||||
add(stack, stack.getCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(@Nonnull ItemStack stack, int size) {
|
||||
for (ItemStack otherStack : stacks.get(stack.getItem())) {
|
||||
@@ -54,6 +59,11 @@ public class StackListItem implements IStackList<ItemStack> {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(@Nonnull ItemStack stack) {
|
||||
return remove(stack, stack.getCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ItemStack get(@Nonnull ItemStack stack, int flags) {
|
||||
@@ -88,14 +98,9 @@ public class StackListItem implements IStackList<ItemStack> {
|
||||
return stacks.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSizeFromStack(ItemStack stack) {
|
||||
return stack.getCount();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Collection<ItemStack> getStacks() {
|
||||
public List<ItemStack> getStacks() {
|
||||
return stacks.values();
|
||||
}
|
||||
|
||||
|
@@ -1,46 +1,131 @@
|
||||
package com.raoulvdberge.refinedstorage.inventory.fluid;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.api.util.Action;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.FluidTank;
|
||||
import net.minecraftforge.fluids.capability.FluidTankPropertiesWrapper;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.IFluidTankProperties;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public class FluidHandlerFluidInterface implements IFluidHandler {
|
||||
private FluidTank input;
|
||||
private FluidTank output;
|
||||
private IFluidTankProperties[] properties;
|
||||
private static final IFluidTankProperties[] NO_PROPS = new IFluidTankProperties[0];
|
||||
|
||||
public FluidHandlerFluidInterface(FluidTank input, FluidTank output) {
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
this.properties = new IFluidTankProperties[]{
|
||||
new FluidTankPropertiesWrapper(input),
|
||||
new FluidTankPropertiesWrapper(output)
|
||||
};
|
||||
private INetworkNode node;
|
||||
|
||||
public FluidHandlerFluidInterface(INetworkNode node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private INetwork getNetwork() {
|
||||
if (node.getNetwork() != null && node.canUpdate()) {
|
||||
return node.getNetwork();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFluidTankProperties[] getTankProperties() {
|
||||
return properties;
|
||||
INetwork network = getNetwork();
|
||||
|
||||
if (network == null) {
|
||||
return NO_PROPS;
|
||||
}
|
||||
|
||||
List<FluidStack> stacks = network.getFluidStorageCache().getList().getStacks();
|
||||
|
||||
if (stacks.isEmpty()) {
|
||||
return NO_PROPS;
|
||||
}
|
||||
|
||||
IFluidTankProperties[] props = new IFluidTankProperties[stacks.size()];
|
||||
|
||||
for (int i = 0; i < stacks.size(); ++i) {
|
||||
FluidStack stack = stacks.get(i);
|
||||
|
||||
props[i] = new IFluidTankProperties() {
|
||||
@Nullable
|
||||
@Override
|
||||
public FluidStack getContents() {
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCapacity() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canFill() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDrain() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canFillFluidType(FluidStack fluidStack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDrainFluidType(FluidStack fluidStack) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fill(FluidStack resource, boolean doFill) {
|
||||
return input.fill(resource, doFill);
|
||||
INetwork network = getNetwork();
|
||||
|
||||
if (network != null) {
|
||||
FluidStack remainder = network.insertFluid(resource, resource.amount, doFill ? Action.PERFORM : Action.SIMULATE);
|
||||
|
||||
return remainder == null ? resource.amount : resource.amount - remainder.amount;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FluidStack drain(FluidStack resource, boolean doDrain) {
|
||||
return output.drain(resource, doDrain);
|
||||
INetwork network = getNetwork();
|
||||
|
||||
if (network != null) {
|
||||
return network.extractFluid(resource, resource.amount, doDrain ? Action.PERFORM : Action.SIMULATE);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FluidStack drain(int maxDrain, boolean doDrain) {
|
||||
return output.drain(maxDrain, doDrain);
|
||||
INetwork network = getNetwork();
|
||||
|
||||
if (network != null) {
|
||||
List<FluidStack> fluids = network.getFluidStorageCache().getList().getStacks();
|
||||
|
||||
if (fluids.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
FluidStack firstFluid = fluids.get(0);
|
||||
|
||||
return network.extractFluid(firstFluid, Math.min(firstFluid.amount, maxDrain), doDrain ? Action.PERFORM : Action.SIMULATE);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,46 @@
|
||||
package com.raoulvdberge.refinedstorage.inventory.fluid;
|
||||
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.FluidTank;
|
||||
import net.minecraftforge.fluids.capability.FluidTankPropertiesWrapper;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.IFluidTankProperties;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class FluidHandlerProxy implements IFluidHandler {
|
||||
private FluidTank insertHandler;
|
||||
private FluidTank extractHandler;
|
||||
private IFluidTankProperties[] properties;
|
||||
|
||||
public FluidHandlerProxy(FluidTank insertHandler, FluidTank extractHandler) {
|
||||
this.insertHandler = insertHandler;
|
||||
this.extractHandler = extractHandler;
|
||||
this.properties = new IFluidTankProperties[]{
|
||||
new FluidTankPropertiesWrapper(insertHandler),
|
||||
new FluidTankPropertiesWrapper(extractHandler)
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFluidTankProperties[] getTankProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fill(FluidStack resource, boolean doFill) {
|
||||
return insertHandler.fill(resource, doFill);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FluidStack drain(FluidStack resource, boolean doDrain) {
|
||||
return extractHandler.drain(resource, doDrain);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FluidStack drain(int maxDrain, boolean doDrain) {
|
||||
return extractHandler.drain(maxDrain, doDrain);
|
||||
}
|
||||
}
|
@@ -11,6 +11,7 @@ public class FluidInventory {
|
||||
|
||||
private FluidStack[] fluids;
|
||||
private int maxAmount;
|
||||
private boolean empty = true;
|
||||
|
||||
@Nullable
|
||||
private Consumer<Integer> listener;
|
||||
@@ -56,6 +57,24 @@ public class FluidInventory {
|
||||
if (listener != null) {
|
||||
listener.accept(slot);
|
||||
}
|
||||
|
||||
updateEmptyState();
|
||||
}
|
||||
|
||||
private void updateEmptyState() {
|
||||
this.empty = true;
|
||||
|
||||
for (FluidStack fluid : fluids) {
|
||||
if (fluid != null) {
|
||||
this.empty = false;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return empty;
|
||||
}
|
||||
|
||||
public NBTTagCompound writeToNbt() {
|
||||
@@ -80,5 +99,7 @@ public class FluidInventory {
|
||||
fluids[i] = FluidStack.loadFluidStackFromNBT(tag.getCompoundTag(key));
|
||||
}
|
||||
}
|
||||
|
||||
updateEmptyState();
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package com.raoulvdberge.refinedstorage.inventory.item;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@@ -27,15 +28,6 @@ public class ItemHandlerBase extends ItemStackHandler {
|
||||
this(size, null, validators);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStackInSlot(int slot, @Nonnull ItemStack stack) {
|
||||
validateSlotIndex(slot);
|
||||
|
||||
stacks.set(slot, stack);
|
||||
|
||||
onContentsChanged(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
|
||||
@@ -63,6 +55,13 @@ public class ItemHandlerBase extends ItemStackHandler {
|
||||
this.empty = stacks.stream().allMatch(ItemStack::isEmpty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserializeNBT(NBTTagCompound tag) {
|
||||
super.deserializeNBT(tag);
|
||||
|
||||
this.empty = stacks.stream().allMatch(ItemStack::isEmpty);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return empty;
|
||||
}
|
||||
|
@@ -0,0 +1,88 @@
|
||||
package com.raoulvdberge.refinedstorage.inventory.item;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.api.util.Action;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public class ItemHandlerInterface implements IItemHandler {
|
||||
private INetworkNode node;
|
||||
|
||||
public ItemHandlerInterface(INetworkNode node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private INetwork getNetwork() {
|
||||
if (node.getNetwork() != null && node.canUpdate()) {
|
||||
return node.getNetwork();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlots() {
|
||||
INetwork network = getNetwork();
|
||||
|
||||
if (network != null) {
|
||||
// One additional slot for possible input.
|
||||
return network.getItemStorageCache().getList().getStacks().size() + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot) {
|
||||
INetwork network = getNetwork();
|
||||
|
||||
if (network != null) {
|
||||
List<ItemStack> stacks = network.getItemStorageCache().getList().getStacks();
|
||||
|
||||
if (slot < stacks.size()) {
|
||||
return stacks.get(slot);
|
||||
}
|
||||
}
|
||||
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
|
||||
INetwork network = getNetwork();
|
||||
|
||||
if (network != null) {
|
||||
return StackUtils.nullToEmpty(network.insertItem(stack, stack.getCount(), simulate ? Action.SIMULATE : Action.PERFORM));
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||
INetwork network = getNetwork();
|
||||
|
||||
if (network != null) {
|
||||
ItemStack stack = getStackInSlot(slot);
|
||||
|
||||
return StackUtils.nullToEmpty(network.extractItem(stack, Math.min(amount, 64), simulate ? Action.SIMULATE : Action.PERFORM));
|
||||
}
|
||||
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlotLimit(int slot) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
package com.raoulvdberge.refinedstorage.inventory.item;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.util.Action;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.tile.grid.portable.TilePortableGrid;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
|
||||
public class ItemHandlerPortableGrid implements IItemHandler {
|
||||
private TilePortableGrid portableGrid;
|
||||
|
||||
public ItemHandlerPortableGrid(TilePortableGrid portableGrid) {
|
||||
this.portableGrid = portableGrid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlots() {
|
||||
if (portableGrid.getStorageCache() != null) {
|
||||
// One additional slot for possible input.
|
||||
return portableGrid.getStorageCache().getList().getStacks().size() + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot) {
|
||||
if (portableGrid.getStorageCache() != null) {
|
||||
List<ItemStack> stacks = portableGrid.getStorageCache().getList().getStacks();
|
||||
|
||||
if (slot < stacks.size()) {
|
||||
return stacks.get(slot);
|
||||
}
|
||||
}
|
||||
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
|
||||
if (portableGrid.getStorage() != null) {
|
||||
return StackUtils.nullToEmpty(portableGrid.getStorage().insert(stack, stack.getCount(), simulate ? Action.SIMULATE : Action.PERFORM));
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||
if (portableGrid.getStorage() != null) {
|
||||
ItemStack stack = getStackInSlot(slot);
|
||||
|
||||
return StackUtils.nullToEmpty(portableGrid.getStorage().extract(stack, stack.getCount(), IComparer.COMPARE_NBT | IComparer.COMPARE_DAMAGE, simulate ? Action.SIMULATE : Action.PERFORM));
|
||||
}
|
||||
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlotLimit(int slot) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
@@ -10,8 +10,6 @@ import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface IFilterable {
|
||||
int WHITELIST = 0;
|
||||
int BLACKLIST = 1;
|
||||
@@ -76,20 +74,6 @@ public interface IFilterable {
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean isEmpty(@Nullable IItemHandler filter) {
|
||||
if (filter == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < filter.getSlots(); i++) {
|
||||
if (!filter.getStackInSlot(i).isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void setMode(int mode);
|
||||
|
||||
int getMode();
|
||||
|
@@ -30,6 +30,7 @@ import com.raoulvdberge.refinedstorage.gui.GuiBase;
|
||||
import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid;
|
||||
import com.raoulvdberge.refinedstorage.inventory.item.ItemHandlerBase;
|
||||
import com.raoulvdberge.refinedstorage.inventory.item.ItemHandlerFilter;
|
||||
import com.raoulvdberge.refinedstorage.inventory.item.ItemHandlerPortableGrid;
|
||||
import com.raoulvdberge.refinedstorage.inventory.listener.ListenerTile;
|
||||
import com.raoulvdberge.refinedstorage.item.ItemWirelessGrid;
|
||||
import com.raoulvdberge.refinedstorage.item.itemblock.ItemBlockPortableGrid;
|
||||
@@ -55,6 +56,7 @@ import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.energy.CapabilityEnergy;
|
||||
import net.minecraftforge.energy.EnergyStorage;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@@ -142,6 +144,7 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid,
|
||||
private ItemGridHandlerPortable handler = new ItemGridHandlerPortable(this, this);
|
||||
private PortableGridDiskState diskState = PortableGridDiskState.NONE;
|
||||
private boolean connected;
|
||||
private ItemHandlerPortableGrid items = new ItemHandlerPortableGrid(this);
|
||||
|
||||
private StorageTrackerItem storageTracker = new StorageTrackerItem(this::markDirty);
|
||||
|
||||
@@ -626,13 +629,19 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid,
|
||||
|
||||
@Override
|
||||
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) {
|
||||
return capability == CapabilityEnergy.ENERGY || super.hasCapability(capability, facing);
|
||||
return capability == CapabilityEnergy.ENERGY || capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing) {
|
||||
return capability == CapabilityEnergy.ENERGY ? CapabilityEnergy.ENERGY.cast(energyStorage) : super.getCapability(capability, facing);
|
||||
if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
|
||||
return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.cast(items);
|
||||
} else if (capability == CapabilityEnergy.ENERGY) {
|
||||
return CapabilityEnergy.ENERGY.cast(energyStorage);
|
||||
}
|
||||
|
||||
return super.getCapability(capability, facing);
|
||||
}
|
||||
|
||||
public void onOpened() {
|
||||
|
@@ -0,0 +1,54 @@
|
||||
package com.raoulvdberge.refinedstorage.util;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class MultiMap<K, V> {
|
||||
private Map<K, List<V>> map = new HashMap<>();
|
||||
private List<V> allValues = new ArrayList<>();
|
||||
|
||||
public List<V> get(K key) {
|
||||
List<V> values = map.get(key);
|
||||
|
||||
if (values == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
public void put(K key, V value) {
|
||||
List<V> values = map.computeIfAbsent(key, k -> new ArrayList<>());
|
||||
|
||||
allValues.add(value);
|
||||
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
public void remove(K key, V value) {
|
||||
List<V> values = map.get(key);
|
||||
|
||||
if (values != null) {
|
||||
values.remove(value);
|
||||
|
||||
if (values.isEmpty()) {
|
||||
map.remove(key);
|
||||
}
|
||||
|
||||
allValues.remove(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
map.clear();
|
||||
|
||||
allValues.clear();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
public List<V> values() {
|
||||
return allValues;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user