From 90c17c09a82bf4b4a1a6d05edc27b5de7b67c557 Mon Sep 17 00:00:00 2001 From: fscan Date: Fri, 17 Nov 2017 16:20:53 +0100 Subject: [PATCH] Add custom recipe for damageable Ingredients (#3230) --- .../recipes/DamagedRecipeFactory.java | 105 ++++++++++++++++++ .../factories/recipes/PartRecipeFactory.java | 91 ++++++++------- .../recipes/_factories.json | 3 +- .../recipes/network/parts/cable_anchor.json | 3 +- 4 files changed, 153 insertions(+), 49 deletions(-) create mode 100644 src/main/java/appeng/recipes/factories/recipes/DamagedRecipeFactory.java diff --git a/src/main/java/appeng/recipes/factories/recipes/DamagedRecipeFactory.java b/src/main/java/appeng/recipes/factories/recipes/DamagedRecipeFactory.java new file mode 100644 index 000000000..6816e5560 --- /dev/null +++ b/src/main/java/appeng/recipes/factories/recipes/DamagedRecipeFactory.java @@ -0,0 +1,105 @@ +/* + * This file is part of Applied Energistics 2. + * Copyright (c) 2013 - 2017, AlgorithmX2, All rights reserved. + * + * Applied Energistics 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Applied Energistics 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Applied Energistics 2. If not, see . + */ + +package appeng.recipes.factories.recipes; + + +import java.util.Iterator; + +import javax.annotation.Nonnull; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; + +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.util.JsonUtils; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import net.minecraftforge.common.crafting.CraftingHelper; +import net.minecraftforge.common.crafting.IRecipeFactory; +import net.minecraftforge.common.crafting.JsonContext; +import net.minecraftforge.oredict.ShapelessOreRecipe; + + +public class DamagedRecipeFactory implements IRecipeFactory +{ + @Override + public IRecipe parse( JsonContext context, JsonObject json ) + { + String group = JsonUtils.getString( json, "group", "" ); + + NonNullList ings = NonNullList.create(); + for( JsonElement ele : JsonUtils.getJsonArray( json, "ingredients" ) ) + { + ings.add( CraftingHelper.getIngredient( ele, context ) ); + } + + if( ings.isEmpty() ) + { + throw new JsonParseException( "No ingredients for shapeless recipe" ); + } + + return new DamagedRecipe( group.isEmpty() ? null : new ResourceLocation( group ), ings, PartRecipeFactory.getResult( json, context ) ); + } + + private static class DamagedRecipe extends ShapelessOreRecipe + { + public DamagedRecipe( ResourceLocation group, NonNullList input, ItemStack result ) + { + super( group, input, result ); + } + + @Override + public boolean matches( @Nonnull InventoryCrafting inv, @Nonnull World world ) + { + NonNullList required = NonNullList.create(); + required.addAll( input ); + + for( int i = 0; i < inv.getSizeInventory(); ++i ) + { + final ItemStack current = inv.getStackInSlot( i ); + if( !current.isEmpty() ) + { + boolean inRecipe = false; + final Iterator req = required.iterator(); + + while( req.hasNext() ) + { + if( req.next().apply( current ) ) + { + inRecipe = true; + req.remove(); + break; + } + } + if( !inRecipe ) + { + return false; + } + } + } + + return required.isEmpty(); + } + } +} diff --git a/src/main/java/appeng/recipes/factories/recipes/PartRecipeFactory.java b/src/main/java/appeng/recipes/factories/recipes/PartRecipeFactory.java index aaa62377c..496ba4355 100644 --- a/src/main/java/appeng/recipes/factories/recipes/PartRecipeFactory.java +++ b/src/main/java/appeng/recipes/factories/recipes/PartRecipeFactory.java @@ -43,9 +43,9 @@ import net.minecraftforge.common.crafting.JsonContext; import net.minecraftforge.oredict.ShapedOreRecipe; import net.minecraftforge.oredict.ShapelessOreRecipe; +import appeng.api.AEApi; import appeng.api.recipes.ResolverResult; import appeng.core.AELog; -import appeng.core.Api; import appeng.core.AppEng; @@ -72,6 +72,48 @@ public class PartRecipeFactory implements IRecipeFactory } } + public static ItemStack getResult( JsonObject json, JsonContext context ) + { + JsonObject resultObject = JsonUtils.getJsonObject( json, "result" ); + + if( resultObject.has( "part" ) ) + { + return getPart( resultObject ); + } + else if( resultObject.has( "item" ) ) + { + return CraftingHelper.getItemStack( resultObject, context ); + } + else + { + throw new JsonSyntaxException( "Result has no 'part' or 'item' property." ); + } + } + + private static ItemStack getPart( JsonObject resultObject ) + { + String ingredient = JsonUtils.getString( resultObject, "part" ); + Object result = AEApi.instance().registries().recipes().resolveItem( AppEng.MOD_ID, ingredient ); + if( result instanceof ResolverResult ) + { + ResolverResult resolverResult = (ResolverResult) result; + + Item item = Item.getByNameOrId( AppEng.MOD_ID + ":" + resolverResult.itemName ); + + if( item == null ) + { + AELog.warn( "item was null for " + resolverResult.itemName + " ( " + ingredient + " )!" ); + throw new JsonSyntaxException( "Got a null item for " + resolverResult.itemName + " ( " + ingredient + " ). This should never happen!" ); + } + + return new ItemStack( item, JsonUtils.getInt( resultObject, "count", 1 ), resolverResult.damageValue, resolverResult.compound ); + } + else + { + throw new JsonSyntaxException( "Couldn't find the resulting item in AE. This means AE was provided a recipe that it shouldn't be handling.\n" + "Was looking for : '" + ingredient + "'." ); + } + } + // Copied from ShapedOreRecipe.java, modified a bit. private static ShapedOreRecipe shapedFactory( JsonContext context, JsonObject json ) { @@ -141,28 +183,7 @@ public class PartRecipeFactory implements IRecipeFactory throw new JsonSyntaxException( "Key defines symbols that aren't used in pattern: " + keys ); } - JsonObject resultObject = (JsonObject) json.get( "result" ); - int count = JsonUtils.getInt( resultObject, "count", 1 ); - - String ingredient = resultObject.get( "part" ).getAsString(); - Object result = (Object) Api.INSTANCE.registries().recipes().resolveItem( AppEng.MOD_ID, ingredient ); - if( result instanceof ResolverResult ) - { - ResolverResult resolverResult = (ResolverResult) result; - - Item item = Item.getByNameOrId( AppEng.MOD_ID + ":" + resolverResult.itemName ); - if( item == null ) - { - AELog.warn( "item was null for " + resolverResult.itemName + " ( " + ingredient + " )!" ); - throw new JsonSyntaxException( "Got a null item for " + resolverResult.itemName + " ( " + ingredient + " ). This should never happen!" ); - } - ItemStack itemStack = new ItemStack( item, count, resolverResult.damageValue, resolverResult.compound ); - - return new ShapedOreRecipe( group.isEmpty() ? null : new ResourceLocation( group ), itemStack, primer ); - } - - // Should never reach this part unless mangled JSON or bug in AE. - throw new JsonSyntaxException( "Couldn't find the resulting item in AE. This means AE was provided a recipe that it shouldn't be handling.\nWas looking for : '" + ingredient + "'." ); + return new ShapedOreRecipe( group.isEmpty() ? null : new ResourceLocation( group ), getResult( json, context ), primer ); } // Copied from ShapelessOreRecipe.java, modified a bit. @@ -181,28 +202,6 @@ public class PartRecipeFactory implements IRecipeFactory throw new JsonParseException( "No ingredients for shapeless recipe" ); } - JsonObject resultObject = (JsonObject) json.get( "result" ); - int count = JsonUtils.getInt( resultObject, "count", 1 ); - - String ingredient = resultObject.get( "part" ).getAsString(); - Object result = (Object) Api.INSTANCE.registries().recipes().resolveItem( AppEng.MOD_ID, ingredient ); - if( result instanceof ResolverResult ) - { - ResolverResult resolverResult = (ResolverResult) result; - - Item item = Item.getByNameOrId( AppEng.MOD_ID + ":" + resolverResult.itemName ); - - if( item == null ) - { - AELog.warn( "item was null for " + resolverResult.itemName + " ( " + ingredient + " )!" ); - throw new JsonSyntaxException( "Got a null item for " + resolverResult.itemName + " ( " + ingredient + " ). This should never happen!" ); - } - - ItemStack itemStack = new ItemStack( item, count, resolverResult.damageValue, resolverResult.compound ); - - return new ShapelessOreRecipe( group.isEmpty() ? null : new ResourceLocation( group ), ings, itemStack ); - } - - throw new JsonSyntaxException( "Couldn't find the resulting item in AE. This means AE was provided a recipe that it shouldn't be handling.\n" + "Was looking for : '" + ingredient + "'." ); + return new ShapelessOreRecipe( group.isEmpty() ? null : new ResourceLocation( group ), ings, getResult( json, context ) ); } } diff --git a/src/main/resources/assets/appliedenergistics2/recipes/_factories.json b/src/main/resources/assets/appliedenergistics2/recipes/_factories.json index 5f8190ca8..b611ee14f 100644 --- a/src/main/resources/assets/appliedenergistics2/recipes/_factories.json +++ b/src/main/resources/assets/appliedenergistics2/recipes/_factories.json @@ -8,6 +8,7 @@ }, "recipes": { "part_shaped": "appeng.recipes.factories.recipes.PartRecipeFactory", - "part_shapeless": "appeng.recipes.factories.recipes.PartRecipeFactory" + "part_shapeless": "appeng.recipes.factories.recipes.PartRecipeFactory", + "damaged": "appeng.recipes.factories.recipes.DamagedRecipeFactory" } } diff --git a/src/main/resources/assets/appliedenergistics2/recipes/network/parts/cable_anchor.json b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/cable_anchor.json index 29fb484a3..4f6560026 100644 --- a/src/main/resources/assets/appliedenergistics2/recipes/network/parts/cable_anchor.json +++ b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/cable_anchor.json @@ -1,10 +1,9 @@ { + "type": "appliedenergistics2:damaged", "result": { - "type": "appliedenergistics2:part", "part": "part.cable_anchor", "count": 3 }, - "type": "appliedenergistics2:part_shapeless", "ingredients": [ { "item": "#appliedenergistics2:metalIngots"