/* * This file is part of Industrial Wires. * Copyright (C) 2016-2018 malte0811 * Industrial Wires is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * Industrial Wires is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with Industrial Wires. If not, see . */ package malte0811.industrialwires.crafting; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import malte0811.industrialwires.IndustrialWires; import malte0811.industrialwires.items.ItemIC2Coil; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.Ingredient; import net.minecraft.util.NonNullList; import net.minecraft.world.World; import net.minecraftforge.oredict.OreDictionary; import net.minecraftforge.registries.IForgeRegistryEntry; import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.List; import java.util.Random; public class RecipeCoilLength extends IForgeRegistryEntry.Impl implements IRecipe { public final ItemStack coil; public final List> cables; private final int maxLength; public RecipeCoilLength(ItemStack coil, List> cables) { this.coil = coil; this.cables = cables; maxLength = ItemIC2Coil.getMaxWireLength(this.coil); } @Override public boolean matches(@Nonnull InventoryCrafting inv, @Nullable World worldIn) { int l = getLength(inv); return l > 0; } @Nonnull @Override public ItemStack getCraftingResult(@Nonnull InventoryCrafting inv) { ItemStack ret = new ItemStack(IndustrialWires.coil, 1, coil.getItemDamage()); ItemIC2Coil.setLength(ret, Math.min(maxLength, getLength(inv))); return ret; } @Override public boolean canFit(int width, int height) { return width>0 && height>0; } @Nonnull @Override public ItemStack getRecipeOutput() { return coil; } @Nonnull @Override public NonNullList getRemainingItems(@Nonnull InventoryCrafting inv) { NonNullList ret = NonNullList.withSize(inv.getSizeInventory(), ItemStack.EMPTY); int length = Math.min(getLength(inv), maxLength); for (int i = 0; i < ret.size() && length > 0; i++) { ItemStack curr = inv.getStackInSlot(i); if (OreDictionary.itemMatches(curr, coil, false)) { length -= ItemIC2Coil.getLength(curr); if (length < 0) { ItemStack currStack = coil.copy(); ret.set(i, currStack); ItemIC2Coil.setLength(currStack, -length); } } else { length -= getCableLength(curr); } } return ret; } private int getLength(InventoryCrafting inv) { int totalLength = 0; for (int i = 0; i < inv.getSizeInventory(); i++) { ItemStack curr = inv.getStackInSlot(i); if (OreDictionary.itemMatches(curr, coil, false)) { totalLength += ItemIC2Coil.getLength(curr); } else { int slotLength = getCableLength(curr); if (slotLength>0) { totalLength += slotLength; } else if (!curr.isEmpty()) { return -1; } } } return totalLength; } @Nonnull @Override public NonNullList getIngredients() { Random r = new Random(); NonNullList ret = NonNullList.withSize(9, Ingredient.EMPTY); for (int i = 0;i cable:cables) { length += cable.getLeft().getMatchingStacks().length; } ItemStack[] types = new ItemStack[length]; int cablePos = 0; if (r.nextBoolean()) { types[length-1] = coil; } else { types[0] = coil; cablePos = 1; } for (Pair cable : cables) { ItemStack[] matching = cable.getLeft().getMatchingStacks(); System.arraycopy(matching, 0, types, cablePos, matching.length); cablePos += matching.length; } ret.set(i, new UnmatchedIngredient(types)); } return ret; } private int getCableLength(ItemStack stack) { for (Pair ingred:cables) { if (ingred.getLeft().apply(stack)) { return ingred.getRight(); } } return 0; } //There is probably a better way to do this... private static class UnmatchedIngredient extends Ingredient { public UnmatchedIngredient(ItemStack[] in) { super(in); } @Override public boolean apply(@Nullable ItemStack input) { if (input == null) return false; for (ItemStack stack:getMatchingStacks()) { if (ItemStack.areItemsEqual(stack, input) && ItemStack.areItemStackTagsEqual(stack, input)) { return true; } } return false; } @Nonnull @Override public IntList getValidItemStacksPacked() { return new IntArrayList(0); } } }