diff --git a/core/Registration.java b/core/Registration.java index 621f2d42..b593f8cd 100644 --- a/core/Registration.java +++ b/core/Registration.java @@ -113,6 +113,7 @@ import appeng.me.cache.SecurityCache; import appeng.me.cache.SpatialPylonCache; import appeng.me.cache.TickManagerCache; import appeng.me.storage.AEExternalHandler; +import appeng.recipes.AEItemResolver; import appeng.recipes.RecipeHandler; import appeng.recipes.Recipes.ShapedRecipe; import appeng.recipes.Recipes.ShapelessRecipe; @@ -153,6 +154,7 @@ public class Registration public void PreInit(FMLPreInitializationEvent event) { IRecipeHandlerRegistry recipeRegistery = AEApi.instance().registries().recipes(); + recipeRegistery.addNewSubItemResolver( new AEItemResolver() ); recipeRegistery.addNewCraftHandler( "grind", Grind.class ); recipeRegistery.addNewCraftHandler( "pulverizer", Pulverizer.class ); @@ -338,7 +340,6 @@ public class Registration addFeature( ToolReplicatorCard.class ); addFeature( BlockItemGen.class ); addFeature( BlockChunkloader.class ); - } private AEItemDefinition addFeature(Class c, Object... Args) diff --git a/core/features/registries/RecipeHandlerRegistry.java b/core/features/registries/RecipeHandlerRegistry.java index c325e498..61fe5476 100644 --- a/core/features/registries/RecipeHandlerRegistry.java +++ b/core/features/registries/RecipeHandlerRegistry.java @@ -1,39 +1,71 @@ package appeng.core.features.registries; import java.util.HashMap; +import java.util.LinkedList; import appeng.api.features.IRecipeHandlerRegistry; import appeng.api.recipes.ICraftHandler; import appeng.api.recipes.IRecipeHandler; +import appeng.api.recipes.ISubItemResolver; +import appeng.api.recipes.ResolveResult; import appeng.core.AELog; import appeng.recipes.RecipeHandler; -public class RecipeHandlerRegistry implements IRecipeHandlerRegistry{ - - HashMap> handlers = new HashMap>(); +public class RecipeHandlerRegistry implements IRecipeHandlerRegistry +{ + + HashMap> handlers = new HashMap>(); + LinkedList resolvers = new LinkedList(); @Override - public void addNewCraftHandler(String name, Class handler) { - handlers.put(name.toLowerCase(), handler); + public void addNewCraftHandler(String name, Class handler) + { + handlers.put( name.toLowerCase(), handler ); } @Override - public ICraftHandler getCraftHandlerFor(String name) { - Class clz= handlers.get(name); - if ( clz == null ) return null; - try { + public ICraftHandler getCraftHandlerFor(String name) + { + Class clz = handlers.get( name ); + if ( clz == null ) + return null; + try + { return clz.newInstance(); - } catch (Throwable e) { - AELog.severe("Error Caused when trying to construct "+clz.getName()); - AELog.error(e); - handlers.put(name, null); // clear it.. + } + catch (Throwable e) + { + AELog.severe( "Error Caused when trying to construct " + clz.getName() ); + AELog.error( e ); + handlers.put( name, null ); // clear it.. return null; } } @Override - public IRecipeHandler createNewRecipehandler() { + public IRecipeHandler createNewRecipehandler() + { return new RecipeHandler(); } - + + @Override + public void addNewSubItemResolver(ISubItemResolver sir) + { + resolvers.add( sir ); + } + + @Override + public ResolveResult resolveItem(String nameSpace, String itemName) + { + for (ISubItemResolver sir : resolvers) + { + ResolveResult rr = sir.resolveItemByName( nameSpace, itemName ); + + if ( rr != null ) + return rr; + } + + return null; + } + } diff --git a/items/misc/ItemCrystalSeed.java b/items/misc/ItemCrystalSeed.java index 3059d21f..07ca8057 100644 --- a/items/misc/ItemCrystalSeed.java +++ b/items/misc/ItemCrystalSeed.java @@ -26,6 +26,14 @@ import cpw.mods.fml.common.registry.EntityRegistry; public class ItemCrystalSeed extends AEBaseItem implements IGrowableCrystal { + public static final int LEVEL_OFFSET = 200; + public static final int SINGLE_OFFSET = LEVEL_OFFSET * 3; + + public static final int Certus = 0; + public static final int Nether = SINGLE_OFFSET; + public static final int Fluix = SINGLE_OFFSET * 2; + public static final int END = SINGLE_OFFSET * 3; + IIcon certus[] = new IIcon[3]; IIcon fluix[] = new IIcon[3]; IIcon nether[] = new IIcon[3]; @@ -45,13 +53,13 @@ public class ItemCrystalSeed extends AEBaseItem implements IGrowableCrystal { int damage = is.getItemDamage(); - if ( damage < 600 ) + if ( damage < Certus + SINGLE_OFFSET ) return getUnlocalizedName() + ".Certus"; - if ( damage < 1200 ) + if ( damage < Nether + SINGLE_OFFSET ) return getUnlocalizedName() + ".Nether"; - if ( damage < 1800 ) + if ( damage < Fluix + SINGLE_OFFSET ) return getUnlocalizedName() + ".Fluix"; return getUnlocalizedName(); @@ -62,13 +70,13 @@ public class ItemCrystalSeed extends AEBaseItem implements IGrowableCrystal { int newDamage = is.getItemDamage() + 1; - if ( newDamage == 600 ) + if ( newDamage == Certus + SINGLE_OFFSET ) return AEApi.instance().materials().materialPureifiedCertusQuartzCrystal.stack( is.stackSize ); - if ( newDamage == 1200 ) + if ( newDamage == Nether + SINGLE_OFFSET ) return AEApi.instance().materials().materialPureifiedNetherQuartzCrystal.stack( is.stackSize ); - if ( newDamage == 1800 ) + if ( newDamage == Fluix + SINGLE_OFFSET ) return AEApi.instance().materials().materialPureifiedFluixCrystal.stack( is.stackSize ); - if ( newDamage > 1800 ) + if ( newDamage > END ) return null; is.setItemDamage( newDamage ); @@ -106,27 +114,27 @@ public class ItemCrystalSeed extends AEBaseItem implements IGrowableCrystal { IIcon list[] = null; - if ( damage < 600 ) + if ( damage < Certus + SINGLE_OFFSET ) list = certus; - else if ( damage < 1200 ) + else if ( damage < Nether + SINGLE_OFFSET ) { - damage -= 600; + damage -= Nether; list = nether; } - else if ( damage < 1800 ) + else if ( damage < Fluix + SINGLE_OFFSET ) { - damage -= 1200; + damage -= Fluix; list = fluix; } if ( list == null ) return Items.diamond.getIconFromDamage( 0 ); - if ( damage < 200 ) + if ( damage < LEVEL_OFFSET ) return list[0]; - else if ( damage < 400 ) + else if ( damage < LEVEL_OFFSET * 2 ) return list[1]; else return list[2]; @@ -181,19 +189,19 @@ public class ItemCrystalSeed extends AEBaseItem implements IGrowableCrystal public void getSubItems(Item i, CreativeTabs t, List l) { // lvl 0 - l.add( new ItemStack( this, 1, 0 ) ); - l.add( new ItemStack( this, 1, 600 ) ); - l.add( new ItemStack( this, 1, 1200 ) ); + l.add( new ItemStack( this, 1, Certus ) ); + l.add( new ItemStack( this, 1, Nether ) ); + l.add( new ItemStack( this, 1, Fluix ) ); // lvl 1 - l.add( new ItemStack( this, 1, 200 + 0 ) ); - l.add( new ItemStack( this, 1, 200 + 600 ) ); - l.add( new ItemStack( this, 1, 200 + 1200 ) ); + l.add( new ItemStack( this, 1, LEVEL_OFFSET + Certus ) ); + l.add( new ItemStack( this, 1, LEVEL_OFFSET + Nether ) ); + l.add( new ItemStack( this, 1, LEVEL_OFFSET + Fluix ) ); // lvl 2 - l.add( new ItemStack( this, 1, 400 + 0 ) ); - l.add( new ItemStack( this, 1, 400 + 600 ) ); - l.add( new ItemStack( this, 1, 400 + 1200 ) ); + l.add( new ItemStack( this, 1, LEVEL_OFFSET * 2 + Certus ) ); + l.add( new ItemStack( this, 1, LEVEL_OFFSET * 2 + Nether ) ); + l.add( new ItemStack( this, 1, LEVEL_OFFSET * 2 + Fluix ) ); } } diff --git a/recipes/AEItemResolver.java b/recipes/AEItemResolver.java new file mode 100644 index 00000000..4b908669 --- /dev/null +++ b/recipes/AEItemResolver.java @@ -0,0 +1,50 @@ +package appeng.recipes; + +import appeng.api.recipes.ISubItemResolver; +import appeng.api.recipes.ResolveResult; +import appeng.core.AppEng; +import appeng.items.materials.MaterialType; +import appeng.items.misc.ItemCrystalSeed; +import appeng.items.parts.ItemPart; +import appeng.items.parts.PartType; + +public class AEItemResolver implements ISubItemResolver +{ + + @Override + public ResolveResult resolveItemByName(String nameSpace, String itemName) + { + + if ( nameSpace.equals( AppEng.modid ) ) + { + if ( itemName.startsWith( "ItemCrystalSeed." ) ) + { + if ( itemName.equalsIgnoreCase( "ItemCrystalSeed.Certus" ) ) + return new ResolveResult( "ItemCrystalSeed", ItemCrystalSeed.Certus ); + if ( itemName.equalsIgnoreCase( "ItemCrystalSeed.Nether" ) ) + return new ResolveResult( "ItemCrystalSeed", ItemCrystalSeed.Nether ); + if ( itemName.equalsIgnoreCase( "ItemCrystalSeed.Fluix" ) ) + return new ResolveResult( "ItemCrystalSeed", ItemCrystalSeed.Fluix ); + } + + if ( itemName.startsWith( "ItemMaterial." ) ) + { + String materialName = itemName.substring( itemName.indexOf( "." ) + 1 ); + MaterialType mt = MaterialType.valueOf( materialName ); + itemName = itemName.substring( 0, itemName.indexOf( "." ) ); + return new ResolveResult( itemName, mt.damageValue ); + } + + if ( itemName.startsWith( "ItemPart." ) ) + { + String partName = itemName.substring( itemName.indexOf( "." ) + 1 ); + PartType pt = PartType.valueOf( partName ); + itemName = itemName.substring( 0, itemName.indexOf( "." ) ); + return new ResolveResult( itemName, ItemPart.instance.getDamageByType( pt ) ); + } + } + + return null; + } + +} diff --git a/recipes/GroupIngredient.java b/recipes/GroupIngredient.java new file mode 100644 index 00000000..20f84d82 --- /dev/null +++ b/recipes/GroupIngredient.java @@ -0,0 +1,101 @@ +package appeng.recipes; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.OreDictionary; +import appeng.api.exceptions.MissingIngredientError; +import appeng.api.exceptions.RecipeError; +import appeng.api.exceptions.RegistrationError; +import appeng.api.recipes.IIngredient; + +public class GroupIngredient implements IIngredient +{ + + int qty = 0; + final String name; + final List ingredients; + + boolean isInside = false; + + public GroupIngredient(String myName, List ingredients) throws RecipeError { + name = myName; + + for (IIngredient I : ingredients) + if ( I.isAir() ) + throw new RecipeError( "Cannot include air in a group." ); + + this.ingredients = ingredients; + } + + public IIngredient copy(int qty) throws RecipeError + { + GroupIngredient gi = new GroupIngredient( name, ingredients ); + gi.qty = qty; + return gi; + } + + public int getDamageValue() + { + return OreDictionary.WILDCARD_VALUE; + } + + @Override + public String getItemName() + { + return name; + } + + @Override + public ItemStack getItemStack() throws RegistrationError, MissingIngredientError + { + throw new RegistrationError( "Cannot pass group of items to a recipe which desires a single recipe item." ); + } + + @Override + public ItemStack[] getItemStackSet() throws RegistrationError, MissingIngredientError + { + if ( isInside ) + return new ItemStack[0]; + + List out = new LinkedList(); + isInside = true; + try + { + for (IIngredient i : ingredients) + out.addAll( Arrays.asList( i.getItemStackSet() ) ); + } + finally + { + isInside = false; + } + + if ( out.size() == 0 ) + throw new MissingIngredientError( toString() + " - group could not be resolved to any items." ); + + for (ItemStack is : out) + is.stackSize = qty; + + return out.toArray( new ItemStack[out.size()] ); + } + + public String getNameSpace() + { + return ""; + } + + @Override + public int getQty() + { + return 0; + } + + @Override + public boolean isAir() + { + return false; + } + +} diff --git a/recipes/Ingredient.java b/recipes/Ingredient.java index 9969b363..6465bd9f 100644 --- a/recipes/Ingredient.java +++ b/recipes/Ingredient.java @@ -6,14 +6,12 @@ import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraftforge.oredict.OreDictionary; +import appeng.api.AEApi; import appeng.api.exceptions.MissingIngredientError; import appeng.api.exceptions.RecipeError; import appeng.api.exceptions.RegistrationError; import appeng.api.recipes.IIngredient; -import appeng.core.AppEng; -import appeng.items.materials.MaterialType; -import appeng.items.parts.ItemPart; -import appeng.items.parts.PartType; +import appeng.api.recipes.ResolveResult; import cpw.mods.fml.common.registry.GameRegistry; public class Ingredient implements IIngredient @@ -58,24 +56,15 @@ public class Ingredient implements IIngredient throw new RecipeError( "Cannot specify meta when using ore dictionary." ); sel = OreDictionary.WILDCARD_VALUE; } - else if ( nameSpace.equals( AppEng.modid ) ) + else { try { - if ( tmpName.startsWith( "ItemMaterial." ) ) + ResolveResult rr = AEApi.instance().registries().recipes().resolveItem( nameSpace, tmpName ); + if ( rr != null ) { - String materialName = tmpName.substring( tmpName.indexOf( "." ) + 1 ); - MaterialType mt = MaterialType.valueOf( materialName ); - tmpName = tmpName.substring( 0, tmpName.indexOf( "." ) ); - sel = mt.damageValue; - } - - if ( tmpName.startsWith( "ItemPart." ) ) - { - String partName = tmpName.substring( tmpName.indexOf( "." ) + 1 ); - PartType pt = PartType.valueOf( partName ); - tmpName = tmpName.substring( 0, tmpName.indexOf( "." ) ); - sel = ItemPart.instance.getDamageByType( pt ); + tmpName = rr.itemName; + sel = rr.damageValue; } } catch (IllegalArgumentException e) @@ -171,6 +160,9 @@ public class Ingredient implements IIngredient set[x] = is; } + if ( set.length == 0 ) + throw new MissingIngredientError( toString() + " - ore dictionary could not be resolved to any items." ); + return set; } @@ -178,27 +170,32 @@ public class Ingredient implements IIngredient } @Override - public String getNameSpace() { + public String getNameSpace() + { return nameSpace; } @Override - public String getItemName() { + public String getItemName() + { return itemName; } @Override - public int getDamageValue() { + public int getDamageValue() + { return meta; } @Override - public int getQty() { + public int getQty() + { return qty; } - + @Override - public boolean isAir() { + public boolean isAir() + { return isAir; } diff --git a/recipes/RecipeData.java b/recipes/RecipeData.java index 29dbf934..8792a001 100644 --- a/recipes/RecipeData.java +++ b/recipes/RecipeData.java @@ -10,9 +10,12 @@ public class RecipeData { final public HashMap aliases = new HashMap(); + final public HashMap groups = new HashMap(); + final public List Handlers = new LinkedList(); public boolean crash = true; + public boolean exceptions = true; public boolean erroronmissing = true; } diff --git a/recipes/RecipeHandler.java b/recipes/RecipeHandler.java index 19604f29..fd999d99 100644 --- a/recipes/RecipeHandler.java +++ b/recipes/RecipeHandler.java @@ -58,8 +58,9 @@ public class RecipeHandler implements IRecipeHandler } catch (RegistrationError e) { - AELog.warning( "Unable to regsiter a recipe." ); - AELog.error( e ); + AELog.warning( "Unable to regsiter a recipe: " + e.getMessage() ); + if ( data.exceptions ) + AELog.error( e ); if ( data.crash ) throw e; } @@ -67,8 +68,9 @@ public class RecipeHandler implements IRecipeHandler { if ( data.erroronmissing ) { - AELog.warning( "Unable to regsiter a recipe." ); - AELog.error( e ); + AELog.warning( "Unable to regsiter a recipe:" + e.getMessage() ); + if ( data.exceptions ) + AELog.error( e ); if ( data.crash ) throw e; } @@ -77,7 +79,8 @@ public class RecipeHandler implements IRecipeHandler } catch (Throwable e) { - AELog.error( e ); + if ( data.exceptions ) + AELog.error( e ); if ( data.crash ) throw new RuntimeException( e ); } @@ -231,9 +234,9 @@ public class RecipeHandler implements IRecipeHandler List> inputs = parseLines( pre ); - if ( inputs.size() >= 1 && post.size() == 1 ) + if ( inputs.size() == 1 && inputs.get( 0 ).size() > 0 && post.size() == 1 ) { - + data.groups.put( post.get( 0 ), new GroupIngredient( post.get( 0 ), inputs.get( 0 ) ) ); } else throw new RecipeError( "Group must have exactly 1 output, and 1 or more inputs." ); @@ -276,7 +279,16 @@ public class RecipeHandler implements IRecipeHandler { String operation = tokens.remove( 0 ).toLowerCase(); - if ( operation.equals( "crash" ) && (tokens.get( 0 ).equals( "true" ) || tokens.get( 0 ).equals( "false" )) ) + if ( operation.equals( "exceptions" ) && (tokens.get( 0 ).equals( "true" ) || tokens.get( 0 ).equals( "false" )) ) + { + if ( tokens.size() == 1 ) + { + data.exceptions = tokens.get( 0 ).equals( "true" ); + } + else + throw new RecipeError( "exceptions must be true or false explicitly." ); + } + else if ( operation.equals( "crash" ) && (tokens.get( 0 ).equals( "true" ) || tokens.get( 0 ).equals( "false" )) ) { if ( tokens.size() == 1 ) { @@ -309,7 +321,8 @@ public class RecipeHandler implements IRecipeHandler catch (RecipeError e) { AELog.warning( "Recipe Error near line:" + line + " in " + file + " with: " + tokens.toString() ); - AELog.error( e ); + if ( data.exceptions ) + AELog.error( e ); if ( data.crash ) throw e; } @@ -348,11 +361,11 @@ public class RecipeHandler implements IRecipeHandler { if ( hasQty ) { - cList.add( new Ingredient( this, v, qty ) ); + cList.add( findIngrident( v, qty ) ); hasQty = false; } else - cList.add( new Ingredient( this, v, 1 ) ); + cList.add( findIngrident( v, 1 ) ); } } } @@ -363,6 +376,14 @@ public class RecipeHandler implements IRecipeHandler return out; } + private IIngredient findIngrident(String v, int qty) throws RecipeError + { + GroupIngredient gi = data.groups.get( v ); + if ( gi != null ) + return gi.copy( qty ); + return new Ingredient( this, v, qty ); + } + private boolean isNumber(String v) { if ( v.length() <= 0 )