equivalent-exchange-3/ee3_common/com/pahimar/ee3/item/crafting/RecipeRegistry.java

301 lines
11 KiB
Java

package com.pahimar.ee3.item.crafting;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.pahimar.ee3.core.util.EnergyStack;
import com.pahimar.ee3.core.util.ItemUtil;
import com.pahimar.ee3.core.util.OreStack;
import com.pahimar.ee3.core.util.RecipeHelper;
import com.pahimar.ee3.item.CustomWrappedStack;
public class RecipeRegistry {
private static RecipeRegistry recipeRegistry = null;
private Multimap<CustomWrappedStack, List<CustomWrappedStack>> recipeMap;
private ArrayList<CustomWrappedStack> discoveredStacks;
private ArrayList<CustomWrappedStack> recipelessStacks;
private List<CustomWrappedStack> wildCardStacks;
private RecipeRegistry() {
recipeMap = HashMultimap.create();
wildCardStacks = RecipeHelper.populateWildCards();
discoveredStacks = new ArrayList<CustomWrappedStack>();
recipelessStacks = new ArrayList<CustomWrappedStack>();
}
public static RecipeRegistry getInstance() {
if (recipeRegistry == null) {
recipeRegistry = new RecipeRegistry();
recipeRegistry.init();
}
return recipeRegistry;
}
private void init() {
Multimap<CustomWrappedStack, List<CustomWrappedStack>> recipes = HashMultimap.create();
// Add potion recipes
recipes.putAll(RecipesPotions.getPotionRecipes());
// Add smelting recipes in the vanilla smelting manager
recipes.putAll(RecipesSmelting.getSmeltingRecipes());
// Add recipes in the vanilla crafting manager
recipes.putAll(RecipesVanilla.getVanillaRecipes());
// Add recipes gathered via IMC
// TODO Gather IMC recipes
// Populate the discovered stacks list with all stacks that we are involved in a recipe we are aware of
discoverStacks(recipes);
// Add items that have no recipe, using the list of discovered stacks to determine if it's in a recipe or not
for (CustomWrappedStack stack : recipelessStacks) {
recipes.put(stack, new ArrayList<CustomWrappedStack>());
}
// Iterate through every recipe in the map, and add them to the registry
Set<CustomWrappedStack> recipeKeySet = recipes.keySet();
Iterator<CustomWrappedStack> recipeKeySetIterator = recipeKeySet.iterator();
CustomWrappedStack recipeOutput = null;
while (recipeKeySetIterator.hasNext()) {
recipeOutput = recipeKeySetIterator.next();
for (List<CustomWrappedStack> recipeInputs : recipes.get(recipeOutput)) {
addRecipe(recipeOutput, recipeInputs);
}
}
}
private void discoverStacks(Multimap<CustomWrappedStack, List<CustomWrappedStack>> recipes) {
Set<CustomWrappedStack> recipeKeySet = recipes.keySet();
Iterator<CustomWrappedStack> recipeKeySetIterator = recipeKeySet.iterator();
CustomWrappedStack recipeOutput = null;
// Discover all stacks involved in the recipes we know about
while (recipeKeySetIterator.hasNext()) {
recipeOutput = recipeKeySetIterator.next();
if (!discoveredStacks.contains(new CustomWrappedStack(recipeOutput.getWrappedStack())) && recipeOutput.getWrappedStack() != null) {
discoveredStacks.add(new CustomWrappedStack(recipeOutput.getWrappedStack()));
}
for (List<CustomWrappedStack> recipeInputs : recipes.get(recipeOutput)) {
for (CustomWrappedStack recipeInput : recipeInputs) {
CustomWrappedStack unwrappedRecipeInput = new CustomWrappedStack(recipeInput.getWrappedStack());
if (!discoveredStacks.contains(unwrappedRecipeInput) && recipeInput.getWrappedStack() != null) {
discoveredStacks.add(unwrappedRecipeInput);
}
}
}
}
CustomWrappedStack customWrappedStack;
// Discover all stacks from the vanilla Items array
for (int i = 0; i < Item.itemsList.length; i++) {
if (Item.itemsList[i] != null) {
if (Item.itemsList[i].getHasSubtypes()) {
for (int meta = 0; meta < 16; meta++) {
customWrappedStack = new CustomWrappedStack(new ItemStack(Item.itemsList[i].itemID, 1, meta));
if (!discoveredStacks.contains(customWrappedStack)) {
discoveredStacks.add(customWrappedStack);
}
}
}
else {
customWrappedStack = new CustomWrappedStack(new ItemStack(Item.itemsList[i]));
if (!discoveredStacks.contains(customWrappedStack)) {
discoveredStacks.add(customWrappedStack);
}
}
}
}
/*
* For every stack we have discovered, check to see if we know a recipe for it. If we don't
* and we haven't already added it to the recipeless stack list, add it to the recipeless stack
* list
*/
for (CustomWrappedStack discoveredStack : discoveredStacks) {
if (recipes.get(discoveredStack).size() == 0 && !recipelessStacks.contains(discoveredStack)) {
recipelessStacks.add(discoveredStack);
}
}
}
public boolean hasRecipe(CustomWrappedStack customWrappedStack) {
return recipeMap.containsKey(customWrappedStack);
}
public boolean hasRecipe(ItemStack itemStack) {
return hasRecipe(new CustomWrappedStack(itemStack));
}
public int countRecipesFor(CustomWrappedStack customWrappedStack) {
Collection<List<CustomWrappedStack>> keys = recipeMap.get(customWrappedStack);
return keys.size();
}
public int countRecipesFor(ItemStack itemStack) {
return countRecipesFor(new CustomWrappedStack(itemStack));
}
public Collection<List<CustomWrappedStack>> getRecipesFor(CustomWrappedStack customWrappedStack) {
return recipeMap.get(customWrappedStack);
}
public Collection<List<CustomWrappedStack>> getRecipesFor(ItemStack itemStack) {
return getRecipesFor(new CustomWrappedStack(itemStack));
}
/*
* Item: Item (Output) <- { ... }
*/
public void addRecipe(CustomWrappedStack recipeOutput, List<?> recipeInputs) {
ArrayList<CustomWrappedStack> collatedStacks = new ArrayList<CustomWrappedStack>();
CustomWrappedStack wrappedInputStack = null;
boolean found = false;
/**
* For every input in the input list, check to see if we have discovered
* it already - If we have, add it to the one we already have - If we
* have not, add it to the collection of discovered items
*/
for (Object object : recipeInputs) {
if (object instanceof ItemStack || object instanceof OreStack) {
wrappedInputStack = new CustomWrappedStack(object);
}
else if (object instanceof CustomWrappedStack) {
wrappedInputStack = (CustomWrappedStack) object;
}
if (wildCardStacks.contains(wrappedInputStack)) {
Iterator<CustomWrappedStack> wildIter = wildCardStacks.iterator();
while (wildIter.hasNext()) {
CustomWrappedStack wildCard = wildIter.next();
if (wildCard.equals(wrappedInputStack)) {
wrappedInputStack = wildCard;
break;
}
}
}
if (collatedStacks.size() == 0) {
collatedStacks.add(wrappedInputStack);
}
else {
found = false;
for (int i = 0; i < collatedStacks.size(); i++) {
if (collatedStacks.get(i) != null) {
if (wrappedInputStack.getWrappedStack() instanceof ItemStack && collatedStacks.get(i).getWrappedStack() instanceof ItemStack) {
if (ItemUtil.compare((ItemStack) wrappedInputStack.getWrappedStack(), (ItemStack) collatedStacks.get(i).getWrappedStack())) {
collatedStacks.get(i).setStackSize(collatedStacks.get(i).getStackSize() + wrappedInputStack.getStackSize());
found = true;
}
}
else if (wrappedInputStack.getWrappedStack() instanceof OreStack && collatedStacks.get(i).getWrappedStack() instanceof OreStack) {
if (OreStack.compareStacks((OreStack) wrappedInputStack.getWrappedStack(), (OreStack) collatedStacks.get(i).getWrappedStack())) {
collatedStacks.get(i).setStackSize(collatedStacks.get(i).getStackSize() + wrappedInputStack.getStackSize());
found = true;
}
}
else if (wrappedInputStack.getWrappedStack() instanceof EnergyStack && collatedStacks.get(i).getWrappedStack() instanceof EnergyStack) {
if (((EnergyStack) wrappedInputStack.getWrappedStack()).energyName.equalsIgnoreCase(((EnergyStack) collatedStacks.get(i).getWrappedStack()).energyName)) {
collatedStacks.get(i).setStackSize(collatedStacks.get(i).getStackSize() + wrappedInputStack.getStackSize());
found = true;
}
}
}
}
if (!found) {
collatedStacks.add(wrappedInputStack);
}
}
}
if (!recipeMap.containsEntry(recipeOutput, collatedStacks)) {
recipeMap.put(recipeOutput, collatedStacks);
}
}
public int size() {
return recipeMap.size();
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
for (CustomWrappedStack key : recipeMap.keySet()) {
Collection<List<CustomWrappedStack>> recipeMappings = recipeMap.get(key);
for (List<CustomWrappedStack> recipeList : recipeMappings) {
stringBuilder.append(String.format("Recipe Output: %s, Recipe Input: %s\n", key.toString(), recipeList.toString()));
}
}
return stringBuilder.toString();
}
public Multimap<CustomWrappedStack, List<CustomWrappedStack>> getRecipeMappings() {
return recipeMap;
}
public List<CustomWrappedStack> getDiscoveredStacks() {
return discoveredStacks;
}
public List<CustomWrappedStack> getRecipelessStacks() {
return recipelessStacks;
}
public List<CustomWrappedStack> getWildCardStacks() {
return wildCardStacks;
}
}