Skip to content

Instantly share code, notes, and snippets.

@Unh0lyTigg
Last active August 29, 2015 14:02
Show Gist options
  • Save Unh0lyTigg/c1a98c86bb6a51077a50 to your computer and use it in GitHub Desktop.
Save Unh0lyTigg/c1a98c86bb6a51077a50 to your computer and use it in GitHub Desktop.
CraftingRecipeBuilder
package net.minecraftforge.common;
import java.util.List;
import java.util.Map;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.ShapedRecipes;
import net.minecraft.item.crafting.ShapelessRecipes;
import org.apache.commons.lang3.ArrayUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.registry.GameRegistry;
public abstract class CraftingRecipeBuilder {
public static ShapedCraftingRecipeBuilder shaped() {
return new ShapedCraftingRecipeBuilder();
}
public static ShapelessCraftingRecipeBuilder shapeless() {
return new ShapelessCraftingRecipeBuilder();
}
protected ItemStack output = null;
protected IRecipe cached = null;
public abstract IRecipe build();
public final void add() {
IRecipe r = build();
if (r != null)
GameRegistry.addRecipe(r);
}
public static final class ShapedCraftingRecipeBuilder extends CraftingRecipeBuilder {
private int width;
private int height;
private String[] grid;
private Map<Character, ItemStack> replacements = Maps.newHashMap();
private ShapedCraftingRecipeBuilder() { }
public ShapedCraftingRecipeBuilder output(ItemStack item) {
this.output = item;
// invalidate cached recipe if it exists
if (cached != null)
cached = null;
return this;
}
public ShapedCraftingRecipeBuilder output(Item item) {
return output(new ItemStack(item));
}
public ShapedCraftingRecipeBuilder output(Block item) {
return output(new ItemStack(item));
}
public ShapedCraftingRecipeBuilder where(char ingredient, ItemStack input) {
if (replacements.containsKey(Character.valueOf(ingredient))) {
FMLLog.warning("ShapedCraftingRecipeBuilder: It is bad practice to have more than one where(char,[ItemStack|Item|Block]) calls where the ingredient (char) is not unique. Replacing now.");
replacements.remove(Character.valueOf(ingredient));
}
replacements.put(Character.valueOf(ingredient), input);
// invalidate cached recipe if it exists
if (cached != null)
cached = null;
return this;
}
public ShapedCraftingRecipeBuilder where(char ingredient, Item input) {
return where(ingredient, new ItemStack(input));
}
public ShapedCraftingRecipeBuilder where(char ingredient, Block input) {
return where(ingredient, new ItemStack(input));
}
public ShapedCraftingRecipeBuilder input(String... recipe) {
if (recipe.length > 3) {
FMLLog.warning("ShapedCraftingRecipeBuilder: Recipe input array has more than 3 elements, truncating to maximum.");
recipe = ArrayUtils.subarray(recipe, 0, 3);
}
grid = ArrayUtils.subarray(recipe, 0, recipe.length);
this.height = grid.length;
for (int i = 0; i < grid.length; i++) {
this.width = Math.max(this.width, grid[i].length() > 3 ? 3 : grid[i].length());
}
// invalidate cached recipe if it exists
if (cached != null)
cached = null;
return this;
}
public IRecipe build() {
if (cached != null)
return cached;
return (cached = new ShapedRecipes(width, height, generateRecipe(), output));
}
private ItemStack[] generateRecipe() {
ItemStack[] recipe = new ItemStack[width * height];
String pattern = "";
for (int i = 0; i < height; i++) {
pattern += grid[i].substring(0, Math.min(grid[i].length(), 3));
}
for (int i = 0; i < width * height; i++) {
char c = pattern.charAt(i);
if (replacements.containsKey(Character.valueOf(c))) {
recipe[i] = replacements.get(Character.valueOf(c)).copy();
} else {
recipe[i] = null;
}
}
return recipe;
}
}
public static final class ShapelessCraftingRecipeBuilder extends CraftingRecipeBuilder {
private List<ItemStack> inputs;
private ShapelessCraftingRecipeBuilder() {
inputs = Lists.newArrayList();
}
public ShapelessCraftingRecipeBuilder output(ItemStack item) {
this.output = item;
// invalidate cached recipe if it exists
if (cached != null)
cached = null;
return this;
}
public ShapelessCraftingRecipeBuilder output(Item item) {
return output(new ItemStack(item));
}
public ShapelessCraftingRecipeBuilder output(Block block) {
return output(new ItemStack(block));
}
public ShapelessCraftingRecipeBuilder addInput(ItemStack item) {
this.inputs.add(item);
// invalidate cached recipe if it exists
if (cached != null)
cached = null;
return this;
}
public ShapelessCraftingRecipeBuilder addInput(ItemStack item, int times) {
for (int i = 0; i < times; i++) {
this.inputs.add(item);
}
// invalidate cached recipe if it exists
if (cached != null)
cached = null;
return this;
}
public ShapelessCraftingRecipeBuilder addInput(Item item) {
return addInput(new ItemStack(item));
}
public ShapelessCraftingRecipeBuilder addInput(Item item, int times) {
return addInput(new ItemStack(item), times);
}
public ShapelessCraftingRecipeBuilder addInput(Block block) {
return addInput(new ItemStack(block));
}
public ShapelessCraftingRecipeBuilder addInput(Block block, int times) {
return addInput(new ItemStack(block), times);
}
@Override
public IRecipe build() {
if (cached != null)
return cached;
return (cached = new ShapelessRecipes(output, inputs));
}
}
}
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.crafting.IRecipe;
import net.minecraftforge.common.CraftingRecipeBuilder;
public class CraftingRecipeBuilderUsage {
public static void addRecipes() {
// Replicates the recipe for an anvil, but it's much more verbose...
IRecipe recipe = CraftingRecipeBuilder.shaped()
.input("III",
" i ",
"iii")
.output(Blocks.anvil)
.where('I', Blocks.iron_block)
.where('i', Items.iron_ingot)
.build();
GameRegistry.addRecipe(recipe);
// Replicates the recipe for a book, is more verbose, and shows you don't have to store the IRecipe (or even feed it directly to GameRegistry) to add it...
CraftingRecipeBuilder.shapeless()
.output(Items.book)
.addInput(Items.paper, 3)
.addInput(Items.leather)
.add();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment