Added fluid autocrafting, not finished yet. #461

This commit is contained in:
raoulvdberge
2018-07-22 17:07:48 +02:00
parent 5a595c9120
commit 26d36b0d65
81 changed files with 1680 additions and 409 deletions

View File

@@ -5,6 +5,8 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftin
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElementRegistry;
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElementRegistry;
import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskRegistry;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingRequestInfo;
import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.api.network.grid.wireless.IWirelessGridFactory;
import com.raoulvdberge.refinedstorage.api.network.grid.wireless.IWirelessGridRegistry;
@@ -25,6 +27,7 @@ import com.raoulvdberge.refinedstorage.api.util.IQuantityFormatter;
import com.raoulvdberge.refinedstorage.api.util.IStackList;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -171,6 +174,30 @@ public interface IRSAPI {
@Nonnull
IStorageDisk<FluidStack> createDefaultFluidDisk(World world, int capacity);
/**
* Creates crafting request info for an item.
*
* @param stack the stack
* @return the request info
*/
ICraftingRequestInfo createCraftingRequestInfo(ItemStack stack);
/**
* Creates crafting request info for a fluid.
*
* @param stack the stack
* @return the request info
*/
ICraftingRequestInfo createCraftingRequestInfo(FluidStack stack);
/**
* Creates crafting request info from NBT.
*
* @param tag the nbt tag
* @return the request info
*/
ICraftingRequestInfo createCraftingRequestInfo(NBTTagCompound tag) throws CraftingTaskReadException;
/**
* Returns a helper for the 1.6.x migration.
* Will be removed in 1.7.x!

View File

@@ -4,6 +4,7 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftin
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.items.IItemHandlerModifiable;
import javax.annotation.Nonnull;
@@ -60,6 +61,16 @@ public interface ICraftingManager {
@Nullable
ICraftingTask create(ItemStack stack, int quantity);
/**
* Creates a crafting task for a given stack, but doesn't add it to the list.
*
* @param stack the stack to craft
* @param quantity the quantity to craft
* @return the crafting task, or null if no pattern was found for the given stack
*/
@Nullable
ICraftingTask create(FluidStack stack, int quantity);
/**
* @return a new pattern chain list
*/
@@ -82,6 +93,13 @@ public interface ICraftingManager {
*/
void track(ItemStack stack, int size);
/**
* Tracks an incoming stack.
*
* @param stack the stack
*/
void track(FluidStack stack, int size);
/**
* @return a list of crafting patterns in this network, do NOT modify this list
*/
@@ -101,6 +119,15 @@ public interface ICraftingManager {
@Nullable
ICraftingPattern getPattern(ItemStack pattern);
/**
* Return a crafting pattern from a fluid stack.
*
* @param pattern the stack to get a pattern for
* @return the crafting pattern, or null if none is found
*/
@Nullable
ICraftingPattern getPattern(FluidStack pattern);
/**
* Updates the tasks in this manager.
*/

View File

@@ -2,6 +2,7 @@ package com.raoulvdberge.refinedstorage.api.autocrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.util.NonNullList;
import net.minecraftforge.fluids.FluidStack;
import java.util.List;
@@ -61,6 +62,10 @@ public interface ICraftingPattern {
*/
NonNullList<ItemStack> getByproducts(NonNullList<ItemStack> took);
NonNullList<FluidStack> getFluidInputs();
NonNullList<FluidStack> getFluidOutputs();
/**
* @return the id of the factory that creates a crafting task for this pattern, as defined in the {@link com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskRegistry}
*/

View File

@@ -3,6 +3,7 @@ package com.raoulvdberge.refinedstorage.api.autocrafting;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
@@ -25,6 +26,9 @@ public interface ICraftingPatternContainer {
@Nullable
IItemHandler getConnectedInventory();
@Nullable
IFluidHandler getConnectedFluidInventory();
/**
* @return the tile that this container is connected to, or null if no tile is present
*/

View File

@@ -2,9 +2,9 @@ package com.raoulvdberge.refinedstorage.api.autocrafting.registry;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingRequestInfo;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
import com.raoulvdberge.refinedstorage.api.network.INetwork;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import javax.annotation.Nonnull;
@@ -17,14 +17,14 @@ public interface ICraftingTaskFactory {
/**
* Returns a crafting task for a given pattern.
*
* @param network the network
* @param stack the stack to create a task for
* @param pattern the pattern
* @param quantity the quantity
* @param network the network
* @param requested the request info
* @param pattern the pattern
* @param quantity the quantity
* @return the crafting task
*/
@Nonnull
ICraftingTask create(INetwork network, ItemStack stack, int quantity, ICraftingPattern pattern);
ICraftingTask create(INetwork network, ICraftingRequestInfo requested, int quantity, ICraftingPattern pattern);
/**
* Returns a crafting task for a given NBT tag.

View File

@@ -0,0 +1,29 @@
package com.raoulvdberge.refinedstorage.api.autocrafting.task;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
/**
* Contains information about a crafting request.
*/
public interface ICraftingRequestInfo {
/**
* @return the item requested, or null if no item was requested
*/
@Nullable
ItemStack getItem();
/**
* @return the fluid requested, or null if no fluid was requested
*/
@Nullable
FluidStack getFluid();
/**
* @return the written tag
*/
NBTTagCompound writeToNbt();
}

View File

@@ -6,6 +6,7 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreview
import com.raoulvdberge.refinedstorage.api.util.IStackList;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
import java.util.List;
@@ -44,7 +45,7 @@ public interface ICraftingTask {
/**
* @return the stack requested
*/
ItemStack getRequested();
ICraftingRequestInfo getRequested();
/**
* Called when a stack is inserted into the system through {@link com.raoulvdberge.refinedstorage.api.network.INetwork#insertItemTracked(ItemStack, int)}.
@@ -52,7 +53,15 @@ public interface ICraftingTask {
* @param stack the stack
* @return the size remaining, decremented by the crafting task when it was relevant to it
*/
int onTrackedItemInserted(ItemStack stack, int size);
int onTrackedInsert(ItemStack stack, int size);
/**
* Called when a stack is inserted into the system through {@link com.raoulvdberge.refinedstorage.api.network.INetwork#insertFluidTracked(FluidStack, int)}.
*
* @param stack the stack
* @return the size remaining, decremented by the crafting task when it was relevant to it
*/
int onTrackedInsert(FluidStack stack, int size);
/**
* Writes this task to NBT.

View File

@@ -167,6 +167,16 @@ public interface INetwork {
@Nullable
FluidStack insertFluid(@Nonnull FluidStack stack, int size, Action action);
default FluidStack insertFluidTracked(@Nonnull FluidStack stack, int size) {
FluidStack remainder = insertFluid(stack, size, Action.PERFORM);
int inserted = remainder == null ? size : (size - remainder.amount);
getCraftingManager().track(stack, inserted);
return remainder;
}
/**
* Extracts a fluid from this network.
*

View File

@@ -47,7 +47,7 @@ public interface IGrid {
/**
* @return the grid type
*/
GridType getType();
GridType getGridType();
/**
* @param player the player to create a listener for

View File

@@ -1,8 +1,10 @@
package com.raoulvdberge.refinedstorage.api.network.grid;
import com.raoulvdberge.refinedstorage.api.render.IElementDrawer;
import com.raoulvdberge.refinedstorage.api.util.IFilter;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import java.util.List;
@@ -30,7 +32,10 @@ public interface IGridTab {
void drawTooltip(int x, int y, int screenWidth, int screenHeight, FontRenderer fontRenderer);
/**
* @return the icon
* Draws the icon.
*
* @param x the x position
* @param y the y position
*/
ItemStack getIcon();
void drawIcon(int x, int y, IElementDrawer<ItemStack> itemDrawer, IElementDrawer<FluidStack> fluidDrawer);
}

View File

@@ -45,4 +45,24 @@ public interface IFluidGridHandler {
* @return the remainder container
*/
ItemStack onShiftClick(EntityPlayerMP player, ItemStack container);
/**
* Called when a player requests the crafting preview window to be opened.
*
* @param player the player
* @param hash the item stack hash
* @param quantity the amount of that item that we need a preview for
* @param noPreview true if the crafting preview window shouldn't be shown, false otherwise
*/
void onCraftingPreviewRequested(EntityPlayerMP player, int hash, int quantity, boolean noPreview);
/**
* Called when a player requested crafting for an item.
*
* @param player the player that is requesting the crafting
* @param hash the hash of the item to request a craft for
* @param quantity the amount of the item that has to be crafted
*/
void onCraftingRequested(EntityPlayerMP player, int hash, int quantity);
}

View File

@@ -24,4 +24,20 @@ public interface IQuantityFormatter {
* @return the formatted quantity
*/
String format(int qty);
/**
* Divides quantity by 1000 and appends "B".
*
* @param qty the quantity
* @return the formatted quantity
*/
String formatInBucketForm(int qty);
/**
* Used in Fluid Grid.
*
* @param qty the quantity
* @return the formatted quantity
*/
String formatInBucketFormWithOnlyTrailingDigitsIfZero(int qty);
}

View File

@@ -9,6 +9,8 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftin
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElementRegistry;
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElementRegistry;
import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskRegistry;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingRequestInfo;
import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.api.network.grid.wireless.IWirelessGridRegistry;
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
@@ -27,6 +29,7 @@ import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.api.util.IOneSixMigrationHelper;
import com.raoulvdberge.refinedstorage.api.util.IQuantityFormatter;
import com.raoulvdberge.refinedstorage.api.util.IStackList;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.CraftingRequestInfo;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementList;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementRegistry;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementRegistry;
@@ -246,6 +249,21 @@ public class API implements IRSAPI {
return new StorageDiskFluid(world, capacity);
}
@Override
public ICraftingRequestInfo createCraftingRequestInfo(ItemStack stack) {
return new CraftingRequestInfo(stack);
}
@Override
public ICraftingRequestInfo createCraftingRequestInfo(FluidStack stack) {
return new CraftingRequestInfo(stack);
}
@Override
public ICraftingRequestInfo createCraftingRequestInfo(NBTTagCompound tag) throws CraftingTaskReadException {
return new CraftingRequestInfo(tag);
}
@Override
@Nonnull
public IOneSixMigrationHelper getOneSixMigrationHelper() {

View File

@@ -10,12 +10,14 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadExc
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTaskError;
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.tile.TileController;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.items.IItemHandlerModifiable;
import javax.annotation.Nonnull;
@@ -91,7 +93,23 @@ public class CraftingManager implements ICraftingManager {
return null;
}
return factory.create(network, stack, quantity, pattern);
return factory.create(network, API.instance().createCraftingRequestInfo(stack), quantity, pattern);
}
@Nullable
@Override
public ICraftingTask create(FluidStack stack, int quantity) {
ICraftingPattern pattern = getPattern(stack);
if (pattern == null) {
return null;
}
ICraftingTaskFactory factory = API.instance().getCraftingTaskRegistry().get(pattern.getId());
if (factory == null) {
return null;
}
return factory.create(network, API.instance().createCraftingRequestInfo(stack), quantity, pattern);
}
@Override
@@ -200,12 +218,15 @@ public class CraftingManager implements ICraftingManager {
listeners.forEach(ICraftingMonitorListener::onChanged);
}
//TODO: Make fluid version
@Override
@Nullable
public ICraftingTask request(ItemStack stack, int amount) {
for (ICraftingTask task : getTasks()) {
if (API.instance().getComparer().isEqualNoQuantity(task.getRequested(), stack)) {
amount -= task.getQuantity();
if (task.getRequested().getItem() != null) {
if (API.instance().getComparer().isEqualNoQuantity(task.getRequested().getItem(), stack)) {
amount -= task.getQuantity();
}
}
}
@@ -231,7 +252,24 @@ public class CraftingManager implements ICraftingManager {
int initialSize = size;
for (ICraftingTask task : tasks.values()) {
size = task.onTrackedItemInserted(stack, size);
size = task.onTrackedInsert(stack, size);
if (size == 0) {
break;
}
}
if (size != initialSize) {
this.onTaskChanged();
}
}
@Override
public void track(FluidStack stack, int size) {
int initialSize = size;
for (ICraftingTask task : tasks.values()) {
size = task.onTrackedInsert(stack, size);
if (size == 0) {
break;
@@ -286,4 +324,18 @@ public class CraftingManager implements ICraftingManager {
return null;
}
@Nullable
@Override
public ICraftingPattern getPattern(FluidStack pattern) {
for (ICraftingPattern patternInList : patterns) {
for (FluidStack output : patternInList.getFluidOutputs()) {
if (API.instance().getComparer().isEqual(output, pattern, IComparer.COMPARE_NBT)) {
return patternInList;
}
}
}
return null;
}
}

View File

@@ -2,6 +2,7 @@ package com.raoulvdberge.refinedstorage.apiimpl.autocrafting;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry.CraftingTaskFactory;
import com.raoulvdberge.refinedstorage.apiimpl.util.OneSixMigrationHelper;
@@ -15,6 +16,7 @@ import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.NonNullList;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.oredict.OreDictionary;
import java.util.ArrayList;
@@ -30,6 +32,8 @@ public class CraftingPattern implements ICraftingPattern {
private List<NonNullList<ItemStack>> inputs = new ArrayList<>();
private NonNullList<ItemStack> outputs = NonNullList.create();
private NonNullList<ItemStack> byproducts = NonNullList.create();
private NonNullList<FluidStack> fluidInputs = NonNullList.create();
private NonNullList<FluidStack> fluidOutputs = NonNullList.create();
public CraftingPattern(World world, ICraftingPatternContainer container, ItemStack stack) {
if (!OneSixMigrationHelper.isValidOneSixPattern(stack)) {
@@ -77,6 +81,20 @@ public class CraftingPattern implements ICraftingPattern {
outputs.add(output);
}
FluidStack fluidInput = ItemPattern.getFluidInputSlot(stack, i);
if (fluidInput != null) {
this.valid = true;
fluidInputs.add(fluidInput);
}
FluidStack fluidOutput = ItemPattern.getFluidOutputSlot(stack, i);
if (fluidOutput != null) {
this.valid = true;
fluidOutputs.add(fluidOutput);
}
}
} else {
InventoryCrafting inv = new InventoryCraftingDummy();
@@ -218,6 +236,16 @@ public class CraftingPattern implements ICraftingPattern {
return sanitized;
}
@Override
public NonNullList<FluidStack> getFluidInputs() {
return fluidInputs;
}
@Override
public NonNullList<FluidStack> getFluidOutputs() {
return fluidOutputs;
}
@Override
public String getId() {
return CraftingTaskFactory.ID;
@@ -229,7 +257,10 @@ public class CraftingPattern implements ICraftingPattern {
return false;
}
if ((other.getInputs().size() != inputs.size()) || (other.getOutputs().size() != outputs.size())) {
if ((other.getInputs().size() != inputs.size()) ||
(other.getFluidInputs().size() != fluidInputs.size()) ||
(other.getOutputs().size() != outputs.size()) ||
(other.getFluidOutputs().size() != fluidOutputs.size())) {
return false;
}
@@ -252,12 +283,24 @@ public class CraftingPattern implements ICraftingPattern {
}
}
for (int i = 0; i < fluidInputs.size(); ++i) {
if (!API.instance().getComparer().isEqual(fluidInputs.get(i), other.getFluidInputs().get(i), IComparer.COMPARE_NBT | IComparer.COMPARE_QUANTITY)) {
return false;
}
}
for (int i = 0; i < outputs.size(); ++i) {
if (!API.instance().getComparer().isEqual(outputs.get(i), other.getOutputs().get(i))) {
return false;
}
}
for (int i = 0; i < fluidOutputs.size(); ++i) {
if (!API.instance().getComparer().isEqual(fluidOutputs.get(i), other.getFluidOutputs().get(i), IComparer.COMPARE_NBT | IComparer.COMPARE_QUANTITY)) {
return false;
}
}
if (!processing) {
for (int i = 0; i < byproducts.size(); ++i) {
if (!API.instance().getComparer().isEqual(byproducts.get(i), other.getByproducts().get(i))) {
@@ -282,10 +325,18 @@ public class CraftingPattern implements ICraftingPattern {
}
}
for (FluidStack input : this.fluidInputs) {
result = 31 * result + API.instance().getFluidStackHashCode(input);
}
for (ItemStack output : this.outputs) {
result = 31 * result + API.instance().getItemStackHashCode(output);
}
for (FluidStack output : this.fluidOutputs) {
result = 31 * result + API.instance().getFluidStackHashCode(output);
}
for (ItemStack byproduct : this.byproducts) {
result = 31 * result + API.instance().getItemStackHashCode(byproduct);
}

View File

@@ -0,0 +1,69 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingRequestInfo;
import com.raoulvdberge.refinedstorage.util.StackUtils;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
public class CraftingRequestInfo implements ICraftingRequestInfo {
private static final String NBT_FLUID = "Fluid";
private static final String NBT_STACK = "Stack";
private ItemStack item;
private FluidStack fluid;
public CraftingRequestInfo(NBTTagCompound tag) throws CraftingTaskReadException {
if (!tag.getBoolean(NBT_FLUID)) {
item = StackUtils.deserializeStackFromNbt(tag.getCompoundTag(NBT_STACK));
if (item.isEmpty()) {
throw new CraftingTaskReadException("Extractor stack is empty");
}
} else {
fluid = FluidStack.loadFluidStackFromNBT(tag.getCompoundTag(NBT_STACK));
if (fluid == null) {
throw new CraftingTaskReadException("Extractor fluid stack is emty");
}
}
}
public CraftingRequestInfo(ItemStack item) {
this.item = item;
}
public CraftingRequestInfo(FluidStack fluid) {
this.fluid = fluid;
}
@Nullable
@Override
public ItemStack getItem() {
return item;
}
@Nullable
@Override
public FluidStack getFluid() {
return fluid;
}
@Override
public NBTTagCompound writeToNbt() {
NBTTagCompound tag = new NBTTagCompound();
tag.setBoolean(NBT_FLUID, fluid != null);
if (fluid != null) {
tag.setTag(NBT_STACK, fluid.writeToNBT(new NBTTagCompound()));
} else {
tag.setTag(NBT_STACK, StackUtils.serializeStackToNbt(item));
}
return tag;
}
}

View File

@@ -15,10 +15,12 @@ public class CraftingMonitorElementFluidRender implements ICraftingMonitorElemen
public static final String ID = "fluid_render";
private FluidStack stack;
private int quantity;
private int offset;
public CraftingMonitorElementFluidRender(FluidStack stack, int offset) {
public CraftingMonitorElementFluidRender(FluidStack stack, int quantity, int offset) {
this.stack = stack;
this.quantity = quantity;
this.offset = offset;
}
@@ -36,7 +38,7 @@ public class CraftingMonitorElementFluidRender implements ICraftingMonitorElemen
GlStateManager.pushMatrix();
GlStateManager.scale(scale, scale, 1);
drawers.getStringDrawer().draw(RenderUtils.getOffsetOnScale(x + 21 + offset, scale), RenderUtils.getOffsetOnScale(y + 7, scale), API.instance().getQuantityFormatter().format(stack.amount) + " mB " + stack.getLocalizedName());
drawers.getStringDrawer().draw(RenderUtils.getOffsetOnScale(x + 21 + offset, scale), RenderUtils.getOffsetOnScale(y + 7, scale), API.instance().getQuantityFormatter().formatInBucketForm(quantity) + " " + stack.getLocalizedName());
GlStateManager.popMatrix();
}
@@ -49,13 +51,14 @@ public class CraftingMonitorElementFluidRender implements ICraftingMonitorElemen
@Override
public void write(ByteBuf buf) {
StackUtils.writeFluidStack(buf, stack);
buf.writeInt(quantity);
buf.writeInt(offset);
}
@Override
public boolean merge(ICraftingMonitorElement element) {
if (element.getId().equals(getId()) && elementHashCode() == element.elementHashCode()) {
this.stack.amount += ((CraftingMonitorElementFluidRender) element).stack.amount;
this.quantity += ((CraftingMonitorElementFluidRender) element).quantity;
return true;
}

View File

@@ -2,6 +2,7 @@ package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview;
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement;
import com.raoulvdberge.refinedstorage.api.render.IElementDrawers;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.gui.GuiBase;
import com.raoulvdberge.refinedstorage.util.RenderUtils;
import io.netty.buffer.ByteBuf;
@@ -25,7 +26,6 @@ public class CraftingPreviewElementFluidStack implements ICraftingPreviewElement
public CraftingPreviewElementFluidStack(FluidStack stack) {
this.stack = stack.copy();
this.available = stack.amount;
}
public CraftingPreviewElementFluidStack(FluidStack stack, int available, boolean missing, int toCraft) {
@@ -73,11 +73,21 @@ public class CraftingPreviewElementFluidStack implements ICraftingPreviewElement
float scale = drawers.getFontRenderer().getUnicodeFlag() ? 1F : 0.5F;
y += 2;
GlStateManager.pushMatrix();
GlStateManager.scale(scale, scale, 1);
drawers.getStringDrawer().draw(RenderUtils.getOffsetOnScale(x + 23, scale), RenderUtils.getOffsetOnScale(y + 3, scale), GuiBase.t("gui.refinedstorage:crafting_preview.available", ""));
drawers.getStringDrawer().draw(RenderUtils.getOffsetOnScale(x + 23, scale), RenderUtils.getOffsetOnScale(y + 9, scale), getAvailable() + " mB");
if (getToCraft() > 0) {
String format = hasMissing() ? "gui.refinedstorage:crafting_preview.missing" : "gui.refinedstorage:crafting_preview.to_craft";
drawers.getStringDrawer().draw(RenderUtils.getOffsetOnScale(x + 23, scale), RenderUtils.getOffsetOnScale(y, scale), GuiBase.t(format, API.instance().getQuantityFormatter().formatInBucketForm(getToCraft())));
y += 7;
}
if (getAvailable() > 0) {
drawers.getStringDrawer().draw(RenderUtils.getOffsetOnScale(x + 23, scale), RenderUtils.getOffsetOnScale(y, scale), GuiBase.t("gui.refinedstorage:crafting_preview.available", API.instance().getQuantityFormatter().formatInBucketForm(getAvailable())));
}
GlStateManager.popMatrix();
}

View File

@@ -3,10 +3,10 @@ package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskFactory;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingRequestInfo;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.CraftingTask;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import javax.annotation.Nonnull;
@@ -16,8 +16,8 @@ public class CraftingTaskFactory implements ICraftingTaskFactory {
@Nonnull
@Override
public ICraftingTask create(INetwork network, ItemStack stack, int quantity, ICraftingPattern pattern) {
return new CraftingTask(network, stack, quantity, pattern);
public ICraftingTask create(INetwork network, ICraftingRequestInfo requested, int quantity, ICraftingPattern pattern) {
return new CraftingTask(network, requested, quantity, pattern);
}
@Override

View File

@@ -4,21 +4,21 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.*;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElementList;
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskErrorType;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTaskError;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.*;
import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.api.util.IStackList;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementColor;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementFluidRender;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementItemRender;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementText;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementFluidStack;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementItemStack;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractor;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractorItemStatus;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractorStack;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractorStatus;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter.CraftingInserter;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter.CraftingInserterItem;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter.CraftingInserterItemStatus;
@@ -33,6 +33,7 @@ import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.items.ItemHandlerHelper;
import org.apache.commons.lang3.tuple.Pair;
@@ -56,7 +57,7 @@ public class CraftingTask implements ICraftingTask {
private static final String NBT_PATTERN_CONTAINER_POS = "ContainerPos";
private INetwork network;
private ItemStack requested;
private ICraftingRequestInfo requested;
private int quantity;
private ICraftingPattern pattern;
private List<CraftingStep> steps = new LinkedList<>();
@@ -68,10 +69,15 @@ public class CraftingTask implements ICraftingTask {
private UUID id = UUID.randomUUID();
private IStackList<ItemStack> toTake = API.instance().createItemStackList();
private IStackList<ItemStack> missing = API.instance().createItemStackList();
private IStackList<ItemStack> toCraft = API.instance().createItemStackList();
private IStackList<FluidStack> toTakeFluids = API.instance().createFluidStackList();
public CraftingTask(INetwork network, ItemStack requested, int quantity, ICraftingPattern pattern) {
private IStackList<ItemStack> missing = API.instance().createItemStackList();
private IStackList<FluidStack> missingFluids = API.instance().createFluidStackList();
private IStackList<ItemStack> toCraft = API.instance().createItemStackList();
private IStackList<FluidStack> toCraftFluids = API.instance().createFluidStackList();
public CraftingTask(INetwork network, ICraftingRequestInfo requested, int quantity, ICraftingPattern pattern) {
this.network = network;
this.inserter = new CraftingInserter(network);
this.requested = requested;
@@ -82,11 +88,7 @@ public class CraftingTask implements ICraftingTask {
public CraftingTask(INetwork network, NBTTagCompound tag) throws CraftingTaskReadException {
this.network = network;
this.requested = new ItemStack(tag.getCompoundTag(NBT_REQUESTED));
if (requested.isEmpty()) {
throw new CraftingTaskReadException("Requested item doesn't exist anymore");
}
this.requested = API.instance().createCraftingRequestInfo(tag.getCompoundTag(NBT_REQUESTED));
this.quantity = tag.getInteger(NBT_QUANTITY);
this.pattern = readPatternFromNbt(tag.getCompoundTag(NBT_PATTERN), network.world());
this.inserter = new CraftingInserter(network, tag.getTagList(NBT_INSERTER, Constants.NBT.TAG_COMPOUND));
@@ -134,7 +136,10 @@ public class CraftingTask implements ICraftingTask {
int crafted = 0;
IStackList<ItemStack> results = API.instance().createItemStackList();
IStackList<FluidStack> fluidResults = API.instance().createFluidStackList();
IStackList<ItemStack> storage = network.getItemStorageCache().getList().copy();
IStackList<FluidStack> fluidStorage = network.getFluidStorageCache().getList().copy();
// Items that are being handled in other tasks aren't available to us.
for (ICraftingTask task : network.getCraftingManager().getTasks()) {
@@ -149,8 +154,20 @@ public class CraftingTask implements ICraftingTask {
}
if (extractor != null) {
for (ItemStack inUse : extractor.getItems()) {
storage.remove(inUse);
for (CraftingExtractorStack inUse : extractor.getStacks()) {
ItemStack inUseItem = inUse.getItem();
if (inUseItem != null) {
storage.remove(inUseItem);
} else {
FluidStack inUseFluid = inUse.getFluid();
if (inUseFluid != null) {
fluidStorage.remove(inUseFluid);
} else {
throw new IllegalStateException("Extractor stack is neither a fluid or an item!");
}
}
}
}
}
@@ -162,7 +179,7 @@ public class CraftingTask implements ICraftingTask {
ICraftingPatternChain patternChain = patternChainList.getChain(pattern);
while (qty > 0) {
Pair<CraftingStep, ICraftingTaskError> result = calculateInternal(storage, results, patternChainList, patternChain.current());
Pair<CraftingStep, ICraftingTaskError> result = calculateInternal(storage, fluidStorage, results, fluidResults, patternChainList, patternChain.current());
if (result.getRight() != null) {
return result.getRight();
@@ -177,12 +194,23 @@ public class CraftingTask implements ICraftingTask {
patternChain.cycle();
}
this.toCraft.add(requested, crafted);
if (requested.getItem() != null) {
this.toCraft.add(requested.getItem(), crafted);
} else {
this.toCraftFluids.add(requested.getFluid(), crafted);
}
return null;
}
private Pair<CraftingStep, ICraftingTaskError> calculateInternal(IStackList<ItemStack> mutatedStorage, IStackList<ItemStack> results, ICraftingPatternChainList patternChainList, ICraftingPattern pattern) {
private Pair<CraftingStep, ICraftingTaskError> calculateInternal(
IStackList<ItemStack> mutatedStorage,
IStackList<FluidStack> mutatedFluidStorage,
IStackList<ItemStack> results,
IStackList<FluidStack> fluidResults,
ICraftingPatternChainList patternChainList,
ICraftingPattern pattern) {
if (System.currentTimeMillis() - calculationStarted > CALCULATION_TIMEOUT_MS) {
return Pair.of(null, new CraftingTaskError(CraftingTaskErrorType.TOO_COMPLEX));
}
@@ -192,6 +220,7 @@ public class CraftingTask implements ICraftingTask {
}
IStackList<ItemStack> itemsToExtract = API.instance().createItemStackList();
IStackList<FluidStack> fluidsToExtract = API.instance().createFluidStackList();
NonNullList<ItemStack> took = NonNullList.create();
@@ -270,7 +299,7 @@ public class CraftingTask implements ICraftingTask {
ICraftingPatternChain subPatternChain = patternChainList.getChain(subPattern);
while ((fromSelf == null ? 0 : fromSelf.getCount()) < remaining) {
Pair<CraftingStep, ICraftingTaskError> result = calculateInternal(mutatedStorage, results, patternChainList, subPatternChain.current());
Pair<CraftingStep, ICraftingTaskError> result = calculateInternal(mutatedStorage, mutatedFluidStorage, results, fluidResults, patternChainList, subPatternChain.current());
if (result.getRight() != null) {
return Pair.of(null, result.getRight());
@@ -301,6 +330,73 @@ public class CraftingTask implements ICraftingTask {
}
}
for (FluidStack input : pattern.getFluidInputs()) {
FluidStack fromSelf = fluidResults.get(input, IComparer.COMPARE_NBT);
FluidStack fromNetwork = mutatedFluidStorage.get(input, IComparer.COMPARE_NBT);
int remaining = input.amount;
while (remaining > 0) {
if (fromSelf != null) {
int toTake = Math.min(remaining, fromSelf.amount);
fluidsToExtract.add(input, toTake);
fluidResults.remove(input, toTake);
remaining -= toTake;
fromSelf = fluidResults.get(input, IComparer.COMPARE_NBT);
} else if (fromNetwork != null) {
int toTake = Math.min(remaining, fromNetwork.amount);
this.toTakeFluids.add(input, toTake);
fluidsToExtract.add(input, toTake);
mutatedFluidStorage.remove(fromNetwork, toTake);
remaining -= toTake;
fromNetwork = mutatedFluidStorage.get(input, IComparer.COMPARE_NBT);
} else {
ICraftingPattern subPattern = network.getCraftingManager().getPattern(input);
if (subPattern != null) {
ICraftingPatternChain subPatternChain = patternChainList.getChain(subPattern);
while ((fromSelf == null ? 0 : fromSelf.amount) < remaining) {
Pair<CraftingStep, ICraftingTaskError> result = calculateInternal(mutatedStorage, mutatedFluidStorage, results, fluidResults, patternChainList, subPatternChain.current());
if (result.getRight() != null) {
return Pair.of(null, result.getRight());
}
this.steps.add(result.getLeft());
fromSelf = fluidResults.get(input, IComparer.COMPARE_NBT);
if (fromSelf == null) {
throw new IllegalStateException("Recursive fluid calculation didn't yield anything");
}
fromNetwork = mutatedFluidStorage.get(input, IComparer.COMPARE_NBT);
subPatternChain.cycle();
}
// fromSelf contains the amount crafted after the loop.
this.toCraftFluids.add(input, fromSelf.amount);
} else {
this.missingFluids.add(input, remaining);
fluidsToExtract.add(input, remaining);
remaining = 0;
}
}
}
}
patternsUsed.remove(pattern);
if (pattern.isProcessing()) {
@@ -308,8 +404,16 @@ public class CraftingTask implements ICraftingTask {
results.add(output);
}
return Pair.of(new CraftingStepProcess(pattern, network, new ArrayList<>(itemsToExtract.getStacks())), null);
for (FluidStack output : pattern.getFluidOutputs()) {
fluidResults.add(output);
}
return Pair.of(new CraftingStepProcess(pattern, network, new ArrayList<>(itemsToExtract.getStacks()), new ArrayList<>(fluidsToExtract.getStacks())), null);
} else {
if (!fluidsToExtract.isEmpty()) {
throw new IllegalStateException("Cannot extract fluids in normal pattern!");
}
results.add(pattern.getOutput(took));
for (ItemStack byproduct : pattern.getByproducts(took)) {
@@ -320,15 +424,23 @@ public class CraftingTask implements ICraftingTask {
}
}
private int getQuantityPerCraft(ICraftingPattern pattern, ItemStack requested) {
private int getQuantityPerCraft(ICraftingPattern pattern, ICraftingRequestInfo requested) {
int qty = 0;
for (ItemStack output : pattern.getOutputs()) {
if (API.instance().getComparer().isEqualNoQuantity(output, requested)) {
qty += output.getCount();
if (requested.getItem() != null) {
for (ItemStack output : pattern.getOutputs()) {
if (API.instance().getComparer().isEqualNoQuantity(output, requested.getItem())) {
qty += output.getCount();
if (!pattern.isProcessing()) {
break;
if (!pattern.isProcessing()) {
break;
}
}
}
} else {
for (FluidStack output : pattern.getFluidOutputs()) {
if (API.instance().getComparer().isEqual(output, requested.getFluid(), IComparer.COMPARE_NBT)) {
qty += output.amount;
}
}
}
@@ -376,12 +488,12 @@ public class CraftingTask implements ICraftingTask {
}
@Override
public ItemStack getRequested() {
public ICraftingRequestInfo getRequested() {
return requested;
}
@Override
public int onTrackedItemInserted(ItemStack stack, int size) {
public int onTrackedInsert(ItemStack stack, int size) {
for (CraftingStep step : steps) {
if (step instanceof CraftingStepProcess) {
size = ((CraftingStepProcess) step).onTrackedItemInserted(stack, size);
@@ -395,13 +507,31 @@ public class CraftingTask implements ICraftingTask {
return size;
}
@Override
public int onTrackedInsert(FluidStack stack, int size) {
for (CraftingStep step : steps) {
if (step instanceof CraftingStepProcess) {
size = ((CraftingStepProcess) step).onTrackedFluidInserted(stack, size);
if (size == 0) {
break;
}
}
}
return size;
}
// TODO: Fix lang keys.
@Override
public List<ICraftingMonitorElement> getCraftingMonitorElements() {
ICraftingMonitorElementList elements = API.instance().createCraftingMonitorElementList();
if (!missing.isEmpty()) {
if (!missing.isEmpty() || !missingFluids.isEmpty()) {
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_missing", 5));
}
if (!missing.isEmpty()) {
for (ItemStack missing : this.missing.getStacks()) {
elements.add(new CraftingMonitorElementColor(new CraftingMonitorElementItemRender(missing, missing.getCount(), 0), "", CraftingMonitorElementColor.COLOR_ERROR));
}
@@ -409,6 +539,14 @@ public class CraftingTask implements ICraftingTask {
elements.commit();
}
if (!missingFluids.isEmpty()) {
for (FluidStack missing : this.missingFluids.getStacks()) {
elements.add(new CraftingMonitorElementColor(new CraftingMonitorElementFluidRender(missing, missing.amount, 0), "", CraftingMonitorElementColor.COLOR_ERROR));
}
elements.commit();
}
if (!inserter.getItems().isEmpty()) {
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_inserting", 5));
@@ -425,20 +563,20 @@ public class CraftingTask implements ICraftingTask {
elements.commit();
}
if (steps.stream().anyMatch(s -> s instanceof CraftingStepCraft && !s.isCompleted() && !((CraftingStepCraft) s).getExtractor().getItems().isEmpty())) {
if (steps.stream().anyMatch(s -> s instanceof CraftingStepCraft && !s.isCompleted() && !((CraftingStepCraft) s).getExtractor().getStacks().isEmpty())) {
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_crafting", 5));
for (CraftingStep step : steps) {
if (step instanceof CraftingStepCraft && !step.isCompleted()) {
CraftingExtractor extractor = ((CraftingStepCraft) step).getExtractor();
for (int i = 0; i < extractor.getItems().size(); ++i) {
ItemStack item = extractor.getItems().get(i);
CraftingExtractorItemStatus status = extractor.getStatus().get(i);
for (int i = 0; i < extractor.getStacks().size(); ++i) {
// Assume we have an item here.
CraftingExtractorStack stack = extractor.getStacks().get(i);
ICraftingMonitorElement element = new CraftingMonitorElementItemRender(item, item.getCount(), 0);
ICraftingMonitorElement element = new CraftingMonitorElementItemRender(stack.getItem(), stack.getItem().getCount(), 0);
if (status == CraftingExtractorItemStatus.MISSING) {
if (stack.getStatus() == CraftingExtractorStatus.MISSING) {
element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.waiting_for_items", CraftingMonitorElementColor.COLOR_INFO);
}
@@ -450,6 +588,7 @@ public class CraftingTask implements ICraftingTask {
elements.commit();
}
// TODO: Make better?
if (steps.stream().anyMatch(s -> s instanceof CraftingStepProcess && !s.isCompleted())) {
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_processing", 5));
@@ -457,19 +596,54 @@ public class CraftingTask implements ICraftingTask {
if (step instanceof CraftingStepProcess && !step.isCompleted()) {
CraftingExtractor extractor = ((CraftingStepProcess) step).getExtractor();
for (int i = 0; i < extractor.getItems().size(); ++i) {
ItemStack item = extractor.getItems().get(i);
CraftingExtractorItemStatus status = extractor.getStatus().get(i);
for (int i = 0; i < extractor.getStacks().size(); ++i) {
CraftingExtractorStack stack = extractor.getStacks().get(i);
ICraftingMonitorElement element = new CraftingMonitorElementItemRender(item, item.getCount(), 0);
if (stack.getItem() == null) {
continue;
}
if (status == CraftingExtractorItemStatus.MISSING) {
ICraftingMonitorElement element = new CraftingMonitorElementItemRender(stack.getItem(), stack.getItem().getCount(), 0);
if (stack.getStatus() == CraftingExtractorStatus.MISSING) {
element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.waiting_for_items", CraftingMonitorElementColor.COLOR_INFO);
} else if (status == CraftingExtractorItemStatus.MACHINE_DOES_NOT_ACCEPT) {
} else if (stack.getStatus() == CraftingExtractorStatus.MACHINE_DOES_NOT_ACCEPT) {
element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.machine_does_not_accept", CraftingMonitorElementColor.COLOR_ERROR);
} else if (status == CraftingExtractorItemStatus.MACHINE_NONE) {
} else if (stack.getStatus() == CraftingExtractorStatus.MACHINE_NONE) {
element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.machine_none", CraftingMonitorElementColor.COLOR_ERROR);
} else if (status == CraftingExtractorItemStatus.EXTRACTED) {
} else if (stack.getStatus() == CraftingExtractorStatus.EXTRACTED) {
element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.item_inserted_into_machine", CraftingMonitorElementColor.COLOR_SUCCESS);
}
elements.add(element);
}
}
}
elements.commit();
for (CraftingStep step : steps) {
if (step instanceof CraftingStepProcess && !step.isCompleted()) {
CraftingExtractor extractor = ((CraftingStepProcess) step).getExtractor();
for (int i = 0; i < extractor.getStacks().size(); ++i) {
CraftingExtractorStack stack = extractor.getStacks().get(i);
ICraftingMonitorElement element;
if (stack.getItem() != null) {
continue;
}
element = new CraftingMonitorElementFluidRender(stack.getFluid(), stack.getFluid().amount, 0);
if (stack.getStatus() == CraftingExtractorStatus.MISSING) {
element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.waiting_for_items", CraftingMonitorElementColor.COLOR_INFO);
} else if (stack.getStatus() == CraftingExtractorStatus.MACHINE_DOES_NOT_ACCEPT) {
element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.machine_does_not_accept", CraftingMonitorElementColor.COLOR_ERROR);
} else if (stack.getStatus() == CraftingExtractorStatus.MACHINE_NONE) {
element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.machine_none", CraftingMonitorElementColor.COLOR_ERROR);
} else if (stack.getStatus() == CraftingExtractorStatus.EXTRACTED) {
element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.item_inserted_into_machine", CraftingMonitorElementColor.COLOR_SUCCESS);
}
@@ -487,6 +661,7 @@ public class CraftingTask implements ICraftingTask {
@Override
public List<ICraftingPreviewElement> getPreviewStacks() {
Map<Integer, CraftingPreviewElementItemStack> map = new LinkedHashMap<>();
Map<Integer, CraftingPreviewElementFluidStack> mapFluids = new LinkedHashMap<>();
for (ItemStack stack : toCraft.getStacks()) {
int hash = API.instance().getItemStackHashCode(stack);
@@ -502,6 +677,20 @@ public class CraftingTask implements ICraftingTask {
map.put(hash, previewStack);
}
for (FluidStack stack : toCraftFluids.getStacks()) {
int hash = API.instance().getFluidStackHashCode(stack);
CraftingPreviewElementFluidStack previewStack = mapFluids.get(hash);
if (previewStack == null) {
previewStack = new CraftingPreviewElementFluidStack(stack);
}
previewStack.addToCraft(stack.amount);
mapFluids.put(hash, previewStack);
}
for (ItemStack stack : missing.getStacks()) {
int hash = API.instance().getItemStackHashCode(stack);
@@ -517,6 +706,21 @@ public class CraftingTask implements ICraftingTask {
map.put(hash, previewStack);
}
for (FluidStack stack : missingFluids.getStacks()) {
int hash = API.instance().getFluidStackHashCode(stack);
CraftingPreviewElementFluidStack previewStack = mapFluids.get(hash);
if (previewStack == null) {
previewStack = new CraftingPreviewElementFluidStack(stack);
}
previewStack.setMissing(true);
previewStack.addToCraft(stack.amount);
mapFluids.put(hash, previewStack);
}
for (ItemStack stack : toTake.getStacks()) {
int hash = API.instance().getItemStackHashCode(stack);
@@ -531,7 +735,26 @@ public class CraftingTask implements ICraftingTask {
map.put(hash, previewStack);
}
return new ArrayList<>(map.values());
for (FluidStack stack : toTakeFluids.getStacks()) {
int hash = API.instance().getFluidStackHashCode(stack);
CraftingPreviewElementFluidStack previewStack = mapFluids.get(hash);
if (previewStack == null) {
previewStack = new CraftingPreviewElementFluidStack(stack);
}
previewStack.addAvailable(stack.amount);
mapFluids.put(hash, previewStack);
}
List<ICraftingPreviewElement> elements = new ArrayList<>();
elements.addAll(map.values());
elements.addAll(mapFluids.values());
return elements;
}
@Override
@@ -561,7 +784,7 @@ public class CraftingTask implements ICraftingTask {
@Override
public NBTTagCompound writeToNbt(NBTTagCompound tag) {
tag.setTag(NBT_REQUESTED, requested.serializeNBT());
tag.setTag(NBT_REQUESTED, requested.writeToNbt());
tag.setInteger(NBT_QUANTITY, quantity);
tag.setTag(NBT_PATTERN, writePatternToNbt(pattern));
tag.setTag(NBT_INSERTER, inserter.writeToNbt());

View File

@@ -3,11 +3,12 @@ package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.api.util.Action;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.CraftingTask;
import com.raoulvdberge.refinedstorage.util.StackUtils;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
@@ -16,80 +17,75 @@ import java.util.ArrayList;
import java.util.List;
public class CraftingExtractor {
private static final String NBT_ITEM = "Item";
private static final String NBT_STATUS = "Status";
private INetwork network;
private List<ItemStack> items;
private List<CraftingExtractorItemStatus> status = new ArrayList<>();
private List<CraftingExtractorStack> stacks;
private boolean processing;
public CraftingExtractor(INetwork network, List<ItemStack> items, boolean processing) {
public CraftingExtractor(INetwork network, List<CraftingExtractorStack> stacks, boolean processing) {
this.network = network;
this.items = items;
this.stacks = stacks;
this.processing = processing;
for (int i = 0; i < items.size(); ++i) {
status.add(CraftingExtractorItemStatus.MISSING);
}
}
public CraftingExtractor(INetwork network, NBTTagList tag, boolean processing) throws CraftingTaskReadException {
this.network = network;
this.processing = processing;
this.items = new ArrayList<>();
this.stacks = new ArrayList<>();
for (int i = 0; i < tag.tagCount(); ++i) {
NBTTagCompound itemTag = tag.getCompoundTagAt(i);
ItemStack stack = StackUtils.deserializeStackFromNbt(itemTag.getCompoundTag(NBT_ITEM));
if (stack.isEmpty()) {
throw new CraftingTaskReadException("Extractor stack is empty");
}
CraftingExtractorItemStatus status = CraftingExtractorItemStatus.values()[itemTag.getInteger(NBT_STATUS)];
this.items.add(stack);
this.status.add(status);
this.stacks.add(new CraftingExtractorStack(tag.getCompoundTagAt(i)));
}
}
public List<ItemStack> getItems() {
return items;
public List<CraftingExtractorStack> getStacks() {
return stacks;
}
public List<CraftingExtractorItemStatus> getStatus() {
return status;
}
public void updateStatus(@Nullable IItemHandler processingInventory) {
public void updateStatus(@Nullable IItemHandler processingInventory, @Nullable IFluidHandler processingFluidInventory) {
boolean updated = false;
for (int i = 0; i < items.size(); ++i) {
if (status.get(i) != CraftingExtractorItemStatus.EXTRACTED) {
ItemStack stack = items.get(i);
for (CraftingExtractorStack stack : stacks) {
if (stack.getStatus() != CraftingExtractorStatus.EXTRACTED) {
CraftingExtractorStatus previousStatus = stack.getStatus();
ItemStack inNetwork = network.extractItem(stack, stack.getCount(), CraftingTask.getFlags(stack), Action.SIMULATE);
if (stack.getItem() != null) {
ItemStack item = stack.getItem();
CraftingExtractorItemStatus previousStatus = status.get(i);
ItemStack inNetwork = network.extractItem(item, item.getCount(), CraftingTask.getFlags(item), Action.SIMULATE);
if (inNetwork == null || inNetwork.getCount() < stack.getCount()) {
status.set(i, CraftingExtractorItemStatus.MISSING);
if (inNetwork == null || inNetwork.getCount() < item.getCount()) {
stack.setStatus(CraftingExtractorStatus.MISSING);
} else {
stack.setStatus(CraftingExtractorStatus.AVAILABLE);
if (processing) {
if (processingInventory == null) {
stack.setStatus(CraftingExtractorStatus.MACHINE_NONE);
} else if (!ItemHandlerHelper.insertItem(processingInventory, item, true).isEmpty()) {
stack.setStatus(CraftingExtractorStatus.MACHINE_DOES_NOT_ACCEPT);
}
}
}
} else {
status.set(i, CraftingExtractorItemStatus.AVAILABLE);
FluidStack fluid = stack.getFluid();
if (processing) {
if (processingInventory == null) {
status.set(i, CraftingExtractorItemStatus.MACHINE_NONE);
} else if (!ItemHandlerHelper.insertItem(processingInventory, stack, true).isEmpty()) {
status.set(i, CraftingExtractorItemStatus.MACHINE_DOES_NOT_ACCEPT);
FluidStack inNetwork = network.extractFluid(fluid, fluid.amount, IComparer.COMPARE_NBT, Action.SIMULATE);
if (inNetwork == null || inNetwork.amount < fluid.amount) {
stack.setStatus(CraftingExtractorStatus.MISSING);
} else {
stack.setStatus(CraftingExtractorStatus.AVAILABLE);
if (processingFluidInventory == null) {
stack.setStatus(CraftingExtractorStatus.MACHINE_NONE);
} else if (processingFluidInventory.fill(fluid, false) != fluid.amount) {
stack.setStatus(CraftingExtractorStatus.MACHINE_DOES_NOT_ACCEPT);
}
}
}
if (previousStatus != status.get(i)) {
if (previousStatus != stack.getStatus()) {
updated = true;
}
}
@@ -101,43 +97,67 @@ public class CraftingExtractor {
}
public boolean isAllAvailable() {
return !items.isEmpty() && status.stream().allMatch(s -> s == CraftingExtractorItemStatus.AVAILABLE || s == CraftingExtractorItemStatus.EXTRACTED);
return !stacks.isEmpty() && stacks.stream().allMatch(s -> s.getStatus() == CraftingExtractorStatus.AVAILABLE || s.getStatus() == CraftingExtractorStatus.EXTRACTED);
}
public boolean isAllExtracted() {
return !items.isEmpty() && status.stream().allMatch(s -> s == CraftingExtractorItemStatus.EXTRACTED);
return !stacks.isEmpty() && stacks.stream().allMatch(s -> s.getStatus() == CraftingExtractorStatus.EXTRACTED);
}
public void extractOne(@Nullable IItemHandler processingInventory) {
public void extractOne(@Nullable IItemHandler processingInventory, @Nullable IFluidHandler processingFluidInventory) {
boolean changed = false;
for (int i = 0; i < items.size(); ++i) {
if (status.get(i) == CraftingExtractorItemStatus.AVAILABLE) {
ItemStack extracted = network.extractItem(items.get(i), items.get(i).getCount(), CraftingTask.getFlags(items.get(i)), Action.PERFORM);
if (extracted == null) {
throw new IllegalStateException("Did not extract anything while available");
}
for (CraftingExtractorStack stack : stacks) {
if (stack.getStatus() == CraftingExtractorStatus.AVAILABLE) {
if (stack.getItem() != null) {
ItemStack item = stack.getItem();
if (processing) {
if (processingInventory == null) {
throw new IllegalStateException("Processing inventory is null");
ItemStack extracted = network.extractItem(item, item.getCount(), CraftingTask.getFlags(item), Action.PERFORM);
if (extracted == null) {
throw new IllegalStateException("Did not extract anything while available");
}
ItemStack remainder = ItemHandlerHelper.insertItem(processingInventory, extracted, false);
if (!remainder.isEmpty()) {
throw new IllegalStateException("The processing inventory gave back a remainder while it previously stated it could handle all");
if (processing) {
if (processingInventory == null) {
throw new IllegalStateException("Processing inventory is null");
}
ItemStack remainder = ItemHandlerHelper.insertItem(processingInventory, extracted, false);
if (!remainder.isEmpty()) {
throw new IllegalStateException("The processing inventory gave back a remainder while it previously stated it could handle all");
}
}
stack.setStatus(CraftingExtractorStatus.EXTRACTED);
changed = true;
} else {
FluidStack fluid = stack.getFluid();
FluidStack extracted = network.extractFluid(fluid, fluid.amount, IComparer.COMPARE_NBT, Action.PERFORM);
if (extracted == null) {
throw new IllegalStateException("Did not extract any fluids while available");
}
if (processingFluidInventory == null) {
throw new IllegalStateException("Processing fluid inventory is null");
}
int filled = processingFluidInventory.fill(fluid, true);
if (filled != fluid.amount) {
throw new IllegalStateException("The processing fluid inventory gave back a remainder while it previously stated it could handle all");
}
stack.setStatus(CraftingExtractorStatus.EXTRACTED);
changed = true;
}
status.set(i, CraftingExtractorItemStatus.EXTRACTED);
changed = true;
// For processing patterns we want to insert all items at once to avoid conflicts with other crafting steps.
if (!processing) {
return;
} else {
updateStatus(processingInventory);
updateStatus(processingInventory, processingFluidInventory);
}
}
}
@@ -150,13 +170,8 @@ public class CraftingExtractor {
public NBTTagList writeToNbt() {
NBTTagList list = new NBTTagList();
for (int i = 0; i < items.size(); ++i) {
NBTTagCompound tag = new NBTTagCompound();
tag.setTag(NBT_ITEM, StackUtils.serializeStackToNbt(items.get(i)));
tag.setInteger(NBT_STATUS, status.get(i).ordinal());
list.appendTag(tag);
for (CraftingExtractorStack stack : stacks) {
list.appendTag(stack.writeToNbt());
}
return list;

View File

@@ -0,0 +1,79 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
import com.raoulvdberge.refinedstorage.util.StackUtils;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
public class CraftingExtractorStack {
private static final String NBT_FLUID = "Fluid";
private static final String NBT_STACK = "Stack";
private static final String NBT_STATUS = "Status";
private ItemStack item;
private FluidStack fluid;
private CraftingExtractorStatus status = CraftingExtractorStatus.MISSING;
public CraftingExtractorStack(ItemStack item) {
this.item = item;
}
public CraftingExtractorStack(FluidStack fluid) {
this.fluid = fluid;
}
public CraftingExtractorStack(NBTTagCompound tag) throws CraftingTaskReadException {
if (!tag.getBoolean(NBT_FLUID)) {
item = StackUtils.deserializeStackFromNbt(tag.getCompoundTag(NBT_STACK));
if (item.isEmpty()) {
throw new CraftingTaskReadException("Extractor stack is empty");
}
} else {
fluid = FluidStack.loadFluidStackFromNBT(tag.getCompoundTag(NBT_STACK));
if (fluid == null) {
throw new CraftingTaskReadException("Extractor fluid stack is empty");
}
}
status = CraftingExtractorStatus.values()[tag.getInteger(NBT_STATUS)];
}
@Nullable
public ItemStack getItem() {
return item;
}
@Nullable
public FluidStack getFluid() {
return fluid;
}
public NBTTagCompound writeToNbt() {
NBTTagCompound tag = new NBTTagCompound();
tag.setBoolean(NBT_FLUID, fluid != null);
if (fluid != null) {
tag.setTag(NBT_STACK, fluid.writeToNBT(new NBTTagCompound()));
} else {
tag.setTag(NBT_STACK, StackUtils.serializeStackToNbt(item));
}
tag.setInteger(NBT_STATUS, status.ordinal());
return tag;
}
public CraftingExtractorStatus getStatus() {
return status;
}
public void setStatus(CraftingExtractorStatus status) {
this.status = status;
}
}

View File

@@ -1,6 +1,6 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor;
public enum CraftingExtractorItemStatus {
public enum CraftingExtractorStatus {
AVAILABLE,
MISSING,
EXTRACTED,

View File

@@ -4,6 +4,7 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractor;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractorStack;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter.CraftingInserter;
import com.raoulvdberge.refinedstorage.util.StackUtils;
import net.minecraft.item.ItemStack;
@@ -13,6 +14,7 @@ import net.minecraft.util.NonNullList;
import net.minecraftforge.common.util.Constants;
import java.util.List;
import java.util.stream.Collectors;
public class CraftingStepCraft extends CraftingStep {
public static final String TYPE = "craft";
@@ -33,7 +35,7 @@ public class CraftingStepCraft extends CraftingStep {
}
this.inserter = inserter;
this.extractor = new CraftingExtractor(network, toExtract, false);
this.extractor = new CraftingExtractor(network, toExtract.stream().map(CraftingExtractorStack::new).collect(Collectors.toList()), false);
this.took = took;
}
@@ -57,14 +59,14 @@ public class CraftingStepCraft extends CraftingStep {
@Override
public boolean canExecute() {
extractor.updateStatus(null);
extractor.updateStatus(null, null);
return extractor.isAllAvailable();
}
@Override
public boolean execute() {
extractor.extractOne(null);
extractor.extractOne(null, null);
boolean allExtracted = extractor.isAllExtracted();

View File

@@ -6,12 +6,15 @@ import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.api.util.IStackList;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractor;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractorStack;
import com.raoulvdberge.refinedstorage.util.StackUtils;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fluids.FluidStack;
import java.util.ArrayList;
import java.util.List;
public class CraftingStepProcess extends CraftingStep {
@@ -19,22 +22,39 @@ public class CraftingStepProcess extends CraftingStep {
private static final String NBT_EXTRACTOR = "Extractor";
private static final String NBT_TO_RECEIVE = "ToReceive";
private static final String NBT_TO_RECEIVE_FLUIDS = "ToReceiveFluids";
private CraftingExtractor extractor;
private IStackList<ItemStack> itemsToReceive = API.instance().createItemStackList();
public CraftingStepProcess(ICraftingPattern pattern, INetwork network, List<ItemStack> toExtract) {
private IStackList<ItemStack> itemsToReceive = API.instance().createItemStackList();
private IStackList<FluidStack> fluidsToReceive = API.instance().createFluidStackList();
public CraftingStepProcess(ICraftingPattern pattern, INetwork network, List<ItemStack> toExtract, List<FluidStack> fluidsToExtract) {
super(pattern);
if (!pattern.isProcessing()) {
throw new IllegalArgumentException("Cannot pass non-processing pattern to processing handler");
}
this.extractor = new CraftingExtractor(network, toExtract, true);
List<CraftingExtractorStack> stacks = new ArrayList<>();
for (ItemStack item : toExtract) {
stacks.add(new CraftingExtractorStack(item));
}
for (FluidStack fluid : fluidsToExtract) {
stacks.add(new CraftingExtractorStack(fluid));
}
this.extractor = new CraftingExtractor(network, stacks, true);
for (ItemStack output : pattern.getOutputs()) {
this.itemsToReceive.add(output);
}
for (FluidStack output : pattern.getFluidOutputs()) {
this.fluidsToReceive.add(output);
}
}
public CraftingStepProcess(ICraftingPattern pattern, INetwork network, NBTTagCompound tag) throws CraftingTaskReadException {
@@ -56,11 +76,22 @@ public class CraftingStepProcess extends CraftingStep {
this.itemsToReceive.add(toReceive);
}
NBTTagList toReceiveFluidsList = tag.getTagList(NBT_TO_RECEIVE_FLUIDS, Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < toReceiveFluidsList.tagCount(); ++i) {
FluidStack toReceive = FluidStack.loadFluidStackFromNBT(toReceiveFluidsList.getCompoundTagAt(i));
if (toReceive == null) {
throw new CraftingTaskReadException("Fluid to receive is null");
}
this.fluidsToReceive.add(toReceive);
}
}
@Override
public boolean canExecute() {
extractor.updateStatus(pattern.getContainer().getConnectedInventory());
extractor.updateStatus(pattern.getContainer().getConnectedInventory(), pattern.getContainer().getConnectedFluidInventory());
return extractor.isAllAvailable();
}
@@ -82,13 +113,30 @@ public class CraftingStepProcess extends CraftingStep {
return size - toExtract;
}
public int onTrackedFluidInserted(FluidStack stack, int size) {
if (!extractor.isAllExtracted()) {
return size;
}
FluidStack inList = fluidsToReceive.get(stack);
if (inList == null) {
return size;
}
int toExtract = Math.min(size, inList.amount);
fluidsToReceive.remove(stack, toExtract);
return size - toExtract;
}
@Override
public boolean execute() {
if (!extractor.isAllExtracted()) {
extractor.extractOne(pattern.getContainer().getConnectedInventory());
extractor.extractOne(pattern.getContainer().getConnectedInventory(), pattern.getContainer().getConnectedFluidInventory());
}
return extractor.isAllExtracted() && itemsToReceive.isEmpty();
return extractor.isAllExtracted() && itemsToReceive.isEmpty() && fluidsToReceive.isEmpty();
}
@Override
@@ -110,6 +158,14 @@ public class CraftingStepProcess extends CraftingStep {
tag.setTag(NBT_TO_RECEIVE, toReceive);
NBTTagList toReceiveFluids = new NBTTagList();
for (FluidStack toReceiveStack : fluidsToReceive.getStacks()) {
toReceiveFluids.appendTag(toReceiveStack.writeToNBT(new NBTTagCompound()));
}
tag.setTag(NBT_TO_RECEIVE_FLUIDS, toReceiveFluids);
return tag;
}

View File

@@ -1,9 +1,12 @@
package com.raoulvdberge.refinedstorage.apiimpl.network.grid;
import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab;
import com.raoulvdberge.refinedstorage.api.render.IElementDrawer;
import com.raoulvdberge.refinedstorage.api.util.IFilter;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.client.config.GuiUtils;
import java.util.Collections;
@@ -33,7 +36,9 @@ public class GridTab implements IGridTab {
}
@Override
public ItemStack getIcon() {
return icon;
public void drawIcon(int x, int y, IElementDrawer<ItemStack> itemDrawer, IElementDrawer<FluidStack> fluidDrawer) {
RenderHelper.enableGUIStandardItemLighting();
itemDrawer.draw(x, y, icon);
}
}

View File

@@ -1,12 +1,20 @@
package com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTaskError;
import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.api.network.grid.handler.IFluidGridHandler;
import com.raoulvdberge.refinedstorage.api.network.item.INetworkItem;
import com.raoulvdberge.refinedstorage.api.network.item.NetworkItemAction;
import com.raoulvdberge.refinedstorage.api.network.security.Permission;
import com.raoulvdberge.refinedstorage.api.util.Action;
import com.raoulvdberge.refinedstorage.api.util.IStackList;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementError;
import com.raoulvdberge.refinedstorage.network.MessageGridCraftingPreviewResponse;
import com.raoulvdberge.refinedstorage.network.MessageGridCraftingStartResponse;
import com.raoulvdberge.refinedstorage.util.StackUtils;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.InventoryHelper;
@@ -18,6 +26,7 @@ import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nullable;
import java.util.Collections;
public class FluidGridHandler implements IFluidGridHandler {
private INetwork network;
@@ -116,4 +125,79 @@ public class FluidGridHandler implements IFluidGridHandler {
public ItemStack onShiftClick(EntityPlayerMP player, ItemStack container) {
return StackUtils.nullToEmpty(onInsert(player, container));
}
@Override
public void onCraftingPreviewRequested(EntityPlayerMP player, int hash, int quantity, boolean noPreview) {
if (!network.getSecurityManager().hasPermission(Permission.AUTOCRAFTING, player)) {
return;
}
IStackList<FluidStack> cache = API.instance().createFluidStackList();
for (ICraftingPattern pattern : network.getCraftingManager().getPatterns()) {
for (FluidStack output : pattern.getFluidOutputs()) {
cache.add(output);
}
}
FluidStack stack = cache.get(hash);
if (stack != null) {
Thread calculationThread = new Thread(() -> {
ICraftingTask task = network.getCraftingManager().create(stack, quantity);
if (task == null) {
return;
}
ICraftingTaskError error = task.calculate();
if (error != null) {
RS.INSTANCE.network.sendTo(new MessageGridCraftingPreviewResponse(Collections.singletonList(new CraftingPreviewElementError(error.getType(), error.getRecursedPattern() == null ? ItemStack.EMPTY : error.getRecursedPattern().getStack())), hash, quantity, true), player);
} else if (noPreview && task.getMissing().isEmpty()) {
network.getCraftingManager().add(task);
RS.INSTANCE.network.sendTo(new MessageGridCraftingStartResponse(), player);
} else {
RS.INSTANCE.network.sendTo(new MessageGridCraftingPreviewResponse(task.getPreviewStacks(), hash, quantity, true), player);
}
}, "RS crafting preview calculation");
calculationThread.start();
}
}
@Override
public void onCraftingRequested(EntityPlayerMP player, int hash, int quantity) {
if (quantity <= 0 || !network.getSecurityManager().hasPermission(Permission.AUTOCRAFTING, player)) {
return;
}
FluidStack stack = null;
for (ICraftingPattern pattern : network.getCraftingManager().getPatterns()) {
for (FluidStack output : pattern.getFluidOutputs()) {
if (API.instance().getFluidStackHashCode(output) == hash) {
stack = output;
break;
}
}
if (stack != null) {
break;
}
}
if (stack != null) {
ICraftingTask task = network.getCraftingManager().create(stack, quantity);
if (task == null) {
return;
}
ICraftingTaskError error = task.calculate();
if (error == null) {
network.getCraftingManager().add(task);
}
}
}
}

View File

@@ -196,13 +196,13 @@ public class ItemGridHandler implements IItemGridHandler {
ICraftingTaskError error = task.calculate();
if (error != null) {
RS.INSTANCE.network.sendTo(new MessageGridCraftingPreviewResponse(Collections.singletonList(new CraftingPreviewElementError(error.getType(), error.getRecursedPattern() == null ? ItemStack.EMPTY : error.getRecursedPattern().getStack())), hash, quantity), player);
RS.INSTANCE.network.sendTo(new MessageGridCraftingPreviewResponse(Collections.singletonList(new CraftingPreviewElementError(error.getType(), error.getRecursedPattern() == null ? ItemStack.EMPTY : error.getRecursedPattern().getStack())), hash, quantity, false), player);
} else if (noPreview && task.getMissing().isEmpty()) {
network.getCraftingManager().add(task);
RS.INSTANCE.network.sendTo(new MessageGridCraftingStartResponse(), player);
} else {
RS.INSTANCE.network.sendTo(new MessageGridCraftingPreviewResponse(task.getPreviewStacks(), hash, quantity), player);
RS.INSTANCE.network.sendTo(new MessageGridCraftingPreviewResponse(task.getPreviewStacks(), hash, quantity, false), player);
}
}, "RS crafting preview calculation");

View File

@@ -48,6 +48,7 @@ import net.minecraftforge.items.wrapper.CombinedInvWrapper;
import javax.annotation.Nullable;
// TODO: Crafting upgrade for fluids.
public class NetworkNodeConstructor extends NetworkNode implements IComparable, IType, ICoverable {
public static final String ID = "constructor";

View File

@@ -19,6 +19,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorldNameable;
import net.minecraft.world.World;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
@@ -187,6 +188,17 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC
return WorldUtils.getItemHandler(proxy.getFacingTile(), proxy.getDirection().getOpposite());
}
@Nullable
@Override
public IFluidHandler getConnectedFluidInventory() {
ICraftingPatternContainer proxy = getRootContainer();
if (proxy == null) {
return null;
}
return WorldUtils.getFluidHandler(proxy.getFacingTile(), proxy.getDirection().getOpposite());
}
@Override
@Nullable
public TileEntity getConnectedTile() {

View File

@@ -183,7 +183,7 @@ public class NetworkNodeDestructor extends NetworkNode implements IComparable, I
if (stack != null && IFilterable.acceptsFluid(fluidFilters, mode, compare, stack) && network.insertFluid(stack, stack.amount, Action.SIMULATE) == null) {
FluidStack drained = handler.drain(Fluid.BUCKET_VOLUME, true);
network.insertFluid(drained, drained.amount, Action.PERFORM);
network.insertFluidTracked(drained, drained.amount);
}
}
}

View File

@@ -29,6 +29,7 @@ import net.minecraftforge.items.wrapper.CombinedInvWrapper;
import javax.annotation.Nullable;
// TODO: Crafting upgrade for fluids
public class NetworkNodeExporter extends NetworkNode implements IComparable, IType, ICoverable {
public static final String ID = "exporter";

View File

@@ -19,6 +19,7 @@ import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
import org.apache.commons.lang3.tuple.Pair;
// TODO: Crafting upgrade
public class NetworkNodeFluidInterface extends NetworkNode implements IComparable {
public static final String ID = "fluid_interface";
@@ -96,7 +97,7 @@ public class NetworkNodeFluidInterface extends NetworkNode implements IComparabl
// Drain in tank
if (drained != null) {
FluidStack remainder = network.insertFluid(drained, drained.amount, Action.PERFORM);
FluidStack remainder = network.insertFluidTracked(drained, drained.amount);
if (remainder != null) {
tankIn.fillInternal(remainder, true);
@@ -112,7 +113,7 @@ public class NetworkNodeFluidInterface extends NetworkNode implements IComparabl
FluidStack remainder = tankOut.drainInternal(Fluid.BUCKET_VOLUME * upgrades.getItemInteractCount(), true);
if (remainder != null) {
network.insertFluid(remainder, remainder.amount, Action.PERFORM);
network.insertFluidTracked(remainder, remainder.amount);
}
} else if (stack != null) {
// Fill the out fluid

View File

@@ -22,11 +22,9 @@ import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheListenerGridFluid;
import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheListenerGridItem;
import com.raoulvdberge.refinedstorage.block.BlockGrid;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerFilter;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerListenerNetworkNode;
import com.raoulvdberge.refinedstorage.inventory.ItemValidatorBasic;
import com.raoulvdberge.refinedstorage.inventory.*;
import com.raoulvdberge.refinedstorage.item.ItemPattern;
import com.raoulvdberge.refinedstorage.tile.config.IType;
import com.raoulvdberge.refinedstorage.tile.data.TileDataManager;
import com.raoulvdberge.refinedstorage.tile.grid.TileGrid;
import com.raoulvdberge.refinedstorage.util.StackUtils;
@@ -41,6 +39,7 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
@@ -53,7 +52,7 @@ import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware, IType {
public static final String ID = "grid";
public static final String NBT_VIEW_TYPE = "ViewType";
@@ -65,6 +64,7 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
public static final String NBT_TAB_PAGE = "TabPage";
public static final String NBT_SIZE = "Size";
public static final String NBT_PROCESSING_PATTERN = "ProcessingPattern";
public static final String NBT_PROCESSING_TYPE = "ProcessingType";
private Container craftingContainer = new Container() {
@Override
@@ -81,6 +81,7 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
private InventoryCrafting matrix = new InventoryCrafting(craftingContainer, 3, 3);
private InventoryCraftResult result = new InventoryCraftResult();
private ItemHandlerBase matrixProcessing = new ItemHandlerBase(9 * 2, new ItemHandlerListenerNetworkNode(this));
private ItemHandlerFluid matrixProcessingFluids = new ItemHandlerFluid(9 * 2, new ItemHandlerListenerNetworkNode(this));
private ItemHandlerBase patterns = new ItemHandlerBase(2, new ItemHandlerListenerNetworkNode(this), new ItemValidatorBasic(RSItems.PATTERN)) {
@Override
@@ -144,6 +145,7 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
private boolean oredictPattern = false;
private boolean processingPattern = false;
private int processingType = IType.ITEMS;
public NetworkNodeGrid(World world, BlockPos pos) {
super(world, pos);
@@ -151,7 +153,7 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
@Override
public int getEnergyUsage() {
switch (getType()) {
switch (getGridType()) {
case NORMAL:
return RS.INSTANCE.config.gridUsage;
case CRAFTING:
@@ -209,7 +211,8 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
this.processingPattern = processingPattern;
}
public GridType getType() {
@Override
public GridType getGridType() {
if (type == null) {
IBlockState state = world.getBlockState(pos);
if (state.getBlock() == RSBlocks.GRID) {
@@ -222,13 +225,13 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
@Override
public IStorageCacheListener createListener(EntityPlayerMP player) {
return getType() == GridType.FLUID ? new StorageCacheListenerGridFluid(player, network) : new StorageCacheListenerGridItem(player, network);
return getGridType() == GridType.FLUID ? new StorageCacheListenerGridFluid(player, network) : new StorageCacheListenerGridItem(player, network);
}
@Nullable
@Override
public IStorageCache getStorageCache() {
return network != null ? (getType() == GridType.FLUID ? network.getFluidStorageCache() : network.getItemStorageCache()) : null;
return network != null ? (getGridType() == GridType.FLUID ? network.getFluidStorageCache() : network.getItemStorageCache()) : null;
}
@Nullable
@@ -245,7 +248,7 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
@Override
public String getGuiTitle() {
GridType type = getType();
GridType type = getGridType();
switch (type) {
case CRAFTING:
@@ -292,6 +295,10 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
return matrixProcessing;
}
public ItemHandlerFluid getMatrixProcessingFluids() {
return matrixProcessingFluids;
}
@Override
public void onCraftingMatrixChanged() {
if (currentRecipe == null || !currentRecipe.matches(matrix, world)) {
@@ -315,7 +322,7 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
public static void onRecipeTransfer(IGridNetworkAware grid, EntityPlayer player, ItemStack[][] recipe) {
INetwork network = grid.getNetwork();
if (network != null && grid.getType() == GridType.CRAFTING && !network.getSecurityManager().hasPermission(Permission.EXTRACT, player)) {
if (network != null && grid.getGridType() == GridType.CRAFTING && !network.getSecurityManager().hasPermission(Permission.EXTRACT, player)) {
return;
}
@@ -325,7 +332,7 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
if (!slot.isEmpty()) {
// Only if we are a crafting grid. Pattern grids can just be emptied.
if (grid.getType() == GridType.CRAFTING) {
if (grid.getGridType() == GridType.CRAFTING) {
// If we are connected, try to insert into network. If it fails, stop.
if (network != null) {
if (network.insertItem(slot, slot.getCount(), Action.SIMULATE) != null) {
@@ -351,7 +358,7 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
ItemStack[] possibilities = recipe[i];
// If we are a crafting grid
if (grid.getType() == GridType.CRAFTING) {
if (grid.getGridType() == GridType.CRAFTING) {
boolean found = false;
// If we are connected, first try to get the possibilities from the network
@@ -389,7 +396,7 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
}
}
}
} else if (grid.getType() == GridType.PATTERN) {
} else if (grid.getGridType() == GridType.PATTERN) {
// If we are a pattern grid we can just set the slot
grid.getCraftingMatrix().setInventorySlotContents(i, possibilities.length == 0 ? ItemStack.EMPTY : possibilities[0]);
}
@@ -402,6 +409,10 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
matrixProcessing.setStackInSlot(i, ItemStack.EMPTY);
}
for (int i = 0; i < matrixProcessingFluids.getSlots(); ++i) {
matrixProcessingFluids.setStackInSlot(i, ItemStack.EMPTY);
}
for (int i = 0; i < matrix.getSizeInventory(); ++i) {
matrix.setInventorySlotContents(i, ItemStack.EMPTY);
}
@@ -520,6 +531,20 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
ItemPattern.setInputSlot(pattern, i, matrixProcessing.getStackInSlot(i));
}
}
if (!matrixProcessingFluids.getStackInSlot(i).isEmpty()) {
if (i >= 9) {
FluidStack fluid = StackUtils.getFluid(ItemHandlerHelper.copyStackWithSize(matrixProcessingFluids.getStackInSlot(i), 1), true).getValue();
if (fluid != null) {
ItemPattern.setFluidOutputSlot(pattern, i - 9, StackUtils.copy(fluid, matrixProcessingFluids.getStackInSlot(i).getCount()));
}
} else {
FluidStack fluid = StackUtils.getFluid(ItemHandlerHelper.copyStackWithSize(matrixProcessingFluids.getStackInSlot(i), 1), true).getValue();
if (fluid != null) {
ItemPattern.setFluidInputSlot(pattern, i, StackUtils.copy(fluid, matrixProcessingFluids.getStackInSlot(i).getCount()));
}
}
}
}
} else {
for (int i = 0; i < 9; ++i) {
@@ -552,12 +577,20 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
if (!matrixProcessing.getStackInSlot(i).isEmpty()) {
inputsFilled++;
}
if (!matrixProcessingFluids.getStackInSlot(i).isEmpty()) {
inputsFilled++;
}
}
for (int i = 9; i < 18; ++i) {
if (!matrixProcessing.getStackInSlot(i).isEmpty()) {
outputsFilled++;
}
if (!matrixProcessingFluids.getStackInSlot(i).isEmpty()) {
outputsFilled++;
}
}
return inputsFilled > 0 && outputsFilled > 0;
@@ -643,6 +676,23 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
}
}
@Override
public int getType() {
return world.isRemote ? TileGrid.PROCESSING_TYPE.getValue() : processingType;
}
@Override
public void setType(int type) {
this.processingType = type;
this.markDirty();
}
@Override
public IItemHandler getFilterInventory() {
return getType() == IType.FLUIDS ? matrixProcessingFluids : matrixProcessing;
}
@Override
public boolean hasConnectivityState() {
return true;
@@ -656,6 +706,7 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
StackUtils.readItems(patterns, 1, tag);
StackUtils.readItems(filter, 2, tag);
StackUtils.readItems(matrixProcessing, 3, tag);
StackUtils.readItems(matrixProcessingFluids, 4, tag, StackUtils::deserializeStackFromNbt);
if (tag.hasKey(NBT_TAB_SELECTED)) {
tabSelected = tag.getInteger(NBT_TAB_SELECTED);
@@ -679,6 +730,7 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
StackUtils.writeItems(patterns, 1, tag);
StackUtils.writeItems(filter, 2, tag);
StackUtils.writeItems(matrixProcessing, 3, tag);
StackUtils.writeItems(matrixProcessingFluids, 4, tag, StackUtils::serializeStackToNbt);
tag.setInteger(NBT_TAB_SELECTED, tabSelected);
tag.setInteger(NBT_TAB_PAGE, tabPage);
@@ -698,6 +750,7 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
tag.setBoolean(NBT_OREDICT_PATTERN, oredictPattern);
tag.setBoolean(NBT_PROCESSING_PATTERN, processingPattern);
tag.setInteger(NBT_PROCESSING_TYPE, processingType);
return tag;
}
@@ -733,11 +786,15 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
if (tag.hasKey(NBT_PROCESSING_PATTERN)) {
processingPattern = tag.getBoolean(NBT_PROCESSING_PATTERN);
}
if (tag.hasKey(NBT_PROCESSING_TYPE)) {
processingType = tag.getInteger(NBT_PROCESSING_TYPE);
}
}
@Override
public IItemHandler getDrops() {
switch (getType()) {
switch (getGridType()) {
case CRAFTING:
return new CombinedInvWrapper(filter, new InvWrapper(matrix));
case PATTERN:

View File

@@ -115,7 +115,7 @@ public class NetworkNodeImporter extends NetworkNode implements IComparable, IFi
FluidStack toDrain = handler.drain(Fluid.BUCKET_VOLUME * upgrades.getItemInteractCount(), false);
if (toDrain != null) {
FluidStack remainder = network.insertFluid(toDrain, toDrain.amount, Action.PERFORM);
FluidStack remainder = network.insertFluidTracked(toDrain, toDrain.amount);
if (remainder != null) {
toDrain.amount -= remainder.amount;
}

View File

@@ -1,6 +1,8 @@
package com.raoulvdberge.refinedstorage.apiimpl.util;
import com.raoulvdberge.refinedstorage.api.util.IQuantityFormatter;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraftforge.fluids.Fluid;
import java.math.RoundingMode;
import java.text.DecimalFormat;
@@ -10,6 +12,7 @@ import java.util.Locale;
public class QuantityFormatter implements IQuantityFormatter {
private DecimalFormat formatterWithUnits = new DecimalFormat("####0.#", DecimalFormatSymbols.getInstance(Locale.US));
private DecimalFormat formatter = new DecimalFormat("#,###", DecimalFormatSymbols.getInstance(Locale.US));
private DecimalFormat bucketFormatter = new DecimalFormat("####0.###", DecimalFormatSymbols.getInstance(Locale.US));
public QuantityFormatter() {
formatterWithUnits.setRoundingMode(RoundingMode.DOWN);
@@ -42,4 +45,21 @@ public class QuantityFormatter implements IQuantityFormatter {
public String format(int qty) {
return formatter.format(qty);
}
@Override
public String formatInBucketForm(int qty) {
return bucketFormatter.format((float) qty / (float) Fluid.BUCKET_VOLUME) + " B";
}
@Override
public String formatInBucketFormWithOnlyTrailingDigitsIfZero(int qty) {
float amountRaw = ((float) qty / (float) Fluid.BUCKET_VOLUME);
int amount = (int) amountRaw;
if (amount >= 1) {
return API.instance().getQuantityFormatter().formatWithUnits(amount);
} else {
return String.format("%.1f", amountRaw);
}
}
}

View File

@@ -2,15 +2,22 @@ package com.raoulvdberge.refinedstorage.container;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.container.slot.*;
import com.raoulvdberge.refinedstorage.gui.GuiBase;
import com.raoulvdberge.refinedstorage.gui.GuiFluidAmount;
import com.raoulvdberge.refinedstorage.tile.TileBase;
import com.raoulvdberge.refinedstorage.tile.config.IType;
import com.raoulvdberge.refinedstorage.tile.data.TileDataWatcher;
import invtweaks.api.container.InventoryContainer;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.ClickType;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.items.ItemHandlerHelper;
import javax.annotation.Nonnull;
@@ -77,21 +84,21 @@ public abstract class ContainerBase extends Container {
}
if (slot instanceof SlotFilter) {
if (((SlotFilter) slot).allowsSize()) {
if (((SlotFilter) slot).isSizeAllowed()) {
if (clickType == ClickType.QUICK_MOVE) {
slot.putStack(ItemStack.EMPTY);
} else if (!player.inventory.getItemStack().isEmpty()) {
slot.putStack(player.inventory.getItemStack().copy());
slot.putStack(ItemHandlerHelper.copyStackWithSize(player.inventory.getItemStack(), ((SlotFilter) slot).getInitialAmount(player.inventory.getItemStack())));
} else if (slot.getHasStack()) {
int amount = slot.getStack().getCount();
if (slot instanceof SlotFilterType && ((SlotFilterType) slot).getType().getType() == IType.FLUIDS) {
if (FMLCommonHandler.instance().getSide() == Side.CLIENT) {
FMLClientHandler.instance().showGuiScreen(new GuiFluidAmount((GuiBase) Minecraft.getMinecraft().currentScreen, player, slot.getSlotIndex(), ((SlotFilterType) slot).getActualStack()));
}
} else {
slot.getStack().setCount(((SlotFilter) slot).getAmountModified(dragType));
if (dragType == 0) {
amount = Math.max(1, amount - 1);
} else if (dragType == 1) {
amount = Math.min(slot.getStack().getMaxStackSize(), amount + 1);
detectAndSendChanges();
}
slot.getStack().setCount(amount);
}
} else if (player.inventory.getItemStack().isEmpty()) {
slot.putStack(ItemStack.EMPTY);
@@ -149,7 +156,7 @@ public abstract class ContainerBase extends Container {
if (slot instanceof SlotFilterFluid) {
stackInSlot = ((SlotFilterFluid) slot).getRealStack();
} else if (slot instanceof SlotFilterType) {
stackInSlot = ((SlotFilterType) slot).getRealStack();
stackInSlot = ((SlotFilterType) slot).getActualStack();
}
}

View File

@@ -1,112 +1,45 @@
package com.raoulvdberge.refinedstorage.container;
import com.raoulvdberge.refinedstorage.container.slot.SlotDisabled;
import com.raoulvdberge.refinedstorage.gui.grid.stack.GridStackFluid;
import com.raoulvdberge.refinedstorage.gui.grid.stack.GridStackItem;
import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerFluid;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.SlotItemHandler;
import javax.annotation.Nullable;
import javax.annotation.Nonnull;
public class ContainerCraftingSettings extends ContainerBase {
public ContainerCraftingSettings(EntityPlayer player, final ItemStack stack) {
public ContainerCraftingSettings(EntityPlayer player, IGridStack stack) {
super(null, player);
final ItemStack slot = ItemHandlerHelper.copyStackWithSize(stack, 1);
IItemHandler handler = null;
addSlotToContainer(new SlotDisabled(new IInventory() {
@Override
public int getSizeInventory() {
return 1;
}
if (stack instanceof GridStackFluid) {
handler = new ItemHandlerFluid(1, null);
@Override
public boolean isEmpty() {
return true;
}
((ItemHandlerFluid) handler).setFluidStack(0, ((GridStackFluid) stack).getStack());
} else if (stack instanceof GridStackItem) {
handler = new ItemStackHandler(1);
@Nullable
@Override
public ItemStack getStackInSlot(int index) {
return slot;
}
((ItemStackHandler) handler).setStackInSlot(0, ItemHandlerHelper.copyStackWithSize(((GridStackItem) stack).getStack(), 1));
}
@Nullable
addSlotToContainer(new SlotItemHandler(handler, 0, 89, 48) {
@Override
public ItemStack decrStackSize(int index, int count) {
return null;
}
@Nullable
@Override
public ItemStack removeStackFromSlot(int index) {
return null;
}
@Override
public void setInventorySlotContents(int index, @Nullable ItemStack stack) {
}
@Override
public int getInventoryStackLimit() {
return 0;
}
@Override
public void markDirty() {
}
@Override
public boolean isUsableByPlayer(EntityPlayer player) {
public boolean isItemValid(@Nonnull ItemStack stack) {
return false;
}
@Nonnull
@Override
public void openInventory(EntityPlayer player) {
public ItemStack getStack() {
return stack instanceof GridStackFluid ? ItemStack.EMPTY : super.getStack();
}
@Override
public void closeInventory(EntityPlayer player) {
}
@Override
public boolean isItemValidForSlot(int index, ItemStack stack) {
return false;
}
@Override
public int getField(int id) {
return 0;
}
@Override
public void setField(int id, int value) {
}
@Override
public int getFieldCount() {
return 0;
}
@Override
public void clear() {
}
@Override
public String getName() {
return null;
}
@Override
public boolean hasCustomName() {
return false;
}
@Override
public ITextComponent getDisplayName() {
return null;
}
}, 0, 89, 48));
});
}
}

View File

@@ -0,0 +1,32 @@
package com.raoulvdberge.refinedstorage.container;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerFluid;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.SlotItemHandler;
import javax.annotation.Nonnull;
public class ContainerFluidAmount extends ContainerBase {
public ContainerFluidAmount(EntityPlayer player, ItemStack fluidContainer) {
super(null, player);
ItemHandlerFluid handler = new ItemHandlerFluid(1, null);
handler.setStackInSlot(0, ItemHandlerHelper.copyStackWithSize(fluidContainer, 1));
addSlotToContainer(new SlotItemHandler(handler, 0, 89, 48) {
@Override
public boolean isItemValid(@Nonnull ItemStack stack) {
return false;
}
@Nonnull
@Override
public ItemStack getStack() {
return ItemStack.EMPTY;
}
});
}
}

View File

@@ -49,7 +49,7 @@ public class ContainerGrid extends ContainerBase {
int headerAndSlots = getTabDelta() + display.getTopHeight() + (display.getVisibleRows() * 18);
if (grid.getType() != GridType.FLUID) {
if (grid.getGridType() != GridType.FLUID) {
int yStart = 6;
if (grid instanceof IPortableGrid) {
@@ -61,7 +61,7 @@ public class ContainerGrid extends ContainerBase {
}
}
if (grid.getType() == GridType.PATTERN) {
if (grid.getGridType() == GridType.PATTERN) {
addSlotToContainer(new SlotItemHandler(((NetworkNodeGrid) grid).getPatterns(), 0, 172, headerAndSlots + 4));
addSlotToContainer(new SlotItemHandler(((NetworkNodeGrid) grid).getPatterns(), 1, 172, headerAndSlots + 40));
}
@@ -72,7 +72,7 @@ public class ContainerGrid extends ContainerBase {
addPlayerInventory(8, display.getYPlayerInventory());
if (grid.getType() == GridType.CRAFTING) {
if (grid.getGridType() == GridType.CRAFTING) {
int x = 26;
int y = headerAndSlots + 4;
@@ -88,14 +88,14 @@ public class ContainerGrid extends ContainerBase {
}
addSlotToContainer(craftingResultSlot = new SlotGridCraftingResult(this, getPlayer(), grid, 0, 130 + 4, headerAndSlots + 22));
} else if (grid.getType() == GridType.PATTERN) {
} else if (grid.getGridType() == GridType.PATTERN) {
if (((NetworkNodeGrid) grid).isProcessingPattern()) {
int ox = 8;
int x = ox;
int y = headerAndSlots + 4;
for (int i = 0; i < 9 * 2; ++i) {
addSlotToContainer(new SlotFilter(((NetworkNodeGrid) grid).getProcessingMatrix(), i, x, y, SlotFilter.FILTER_ALLOW_SIZE));
addSlotToContainer(new SlotFilterType((NetworkNodeGrid) grid, i, x, y, SlotFilter.FILTER_ALLOW_SIZE));
x += 18;
@@ -210,7 +210,7 @@ public class ContainerGrid extends ContainerBase {
if (slot.getHasStack()) {
if (grid instanceof IPortableGrid && slot.slotNumber == 4) { // Prevent moving disk slot into portable grid itself
return ItemStack.EMPTY;
} else if (grid.getType() == GridType.PATTERN && slot.slotNumber == 5) { // From output slot to inventory
} else if (grid.getGridType() == GridType.PATTERN && slot.slotNumber == 5) { // From output slot to inventory
ItemStack stack = slot.getStack();
int startIndex = 5;
@@ -231,7 +231,7 @@ public class ContainerGrid extends ContainerBase {
} else if (slot != patternResultSlot && !(slot instanceof SlotFilterLegacy)) {
ItemStack stack = slot.getStack();
if (grid.getType() != GridType.FLUID && stack.getItem() == RSItems.FILTER) {
if (grid.getGridType() != GridType.FLUID && stack.getItem() == RSItems.FILTER) {
int startIndex = 0;
int endIndex = 4;
@@ -239,7 +239,7 @@ public class ContainerGrid extends ContainerBase {
if (slotIndex < 4) {
startIndex = 4;
if (grid.getType() == GridType.PATTERN) {
if (grid.getGridType() == GridType.PATTERN) {
startIndex += 2; // Skip the pattern slots
}
@@ -258,7 +258,7 @@ public class ContainerGrid extends ContainerBase {
return ItemStack.EMPTY;
}
} else if ((grid.getType() == GridType.PATTERN && stack.getItem() == RSItems.PATTERN) || (grid instanceof IPortableGrid && stack.getItem() instanceof IStorageDiskFactory)) {
} else if ((grid.getGridType() == GridType.PATTERN && stack.getItem() == RSItems.PATTERN) || (grid instanceof IPortableGrid && stack.getItem() instanceof IStorageDiskFactory)) {
int startIndex = 4;
int endIndex = startIndex + 1;
@@ -287,7 +287,7 @@ public class ContainerGrid extends ContainerBase {
}
}
if (grid.getType() == GridType.FLUID) {
if (grid.getGridType() == GridType.FLUID) {
IFluidGridHandler fluidHandler = grid.getFluidHandler();
if (fluidHandler != null) {

View File

@@ -31,7 +31,7 @@ public class SlotFilter extends SlotItemHandler {
@Override
public boolean isItemValid(@Nonnull ItemStack stack) {
if (super.isItemValid(stack)) {
if (allowsBlocks()) {
if (isBlockAllowed()) {
return stack.getItem() instanceof ItemBlock || stack.getItem() instanceof ItemBlockSpecial || stack.getItem() instanceof IPlantable || stack.getItem() instanceof ItemSkull;
}
@@ -43,21 +43,37 @@ public class SlotFilter extends SlotItemHandler {
@Override
public void putStack(@Nonnull ItemStack stack) {
if (!stack.isEmpty() && !allowsSize()) {
if (!stack.isEmpty() && !isSizeAllowed()) {
stack.setCount(1);
}
super.putStack(stack);
}
public boolean allowsSize() {
public boolean isSizeAllowed() {
return (flags & FILTER_ALLOW_SIZE) == FILTER_ALLOW_SIZE;
}
public boolean allowsBlocks() {
public boolean isBlockAllowed() {
return (flags & FILTER_ALLOW_BLOCKS) == FILTER_ALLOW_BLOCKS;
}
public int getAmountModified(int dragType) {
int amount = getStack().getCount();
if (dragType == 0) {
amount = Math.max(1, amount - 1);
} else if (dragType == 1) {
amount = Math.min(getStack().getMaxStackSize(), amount + 1);
}
return amount;
}
public int getInitialAmount(ItemStack stack) {
return stack.getCount();
}
@Nullable
public static IBlockState getBlockState(IBlockAccess world, BlockPos pos, @Nullable ItemStack stack) {
if (stack != null) {

View File

@@ -3,6 +3,7 @@ package com.raoulvdberge.refinedstorage.container.slot;
import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNode;
import com.raoulvdberge.refinedstorage.tile.config.IType;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.items.IItemHandler;
import javax.annotation.Nonnull;
@@ -26,13 +27,8 @@ public class SlotFilterType extends SlotFilter {
}
@Override
public boolean allowsSize() {
return super.allowsSize() && type.getType() != IType.FLUIDS;
}
@Override
public boolean allowsBlocks() {
return super.allowsBlocks() && type.getType() == IType.ITEMS;
public boolean isBlockAllowed() {
return super.isBlockAllowed() && type.getType() == IType.ITEMS;
}
@Override
@@ -41,7 +37,20 @@ public class SlotFilterType extends SlotFilter {
return (type.getType() == IType.ITEMS || !((NetworkNode) type).getWorld().isRemote) ? super.getStack() : ItemStack.EMPTY;
}
public ItemStack getRealStack() {
public ItemStack getActualStack() {
return super.getStack();
}
public IType getType() {
return type;
}
@Override
public int getInitialAmount(ItemStack stack) {
if (type.getType() == IType.FLUIDS && isSizeAllowed()) {
return Fluid.BUCKET_VOLUME;
}
return super.getInitialAmount(stack);
}
}

View File

@@ -3,6 +3,7 @@ package com.raoulvdberge.refinedstorage.gui;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.api.render.IElementDrawer;
import com.raoulvdberge.refinedstorage.api.render.IElementDrawers;
import com.raoulvdberge.refinedstorage.container.slot.SlotFilterType;
import com.raoulvdberge.refinedstorage.gui.control.Scrollbar;
import com.raoulvdberge.refinedstorage.gui.control.SideButton;
import com.raoulvdberge.refinedstorage.integration.jei.IntegrationJEI;
@@ -24,6 +25,7 @@ import net.minecraftforge.fml.client.config.GuiUtils;
import net.minecraftforge.items.SlotItemHandler;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -187,6 +189,16 @@ public abstract class GuiBase extends GuiContainer {
if (stack != null) {
FLUID_RENDERER.draw(mc, guiLeft + slot.xPos, guiTop + slot.yPos, stack);
if (slot instanceof SlotFilterType) {
int count = ((SlotFilterType) slot).getActualStack().getCount();
if (count != 1) {
drawQuantity(guiLeft + slot.xPos, guiTop + slot.yPos, String.valueOf(count));
GL11.glDisable(GL11.GL_LIGHTING);
}
}
if (inBounds(guiLeft + slot.xPos, guiTop + slot.yPos, 18, 18, mouseX, mouseY)) {
this.hoveringFluid = stack.getLocalizedName();
}

View File

@@ -4,11 +4,13 @@ import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingRequestInfo;
import com.raoulvdberge.refinedstorage.api.network.grid.IGrid;
import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab;
import com.raoulvdberge.refinedstorage.api.render.IElementDrawer;
import com.raoulvdberge.refinedstorage.api.render.IElementDrawers;
import com.raoulvdberge.refinedstorage.api.util.IFilter;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.container.ContainerCraftingMonitor;
import com.raoulvdberge.refinedstorage.gui.control.Scrollbar;
import com.raoulvdberge.refinedstorage.gui.control.SideButtonGridSize;
@@ -23,6 +25,7 @@ import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.resources.I18n;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
import java.io.IOException;
@@ -46,12 +49,12 @@ public class GuiCraftingMonitor extends GuiBase implements IResizableDisplay {
public static class CraftingMonitorTask implements IGridTab {
private UUID id;
private ItemStack requested;
private ICraftingRequestInfo requested;
private int qty;
private long executionStarted;
private List<ICraftingMonitorElement> elements;
public CraftingMonitorTask(UUID id, ItemStack requested, int qty, long executionStarted, List<ICraftingMonitorElement> elements) {
public CraftingMonitorTask(UUID id, ICraftingRequestInfo requested, int qty, long executionStarted, List<ICraftingMonitorElement> elements) {
this.id = id;
this.requested = requested;
this.qty = qty;
@@ -66,22 +69,26 @@ public class GuiCraftingMonitor extends GuiBase implements IResizableDisplay {
@Override
public void drawTooltip(int x, int y, int screenWidth, int screenHeight, FontRenderer fontRenderer) {
List<String> textLines = Lists.newArrayList(requested.getDisplayName());
List<String> textLines = Lists.newArrayList(requested.getItem() != null ? requested.getItem().getDisplayName() : requested.getFluid().getLocalizedName());
List<String> smallTextLines = Lists.newArrayList();
int totalSecs = (int) (System.currentTimeMillis() - executionStarted) / 1000;
int minutes = (totalSecs % 3600) / 60;
int seconds = totalSecs % 60;
smallTextLines.add(I18n.format("gui.refinedstorage:crafting_monitor.tooltip.requested", qty));
smallTextLines.add(I18n.format("gui.refinedstorage:crafting_monitor.tooltip.requested", requested.getFluid() != null ? API.instance().getQuantityFormatter().formatInBucketForm(qty) : API.instance().getQuantityFormatter().format(qty)));
smallTextLines.add(String.format("%02d:%02d", minutes, seconds));
RenderUtils.drawTooltipWithSmallText(textLines, smallTextLines, true, ItemStack.EMPTY, x, y, screenWidth, screenHeight, fontRenderer);
}
@Override
public ItemStack getIcon() {
return requested;
public void drawIcon(int x, int y, IElementDrawer<ItemStack> itemDrawer, IElementDrawer<FluidStack> fluidDrawer) {
if (requested.getItem() != null) {
itemDrawer.draw(x, y, requested.getItem());
} else {
fluidDrawer.draw(x, y, requested.getFluid());
}
}
}
@@ -105,7 +112,7 @@ public class GuiCraftingMonitor extends GuiBase implements IResizableDisplay {
this.craftingMonitor = craftingMonitor;
this.tabs = new TabList(this, () -> tasks, () -> (int) Math.floor((float) Math.max(0, tasks.size() - 1) / (float) ICraftingMonitor.TABS_PER_PAGE), craftingMonitor::getTabPage, () -> {
this.tabs = new TabList(this, new ElementDrawers(), () -> tasks, () -> (int) Math.floor((float) Math.max(0, tasks.size() - 1) / (float) ICraftingMonitor.TABS_PER_PAGE), craftingMonitor::getTabPage, () -> {
IGridTab tab = getCurrentTab();
if (tab == null) {

View File

@@ -31,6 +31,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
// TODO: Make bigger/resizeable and allow more space?
public class GuiCraftingPreview extends GuiBase {
public class CraftingPreviewElementDrawers extends ElementDrawers {
private IElementDrawer<Integer> overlayDrawer = (x, y, colour) -> {
@@ -61,7 +62,9 @@ public class GuiCraftingPreview extends GuiBase {
private IElementDrawers drawers = new CraftingPreviewElementDrawers();
public GuiCraftingPreview(GuiScreen parent, List<ICraftingPreviewElement> stacks, int hash, int quantity) {
private boolean fluids;
public GuiCraftingPreview(GuiScreen parent, List<ICraftingPreviewElement> stacks, int hash, int quantity, boolean fluids) {
super(new Container() {
@Override
public boolean canInteractWith(EntityPlayer player) {
@@ -74,6 +77,7 @@ public class GuiCraftingPreview extends GuiBase {
this.hash = hash;
this.quantity = quantity;
this.fluids = fluids;
this.scrollbar = new Scrollbar(149, 20, 12, 119);
}
@@ -247,7 +251,7 @@ public class GuiCraftingPreview extends GuiBase {
}
private void startRequest() {
RS.INSTANCE.network.sendToServer(new MessageGridCraftingStart(hash, quantity));
RS.INSTANCE.network.sendToServer(new MessageGridCraftingStart(hash, quantity, fluids));
close();
}

View File

@@ -0,0 +1,66 @@
package com.raoulvdberge.refinedstorage.gui;
import com.google.common.primitives.Ints;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.container.ContainerFluidAmount;
import com.raoulvdberge.refinedstorage.gui.grid.GuiCraftingStart;
import com.raoulvdberge.refinedstorage.network.MessageGridFluidAmount;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.Fluid;
public class GuiFluidAmount extends GuiCraftingStart {
private int slot;
private ItemStack fluidContainer;
public GuiFluidAmount(GuiBase parent, EntityPlayer player, int slot, ItemStack fluidContainer) {
super(parent, null, new ContainerFluidAmount(player, fluidContainer), 172, 99);
this.slot = slot;
this.fluidContainer = fluidContainer;
}
@Override
protected int getAmount() {
return fluidContainer.getCount();
}
@Override
protected String getStartButtonText() {
return t("misc.refinedstorage:set");
}
@Override
protected String getTitle() {
return t("gui.refinedstorage:pattern_grid.fluid_amount");
}
@Override
protected boolean canAmountGoNegative() {
return false;
}
@Override
protected int[] getIncrements() {
return new int[]{
10, 50, 100,
-10, -50, -100
};
}
@Override
protected int getMaxAmount() {
return Fluid.BUCKET_VOLUME;
}
@Override
protected void startRequest(boolean noPreview) {
Integer amount = Ints.tryParse(amountField.getText());
if (amount != null && amount > 0 && amount <= Fluid.BUCKET_VOLUME) {
RS.INSTANCE.network.sendToServer(new MessageGridFluidAmount(slot, amount));
close();
}
}
}

View File

@@ -38,7 +38,7 @@ public class SideButtonGridSortingType extends SideButton {
if (type == IGrid.SORTING_TYPE_QUANTITY) {
type = IGrid.SORTING_TYPE_NAME;
} else if (type == IGrid.SORTING_TYPE_NAME) {
if (grid.getType() == GridType.FLUID) {
if (grid.getGridType() == GridType.FLUID) {
type = IGrid.SORTING_TYPE_LAST_MODIFIED;
} else {
type = IGrid.SORTING_TYPE_ID;
@@ -46,7 +46,7 @@ public class SideButtonGridSortingType extends SideButton {
} else if (type == IGrid.SORTING_TYPE_ID) {
type = IGrid.SORTING_TYPE_LAST_MODIFIED;
} else if (type == NetworkNodeGrid.SORTING_TYPE_LAST_MODIFIED) {
if (grid.getType() == GridType.FLUID || !Loader.isModLoaded(GridSorterInventoryTweaks.MOD_ID)) {
if (grid.getGridType() == GridType.FLUID || !Loader.isModLoaded(GridSorterInventoryTweaks.MOD_ID)) {
type = IGrid.SORTING_TYPE_QUANTITY;
} else {
type = IGrid.SORTING_TYPE_INVENTORYTWEAKS;

View File

@@ -4,7 +4,6 @@ import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab;
import com.raoulvdberge.refinedstorage.gui.GuiBase;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.RenderHelper;
import java.util.LinkedList;
import java.util.List;
@@ -18,6 +17,7 @@ public class TabList {
}
private GuiBase gui;
private GuiBase.ElementDrawers drawers;
private Supplier<List<IGridTab>> tabs;
private int tabHovering;
@@ -34,8 +34,9 @@ public class TabList {
private int width;
public TabList(GuiBase gui, Supplier<List<IGridTab>> tabs, Supplier<Integer> pages, Supplier<Integer> page, Supplier<Integer> selected, int tabsPerPage) {
public TabList(GuiBase gui, GuiBase.ElementDrawers drawers, Supplier<List<IGridTab>> tabs, Supplier<Integer> pages, Supplier<Integer> page, Supplier<Integer> selected, int tabsPerPage) {
this.gui = gui;
this.drawers = drawers;
this.tabs = tabs;
this.pages = pages;
this.page = page;
@@ -138,9 +139,7 @@ public class TabList {
gui.drawTexture(tx, ty, uvx, uvy, tbw, IGridTab.TAB_HEIGHT);
RenderHelper.enableGUIStandardItemLighting();
gui.drawItem(otx + 6, ty + 9 - (!isSelected ? 3 : 0), tab.getIcon());
tab.drawIcon(otx + 6, ty + 9 - (!isSelected ? 3 : 0), drawers.getItemDrawer(), drawers.getFluidDrawer());
}
public void drawTooltip(FontRenderer fontRenderer, int mouseX, int mouseY) {

View File

@@ -4,7 +4,8 @@ import com.google.common.primitives.Ints;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.container.ContainerCraftingSettings;
import com.raoulvdberge.refinedstorage.gui.GuiBase;
import com.raoulvdberge.refinedstorage.gui.grid.stack.GridStackItem;
import com.raoulvdberge.refinedstorage.gui.grid.stack.GridStackFluid;
import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack;
import com.raoulvdberge.refinedstorage.network.MessageGridCraftingPreview;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiTextField;
@@ -16,25 +17,27 @@ import org.lwjgl.input.Keyboard;
import java.io.IOException;
// TODO: Change quantities for fluid craft.
// TODO: Cleanup childclasses.
public class GuiCraftingStart extends GuiBase {
private static final int DEFAULT_AMOUNT = 1;
protected GuiTextField amountField;
private GuiBase parent;
private GridStackItem stack;
private IGridStack stack;
private GuiButton startButton;
private GuiButton cancelButton;
private GuiButton[] incrementButtons = new GuiButton[6];
public GuiCraftingStart(GuiBase parent, GridStackItem stack, Container container, int w, int h) {
public GuiCraftingStart(GuiBase parent, IGridStack stack, Container container, int w, int h) {
super(container, w, h);
this.parent = parent;
this.stack = stack;
}
public GuiCraftingStart(GuiGrid parent, EntityPlayer player, GridStackItem stack) {
this(parent, stack, new ContainerCraftingSettings(player, stack.getStack()), 172, 99);
public GuiCraftingStart(GuiGrid parent, EntityPlayer player, IGridStack stack) {
this(parent, stack, new ContainerCraftingSettings(player, stack), 172, 99);
}
protected String getStartButtonText() {
@@ -50,14 +53,21 @@ public class GuiCraftingStart extends GuiBase {
}
protected int[] getIncrements() {
return new int[]{
1, 10, 64,
-1, -10, -64
};
if (stack instanceof GridStackFluid) {
return new int[]{
1, 500, 1000,
-1, -500, -1000
};
} else {
return new int[]{
1, 10, 64,
-1, -10, -64
};
}
}
protected int getAmount() {
return DEFAULT_AMOUNT;
return stack instanceof GridStackFluid ? 1000 : DEFAULT_AMOUNT;
}
protected Tuple<Integer, Integer> getAmountPos() {
@@ -164,6 +174,10 @@ public class GuiCraftingStart extends GuiBase {
newAmount = oldAmount + newAmount;
}
if (newAmount > getMaxAmount()) {
newAmount = getMaxAmount();
}
amountField.setText(String.valueOf(newAmount));
break;
@@ -172,11 +186,15 @@ public class GuiCraftingStart extends GuiBase {
}
}
protected int getMaxAmount() {
return Integer.MAX_VALUE;
}
protected void startRequest(boolean noPreview) {
Integer quantity = Ints.tryParse(amountField.getText());
if (quantity != null && quantity > 0) {
RS.INSTANCE.network.sendToServer(new MessageGridCraftingPreview(stack.getHash(), quantity, noPreview));
RS.INSTANCE.network.sendToServer(new MessageGridCraftingPreview(stack.getHash(), quantity, noPreview, stack instanceof GridStackFluid));
startButton.enabled = false;
}

View File

@@ -55,7 +55,7 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
private int slotNumber;
public GuiGrid(ContainerGrid container, IGrid grid) {
super(container, grid.getType() == GridType.FLUID ? 193 : 227, 0);
super(container, grid.getGridType() == GridType.FLUID ? 193 : 227, 0);
IGridSorter defaultSorter;
@@ -67,9 +67,9 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
sorters.add(new GridSorterLastModified());
this.grid = grid;
this.view = grid.getType() == GridType.FLUID ? new GridViewFluid(this, defaultSorter, sorters) : new GridViewItem(this, defaultSorter, sorters);
this.view = grid.getGridType() == GridType.FLUID ? new GridViewFluid(this, defaultSorter, sorters) : new GridViewItem(this, defaultSorter, sorters);
this.wasConnected = this.grid.isActive();
this.tabs = new TabList(this, grid::getTabs, grid::getTotalTabPages, grid::getTabPage, grid::getTabSelected, IGrid.TABS_PER_PAGE);
this.tabs = new TabList(this, new ElementDrawers(), grid::getTabs, grid::getTotalTabPages, grid::getTabPage, grid::getTabSelected, IGrid.TABS_PER_PAGE);
this.tabs.addListener(new TabList.ITabListListener() {
@Override
public void onSelectionChanged(int tab) {
@@ -113,12 +113,7 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
searchField.y = sy;
}
if (grid.getType() == GridType.PATTERN) {
processingPattern = addCheckBox(x + 7, y + tabs.getHeight() + getTopHeight() + (getVisibleRows() * 18) + 60, t("misc.refinedstorage:processing"), TileGrid.PROCESSING_PATTERN.getValue());
oredictPattern = addCheckBox(processingPattern.x + processingPattern.width + 5, y + tabs.getHeight() + getTopHeight() + (getVisibleRows() * 18) + 60, t("misc.refinedstorage:oredict"), TileGrid.OREDICT_PATTERN.getValue());
}
if (grid.getType() != GridType.FLUID && grid.getViewType() != -1) {
if (grid.getGridType() != GridType.FLUID && grid.getViewType() != -1) {
addSideButton(new SideButtonGridViewType(this, grid));
}
@@ -127,6 +122,13 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
addSideButton(new SideButtonGridSearchBoxMode(this));
addSideButton(new SideButtonGridSize(this, () -> grid.getSize(), size -> grid.onSizeChanged(size)));
if (grid.getGridType() == GridType.PATTERN) {
processingPattern = addCheckBox(x + 7, y + tabs.getHeight() + getTopHeight() + (getVisibleRows() * 18) + 60, t("misc.refinedstorage:processing"), TileGrid.PROCESSING_PATTERN.getValue());
oredictPattern = addCheckBox(processingPattern.x + processingPattern.width + 5, y + tabs.getHeight() + getTopHeight() + (getVisibleRows() * 18) + 60, t("misc.refinedstorage:oredict"), TileGrid.OREDICT_PATTERN.getValue());
addSideButton(new SideButtonType(this, TileGrid.PROCESSING_TYPE));
}
updateScrollbar();
}
@@ -161,9 +163,9 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
@Override
public int getBottomHeight() {
if (grid.getType() == GridType.CRAFTING) {
if (grid.getGridType() == GridType.CRAFTING) {
return 156;
} else if (grid.getType() == GridType.PATTERN) {
} else if (grid.getGridType() == GridType.PATTERN) {
return 169;
} else {
return 99;
@@ -174,11 +176,11 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
public int getYPlayerInventory() {
int yp = tabs.getHeight() + getTopHeight() + (getVisibleRows() * 18);
if (grid.getType() == GridType.NORMAL || grid.getType() == GridType.FLUID) {
if (grid.getGridType() == GridType.NORMAL || grid.getGridType() == GridType.FLUID) {
yp += 16;
} else if (grid.getType() == GridType.CRAFTING) {
} else if (grid.getGridType() == GridType.CRAFTING) {
yp += 73;
} else if (grid.getType() == GridType.PATTERN) {
} else if (grid.getGridType() == GridType.PATTERN) {
yp += 86;
}
@@ -237,7 +239,7 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
private boolean isOverClear(int mouseX, int mouseY) {
int y = tabs.getHeight() + getTopHeight() + (getVisibleRows() * 18) + 4;
switch (grid.getType()) {
switch (grid.getGridType()) {
case CRAFTING:
return inBounds(82, y, 7, 7, mouseX, mouseY);
case PATTERN:
@@ -252,16 +254,16 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
}
private boolean isOverCreatePattern(int mouseX, int mouseY) {
return grid.getType() == GridType.PATTERN && inBounds(172, tabs.getHeight() + getTopHeight() + (getVisibleRows() * 18) + 22, 16, 16, mouseX, mouseY) && ((NetworkNodeGrid) grid).canCreatePattern();
return grid.getGridType() == GridType.PATTERN && inBounds(172, tabs.getHeight() + getTopHeight() + (getVisibleRows() * 18) + 22, 16, 16, mouseX, mouseY) && ((NetworkNodeGrid) grid).canCreatePattern();
}
@Override
public void drawBackground(int x, int y, int mouseX, int mouseY) {
tabs.drawBackground(x, y);
if (grid.getType() == GridType.CRAFTING) {
if (grid.getGridType() == GridType.CRAFTING) {
bindTexture("gui/crafting_grid.png");
} else if (grid.getType() == GridType.PATTERN) {
} else if (grid.getGridType() == GridType.PATTERN) {
bindTexture("gui/pattern_grid" + (((NetworkNodeGrid) grid).isProcessingPattern() ? "_processing" : "") + ".png");
} else if (grid instanceof IPortableGrid) {
bindTexture("gui/portable_grid.png");
@@ -271,9 +273,9 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
int yy = y + tabs.getHeight();
drawTexture(x, yy, 0, 0, screenWidth - (grid.getType() != GridType.FLUID ? 34 : 0), getTopHeight());
drawTexture(x, yy, 0, 0, screenWidth - (grid.getGridType() != GridType.FLUID ? 34 : 0), getTopHeight());
if (grid.getType() != GridType.FLUID) {
if (grid.getGridType() != GridType.FLUID) {
drawTexture(x + screenWidth - 34 + 4, y + tabs.getHeight(), 197, 0, 30, grid instanceof IPortableGrid ? 114 : 82);
}
@@ -282,14 +284,14 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
for (int i = 0; i < rows; ++i) {
yy += 18;
drawTexture(x, yy, 0, getTopHeight() + (i > 0 ? (i == rows - 1 ? 18 * 2 : 18) : 0), screenWidth - (grid.getType() != GridType.FLUID ? 34 : 0), 18);
drawTexture(x, yy, 0, getTopHeight() + (i > 0 ? (i == rows - 1 ? 18 * 2 : 18) : 0), screenWidth - (grid.getGridType() != GridType.FLUID ? 34 : 0), 18);
}
yy += 18;
drawTexture(x, yy, 0, getTopHeight() + (18 * 3), screenWidth - (grid.getType() != GridType.FLUID ? 34 : 0), getBottomHeight());
drawTexture(x, yy, 0, getTopHeight() + (18 * 3), screenWidth - (grid.getGridType() != GridType.FLUID ? 34 : 0), getBottomHeight());
if (grid.getType() == GridType.PATTERN) {
if (grid.getGridType() == GridType.PATTERN) {
int ty = 0;
if (isOverCreatePattern(mouseX - guiLeft, mouseY - guiTop)) {
@@ -383,7 +385,7 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
List<String> textLines = Lists.newArrayList(gridStack.getTooltip().split("\n"));
List<String> smallTextLines = Lists.newArrayList();
if (!(gridStack instanceof GridStackItem) || !((GridStackItem) gridStack).doesDisplayCraftText()) {
if (!gridStack.doesDisplayCraftText()) {
smallTextLines.add(I18n.format("misc.refinedstorage:total", gridStack.getFormattedFullQuantity()));
}
@@ -439,16 +441,21 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
ItemStack held = ((ContainerGrid) this.inventorySlots).getPlayer().inventory.getItemStack();
if (isOverSlotArea(mouseX - guiLeft, mouseY - guiTop) && !held.isEmpty() && (clickedButton == 0 || clickedButton == 1)) {
RS.INSTANCE.network.sendToServer(grid.getType() == GridType.FLUID ? new MessageGridFluidInsertHeld() : new MessageGridItemInsertHeld(clickedButton == 1));
RS.INSTANCE.network.sendToServer(grid.getGridType() == GridType.FLUID ? new MessageGridFluidInsertHeld() : new MessageGridItemInsertHeld(clickedButton == 1));
}
if (isOverSlotWithStack()) {
if (grid.getType() != GridType.FLUID && (held.isEmpty() || (!held.isEmpty() && clickedButton == 2))) {
GridStackItem stack = (GridStackItem) view.getStacks().get(slotNumber);
boolean isMiddleClickPulling = !held.isEmpty() && clickedButton == 2;
boolean isPulling = held.isEmpty() || isMiddleClickPulling;
if (stack.isCraftable() && (stack.doesDisplayCraftText() || (GuiScreen.isShiftKeyDown() && GuiScreen.isCtrlKeyDown())) && view.canCraft()) {
IGridStack stack = view.getStacks().get(slotNumber);
if (isPulling) {
if (stack.isCraftable() && view.canCraft() && (stack.doesDisplayCraftText() || (GuiScreen.isShiftKeyDown() && GuiScreen.isCtrlKeyDown()))) {
FMLCommonHandler.instance().showGuiScreen(new GuiCraftingStart(this, ((ContainerGrid) this.inventorySlots).getPlayer(), stack));
} else {
} else if (grid.getGridType() == GridType.FLUID && held.isEmpty()) {
RS.INSTANCE.network.sendToServer(new MessageGridFluidPull(view.getStacks().get(slotNumber).getHash(), GuiScreen.isShiftKeyDown()));
} else if (grid.getGridType() == GridType.NORMAL || grid.getGridType() == GridType.PATTERN) {
int flags = 0;
if (clickedButton == 1) {
@@ -465,8 +472,6 @@ public class GuiGrid extends GuiBase implements IResizableDisplay {
RS.INSTANCE.network.sendToServer(new MessageGridItemPull(stack.getHash(), flags));
}
} else if (grid.getType() == GridType.FLUID && held.isEmpty()) {
RS.INSTANCE.network.sendToServer(new MessageGridFluidPull(view.getStacks().get(slotNumber).getHash(), GuiScreen.isShiftKeyDown()));
}
}
}

View File

@@ -3,6 +3,7 @@ package com.raoulvdberge.refinedstorage.gui.grid.stack;
import com.raoulvdberge.refinedstorage.api.storage.IStorageTracker;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.gui.GuiBase;
import net.minecraft.client.resources.I18n;
import net.minecraftforge.fluids.FluidStack;
import org.apache.commons.lang3.tuple.Pair;
@@ -13,17 +14,36 @@ public class GridStackFluid implements IGridStack {
private FluidStack stack;
@Nullable
private IStorageTracker.IStorageTrackerEntry entry;
private boolean craftable;
private boolean displayCraftText;
public GridStackFluid(Pair<Integer, FluidStack> data, @Nullable IStorageTracker.IStorageTrackerEntry entry) {
public GridStackFluid(Pair<Integer, FluidStack> data, @Nullable IStorageTracker.IStorageTrackerEntry entry, boolean craftable, boolean displayCraftText) {
this.hash = data.getLeft();
this.stack = data.getRight();
this.entry = entry;
this.craftable = craftable;
this.displayCraftText = displayCraftText;
}
public FluidStack getStack() {
return stack;
}
@Override
public boolean isCraftable() {
return craftable;
}
@Override
public boolean doesDisplayCraftText() {
return displayCraftText;
}
@Override
public void setDisplayCraftText(boolean displayCraftText) {
this.displayCraftText = displayCraftText;
}
@Override
public int getHash() {
return hash;
@@ -63,11 +83,15 @@ public class GridStackFluid implements IGridStack {
public void draw(GuiBase gui, int x, int y) {
GuiBase.FLUID_RENDERER.draw(gui.mc, x, y, stack);
float amountRaw = ((float) stack.amount / 1000F);
int amount = (int) amountRaw;
String formattedAmount = amount >= 1 ? API.instance().getQuantityFormatter().formatWithUnits(amount) : String.format("%.1f", amountRaw);
String text;
gui.drawQuantity(x, y, formattedAmount);
if (displayCraftText) {
text = I18n.format("gui.refinedstorage:grid.craft");
} else {
text = API.instance().getQuantityFormatter().formatInBucketFormWithOnlyTrailingDigitsIfZero(getQuantity());
}
gui.drawQuantity(x, y, text);
}
@Override

View File

@@ -45,14 +45,17 @@ public class GridStackItem implements IGridStack {
return stack;
}
@Override
public boolean isCraftable() {
return craftable;
}
@Override
public boolean doesDisplayCraftText() {
return displayCraftText;
}
@Override
public void setDisplayCraftText(boolean displayCraftText) {
this.displayCraftText = displayCraftText;

View File

@@ -28,4 +28,10 @@ public interface IGridStack {
IStorageTracker.IStorageTrackerEntry getTrackerEntry();
void setTrackerEntry(@Nullable IStorageTracker.IStorageTrackerEntry entry);
boolean isCraftable();
boolean doesDisplayCraftText();
void setDisplayCraftText(boolean displayCraftText);
}

View File

@@ -17,6 +17,11 @@ public class GridViewFluid extends GridViewBase {
map.clear();
for (IGridStack stack : stacks) {
// Don't let a craftable stack override a normal stack
if (stack.doesDisplayCraftText() && map.containsKey(stack.getHash())) {
continue;
}
map.put(stack.getHash(), stack);
}
}
@@ -30,12 +35,24 @@ public class GridViewFluid extends GridViewBase {
GridStackFluid existing = (GridStackFluid) map.get(stack.getHash());
if (existing == null) {
((GridStackFluid) stack).getStack().amount = delta;
map.put(stack.getHash(), stack);
} else {
if (existing.getStack().amount + delta <= 0) {
map.remove(existing.getHash());
if (existing.isCraftable()) {
existing.setDisplayCraftText(true);
} else {
map.remove(existing.getHash());
}
} else {
existing.getStack().amount += delta;
if (existing.doesDisplayCraftText()) {
existing.setDisplayCraftText(false);
existing.getStack().amount = delta;
} else {
existing.getStack().amount += delta;
}
}
existing.setTrackerEntry(stack.getTrackerEntry());

View File

@@ -18,7 +18,7 @@ public class GridViewItem extends GridViewBase {
for (IGridStack stack : stacks) {
// Don't let a craftable stack override a normal stack
if (((GridStackItem) stack).doesDisplayCraftText() && map.containsKey(stack.getHash())) {
if (stack.doesDisplayCraftText() && map.containsKey(stack.getHash())) {
continue;
}

View File

@@ -30,7 +30,7 @@ public final class IntegrationCraftingTweaks {
public static class ValidContainerPredicate implements Predicate<ContainerGrid> {
@Override
public boolean apply(ContainerGrid containerGrid) {
return containerGrid.getGrid().getType() == GridType.CRAFTING;
return containerGrid.getGrid().getGridType() == GridType.CRAFTING;
}
}

View File

@@ -50,7 +50,7 @@ public class RecipeTransferHandlerGrid implements IRecipeTransferHandler {
if (doTransfer) {
LAST_TRANSFER = System.currentTimeMillis();
if (grid.getType() == GridType.PATTERN && ((NetworkNodeGrid) grid).isProcessingPattern()) {
if (grid.getGridType() == GridType.PATTERN && ((NetworkNodeGrid) grid).isProcessingPattern()) {
List<ItemStack> inputs = new LinkedList<>();
List<ItemStack> outputs = new LinkedList<>();
@@ -71,7 +71,7 @@ public class RecipeTransferHandlerGrid implements IRecipeTransferHandler {
RS.INSTANCE.network.sendToServer(new MessageGridTransfer(recipeLayout.getItemStacks().getGuiIngredients(), container.inventorySlots.stream().filter(s -> s.inventory instanceof InventoryCrafting).collect(Collectors.toList())));
}
} else {
if (grid.getType() == GridType.PATTERN && ((NetworkNodeGrid) grid).isProcessingPattern()) {
if (grid.getGridType() == GridType.PATTERN && ((NetworkNodeGrid) grid).isProcessingPattern()) {
if (recipeLayout.getRecipeCategory().getUid().equals(VanillaRecipeCategoryUid.CRAFTING)) {
return ERROR_CANNOT_TRANSFER;
}

View File

@@ -150,10 +150,12 @@ public class EnvironmentNetwork extends AbstractManagedEnvironment {
int count = 0;
for (ICraftingTask task : node.getNetwork().getCraftingManager().getTasks()) {
if (API.instance().getComparer().isEqual(task.getRequested(), stack, COMPARE_NBT | COMPARE_DAMAGE)) {
node.getNetwork().getCraftingManager().cancel(task.getId());
if (task.getRequested().getItem() != null) {
if (API.instance().getComparer().isEqual(task.getRequested().getItem(), stack, COMPARE_NBT | COMPARE_DAMAGE)) {
node.getNetwork().getCraftingManager().cancel(task.getId());
count++;
count++;
}
}
}

View File

@@ -24,12 +24,16 @@ public class ItemHandlerFluid extends ItemHandlerBase {
ItemStack stack = getStackInSlot(slot);
if (stack.isEmpty()) {
fluids[slot] = null;
setFluidStack(slot, null);
} else {
fluids[slot] = StackUtils.getFluid(ItemHandlerHelper.copyStackWithSize(stack, 1), true).getValue();
setFluidStack(slot, StackUtils.getFluid(ItemHandlerHelper.copyStackWithSize(stack, 1), true).getValue());
}
}
public void setFluidStack(int slot, @Nullable FluidStack stack) {
fluids[slot] = stack;
}
@Nullable
public FluidStack getFluidStackInSlot(int slot) {
return fluids[slot];

View File

@@ -25,6 +25,7 @@ import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -41,6 +42,8 @@ public class ItemPattern extends ItemBase implements ICraftingPatternProvider {
private static final String NBT_VERSION = "Version";
public static final String NBT_INPUT_SLOT = "Input_%d";
public static final String NBT_OUTPUT_SLOT = "Output_%d";
private static final String NBT_FLUID_INPUT_SLOT = "FluidInput_%d";
private static final String NBT_FLUID_OUTPUT_SLOT = "FluidOutput_%d";
private static final String NBT_OREDICT = "Oredict";
public static final String NBT_PROCESSING = "Processing";
@@ -81,11 +84,13 @@ public class ItemPattern extends ItemBase implements ICraftingPatternProvider {
tooltip.add(TextFormatting.YELLOW + I18n.format("misc.refinedstorage:pattern.inputs") + TextFormatting.RESET);
RenderUtils.addCombinedItemsToTooltip(tooltip, true, pattern.getInputs().stream().map(i -> i.size() > 0 ? i.get(0) : ItemStack.EMPTY).collect(Collectors.toList()));
RenderUtils.addCombinedFluidsToTooltip(tooltip, pattern.getFluidInputs());
tooltip.add(TextFormatting.YELLOW + I18n.format("misc.refinedstorage:pattern.outputs") + TextFormatting.RESET);
}
RenderUtils.addCombinedItemsToTooltip(tooltip, true, pattern.getOutputs());
RenderUtils.addCombinedFluidsToTooltip(tooltip, pattern.getFluidOutputs());
if (isOredict(stack)) {
tooltip.add(TextFormatting.BLUE + I18n.format("misc.refinedstorage:pattern.oredict") + TextFormatting.RESET);
@@ -147,6 +152,44 @@ public class ItemPattern extends ItemBase implements ICraftingPatternProvider {
return stack;
}
public static void setFluidInputSlot(ItemStack pattern, int slot, FluidStack stack) {
if (!pattern.hasTagCompound()) {
pattern.setTagCompound(new NBTTagCompound());
}
pattern.getTagCompound().setTag(String.format(NBT_FLUID_INPUT_SLOT, slot), stack.writeToNBT(new NBTTagCompound()));
}
@Nullable
public static FluidStack getFluidInputSlot(ItemStack pattern, int slot) {
String id = String.format(NBT_FLUID_INPUT_SLOT, slot);
if (!pattern.hasTagCompound() || !pattern.getTagCompound().hasKey(id)) {
return null;
}
return FluidStack.loadFluidStackFromNBT(pattern.getTagCompound().getCompoundTag(id));
}
public static void setFluidOutputSlot(ItemStack pattern, int slot, FluidStack stack) {
if (!pattern.hasTagCompound()) {
pattern.setTagCompound(new NBTTagCompound());
}
pattern.getTagCompound().setTag(String.format(NBT_FLUID_OUTPUT_SLOT, slot), stack.writeToNBT(new NBTTagCompound()));
}
@Nullable
public static FluidStack getFluidOutputSlot(ItemStack pattern, int slot) {
String id = String.format(NBT_FLUID_OUTPUT_SLOT, slot);
if (!pattern.hasTagCompound() || !pattern.getTagCompound().hasKey(id)) {
return null;
}
return FluidStack.loadFluidStackFromNBT(pattern.getTagCompound().getCompoundTag(id));
}
public static boolean isProcessing(ItemStack pattern) {
return pattern.hasTagCompound() && pattern.getTagCompound().hasKey(NBT_PROCESSING) && pattern.getTagCompound().getBoolean(NBT_PROCESSING);
}

View File

@@ -1,6 +1,8 @@
package com.raoulvdberge.refinedstorage.network;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingRequestInfo;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab;
import com.raoulvdberge.refinedstorage.apiimpl.API;
@@ -8,7 +10,6 @@ import com.raoulvdberge.refinedstorage.gui.GuiBase;
import com.raoulvdberge.refinedstorage.gui.GuiCraftingMonitor;
import com.raoulvdberge.refinedstorage.tile.craftingmonitor.ICraftingMonitor;
import io.netty.buffer.ByteBuf;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
@@ -37,7 +38,14 @@ public class MessageCraftingMonitorElements implements IMessage, IMessageHandler
for (int i = 0; i < size; ++i) {
UUID id = UUID.fromString(ByteBufUtils.readUTF8String(buf));
ItemStack requested = ByteBufUtils.readItemStack(buf);
ICraftingRequestInfo requested = null;
try {
requested = API.instance().createCraftingRequestInfo(ByteBufUtils.readTag(buf));
} catch (CraftingTaskReadException e) {
e.printStackTrace();
}
int qty = buf.readInt();
long executionStarted = buf.readLong();
@@ -63,7 +71,7 @@ public class MessageCraftingMonitorElements implements IMessage, IMessageHandler
for (ICraftingTask task : craftingMonitor.getTasks()) {
ByteBufUtils.writeUTF8String(buf, task.getId().toString());
ByteBufUtils.writeItemStack(buf, task.getRequested());
ByteBufUtils.writeTag(buf, task.getRequested().writeToNbt());
buf.writeInt(task.getQuantity());
buf.writeLong(task.getExecutionStarted());

View File

@@ -37,7 +37,7 @@ public class MessageGridClear extends MessageHandlerPlayerToServer<MessageGridCl
InventoryCrafting matrix = grid.getCraftingMatrix();
if (grid.getType() == GridType.CRAFTING && grid.getNetwork() != null && grid.getNetwork().getSecurityManager().hasPermission(Permission.INSERT, player)) {
if (grid.getGridType() == GridType.CRAFTING && grid.getNetwork() != null && grid.getNetwork().getSecurityManager().hasPermission(Permission.INSERT, player)) {
for (int i = 0; i < matrix.getSizeInventory(); ++i) {
ItemStack slot = matrix.getStackInSlot(i);
@@ -45,7 +45,7 @@ public class MessageGridClear extends MessageHandlerPlayerToServer<MessageGridCl
matrix.setInventorySlotContents(i, StackUtils.nullToEmpty(grid.getNetwork().insertItem(slot, slot.getCount(), Action.PERFORM)));
}
}
} else if (grid.getType() == GridType.PATTERN) {
} else if (grid.getGridType() == GridType.PATTERN) {
((NetworkNodeGrid) grid).clearMatrix();
}
}

View File

@@ -11,14 +11,16 @@ public class MessageGridCraftingPreview extends MessageHandlerPlayerToServer<Mes
private int hash;
private int quantity;
private boolean noPreview;
private boolean fluids;
public MessageGridCraftingPreview() {
}
public MessageGridCraftingPreview(int hash, int quantity, boolean noPreview) {
public MessageGridCraftingPreview(int hash, int quantity, boolean noPreview, boolean fluids) {
this.hash = hash;
this.quantity = quantity;
this.noPreview = noPreview;
this.fluids = fluids;
}
@Override
@@ -26,6 +28,7 @@ public class MessageGridCraftingPreview extends MessageHandlerPlayerToServer<Mes
hash = buf.readInt();
quantity = buf.readInt();
noPreview = buf.readBoolean();
fluids = buf.readBoolean();
}
@Override
@@ -33,6 +36,7 @@ public class MessageGridCraftingPreview extends MessageHandlerPlayerToServer<Mes
buf.writeInt(hash);
buf.writeInt(quantity);
buf.writeBoolean(noPreview);
buf.writeBoolean(fluids);
}
@Override
@@ -42,8 +46,14 @@ public class MessageGridCraftingPreview extends MessageHandlerPlayerToServer<Mes
if (container instanceof ContainerGrid) {
IGrid grid = ((ContainerGrid) container).getGrid();
if (grid.getItemHandler() != null) {
grid.getItemHandler().onCraftingPreviewRequested(player, message.hash, message.quantity, message.noPreview);
if (message.fluids) {
if (grid.getFluidHandler() != null) {
grid.getFluidHandler().onCraftingPreviewRequested(player, message.hash, message.quantity, message.noPreview);
}
} else {
if (grid.getItemHandler() != null) {
grid.getItemHandler().onCraftingPreviewRequested(player, message.hash, message.quantity, message.noPreview);
}
}
}
}

View File

@@ -19,23 +19,26 @@ import java.util.LinkedList;
import java.util.List;
public class MessageGridCraftingPreviewResponse implements IMessage, IMessageHandler<MessageGridCraftingPreviewResponse, IMessage> {
public List<ICraftingPreviewElement> stacks;
public int hash;
public int quantity;
private List<ICraftingPreviewElement> stacks;
private int hash;
private int quantity;
private boolean fluids;
public MessageGridCraftingPreviewResponse() {
}
public MessageGridCraftingPreviewResponse(List<ICraftingPreviewElement> stacks, int hash, int quantity) {
public MessageGridCraftingPreviewResponse(List<ICraftingPreviewElement> stacks, int hash, int quantity, boolean fluids) {
this.stacks = stacks;
this.hash = hash;
this.quantity = quantity;
this.fluids = fluids;
}
@Override
public void fromBytes(ByteBuf buf) {
this.hash = buf.readInt();
this.quantity = buf.readInt();
this.fluids = buf.readBoolean();
this.stacks = new LinkedList<>();
@@ -50,6 +53,7 @@ public class MessageGridCraftingPreviewResponse implements IMessage, IMessageHan
public void toBytes(ByteBuf buf) {
buf.writeInt(hash);
buf.writeInt(quantity);
buf.writeBoolean(fluids);
buf.writeInt(stacks.size());
@@ -69,7 +73,7 @@ public class MessageGridCraftingPreviewResponse implements IMessage, IMessageHan
screen = ((GuiCraftingStart) screen).getParent();
}
FMLCommonHandler.instance().showGuiScreen(new GuiCraftingPreview(screen, message.stacks, message.hash, message.quantity));
FMLCommonHandler.instance().showGuiScreen(new GuiCraftingPreview(screen, message.stacks, message.hash, message.quantity, message.fluids));
});
return null;

View File

@@ -10,25 +10,29 @@ import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
public class MessageGridCraftingStart extends MessageHandlerPlayerToServer<MessageGridCraftingStart> implements IMessage {
private int hash;
private int quantity;
private boolean fluids;
public MessageGridCraftingStart() {
}
public MessageGridCraftingStart(int hash, int quantity) {
public MessageGridCraftingStart(int hash, int quantity, boolean fluids) {
this.hash = hash;
this.quantity = quantity;
this.fluids = fluids;
}
@Override
public void fromBytes(ByteBuf buf) {
hash = buf.readInt();
quantity = buf.readInt();
fluids = buf.readBoolean();
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeInt(hash);
buf.writeInt(quantity);
buf.writeBoolean(fluids);
}
@Override
@@ -38,8 +42,14 @@ public class MessageGridCraftingStart extends MessageHandlerPlayerToServer<Messa
if (container instanceof ContainerGrid) {
IGrid grid = ((ContainerGrid) container).getGrid();
if (grid.getItemHandler() != null) {
grid.getItemHandler().onCraftingRequested(player, message.hash, message.quantity);
if (message.fluids) {
if (grid.getFluidHandler() != null) {
grid.getFluidHandler().onCraftingRequested(player, message.hash, message.quantity);
}
} else {
if (grid.getItemHandler() != null) {
grid.getItemHandler().onCraftingRequested(player, message.hash, message.quantity);
}
}
}
}

View File

@@ -0,0 +1,53 @@
package com.raoulvdberge.refinedstorage.network;
import com.raoulvdberge.refinedstorage.api.network.grid.IGrid;
import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNodeGrid;
import com.raoulvdberge.refinedstorage.container.ContainerGrid;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.Container;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
public class MessageGridFluidAmount extends MessageHandlerPlayerToServer<MessageGridFluidAmount> implements IMessage {
private int slot;
private int amount;
public MessageGridFluidAmount(int slot, int amount) {
this.slot = slot;
this.amount = amount;
}
public MessageGridFluidAmount() {
// NO OP
}
@Override
protected void handle(MessageGridFluidAmount message, EntityPlayerMP player) {
Container container = player.openContainer;
if (container instanceof ContainerGrid && message.slot >= 0 && message.amount > 0 && message.amount <= Fluid.BUCKET_VOLUME) {
IGrid grid = ((ContainerGrid) container).getGrid();
if (grid instanceof NetworkNodeGrid) {
NetworkNodeGrid node = (NetworkNodeGrid) grid;
if (message.slot < node.getMatrixProcessingFluids().getSlots()) {
node.getMatrixProcessingFluids().getStackInSlot(message.slot).setCount(message.amount);
}
}
}
}
@Override
public void fromBytes(ByteBuf buf) {
slot = buf.readInt();
amount = buf.readInt();
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeInt(slot);
buf.writeInt(amount);
}
}

View File

@@ -32,7 +32,7 @@ public class MessageGridFluidDelta implements IMessage, IMessageHandler<MessageG
@Override
public void fromBytes(ByteBuf buf) {
clientStack = new GridStackFluid(StackUtils.readFluidStack(buf), buf.readBoolean() ? new StorageTrackerEntry(buf) : null);
clientStack = new GridStackFluid(StackUtils.readFluidStack(buf), buf.readBoolean() ? new StorageTrackerEntry(buf) : null, buf.readBoolean(), false);
delta = buf.readInt();
}
@@ -47,6 +47,8 @@ public class MessageGridFluidDelta implements IMessage, IMessageHandler<MessageG
ByteBufUtils.writeUTF8String(buf, entry.getName());
}
buf.writeBoolean(network.getCraftingManager().getPattern(stack) != null);
buf.writeInt(delta);
}

View File

@@ -1,5 +1,6 @@
package com.raoulvdberge.refinedstorage.network;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.api.storage.IStorageTracker;
import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageTrackerEntry;
@@ -38,7 +39,7 @@ public class MessageGridFluidUpdate implements IMessage, IMessageHandler<Message
int items = buf.readInt();
for (int i = 0; i < items; ++i) {
this.stacks.add(new GridStackFluid(StackUtils.readFluidStack(buf), buf.readBoolean() ? new StorageTrackerEntry(buf) : null));
this.stacks.add(new GridStackFluid(StackUtils.readFluidStack(buf), buf.readBoolean() ? new StorageTrackerEntry(buf) : null, buf.readBoolean(), buf.readBoolean()));
}
}
@@ -46,7 +47,13 @@ public class MessageGridFluidUpdate implements IMessage, IMessageHandler<Message
public void toBytes(ByteBuf buf) {
buf.writeBoolean(canCraft);
buf.writeInt(network.getFluidStorageCache().getList().getStacks().size());
int size = network.getFluidStorageCache().getList().getStacks().size();
for (ICraftingPattern pattern : network.getCraftingManager().getPatterns()) {
size += pattern.getFluidOutputs().size();
}
buf.writeInt(size);
for (FluidStack stack : network.getFluidStorageCache().getList().getStacks()) {
StackUtils.writeFluidStack(buf, stack);
@@ -57,6 +64,25 @@ public class MessageGridFluidUpdate implements IMessage, IMessageHandler<Message
buf.writeLong(entry.getTime());
ByteBufUtils.writeUTF8String(buf, entry.getName());
}
buf.writeBoolean(network.getCraftingManager().getPattern(stack) != null);
buf.writeBoolean(false);
}
for (ICraftingPattern pattern : network.getCraftingManager().getPatterns()) {
for (FluidStack stack : pattern.getFluidOutputs()) {
StackUtils.writeFluidStack(buf, stack);
IStorageTracker.IStorageTrackerEntry entry = network.getFluidStorageTracker().get(stack);
buf.writeBoolean(entry != null);
if (entry != null) {
buf.writeLong(entry.getTime());
ByteBufUtils.writeUTF8String(buf, entry.getName());
}
buf.writeBoolean(network.getCraftingManager().getPattern(stack) != null);
buf.writeBoolean(true);
}
}
}

View File

@@ -40,7 +40,7 @@ public class MessageGridPatternCreate extends MessageHandlerPlayerToServer<Messa
public void handle(MessageGridPatternCreate message, EntityPlayerMP player) {
TileEntity tile = player.getEntityWorld().getTileEntity(new BlockPos(message.x, message.y, message.z));
if (tile instanceof TileGrid && ((TileGrid) tile).getNode().getType() == GridType.PATTERN) {
if (tile instanceof TileGrid && ((TileGrid) tile).getNode().getGridType() == GridType.PATTERN) {
((TileGrid) tile).getNode().onCreatePattern();
}
}

View File

@@ -65,7 +65,7 @@ public class MessageGridProcessingTransfer extends MessageHandlerPlayerToServer<
if (player.openContainer instanceof ContainerGrid) {
IGrid grid = ((ContainerGrid) player.openContainer).getGrid();
if (grid.getType() == GridType.PATTERN) {
if (grid.getGridType() == GridType.PATTERN) {
ItemHandlerBase handler = ((NetworkNodeGrid) grid).getProcessingMatrix();
clearInputsAndOutputs(handler);

View File

@@ -74,7 +74,7 @@ public class MessageGridTransfer extends MessageHandlerPlayerToServer<MessageGri
if (player.openContainer instanceof ContainerGrid) {
IGrid grid = ((ContainerGrid) player.openContainer).getGrid();
if (grid.getType() == GridType.CRAFTING || grid.getType() == GridType.PATTERN) {
if (grid.getGridType() == GridType.CRAFTING || grid.getGridType() == GridType.PATTERN) {
grid.onRecipeTransfer(player, message.recipe);
}
}

View File

@@ -95,7 +95,7 @@ public class ProxyCommon {
API.instance().getCraftingTaskRegistry().add(CraftingTaskFactory.ID, new CraftingTaskFactory());
API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementItemRender.ID, buf -> new CraftingMonitorElementItemRender(StackUtils.readItemStack(buf), buf.readInt(), buf.readInt()));
API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementFluidRender.ID, buf -> new CraftingMonitorElementFluidRender(StackUtils.readFluidStack(buf).getRight(), buf.readInt()));
API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementFluidRender.ID, buf -> new CraftingMonitorElementFluidRender(StackUtils.readFluidStack(buf).getRight(), buf.readInt(), buf.readInt()));
API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementText.ID, buf -> new CraftingMonitorElementText(ByteBufUtils.readUTF8String(buf), buf.readInt()));
API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementColor.ID, buf -> {
int color = buf.readInt();
@@ -183,6 +183,7 @@ public class ProxyCommon {
RS.INSTANCE.network.registerMessage(MessageStorageDiskSizeRequest.class, MessageStorageDiskSizeRequest.class, id++, Side.SERVER);
RS.INSTANCE.network.registerMessage(MessageStorageDiskSizeResponse.class, MessageStorageDiskSizeResponse.class, id++, Side.CLIENT);
RS.INSTANCE.network.registerMessage(MessageConfigSync.class, MessageConfigSync.class, id++, Side.CLIENT);
RS.INSTANCE.network.registerMessage(MessageGridFluidAmount.class, MessageGridFluidAmount.class, id++, Side.SERVER);
NetworkRegistry.INSTANCE.registerGuiHandler(RS.INSTANCE, new GuiHandler());

View File

@@ -7,6 +7,7 @@ import com.raoulvdberge.refinedstorage.container.ContainerGrid;
import com.raoulvdberge.refinedstorage.gui.GuiBase;
import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid;
import com.raoulvdberge.refinedstorage.tile.TileNode;
import com.raoulvdberge.refinedstorage.tile.config.IType;
import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.util.EnumFacing;
@@ -82,6 +83,7 @@ public class TileGrid extends TileNode<NetworkNodeGrid> {
((ContainerGrid) player.openContainer).sendAllSlots();
});
}, (initial, p) -> GuiBase.executeLater(GuiGrid.class, GuiBase::initGui));
public static final TileDataParameter<Integer, TileGrid> PROCESSING_TYPE = IType.createParameter();
public static void trySortGrid(boolean initial) {
if (!initial) {
@@ -99,6 +101,7 @@ public class TileGrid extends TileNode<NetworkNodeGrid> {
dataManager.addWatchedParameter(TAB_PAGE);
dataManager.addWatchedParameter(OREDICT_PATTERN);
dataManager.addWatchedParameter(PROCESSING_PATTERN);
dataManager.addWatchedParameter(PROCESSING_TYPE);
}
@Override
@@ -114,12 +117,12 @@ public class TileGrid extends TileNode<NetworkNodeGrid> {
@Override
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing side) {
return (getNode().getType() == GridType.PATTERN && capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) || super.hasCapability(capability, side);
return (getNode().getGridType() == GridType.PATTERN && capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) || super.hasCapability(capability, side);
}
@Override
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing side) {
if (getNode().getType() == GridType.PATTERN && capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
if (getNode().getGridType() == GridType.PATTERN && capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.cast(getNode().getPatterns());
}

View File

@@ -61,7 +61,7 @@ public class WirelessFluidGrid implements IGridNetworkAware {
}
@Override
public GridType getType() {
public GridType getGridType() {
return GridType.FLUID;
}

View File

@@ -90,7 +90,7 @@ public class WirelessGrid implements IGridNetworkAware {
}
@Override
public GridType getType() {
public GridType getGridType() {
return GridType.NORMAL;
}

View File

@@ -186,7 +186,7 @@ public class PortableGrid implements IGrid, IPortableGrid, IStorageDiskContainer
}
@Override
public GridType getType() {
public GridType getGridType() {
return GridType.NORMAL;
}

View File

@@ -257,7 +257,7 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid,
}
@Override
public GridType getType() {
public GridType getGridType() {
return GridType.NORMAL;
}

View File

@@ -1,6 +1,7 @@
package com.raoulvdberge.refinedstorage.util;
import com.google.common.collect.ImmutableMap;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
@@ -20,6 +21,7 @@ import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.client.ForgeHooksClient;
@@ -257,6 +259,30 @@ public final class RenderUtils {
}
}
public static void addCombinedFluidsToTooltip(List<String> tooltip, NonNullList<FluidStack> stacks) {
Set<Integer> combinedIndices = new HashSet<>();
for (int i = 0; i < stacks.size(); ++i) {
if (!combinedIndices.contains(i)) {
FluidStack stack = stacks.get(i);
String data = stack.getLocalizedName();
int amount = stack.amount;
for (int j = i + 1; j < stacks.size(); ++j) {
if (API.instance().getComparer().isEqual(stack, stacks.get(j), IComparer.COMPARE_NBT)) {
amount += stacks.get(j).amount;
combinedIndices.add(j);
}
}
tooltip.add(API.instance().getQuantityFormatter().formatInBucketForm(amount) + " " + data);
}
}
}
// Copied with some tweaks from GuiUtils#drawHoveringText(@Nonnull final ItemStack stack, List<String> textLines, int mouseX, int mouseY, int screenWidth, int screenHeight, int maxTextWidth, FontRenderer font)
public static void drawTooltipWithSmallText(List<String> textLines, List<String> smallTextLines, boolean showSmallText, @Nonnull ItemStack stack, int mouseX, int mouseY, int screenWidth, int screenHeight, FontRenderer fontRenderer) {
// RS BEGIN

View File

@@ -106,17 +106,15 @@ public final class StackUtils {
}
}
public static void writeItems(IItemHandler handler, int id, NBTTagCompound tag) {
public static void writeItems(IItemHandler handler, int id, NBTTagCompound tag, Function<ItemStack, NBTTagCompound> serializer) {
NBTTagList tagList = new NBTTagList();
for (int i = 0; i < handler.getSlots(); i++) {
if (!handler.getStackInSlot(i).isEmpty()) {
NBTTagCompound stackTag = new NBTTagCompound();
NBTTagCompound stackTag = serializer.apply(handler.getStackInSlot(i));
stackTag.setInteger(NBT_SLOT, i);
handler.getStackInSlot(i).writeToNBT(stackTag);
tagList.appendTag(stackTag);
}
}
@@ -124,7 +122,11 @@ public final class StackUtils {
tag.setTag(String.format(NBT_INVENTORY, id), tagList);
}
public static void readItems(IItemHandlerModifiable handler, int id, NBTTagCompound tag) {
public static void writeItems(IItemHandler handler, int id, NBTTagCompound tag) {
writeItems(handler, id, tag, stack -> stack.writeToNBT(new NBTTagCompound()));
}
public static void readItems(IItemHandlerModifiable handler, int id, NBTTagCompound tag, Function<NBTTagCompound, ItemStack> deserializer) {
String name = String.format(NBT_INVENTORY, id);
if (tag.hasKey(name)) {
@@ -134,12 +136,16 @@ public final class StackUtils {
int slot = tagList.getCompoundTagAt(i).getInteger(NBT_SLOT);
if (slot >= 0 && slot < handler.getSlots()) {
handler.setStackInSlot(slot, new ItemStack(tagList.getCompoundTagAt(i)));
handler.setStackInSlot(slot, deserializer.apply(tagList.getCompoundTagAt(i)));
}
}
}
}
public static void readItems(IItemHandlerModifiable handler, int id, NBTTagCompound tag) {
readItems(handler, id, tag, ItemStack::new);
}
public static void writeItems(IInventory inventory, int id, NBTTagCompound tag) {
NBTTagList tagList = new NBTTagList();

View File

@@ -10,6 +10,7 @@ gui.refinedstorage:grid=Grid
gui.refinedstorage:grid.craft=Craft
gui.refinedstorage:crafting_grid=Crafting Grid
gui.refinedstorage:pattern_grid=Pattern Grid
gui.refinedstorage:pattern_grid.fluid_amount=Fluid amount in mB
gui.refinedstorage:grid.pattern_create=Create Pattern
gui.refinedstorage:fluid_grid=Fluid Grid
gui.refinedstorage:disk_drive=Drive