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

@@ -1,5 +1,8 @@
# Refined Storage Changelog
### 1.6.1
- Added fluid autocrafting (raoulvdberge)
### 1.6
NOTE: Worlds that used Refined Storage 1.5.x are fully compatible with Refined Storage 1.6.x and are getting converted upon loading the world. It is however not possible to revert back to Refined Storage 1.5.x when a world has already been converted to Refined Storage 1.6.x.

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