b8a17e2748
-Add NBT-sensitive getMaxDamage() for ItemStack. Signed-off-by: King Lemming <kinglemming@gmail.com>
317 lines
11 KiB
Java
317 lines
11 KiB
Java
package net.minecraftforge.oredict;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
|
|
import net.minecraft.block.Block;
|
|
import net.minecraft.item.Item;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.item.crafting.CraftingManager;
|
|
import net.minecraft.item.crafting.IRecipe;
|
|
import net.minecraft.item.crafting.ShapedRecipes;
|
|
import net.minecraft.item.crafting.ShapelessRecipes;
|
|
import net.minecraftforge.common.MinecraftForge;
|
|
import net.minecraftforge.event.Event;
|
|
|
|
public class OreDictionary
|
|
{
|
|
private static boolean hasInit = false;
|
|
private static int maxID = 0;
|
|
private static HashMap<String, Integer> oreIDs = new HashMap<String, Integer>();
|
|
private static HashMap<Integer, ArrayList<ItemStack>> oreStacks = new HashMap<Integer, ArrayList<ItemStack>>();
|
|
|
|
|
|
/**
|
|
* Minecraft changed from -1 to Short.MAX_VALUE in 1.5 release for the "block wildcard". Use this in case it
|
|
* changes again.
|
|
*/
|
|
public static final int WILDCARD_VALUE = Short.MAX_VALUE;
|
|
|
|
static {
|
|
initVanillaEntries();
|
|
}
|
|
|
|
public static void initVanillaEntries()
|
|
{
|
|
if (!hasInit)
|
|
{
|
|
registerOre("logWood", new ItemStack(Block.wood, 1, WILDCARD_VALUE));
|
|
registerOre("plankWood", new ItemStack(Block.planks, 1, WILDCARD_VALUE));
|
|
registerOre("slabWood", new ItemStack(Block.woodSingleSlab, 1, WILDCARD_VALUE));
|
|
registerOre("stairWood", Block.stairsWoodOak);
|
|
registerOre("stairWood", Block.stairsWoodBirch);
|
|
registerOre("stairWood", Block.stairsWoodJungle);
|
|
registerOre("stairWood", Block.stairsWoodSpruce);
|
|
registerOre("stickWood", Item.stick);
|
|
registerOre("treeSapling", new ItemStack(Block.sapling, 1, WILDCARD_VALUE));
|
|
registerOre("treeLeaves", new ItemStack(Block.leaves, 1, WILDCARD_VALUE));
|
|
registerOre("oreGold", Block.oreGold);
|
|
registerOre("oreIron", Block.oreIron);
|
|
registerOre("oreLapis", Block.oreLapis);
|
|
registerOre("oreDiamond", Block.oreDiamond);
|
|
registerOre("oreRedstone", Block.oreRedstone);
|
|
registerOre("oreEmerald", Block.oreEmerald);
|
|
}
|
|
|
|
// Build our list of items to replace with ore tags
|
|
Map<ItemStack, String> replacements = new HashMap<ItemStack, String>();
|
|
replacements.put(new ItemStack(Block.planks, 1, WILDCARD_VALUE), "plankWood");
|
|
replacements.put(new ItemStack(Item.stick), "stickWood");
|
|
|
|
// Register dyes
|
|
String[] dyes =
|
|
{
|
|
"dyeBlack",
|
|
"dyeRed",
|
|
"dyeGreen",
|
|
"dyeBrown",
|
|
"dyeBlue",
|
|
"dyePurple",
|
|
"dyeCyan",
|
|
"dyeLightGray",
|
|
"dyeGray",
|
|
"dyePink",
|
|
"dyeLime",
|
|
"dyeYellow",
|
|
"dyeLightBlue",
|
|
"dyeMagenta",
|
|
"dyeOrange",
|
|
"dyeWhite"
|
|
};
|
|
|
|
for(int i = 0; i < 16; i++)
|
|
{
|
|
ItemStack dye = new ItemStack(Item.dyePowder, 1, i);
|
|
if (!hasInit)
|
|
{
|
|
registerOre(dyes[i], dye);
|
|
}
|
|
replacements.put(dye, dyes[i]);
|
|
}
|
|
hasInit = true;
|
|
|
|
ItemStack[] replaceStacks = replacements.keySet().toArray(new ItemStack[replacements.keySet().size()]);
|
|
|
|
// Ignore recipes for the following items
|
|
ItemStack[] exclusions = new ItemStack[]
|
|
{
|
|
new ItemStack(Block.blockLapis),
|
|
new ItemStack(Item.cookie),
|
|
};
|
|
|
|
List recipes = CraftingManager.getInstance().getRecipeList();
|
|
List<IRecipe> recipesToRemove = new ArrayList<IRecipe>();
|
|
List<IRecipe> recipesToAdd = new ArrayList<IRecipe>();
|
|
|
|
// Search vanilla recipes for recipes to replace
|
|
for(Object obj : recipes)
|
|
{
|
|
if(obj instanceof ShapedRecipes)
|
|
{
|
|
ShapedRecipes recipe = (ShapedRecipes)obj;
|
|
ItemStack output = recipe.getRecipeOutput();
|
|
if (output != null && containsMatch(false, exclusions, output))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if(containsMatch(true, recipe.recipeItems, replaceStacks))
|
|
{
|
|
recipesToRemove.add(recipe);
|
|
recipesToAdd.add(new ShapedOreRecipe(recipe, replacements));
|
|
}
|
|
}
|
|
else if(obj instanceof ShapelessRecipes)
|
|
{
|
|
ShapelessRecipes recipe = (ShapelessRecipes)obj;
|
|
ItemStack output = recipe.getRecipeOutput();
|
|
if (output != null && containsMatch(false, exclusions, output))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if(containsMatch(true, (ItemStack[])recipe.recipeItems.toArray(new ItemStack[recipe.recipeItems.size()]), replaceStacks))
|
|
{
|
|
recipesToRemove.add((IRecipe)obj);
|
|
IRecipe newRecipe = new ShapelessOreRecipe(recipe, replacements);
|
|
recipesToAdd.add(newRecipe);
|
|
}
|
|
}
|
|
}
|
|
|
|
recipes.removeAll(recipesToRemove);
|
|
recipes.addAll(recipesToAdd);
|
|
if (recipesToRemove.size() > 0)
|
|
{
|
|
System.out.println("Replaced " + recipesToRemove.size() + " ore recipies");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the integer ID for the specified ore name.
|
|
* If the name does not have a ID it assigns it a new one.
|
|
*
|
|
* @param name The unique name for this ore 'oreIron', 'ingotIron', etc..
|
|
* @return A number representing the ID for this ore type
|
|
*/
|
|
public static int getOreID(String name)
|
|
{
|
|
Integer val = oreIDs.get(name);
|
|
if (val == null)
|
|
{
|
|
val = maxID++;
|
|
oreIDs.put(name, val);
|
|
oreStacks.put(val, new ArrayList<ItemStack>());
|
|
}
|
|
return val;
|
|
}
|
|
|
|
/**
|
|
* Reverse of getOreID, will not create new entries.
|
|
*
|
|
* @param id The ID to translate to a string
|
|
* @return The String name, or "Unknown" if not found.
|
|
*/
|
|
public static String getOreName(int id)
|
|
{
|
|
for (Map.Entry<String, Integer> entry : oreIDs.entrySet())
|
|
{
|
|
if (id == entry.getValue())
|
|
{
|
|
return entry.getKey();
|
|
}
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
/**
|
|
* Gets the integer ID for the specified item stack.
|
|
* If the item stack is not linked to any ore, this will return -1 and no new entry will be created.
|
|
*
|
|
* @param itemStack The item stack of the ore.
|
|
* @return A number representing the ID for this ore type, or -1 if couldn't find it.
|
|
*/
|
|
public static int getOreID(ItemStack itemStack)
|
|
{
|
|
if (itemStack == null)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
for(Entry<Integer, ArrayList<ItemStack>> ore : oreStacks.entrySet())
|
|
{
|
|
for(ItemStack target : ore.getValue())
|
|
{
|
|
if(itemStack.itemID == target.itemID && (target.getItemDamage() == WILDCARD_VALUE || itemStack.getItemDamage() == target.getItemDamage()))
|
|
{
|
|
return ore.getKey();
|
|
}
|
|
}
|
|
}
|
|
return -1; // didn't find it.
|
|
}
|
|
|
|
/**
|
|
* Retrieves the ArrayList of items that are registered to this ore type.
|
|
* Creates the list as empty if it did not exist.
|
|
*
|
|
* @param name The ore name, directly calls getOreID
|
|
* @return An arrayList containing ItemStacks registered for this ore
|
|
*/
|
|
public static ArrayList<ItemStack> getOres(String name)
|
|
{
|
|
return getOres(getOreID(name));
|
|
}
|
|
|
|
/**
|
|
* Retrieves a list of all unique ore names that are already registered.
|
|
*
|
|
* @return All unique ore names that are currently registered.
|
|
*/
|
|
public static String[] getOreNames()
|
|
{
|
|
return oreIDs.keySet().toArray(new String[oreIDs.keySet().size()]);
|
|
}
|
|
|
|
/**
|
|
* Retrieves the ArrayList of items that are registered to this ore type.
|
|
* Creates the list as empty if it did not exist.
|
|
*
|
|
* @param id The ore ID, see getOreID
|
|
* @return An arrayList containing ItemStacks registered for this ore
|
|
*/
|
|
public static ArrayList<ItemStack> getOres(Integer id)
|
|
{
|
|
ArrayList<ItemStack> val = oreStacks.get(id);
|
|
if (val == null)
|
|
{
|
|
val = new ArrayList<ItemStack>();
|
|
oreStacks.put(id, val);
|
|
}
|
|
return val;
|
|
}
|
|
|
|
private static boolean containsMatch(boolean strict, ItemStack[] inputs, ItemStack... targets)
|
|
{
|
|
for (ItemStack input : inputs)
|
|
{
|
|
for (ItemStack target : targets)
|
|
{
|
|
if (itemMatches(target, input, strict))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static boolean itemMatches(ItemStack target, ItemStack input, boolean strict)
|
|
{
|
|
if (input == null && target != null || input != null && target == null)
|
|
{
|
|
return false;
|
|
}
|
|
return (target.itemID == input.itemID && ((target.getItemDamage() == WILDCARD_VALUE && !strict) || target.getItemDamage() == input.getItemDamage()));
|
|
}
|
|
|
|
//Convenience functions that make for cleaner code mod side. They all drill down to registerOre(String, int, ItemStack)
|
|
public static void registerOre(String name, Item ore){ registerOre(name, new ItemStack(ore)); }
|
|
public static void registerOre(String name, Block ore){ registerOre(name, new ItemStack(ore)); }
|
|
public static void registerOre(String name, ItemStack ore){ registerOre(name, getOreID(name), ore); }
|
|
public static void registerOre(int id, Item ore){ registerOre(id, new ItemStack(ore)); }
|
|
public static void registerOre(int id, Block ore){ registerOre(id, new ItemStack(ore)); }
|
|
public static void registerOre(int id, ItemStack ore){ registerOre(getOreName(id), id, ore); }
|
|
|
|
/**
|
|
* Registers a ore item into the dictionary.
|
|
* Raises the registerOre function in all registered handlers.
|
|
*
|
|
* @param name The name of the ore
|
|
* @param id The ID of the ore
|
|
* @param ore The ore's ItemStack
|
|
*/
|
|
private static void registerOre(String name, int id, ItemStack ore)
|
|
{
|
|
ArrayList<ItemStack> ores = getOres(id);
|
|
ore = ore.copy();
|
|
ores.add(ore);
|
|
MinecraftForge.EVENT_BUS.post(new OreRegisterEvent(name, ore));
|
|
}
|
|
|
|
public static class OreRegisterEvent extends Event
|
|
{
|
|
public final String Name;
|
|
public final ItemStack Ore;
|
|
|
|
public OreRegisterEvent(String name, ItemStack ore)
|
|
{
|
|
this.Name = name;
|
|
this.Ore = ore;
|
|
}
|
|
}
|
|
}
|