From db825a7aabfbe3bfee8cffee112c5375dd82270b Mon Sep 17 00:00:00 2001 From: SquidDev Date: Tue, 13 Mar 2018 14:14:36 +0000 Subject: [PATCH] Add recipes to convert computer items into their upgraded counterparts This adds IComputerItem.withFamily(ItemStack, ComputerFamily) as well as a ComputerFamilyRecipe class. Each type of computer (normal, turtle, pocket) defines a recipe using this class, as they require a different number of gold ingots to upgrade. --- .../shared/computer/items/IComputerItem.java | 1 + .../shared/computer/items/ItemComputer.java | 12 +++- .../recipe/ComputerConvertRecipe.java | 66 +++++++++++++++++++ .../computer/recipe/ComputerFamilyRecipe.java | 47 +++++++++++++ .../computer/recipe/ComputerIngredient.java | 66 +++++++++++++++++++ .../pocket/items/ItemPocketComputer.java | 9 +++ .../shared/turtle/items/ItemTurtleBase.java | 11 ++++ .../shared/turtle/recipes/TurtleRecipe.java | 14 +--- .../computercraft/shared/util/RecipeUtil.java | 14 ++++ .../computercraft/recipes/_factories.json | 6 +- .../recipes/advanced_computer_upgrade.json | 14 ++++ .../advanced_pocket_computer_upgrade.json | 14 ++++ .../recipes/advanced_turtle_upgrade.json | 18 +++++ 13 files changed, 275 insertions(+), 17 deletions(-) create mode 100644 src/main/java/dan200/computercraft/shared/computer/recipe/ComputerConvertRecipe.java create mode 100644 src/main/java/dan200/computercraft/shared/computer/recipe/ComputerFamilyRecipe.java create mode 100644 src/main/java/dan200/computercraft/shared/computer/recipe/ComputerIngredient.java create mode 100644 src/main/resources/assets/computercraft/recipes/advanced_computer_upgrade.json create mode 100644 src/main/resources/assets/computercraft/recipes/advanced_pocket_computer_upgrade.json create mode 100644 src/main/resources/assets/computercraft/recipes/advanced_turtle_upgrade.json diff --git a/src/main/java/dan200/computercraft/shared/computer/items/IComputerItem.java b/src/main/java/dan200/computercraft/shared/computer/items/IComputerItem.java index febdfe5ee..50aba8ecc 100644 --- a/src/main/java/dan200/computercraft/shared/computer/items/IComputerItem.java +++ b/src/main/java/dan200/computercraft/shared/computer/items/IComputerItem.java @@ -16,4 +16,5 @@ public interface IComputerItem int getComputerID( @Nonnull ItemStack stack ); String getLabel( @Nonnull ItemStack stack ); ComputerFamily getFamily( @Nonnull ItemStack stack ); + ItemStack withFamily(@Nonnull ItemStack stack, @Nonnull ComputerFamily family); } diff --git a/src/main/java/dan200/computercraft/shared/computer/items/ItemComputer.java b/src/main/java/dan200/computercraft/shared/computer/items/ItemComputer.java index a8c6cbe09..4d43c39e1 100644 --- a/src/main/java/dan200/computercraft/shared/computer/items/ItemComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/items/ItemComputer.java @@ -27,7 +27,7 @@ import javax.annotation.Nullable; public class ItemComputer extends ItemComputerBase { public static int HIGHEST_DAMAGE_VALUE_ID = 16382; - + public ItemComputer( Block block ) { super( block ); @@ -87,7 +87,7 @@ public class ItemComputer extends ItemComputerBase TileEntity tile = world.getTileEntity( pos ); if( tile != null && tile instanceof IComputerTile ) { - IComputerTile computer = (IComputerTile)tile; + IComputerTile computer = (IComputerTile) tile; setupComputerAfterPlacement( stack, computer ); } return true; @@ -146,10 +146,16 @@ public class ItemComputer extends ItemComputerBase else { int damage = stack.getItemDamage() & 0x3fff; - return ( damage - 1 ); + return (damage - 1); } } + @Override + public ItemStack withFamily( @Nonnull ItemStack stack, @Nonnull ComputerFamily family ) + { + return ComputerItemFactory.create( getComputerID( stack ), getLabel( stack ), family ); + } + @Override public ComputerFamily getFamily( int damage ) { diff --git a/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerConvertRecipe.java b/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerConvertRecipe.java new file mode 100644 index 000000000..5d3837960 --- /dev/null +++ b/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerConvertRecipe.java @@ -0,0 +1,66 @@ +package dan200.computercraft.shared.computer.recipe; + +import dan200.computercraft.shared.computer.items.IComputerItem; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.item.crafting.ShapedRecipes; +import net.minecraft.world.World; +import net.minecraftforge.common.crafting.CraftingHelper; + +import javax.annotation.Nonnull; + +/** + * Represents a recipe which converts a computer from one form into another. + */ +public abstract class ComputerConvertRecipe extends ShapedRecipes +{ + public ComputerConvertRecipe( String group, @Nonnull CraftingHelper.ShapedPrimer primer, @Nonnull ItemStack result ) + { + super( group, primer.width, primer.height, primer.input, result ); + } + + @Nonnull + protected abstract ItemStack convert( @Nonnull ItemStack stack ); + + @Override + public boolean matches( @Nonnull InventoryCrafting inventory, @Nonnull World world ) + { + // See if we match the recipe, and extract the input computercraft ID + ItemStack computerStack = null; + for( int y = 0; y < 3; ++y ) + { + for( int x = 0; x < 3; ++x ) + { + ItemStack stack = inventory.getStackInRowAndColumn( x, y ); + Ingredient target = getIngredients().get( x + y * 3 ); + + // First verify we match the ingredient + if( !target.apply( stack ) ) return false; + + // We want to ensure we have a computer item somewhere in the recipe + if( stack.getItem() instanceof IComputerItem ) computerStack = stack; + } + } + + return computerStack != null; + } + + @Nonnull + @Override + public ItemStack getCraftingResult( @Nonnull InventoryCrafting inventory ) + { + for( int y = 0; y < 3; ++y ) + { + for( int x = 0; x < 3; ++x ) + { + ItemStack item = inventory.getStackInRowAndColumn( x, y ); + + // If we're a computer, convert! + if( item.getItem() instanceof IComputerItem ) return convert( item ); + } + } + + return ItemStack.EMPTY; + } +} diff --git a/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerFamilyRecipe.java b/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerFamilyRecipe.java new file mode 100644 index 000000000..323209229 --- /dev/null +++ b/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerFamilyRecipe.java @@ -0,0 +1,47 @@ +package dan200.computercraft.shared.computer.recipe; + +import com.google.gson.JsonObject; +import dan200.computercraft.shared.computer.core.ComputerFamily; +import dan200.computercraft.shared.computer.items.IComputerItem; +import dan200.computercraft.shared.util.RecipeUtil; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.util.JsonUtils; +import net.minecraftforge.common.crafting.CraftingHelper; +import net.minecraftforge.common.crafting.IRecipeFactory; +import net.minecraftforge.common.crafting.JsonContext; + +import javax.annotation.Nonnull; + +public class ComputerFamilyRecipe extends ComputerConvertRecipe +{ + private final ComputerFamily family; + + public ComputerFamilyRecipe( String group, @Nonnull CraftingHelper.ShapedPrimer primer, @Nonnull ItemStack result, ComputerFamily family ) + { + super( group, primer, result ); + this.family = family; + } + + @Nonnull + @Override + protected ItemStack convert( @Nonnull ItemStack stack ) + { + return ((IComputerItem) stack.getItem()).withFamily( stack, family ); + } + + public static class Factory implements IRecipeFactory + { + @Override + public IRecipe parse( JsonContext context, JsonObject json ) + { + String group = JsonUtils.getString( json, "group", "" ); + ComputerFamily family = RecipeUtil.getFamily( json, "family" ); + + CraftingHelper.ShapedPrimer primer = RecipeUtil.getPrimer( context, json ); + ItemStack result = deserializeItem( JsonUtils.getJsonObject( json, "result" ), false ); + + return new ComputerFamilyRecipe( group, primer, result, family ); + } + } +} diff --git a/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerIngredient.java b/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerIngredient.java new file mode 100644 index 000000000..e044fc552 --- /dev/null +++ b/src/main/java/dan200/computercraft/shared/computer/recipe/ComputerIngredient.java @@ -0,0 +1,66 @@ +package dan200.computercraft.shared.computer.recipe; + +import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; +import dan200.computercraft.shared.computer.core.ComputerFamily; +import dan200.computercraft.shared.computer.items.IComputerItem; +import dan200.computercraft.shared.util.RecipeUtil; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.util.JsonUtils; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.crafting.IIngredientFactory; +import net.minecraftforge.common.crafting.JsonContext; +import net.minecraftforge.fml.common.registry.ForgeRegistries; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Represents an ingredient which requires an item to have a specific + * computer family. This allows us to have operations which only work + * on normal or + */ +public class ComputerIngredient extends Ingredient +{ + private final IComputerItem item; + private final ComputerFamily family; + + public ComputerIngredient( T item, int data, ComputerFamily family ) + { + super( new ItemStack( item, 1, data ) ); + + this.item = item; + this.family = family; + } + + @Override + public boolean apply( @Nullable ItemStack stack ) + { + return stack != null && stack.getItem() == item && item.getFamily( stack ) == family; + } + + public static class Factory implements IIngredientFactory + { + @Nonnull + @Override + public Ingredient parse( JsonContext context, JsonObject json ) + { + String itemName = context.appendModId( JsonUtils.getString( json, "item" ) ); + int data = JsonUtils.getInt( json, "data", 0 ); + ComputerFamily family = RecipeUtil.getFamily( json, "family" ); + + Item item = ForgeRegistries.ITEMS.getValue( new ResourceLocation( itemName ) ); + + if( item == null ) throw new JsonSyntaxException( "Unknown item '" + itemName + "'" ); + if( !(item instanceof IComputerItem) ) + { + throw new JsonSyntaxException( "Item '" + itemName + "' is not a computer item" ); + } + + + return new ComputerIngredient( (Item & IComputerItem) item, data, family ); + } + } +} diff --git a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java index c998e1dae..7df7f2e15 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java +++ b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java @@ -371,6 +371,15 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I } } + @Override + public ItemStack withFamily( @Nonnull ItemStack stack, @Nonnull ComputerFamily family ) + { + return PocketComputerItemFactory.create( + getComputerID( stack ), getLabel( stack ), getColour( stack ), + family, getUpgrade( stack ) + ); + } + // IMedia @Override diff --git a/src/main/java/dan200/computercraft/shared/turtle/items/ItemTurtleBase.java b/src/main/java/dan200/computercraft/shared/turtle/items/ItemTurtleBase.java index 94ef5f11f..6245721f7 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/items/ItemTurtleBase.java +++ b/src/main/java/dan200/computercraft/shared/turtle/items/ItemTurtleBase.java @@ -170,6 +170,17 @@ public abstract class ItemTurtleBase extends ItemComputerBase implements ITurtle } } + @Override + public ItemStack withFamily( @Nonnull ItemStack stack, @Nonnull ComputerFamily family ) + { + return TurtleItemFactory.create( + getComputerID( stack ), getLabel( stack ), + getColour( stack ), family, + getUpgrade( stack, TurtleSide.Left ), getUpgrade( stack, TurtleSide.Right ), + getFuelLevel( stack ), getOverlay( stack ) + ); + } + @Override public ItemStack setColour( ItemStack stack, int colour ) { diff --git a/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleRecipe.java b/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleRecipe.java index 1cf703185..8e8d5d535 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleRecipe.java +++ b/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleRecipe.java @@ -7,7 +7,6 @@ package dan200.computercraft.shared.turtle.recipes; import com.google.gson.JsonObject; -import com.google.gson.JsonSyntaxException; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.items.IComputerItem; import dan200.computercraft.shared.turtle.items.TurtleItemFactory; @@ -91,18 +90,7 @@ public class TurtleRecipe extends ShapedRecipes public IRecipe parse( JsonContext context, JsonObject json ) { String group = JsonUtils.getString( json, "group", "" ); - - String familyName = JsonUtils.getString( json, "family" ); - ComputerFamily family; - try - { - family = ComputerFamily.valueOf( familyName ); - } - catch( IllegalArgumentException e ) - { - throw new JsonSyntaxException( "Unknown computer family '" + familyName + "'" ); - } - + ComputerFamily family = RecipeUtil.getFamily( json, "family" ); CraftingHelper.ShapedPrimer primer = RecipeUtil.getPrimer( context, json ); return new TurtleRecipe( group, primer.width, primer.height, primer.input, family ); } diff --git a/src/main/java/dan200/computercraft/shared/util/RecipeUtil.java b/src/main/java/dan200/computercraft/shared/util/RecipeUtil.java index e222a06cc..64ca2dfc0 100644 --- a/src/main/java/dan200/computercraft/shared/util/RecipeUtil.java +++ b/src/main/java/dan200/computercraft/shared/util/RecipeUtil.java @@ -9,6 +9,7 @@ package dan200.computercraft.shared.util; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.gson.*; +import dan200.computercraft.shared.computer.core.ComputerFamily; import net.minecraft.item.crafting.Ingredient; import net.minecraft.util.JsonUtils; import net.minecraft.util.NonNullList; @@ -102,4 +103,17 @@ public class RecipeUtil return ings; } + + public static ComputerFamily getFamily( JsonObject json, String name ) + { + String familyName = JsonUtils.getString( json, name ); + try + { + return ComputerFamily.valueOf( familyName ); + } + catch( IllegalArgumentException e ) + { + throw new JsonSyntaxException( "Unknown computer family '" + familyName + "' for field " + name ); + } + } } diff --git a/src/main/resources/assets/computercraft/recipes/_factories.json b/src/main/resources/assets/computercraft/recipes/_factories.json index 8f525a27a..c9a49396f 100644 --- a/src/main/resources/assets/computercraft/recipes/_factories.json +++ b/src/main/resources/assets/computercraft/recipes/_factories.json @@ -2,6 +2,10 @@ "recipes" : { "impostor_shaped" : "dan200.computercraft.shared.util.ImpostorRecipe$Factory", "impostor_shapeless" : "dan200.computercraft.shared.util.ImpostorShapelessRecipe$Factory", - "turtle" : "dan200.computercraft.shared.turtle.recipes.TurtleRecipe$Factory" + "turtle" : "dan200.computercraft.shared.turtle.recipes.TurtleRecipe$Factory", + "computer_upgrade" : "dan200.computercraft.shared.computer.recipe.ComputerFamilyRecipe$Factory" + }, + "ingredients": { + "computer": "dan200.computercraft.shared.computer.recipe.ComputerIngredient$Factory" } } diff --git a/src/main/resources/assets/computercraft/recipes/advanced_computer_upgrade.json b/src/main/resources/assets/computercraft/recipes/advanced_computer_upgrade.json new file mode 100644 index 000000000..2ee91e82d --- /dev/null +++ b/src/main/resources/assets/computercraft/recipes/advanced_computer_upgrade.json @@ -0,0 +1,14 @@ +{ + "type": "computercraft:computer_upgrade", + "pattern": [ + "###", + "#C#", + "# #" + ], + "key": { + "#": { "item": "minecraft:gold_ingot" }, + "C": { "type": "computercraft:computer", "item": "computercraft:computer", "family": "Normal" } + }, + "family": "Advanced", + "result": { "item": "computercraft:computer", "data": 16384 } +} diff --git a/src/main/resources/assets/computercraft/recipes/advanced_pocket_computer_upgrade.json b/src/main/resources/assets/computercraft/recipes/advanced_pocket_computer_upgrade.json new file mode 100644 index 000000000..4476c45e4 --- /dev/null +++ b/src/main/resources/assets/computercraft/recipes/advanced_pocket_computer_upgrade.json @@ -0,0 +1,14 @@ +{ + "type": "computercraft:computer_upgrade", + "pattern": [ + "###", + "#C#", + "# #" + ], + "key": { + "#": { "item": "minecraft:gold_ingot" }, + "C": { "item": "computercraft:pocket_computer", "data": 0 } + }, + "family": "Advanced", + "result": { "item": "computercraft:pocket_computer", "data": 1 } +} diff --git a/src/main/resources/assets/computercraft/recipes/advanced_turtle_upgrade.json b/src/main/resources/assets/computercraft/recipes/advanced_turtle_upgrade.json new file mode 100644 index 000000000..6ef583aa3 --- /dev/null +++ b/src/main/resources/assets/computercraft/recipes/advanced_turtle_upgrade.json @@ -0,0 +1,18 @@ +{ + "type": "computercraft:computer_upgrade", + "pattern": [ + "###", + "#C#", + " B " + ], + "key": { + "#": { "item": "minecraft:gold_ingot" }, + "B": { "item": "minecraft:gold_block" }, + "C": [ + { "type": "computercraft:computer", "item": "computercraft:turtle", "family": "Normal" }, + { "item": "computercraft:turtle_expanded", "data": 0 } + ] + }, + "family": "Advanced", + "result": { "item": "computercraft:turtle_advanced", "data": 0 } +}