com.github.sprial404.ss.item.crafting.RecipeRegistry.java Source code

Java tutorial

Introduction

Here is the source code for com.github.sprial404.ss.item.crafting.RecipeRegistry.java

Source

package com.github.sprial404.ss.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.github.sprial404.ss.core.util.EnergyStack;
import com.github.sprial404.ss.core.util.ItemUtil;
import com.github.sprial404.ss.core.util.OreStack;
import com.github.sprial404.ss.core.util.RecipeHelper;
import com.github.sprial404.ss.item.CustomWrappedStack;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;

/**
 * Sprial-Security
 * 
 * RecipeRegistry
 * 
 * @author Sprial404
 * @license Lesser GNU Public License v3 (http://www.gnu.org/licenses/lgpl.html)
 */
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;
    }
}