package com.pahimar.ee3.emc; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import net.minecraft.item.ItemStack; import net.minecraftforge.oredict.OreDictionary; import com.google.common.collect.ImmutableSortedMap; import com.pahimar.ee3.core.helper.EmcHelper; import com.pahimar.ee3.core.helper.LogHelper; import com.pahimar.ee3.core.helper.RecipeHelper; import com.pahimar.ee3.item.OreStack; import com.pahimar.ee3.item.WrappedStack; import com.pahimar.ee3.item.crafting.RecipeRegistry; public class EmcRegistry { private int MAX_ATTEMPTED_ASSIGNMENT_PASSES = 16; private static EmcRegistry emcRegistry = null; private ImmutableSortedMap stackMappings; private ImmutableSortedMap> valueMappings; public static void lazyInit() { if (emcRegistry == null) { emcRegistry = new EmcRegistry(); emcRegistry.init(); } } private void init() { HashMap stackValueMap = new HashMap(); /* * Default values */ Map defaultValuesMap = EmcValuesDefault.getDefaultValueMap(); for (WrappedStack wrappedStack : defaultValuesMap.keySet()) { if (wrappedStack != null) { if (!stackValueMap.keySet().contains(wrappedStack)) { EmcValue emcValue = defaultValuesMap.get(wrappedStack); if (emcValue != null && emcValue.getValue() > 0f) { stackValueMap.put(wrappedStack, emcValue); } } } } /* * IMC Pre-assigned values */ Map preAssignedValuesMap = EmcValuesIMC.getPreAssignedValues(); for (WrappedStack wrappedStack : preAssignedValuesMap.keySet()) { if (wrappedStack != null) { if (!stackValueMap.keySet().contains(wrappedStack)) { EmcValue emcValue = preAssignedValuesMap.get(wrappedStack); if (emcValue != null && emcValue.getValue() > 0f) { stackValueMap.put(wrappedStack, emcValue); } } } } /* * Auto-assignment */ ImmutableSortedMap.Builder stackMappingsBuilder = ImmutableSortedMap.naturalOrder(); stackMappingsBuilder.putAll(stackValueMap); stackValueMap.clear(); stackMappings = stackMappingsBuilder.build(); int passNumber = 0; Map computedStackValues = computeStackMappings(); while ((computedStackValues.size() > 0) && (passNumber < MAX_ATTEMPTED_ASSIGNMENT_PASSES)) { passNumber++; computedStackValues = computeStackMappings(); stackMappingsBuilder = ImmutableSortedMap.naturalOrder(); stackMappingsBuilder.putAll(stackMappings); stackMappingsBuilder.putAll(computedStackValues); stackMappings = stackMappingsBuilder.build(); } /* * IMC Post-assigned values */ stackValueMap.putAll(stackMappings); Map postAssignedValuesMap = EmcValuesIMC.getPostAssignedValues(); for (WrappedStack wrappedStack : postAssignedValuesMap.keySet()) { if (wrappedStack != null) { EmcValue emcValue = postAssignedValuesMap.get(wrappedStack); if (emcValue != null && emcValue.getValue() > 0f) { stackValueMap.put(wrappedStack, emcValue); } } } stackMappingsBuilder = ImmutableSortedMap.naturalOrder(); stackMappingsBuilder.putAll(stackValueMap); stackMappings = stackMappingsBuilder.build(); /* * Value map resolution */ SortedMap> tempValueMappings = new TreeMap>(); for (WrappedStack stack : stackMappings.keySet()) { EmcValue value = stackMappings.get(stack); if (tempValueMappings.containsKey(value)) { if (!(tempValueMappings.get(value).contains(stack))) { tempValueMappings.get(value).add(stack); } } else { tempValueMappings.put(value, new ArrayList(Arrays.asList(stack))); } } valueMappings = ImmutableSortedMap.copyOf(tempValueMappings); } private static Map computeStackMappings() { Map computedStackMap = new HashMap(); for (WrappedStack recipeOutput : RecipeRegistry.getRecipeMappings().keySet()) { if (!hasEmcValue(recipeOutput.getWrappedStack(), false) && !computedStackMap.containsKey(recipeOutput.getWrappedStack())) { EmcValue lowestValue = null; for (List recipeInputs : RecipeRegistry.getRecipeMappings().get(recipeOutput)) { EmcValue computedValue = EmcHelper.computeEmcValueFromList(recipeInputs); computedValue = EmcHelper.factorEmcValue(computedValue, recipeOutput.getStackSize()); if (computedValue != null) { if (computedValue.compareTo(lowestValue) < 0) { lowestValue = computedValue; } } } if ((lowestValue != null) && (lowestValue.getValue() > 0f)) { computedStackMap.put(new WrappedStack(recipeOutput.getWrappedStack()), lowestValue); } } } return computedStackMap; } public static boolean hasEmcValue(Object object, boolean strict) { lazyInit(); if (WrappedStack.canBeWrapped(object)) { WrappedStack stack = new WrappedStack(object); if (emcRegistry.stackMappings.containsKey(new WrappedStack(stack.getWrappedStack()))) { return emcRegistry.stackMappings.containsKey(new WrappedStack(stack.getWrappedStack())); } else { if (!strict) { if (stack.getWrappedStack() instanceof ItemStack) { ItemStack wrappedItemStack = (ItemStack) stack.getWrappedStack(); // If its an OreDictionary item, scan its siblings for values if (OreDictionary.getOreID(wrappedItemStack) != -1) { OreStack oreStack = new OreStack(wrappedItemStack); if (emcRegistry.stackMappings.containsKey(new WrappedStack(oreStack))) { return emcRegistry.stackMappings.containsKey(new WrappedStack(oreStack)); } else { for (ItemStack itemStack : OreDictionary.getOres(OreDictionary.getOreID(wrappedItemStack))) { if (emcRegistry.stackMappings.containsKey(new WrappedStack(itemStack))) { return emcRegistry.stackMappings.containsKey(new WrappedStack(itemStack)); } } } } // Else, scan for if there is a wildcard value for it else { for (WrappedStack valuedStack : emcRegistry.stackMappings.keySet()) { if (valuedStack.getWrappedStack() instanceof ItemStack) { ItemStack valuedItemStack = (ItemStack) valuedStack.getWrappedStack(); if ((valuedItemStack.getItemDamage() == OreDictionary.WILDCARD_VALUE || wrappedItemStack.getItemDamage() == OreDictionary.WILDCARD_VALUE) && valuedItemStack.itemID == wrappedItemStack.itemID) { return true; } } } } } } } } return false; } public static boolean hasEmcValue(Object object) { return hasEmcValue(object, false); } public static EmcValue getEmcValue(Object object, boolean strict) { lazyInit(); if (hasEmcValue(object, strict)) { WrappedStack stack = new WrappedStack(object); if (emcRegistry.stackMappings.containsKey(new WrappedStack(stack.getWrappedStack()))) { return emcRegistry.stackMappings.get(new WrappedStack(stack.getWrappedStack())); } else { if (stack.getWrappedStack() instanceof ItemStack) { ItemStack wrappedItemStack = (ItemStack) stack.getWrappedStack(); EmcValue lowestValue = null; if (OreDictionary.getOreID(wrappedItemStack) != -1) { OreStack oreStack = new OreStack(wrappedItemStack); if (emcRegistry.stackMappings.containsKey(new WrappedStack(oreStack))) { return emcRegistry.stackMappings.get(new WrappedStack(oreStack)); } else { for (ItemStack itemStack : OreDictionary.getOres(OreDictionary.getOreID(wrappedItemStack))) { if (emcRegistry.stackMappings.containsKey(new WrappedStack(itemStack))) { if (lowestValue == null) { lowestValue = emcRegistry.stackMappings.get(new WrappedStack(itemStack)); } else { EmcValue itemValue = emcRegistry.stackMappings.get(new WrappedStack(itemStack)); if (itemValue.compareTo(lowestValue) < 0) { lowestValue = itemValue; } } } } return lowestValue; } } else { for (WrappedStack valuedStack : emcRegistry.stackMappings.keySet()) { EmcValue stackValue = emcRegistry.stackMappings.get(valuedStack); if (valuedStack.getWrappedStack() instanceof ItemStack) { ItemStack valuedItemStack = (ItemStack) valuedStack.getWrappedStack(); if ((valuedItemStack.getItemDamage() == OreDictionary.WILDCARD_VALUE || wrappedItemStack.getItemDamage() == OreDictionary.WILDCARD_VALUE) && valuedItemStack.itemID == wrappedItemStack.itemID) { if (stackValue.compareTo(lowestValue) < 0) { lowestValue = stackValue; } } } } return lowestValue; } } } } return null; } public static EmcValue getEmcValue(Object object) { return getEmcValue(object, false); } public static List getStacksInRange(int start, int finish) { return getStacksInRange(new EmcValue(start), new EmcValue(finish)); } public static List getStacksInRange(float start, float finish) { return getStacksInRange(new EmcValue(start), new EmcValue(finish)); } public static List getStacksInRange(EmcValue start, EmcValue finish) { lazyInit(); List stacksInRange = new ArrayList(); SortedMap> tailMap = emcRegistry.valueMappings.tailMap(start); SortedMap> headMap = emcRegistry.valueMappings.headMap(finish); SortedMap> smallerMap; SortedMap> biggerMap; if (!tailMap.isEmpty() && !headMap.isEmpty()) { if (tailMap.size() <= headMap.size()) { smallerMap = tailMap; biggerMap = headMap; } else { smallerMap = headMap; biggerMap = tailMap; } for (EmcValue value : smallerMap.keySet()) { if (biggerMap.containsKey(value)) { stacksInRange.addAll(emcRegistry.valueMappings.get(value)); } } } return stacksInRange; } public static void printStackValueMappings() { lazyInit(); for (WrappedStack stack : emcRegistry.stackMappings.keySet()) { LogHelper.debug("Stack: " + stack + ", Value: " + emcRegistry.stackMappings.get(stack)); } } public static void printUnmappedStacks() { lazyInit(); List discoveredStacks = new ArrayList(RecipeRegistry.getDiscoveredStacks()); Collections.sort(discoveredStacks); for (WrappedStack stack : discoveredStacks) { if (!hasEmcValue(stack)) { if (RecipeRegistry.getRecipeMappings().get(stack).size() > 0) { for (List recipeInputs : RecipeRegistry.getRecipeMappings().get(stack)) { LogHelper.debug(stack + ": " + RecipeHelper.collateInputStacks(recipeInputs)); } } else { LogHelper.debug(stack); } } } } public static void printUnmappedCompoundStacks() { lazyInit(); List unmappedStacks = new ArrayList(); for (WrappedStack recipeOutput : RecipeRegistry.getRecipeMappings().keySet()) { WrappedStack unitStack = new WrappedStack(recipeOutput.getWrappedStack()); if (!hasEmcValue(unitStack)) { unmappedStacks.add(recipeOutput); } } Collections.sort(unmappedStacks); for (WrappedStack recipeOutput : unmappedStacks) { for (List recipeInputs : RecipeRegistry.getRecipeMappings().get(recipeOutput)) { LogHelper.debug(String.format("Recipe Output: %s, Recipe Inputs: %s", recipeOutput, RecipeHelper.collateInputStacks(recipeInputs))); } } } }