New autocrafting code, still in the works.

This commit is contained in:
raoulvdberge
2018-05-28 17:38:25 +02:00
parent 1827831fbf
commit c73a725d5e
25 changed files with 356 additions and 408 deletions

View File

@@ -46,9 +46,9 @@ public interface ICraftingPattern {
/**
* @param took the items took per slot
* @return the outputs based on the items took
* @return the output based on the items took
*/
NonNullList<ItemStack> getOutputs(NonNullList<ItemStack> took);
ItemStack getOutput(NonNullList<ItemStack> took);
/**
* @return the outputs

View File

@@ -3,6 +3,7 @@ package com.raoulvdberge.refinedstorage.api.autocrafting.task;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement;
import com.raoulvdberge.refinedstorage.api.util.IStackList;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -74,4 +75,9 @@ public interface ICraftingTask {
* @return true if no recursion was found, false otherwise
*/
boolean isValid();
/**
* @return the missing items
*/
IStackList<ItemStack> getMissing();
}

View File

@@ -13,7 +13,6 @@ public interface IComparer {
int COMPARE_NBT = 2;
int COMPARE_QUANTITY = 4;
int COMPARE_OREDICT = 8;
int COMPARE_STRIP_NBT = 16;
/**
* Compares two stacks by the given flags.

View File

@@ -3,7 +3,6 @@ package com.raoulvdberge.refinedstorage.api.util;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
/**
* A stack list.
@@ -45,37 +44,6 @@ public interface IStackList<T> {
return remove(stack, getSizeFromStack(stack));
}
/**
* Decrements the count of that stack in the list.
* Keeps track of removed stacks and can be undone by calling {@link #undo()}.
*
* @param stack the stack
* @param size the size to remove
* @return true if the remove was successful for the full amount, false otherwise
*/
boolean trackedRemove(@Nonnull T stack, int size);
/**
* Decrements the count of that stack in the list.
* Keeps track of removed stacks and can be undone by calling {@link #undo()}.
*
* @param stack the stack
* @return true if the remove was successful for the full amount, false otherwise
*/
default boolean trackedRemove(@Nonnull T stack) {
return trackedRemove(stack, getSizeFromStack(stack));
}
/**
* Restore all tracked removes.
*/
void undo();
/**
* @return the remove tracker
*/
List<T> getRemoveTracker();
/**
* Returns a stack.
*
@@ -133,9 +101,4 @@ public interface IStackList<T> {
*/
@Nonnull
IStackList<T> copy();
/**
* @return an oredict stack list
*/
IStackList<T> getOredicted();
}

View File

@@ -4,7 +4,6 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry.CraftingTaskFactory;
import com.raoulvdberge.refinedstorage.item.ItemPattern;
import com.raoulvdberge.refinedstorage.util.StackUtils;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.InventoryCrafting;
@@ -69,6 +68,18 @@ public class CraftingPattern implements ICraftingPattern {
this.valid = true;
outputs.add(output);
if (oredict) {
if (recipe.getIngredients().size() > 0) {
inputs.clear();
for (int i = 0; i < recipe.getIngredients().size(); ++i) {
inputs.add(i, NonNullList.from(ItemStack.EMPTY, recipe.getIngredients().get(i).getMatchingStacks()));
}
} else {
this.valid = false;
}
}
}
break;
@@ -112,9 +123,27 @@ public class CraftingPattern implements ICraftingPattern {
return outputs;
}
@Override
public NonNullList<ItemStack> getOutputs(NonNullList<ItemStack> took) {
return StackUtils.emptyNonNullList();
public ItemStack getOutput(NonNullList<ItemStack> took) {
if (processing) {
throw new IllegalStateException("Cannot get crafting outputs from processing pattern");
}
if (took.size() != inputs.size()) {
throw new IllegalArgumentException("The items that are taken (" + took.size() + ") should match the inputs for this pattern (" + inputs.size() + ")");
}
InventoryCrafting inv = new InventoryCraftingDummy();
for (int i = 0; i < took.size(); ++i) {
inv.setInventorySlotContents(i, took.get(i));
}
ItemStack result = recipe.getCraftingResult(inv);
if (result.isEmpty()) {
throw new IllegalStateException("Cannot have empty result");
}
return result;
}
@Override
@@ -124,7 +153,21 @@ public class CraftingPattern implements ICraftingPattern {
@Override
public NonNullList<ItemStack> getByproducts(NonNullList<ItemStack> took) {
return StackUtils.emptyNonNullList();
if (processing) {
throw new IllegalStateException("Cannot get crafting outputs from processing pattern");
}
if (took.size() != inputs.size()) {
throw new IllegalArgumentException("The items that are taken (" + took.size() + ") should match the inputs for this pattern (" + inputs.size() + ")");
}
InventoryCrafting inv = new InventoryCraftingDummy();
for (int i = 0; i < took.size(); ++i) {
inv.setInventorySlotContents(i, took.get(i));
}
return recipe.getRemainingItems(inv);
}
@Override

View File

@@ -0,0 +1,48 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.api.util.IStackList;
import net.minecraft.item.ItemStack;
public class CraftingStepCraft implements ICraftingStep {
private INetwork network;
private IStackList<ItemStack> toExtract;
private ICraftingPattern pattern;
public CraftingStepCraft(INetwork network, IStackList<ItemStack> toExtract, ICraftingPattern pattern) {
this.network = network;
this.toExtract = toExtract;
this.pattern = pattern;
}
@Override
public boolean execute() {
for (ItemStack toExtractItem : toExtract.getStacks()) {
ItemStack inNetwork = network.extractItem(toExtractItem, toExtractItem.getCount(), true);
if (inNetwork == null || inNetwork.getCount() < toExtractItem.getCount()) {
return false;
}
}
for (ItemStack toExtractItem : toExtract.getStacks()) {
network.extractItem(toExtractItem, toExtractItem.getCount(), false);
}
for (ItemStack output : pattern.getOutputs()) {
network.insertItem(output, output.getCount(), false);
}
for (ItemStack byproduct : pattern.getByproducts()) {
network.insertItem(byproduct, byproduct.getCount(), false);
}
return true;
}
@Override
public ICraftingPattern getPattern() {
return pattern;
}
}

View File

@@ -0,0 +1,41 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
public class CraftingStepSlot {
private ICraftingStep step;
private boolean fulfilled;
private int ticks = -1;
public CraftingStepSlot(ICraftingStep step) {
this.step = step;
}
public boolean canExecute() {
ticks++;
switch (step.getPattern().getContainer().getSpeedUpdateCount()) {
case 1:
return ticks % 5 == 0;
case 2:
return ticks % 4 == 0;
case 3:
return ticks % 3 == 0;
case 4:
return ticks % 2 == 0;
default:
case 0:
return ticks % 10 == 0;
}
}
public ICraftingStep getStep() {
return step;
}
public boolean isFulfilled() {
return fulfilled;
}
public void setFulfilled() {
this.fulfilled = true;
}
}

View File

@@ -2,40 +2,166 @@ package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
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.ICraftingTask;
import com.raoulvdberge.refinedstorage.api.network.INetwork;
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.CraftingMonitorElementItemRender;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementItemStack;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.NonNullList;
import java.util.Collections;
import java.util.List;
import java.util.*;
public class CraftingTask implements ICraftingTask {
private INetwork network;
private ItemStack stack;
private ItemStack requested;
private int quantity;
private ICraftingPattern pattern;
private List<CraftingStepSlot> steps = new LinkedList<>();
public CraftingTask(INetwork network, ItemStack stack, int quantity, ICraftingPattern pattern) {
private IStackList<ItemStack> toTake = API.instance().createItemStackList();
private IStackList<ItemStack> missing = API.instance().createItemStackList();
private IStackList<ItemStack> toCraft = API.instance().createItemStackList();
public CraftingTask(INetwork network, ItemStack requested, int quantity, ICraftingPattern pattern) {
this.network = network;
this.stack = stack;
this.requested = requested;
this.quantity = quantity;
this.pattern = pattern;
}
@Override
public void calculate() {
int qty = this.quantity;
IStackList<ItemStack> results = API.instance().createItemStackList();
IStackList<ItemStack> storage = network.getItemStorageCache().getList().copy();
while (qty > 0) {
this.steps.add(new CraftingStepSlot(calculateInternal(storage, results, pattern)));
qty -= getQuantityPerCraft(pattern, requested);
}
}
private ICraftingStep calculateInternal(IStackList<ItemStack> mutatedStorage, IStackList<ItemStack> results, ICraftingPattern pattern) {
IStackList<ItemStack> itemsToExtract = API.instance().createItemStackList();
NonNullList<ItemStack> took = NonNullList.create();
for (NonNullList<ItemStack> possibleInputs : pattern.getInputs()) {
if (possibleInputs.isEmpty()) {
took.add(ItemStack.EMPTY);
continue;
}
ItemStack possibleInput = possibleInputs.get(0); // TODO: Use first for now.
took.add(possibleInput);
int toExtract = possibleInput.getCount();
ItemStack fromSelf = results.get(possibleInput);
if (fromSelf != null) {
results.remove(possibleInput, Math.min(possibleInput.getCount(), fromSelf.getCount()));
toExtract -= fromSelf.getCount();
}
if (toExtract > 0) {
ItemStack fromNetwork = mutatedStorage.get(possibleInput);
int fromNetworkCount = fromNetwork == null ? 0 : Math.min(toExtract, fromNetwork.getCount());
itemsToExtract.add(possibleInput);
if (fromNetworkCount > 0) {
this.toTake.add(possibleInput, fromNetworkCount);
mutatedStorage.remove(possibleInput, fromNetworkCount);
}
if (fromNetworkCount < toExtract) {
int missing = toExtract - fromNetworkCount;
ICraftingPattern subPattern = network.getCraftingManager().getPattern(possibleInput, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT);
if (subPattern == null) {
this.missing.add(possibleInput, missing);
} else {
this.toCraft.add(possibleInput, missing);
while (missing > 0) {
this.steps.add(new CraftingStepSlot(calculateInternal(mutatedStorage, results, subPattern)));
missing -= getQuantityPerCraft(subPattern, possibleInput);
}
}
}
}
}
if (pattern.isProcessing()) {
for (ItemStack output : pattern.getOutputs()) {
results.add(output);
}
for (ItemStack byproduct : pattern.getByproducts()) {
results.add(byproduct);
}
} else {
results.add(pattern.getOutput(took));
for (ItemStack byproduct : pattern.getByproducts(took)) {
results.add(byproduct);
}
}
return new CraftingStepCraft(network, itemsToExtract, pattern);
}
private int getQuantityPerCraft(ICraftingPattern pattern, ItemStack requested) {
int qty = 0;
for (ItemStack output : pattern.getOutputs()) {
if (API.instance().getComparer().isEqualNoQuantity(output, requested)) {
qty += output.getCount();
if (!pattern.isProcessing()) {
break;
}
}
}
return qty;
}
@Override
public boolean update() {
return false;
boolean allFulfilled = true;
for (CraftingStepSlot slot : steps) {
if (!slot.isFulfilled()) {
allFulfilled = false;
if (slot.canExecute() && slot.getStep().execute()) {
slot.setFulfilled();
}
}
}
return allFulfilled;
}
@Override
public void onCancelled() {
// TODO
}
@Override
@@ -45,7 +171,7 @@ public class CraftingTask implements ICraftingTask {
@Override
public ItemStack getRequested() {
return stack;
return requested;
}
@Override
@@ -55,12 +181,61 @@ public class CraftingTask implements ICraftingTask {
@Override
public List<ICraftingMonitorElement> getCraftingMonitorElements() {
return Collections.singletonList(new CraftingMonitorElementItemRender(network.getCraftingManager().getTasks().indexOf(this), stack, quantity, 0));
ICraftingMonitorElementList elements = API.instance().createCraftingMonitorElementList();
elements.directAdd(new CraftingMonitorElementItemRender(network.getCraftingManager().getTasks().indexOf(this), requested, quantity, 0));
return elements.getElements();
}
@Override
public List<ICraftingPreviewElement> getPreviewStacks() {
return Collections.emptyList();
Map<Integer, CraftingPreviewElementItemStack> map = new LinkedHashMap<>();
for (ItemStack stack : toCraft.getStacks()) {
int hash = API.instance().getItemStackHashCode(stack);
CraftingPreviewElementItemStack previewStack = map.get(hash);
if (previewStack == null) {
previewStack = new CraftingPreviewElementItemStack(stack);
}
previewStack.addToCraft(stack.getCount());
map.put(hash, previewStack);
}
for (ItemStack stack : missing.getStacks()) {
int hash = API.instance().getItemStackHashCode(stack);
CraftingPreviewElementItemStack previewStack = map.get(hash);
if (previewStack == null) {
previewStack = new CraftingPreviewElementItemStack(stack);
}
previewStack.setMissing(true);
previewStack.addToCraft(stack.getCount());
map.put(hash, previewStack);
}
for (ItemStack stack : toTake.getStacks()) {
int hash = API.instance().getItemStackHashCode(stack);
CraftingPreviewElementItemStack previewStack = map.get(hash);
if (previewStack == null) {
previewStack = new CraftingPreviewElementItemStack(stack);
}
previewStack.addAvailable(stack.getCount());
map.put(hash, previewStack);
}
return new ArrayList<>(map.values());
}
@Override
@@ -72,4 +247,9 @@ public class CraftingTask implements ICraftingTask {
public boolean isValid() {
return true;
}
@Override
public IStackList<ItemStack> getMissing() {
return missing;
}
}

View File

@@ -0,0 +1,9 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
public interface ICraftingStep {
boolean execute();
ICraftingPattern getPattern();
}

View File

@@ -190,7 +190,7 @@ public class ItemGridHandler implements IItemGridHandler {
task.calculate();
if (noPreview /*&& task.getMissing().isEmpty()*/) { // TODO
if (noPreview && task.getMissing().isEmpty()) {
network.getCraftingManager().add(task);
RS.INSTANCE.network.sendTo(new MessageGridCraftingStartResponse(), player);

View File

@@ -265,7 +265,7 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC
}
visited = true;
ICraftingPatternContainer facingContainer = ((ICraftingPatternContainer)facing).getRootContainer();
ICraftingPatternContainer facingContainer = ((ICraftingPatternContainer) facing).getRootContainer();
visited = false;
return facingContainer;

View File

@@ -339,7 +339,7 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
// If we are connected, first try to get the possibilities from the network
if (network != null) {
for (ItemStack possibility : possibilities) {
ItemStack took = network.extractItem(possibility, 1, IComparer.COMPARE_NBT | IComparer.COMPARE_STRIP_NBT | (possibility.getItem().isDamageable() ? 0 : IComparer.COMPARE_DAMAGE), false);
ItemStack took = network.extractItem(possibility, 1, IComparer.COMPARE_NBT | (possibility.getItem().isDamageable() ? 0 : IComparer.COMPARE_DAMAGE), false);
if (took != null) {
grid.getCraftingMatrix().setInventorySlotContents(i, StackUtils.nullToEmpty(took));
@@ -355,7 +355,7 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware {
if (!found) {
for (ItemStack possibility : possibilities) {
for (int j = 0; j < player.inventory.getSizeInventory(); ++j) {
if (API.instance().getComparer().isEqual(possibility, player.inventory.getStackInSlot(j), IComparer.COMPARE_NBT | IComparer.COMPARE_STRIP_NBT | (possibility.getItem().isDamageable() ? 0 : IComparer.COMPARE_DAMAGE))) {
if (API.instance().getComparer().isEqual(possibility, player.inventory.getStackInSlot(j), IComparer.COMPARE_NBT | (possibility.getItem().isDamageable() ? 0 : IComparer.COMPARE_DAMAGE))) {
grid.getCraftingMatrix().setInventorySlotContents(i, ItemHandlerHelper.copyStackWithSize(player.inventory.getStackInSlot(j), 1));
player.inventory.decrStackSize(j, 1);

View File

@@ -33,7 +33,7 @@ public class NetworkNodeSolderer extends NetworkNode {
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
for (ISoldererRecipe recipe : API.instance().getSoldererRegistry().getRecipes()) {
for (ItemStack possibility : recipe.getRow(slot)) {
if (API.instance().getComparer().isEqual(possibility, stack, IComparer.COMPARE_NBT | IComparer.COMPARE_DAMAGE | IComparer.COMPARE_STRIP_NBT)) {
if (API.instance().getComparer().isEqual(possibility, stack, IComparer.COMPARE_NBT | IComparer.COMPARE_DAMAGE)) {
return super.insertItem(slot, stack, simulate);
}
}

View File

@@ -37,7 +37,7 @@ public class SoldererRegistry implements ISoldererRegistry {
}
for (ItemStack possibility : possibilities) {
if (API.instance().getComparer().isEqual(possibility, ingredients.getStackInSlot(i), IComparer.COMPARE_NBT | IComparer.COMPARE_DAMAGE | IComparer.COMPARE_STRIP_NBT)) {
if (API.instance().getComparer().isEqual(possibility, ingredients.getStackInSlot(i), IComparer.COMPARE_NBT | IComparer.COMPARE_DAMAGE)) {
if (ingredients.getStackInSlot(i).getCount() >= possibility.getCount()) {
rowsFound++;

View File

@@ -8,8 +8,6 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.oredict.OreDictionary;
import javax.annotation.Nullable;
import java.util.Set;
import java.util.stream.Collectors;
public class Comparer implements IComparer {
@Override
@@ -37,11 +35,6 @@ public class Comparer implements IComparer {
}
if ((flags & COMPARE_NBT) == COMPARE_NBT) {
if ((flags & COMPARE_STRIP_NBT) == COMPARE_STRIP_NBT) {
left = stripTags(left.copy());
right = stripTags(right.copy());
}
if (!isEqualNBT(left, right)) {
return false;
}
@@ -141,66 +134,4 @@ public class Comparer implements IComparer {
return EnumActionResult.PASS;
}
@Nullable
public static ItemStack stripTags(@Nullable ItemStack stack) {
if (stack != null && stack.hasTagCompound()) {
switch (stack.getItem().getRegistryName().getResourceDomain()) {
case "mekanism":
case "mekanismgenerators":
case "mekanismtools":
stack.getTagCompound().removeTag("mekData");
break;
case "enderio":
// Soul vials
stack.getTagCompound().removeTag("entity");
stack.getTagCompound().removeTag("isStub");
// Capacitors
stack.getTagCompound().removeTag("Energy");
// Painted
stack.getTagCompound().removeTag("paintSource__null");
stack.getTagCompound().removeTag("paintSource");
// Sided config
stack.getTagCompound().removeTag("faceModes__null");
stack.getTagCompound().removeTag("faceModes");
// Tank
stack.getTagCompound().removeTag("tank");
stack.getTagCompound().removeTag("voidMode");
stack.getTagCompound().removeTag("inventory");
// Name
stack.getTagCompound().removeTag("display");
stack.getTagCompound().removeTag("eio.abstractMachine");
break;
case "simplyjetpacks":
stack.getTagCompound().removeTag("sjData");
stack.getTagCompound().removeTag("PackOn");
break;
case "immersiveengineering":
stack.getTagCompound().removeTag("hammerDmg");
stack.getTagCompound().removeTag("cutterDmg");
break;
case "modularrouters":
stack.getTagCompound().removeTag("ModuleFilter");
stack.getTagCompound().removeTag("Flags");
break;
case "fluxnetworks":
stack.getTagCompound().removeTag("dropped");
stack.getTagCompound().removeTag("energy");
break;
case "draconicevolution":
stack.getTagCompound().removeTag("Energy");
stack.getTagCompound().removeTag("DEUpgrades");
Set<String> profiles = stack.getTagCompound().getKeySet().stream().filter(key -> key.startsWith("Profile")).collect(Collectors.toSet());
for (String profile : profiles) {
stack.getTagCompound().removeTag(profile);
}
break;
case "minecraft":
stack.getTagCompound().removeTag("RepairCost");
break;
}
}
return stack;
}
}

View File

@@ -9,12 +9,9 @@ import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
public class StackListFluid implements IStackList<FluidStack> {
private ArrayListMultimap<Fluid, FluidStack> stacks = ArrayListMultimap.create();
private List<FluidStack> removeTracker = new LinkedList<>();
@Override
public void add(@Nonnull FluidStack stack, int size) {
@@ -50,37 +47,6 @@ public class StackListFluid implements IStackList<FluidStack> {
return false;
}
@Override
public boolean trackedRemove(@Nonnull FluidStack stack, int size) {
for (FluidStack otherStack : stacks.get(stack.getFluid())) {
if (stack.isFluidEqual(otherStack)) {
FluidStack removed = new FluidStack(otherStack.getFluid(), Math.min(size, otherStack.amount));
this.removeTracker.add(removed);
otherStack.amount -= size;
boolean success = otherStack.amount >= 0;
if (otherStack.amount <= 0) {
stacks.remove(otherStack.getFluid(), otherStack);
}
return success;
}
}
return false;
}
@Override
public void undo() {
removeTracker.forEach(s -> add(s, s.amount));
removeTracker.clear();
}
@Override
public List<FluidStack> getRemoveTracker() {
return removeTracker;
}
@Override
@Nullable
public FluidStack get(@Nonnull FluidStack stack, int flags) {
@@ -137,14 +103,4 @@ public class StackListFluid implements IStackList<FluidStack> {
return list;
}
@Override
public IStackList<FluidStack> getOredicted() {
throw new UnsupportedOperationException("Fluid lists have no oredicted version!");
}
@Override
public String toString() {
return stacks.toString();
}
}

View File

@@ -11,12 +11,9 @@ import net.minecraftforge.items.ItemHandlerHelper;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
public class StackListItem implements IStackList<ItemStack> {
private ArrayListMultimap<Item, ItemStack> stacks = ArrayListMultimap.create();
private List<ItemStack> removeTracker = new LinkedList<>();
@Override
public void add(@Nonnull ItemStack stack, int size) {
@@ -58,39 +55,6 @@ public class StackListItem implements IStackList<ItemStack> {
return false;
}
@Override
public boolean trackedRemove(@Nonnull ItemStack stack, int size) {
for (ItemStack otherStack : stacks.get(stack.getItem())) {
if (API.instance().getComparer().isEqualNoQuantity(otherStack, stack)) {
ItemStack removed = ItemHandlerHelper.copyStackWithSize(otherStack, Math.min(size, otherStack.getCount()));
this.removeTracker.add(removed);
boolean success = otherStack.getCount() - size >= 0;
if (otherStack.getCount() - size <= 0) {
stacks.remove(otherStack.getItem(), otherStack);
} else {
otherStack.shrink(size);
}
return success;
}
}
return false;
}
@Override
public List<ItemStack> getRemoveTracker() {
return removeTracker;
}
@Override
public void undo() {
removeTracker.forEach(s -> add(s, s.getCount()));
removeTracker.clear();
}
@Override
@Nullable
public ItemStack get(@Nonnull ItemStack stack, int flags) {
@@ -148,43 +112,4 @@ public class StackListItem implements IStackList<ItemStack> {
return list;
}
@Nonnull
public StackListItemOredicted getOredicted() {
return new StackListItemOredicted(this);
}
@Override
public String toString() {
return stacks.toString();
}
public static ItemStack[] toCraftingGrid(IStackList<ItemStack> list, List<ItemStack> grid, int compare) {
ItemStack[] took = new ItemStack[Math.max(9, grid.size())];
for (int i = 0; i < grid.size(); i++) {
ItemStack input = grid.get(i);
if (input != null) {
// This will be a tool, like a hammer
if (input.isItemStackDamageable()) {
compare &= ~IComparer.COMPARE_DAMAGE;
} else {
compare |= IComparer.COMPARE_DAMAGE;
}
ItemStack actualInput = list.get(input, compare);
if (actualInput != null) {
ItemStack taken = ItemHandlerHelper.copyStackWithSize(actualInput, input.getCount());
took[i] = taken;
list.remove(taken, taken.getCount());
}
}
}
return took;
}
}

View File

@@ -1,149 +0,0 @@
package com.raoulvdberge.refinedstorage.apiimpl.util;
import com.google.common.collect.ArrayListMultimap;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.api.util.IStackList;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class StackListItemOredicted implements IStackList<ItemStack> {
private StackListItem underlyingList;
private ArrayListMultimap<Integer, ItemStack> stacks = ArrayListMultimap.create();
private StackListItemOredicted() {
}
public StackListItemOredicted(StackListItem list) {
this.underlyingList = list;
initOreDict();
}
private void initOreDict() {
for (ItemStack stack : underlyingList.getStacks()) {
if (!stack.isEmpty()) {
for (int id : OreDictionary.getOreIDs(stack)) {
stacks.put(id, stack);
}
}
}
}
@Override
public void add(@Nonnull ItemStack stack, int size) {
underlyingList.add(stack, size);
ItemStack internalStack = underlyingList.get(stack);
if (internalStack != null && internalStack.getCount() == stack.getCount()) {
for (int id : OreDictionary.getOreIDs(internalStack)) {
stacks.put(id, internalStack);
}
}
}
@Override
public boolean remove(@Nonnull ItemStack stack, int size) {
return underlyingList.remove(stack, size);
}
@Override
public boolean trackedRemove(@Nonnull ItemStack stack, int size) {
return underlyingList.trackedRemove(stack, size);
}
@Override
public List<ItemStack> getRemoveTracker() {
return underlyingList.getRemoveTracker();
}
@Override
public void undo() {
underlyingList.getRemoveTracker().forEach(s -> add(s, s.getCount()));
underlyingList.getRemoveTracker().clear();
}
@Nullable
@Override
public ItemStack get(@Nonnull ItemStack stack, int flags) {
// Check the underlying list but don't do oredict things for exact match
ItemStack exact = underlyingList.get(stack, flags & ~IComparer.COMPARE_OREDICT);
if (exact == null) {
if ((flags & IComparer.COMPARE_OREDICT) == IComparer.COMPARE_OREDICT) {
int[] ids = OreDictionary.getOreIDs(stack);
for (int id : ids) {
List<ItemStack> stacks = this.stacks.get(id);
if (stacks != null && !stacks.isEmpty()) {
int i = 0;
ItemStack returnStack = stacks.get(i++);
while (returnStack.isEmpty() && i < stacks.size()) {
returnStack = stacks.get(i++);
}
if (!returnStack.isEmpty()) {
return returnStack;
}
}
}
}
}
return exact;
}
@Nullable
@Override
public ItemStack get(int hash) {
return underlyingList.get(hash);
}
@Override
public void clear() {
stacks.clear();
underlyingList.clear();
}
@Override
public boolean isEmpty() {
return underlyingList.isEmpty();
}
@Override
public int getSizeFromStack(ItemStack stack) {
return underlyingList.getSizeFromStack(stack);
}
@Nonnull
@Override
public Collection<ItemStack> getStacks() {
return underlyingList.getStacks();
}
@Nonnull
@Override
public IStackList<ItemStack> copy() {
StackListItemOredicted newList = new StackListItemOredicted();
newList.underlyingList = (StackListItem) this.underlyingList.copy();
for (Map.Entry<Integer, ItemStack> entry : this.stacks.entries()) {
newList.stacks.put(entry.getKey(), entry.getValue());
}
return newList;
}
@Override
public IStackList<ItemStack> getOredicted() {
return this;
}
}

View File

@@ -20,7 +20,6 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.client.config.GuiCheckBox;
import net.minecraftforge.fml.client.config.GuiUtils;
import net.minecraftforge.items.SlotItemHandler;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;

View File

@@ -77,7 +77,7 @@ public class GuiCraftingPreview extends GuiBase {
public void init(int x, int y) {
cancelButton = addButton(x + 16, y + 144, 50, 20, t("gui.cancel"));
startButton = addButton(x + 85, y + 144, 50, 20, t("misc.refinedstorage:start"));
startButton.enabled = stacks.stream().filter(ICraftingPreviewElement::hasMissing).count() == 0;
startButton.enabled = stacks.stream().noneMatch(ICraftingPreviewElement::hasMissing);
}
@Override

View File

@@ -93,7 +93,7 @@ public class GridStackItem implements IGridStack {
if (stack.isEmpty()) {
oreIds = new String[]{};
} else {
oreIds = Arrays.stream(OreDictionary.getOreIDs(stack)).mapToObj(OreDictionary::getOreName).collect(Collectors.toList()).toArray(new String[0]);
oreIds = Arrays.stream(OreDictionary.getOreIDs(stack)).mapToObj(OreDictionary::getOreName).toArray(String[]::new);
}
}

View File

@@ -12,7 +12,7 @@ public class ConverterCraftingTask implements Converter {
ICraftingTask task = (ICraftingTask) value;
output.put("stack", task.getRequested());
// TODO: output.put("missing", task.getMissing().getStacks());
output.put("missing", task.getMissing().getStacks());
output.put("pattern", task.getPattern());
output.put("quantity", task.getQuantity());
}

View File

@@ -78,9 +78,7 @@ public class EnvironmentNetwork extends AbstractManagedEnvironment {
}
List<ItemStack> patterns = new LinkedList<ItemStack>();
for (ICraftingPattern pattern : node.getNetwork().getCraftingManager().getPatterns()) {
for (ItemStack output : pattern.getOutputs()) {
patterns.add(output);
}
patterns.addAll(pattern.getOutputs());
}
return new Object[]{patterns};
}
@@ -112,8 +110,7 @@ public class EnvironmentNetwork extends AbstractManagedEnvironment {
task.calculate();
//TODO return new Object[]{task.getMissing().getStacks()};
return new Object[]{};
return new Object[]{task.getMissing().getStacks()};
}
@Callback(doc = "function(stack:table[, count: number]) -- Schedules a crafting task.")