Rewrote the crusher recipe handler to be better and more efficient and less buggy

This commit is contained in:
Ellpeck 2015-10-03 21:56:22 +02:00
parent 267546eff4
commit 69ff994375
12 changed files with 310 additions and 281 deletions

View file

@ -12,7 +12,7 @@ package ellpeck.actuallyadditions.booklet.page;
import ellpeck.actuallyadditions.booklet.GuiBooklet;
import ellpeck.actuallyadditions.booklet.InitBooklet;
import ellpeck.actuallyadditions.recipe.CrusherRecipeManualRegistry;
import ellpeck.actuallyadditions.recipe.CrusherRecipeRegistry;
import ellpeck.actuallyadditions.util.ModUtil;
import ellpeck.actuallyadditions.util.StringUtil;
import ellpeck.actuallyadditions.util.Util;
@ -21,9 +21,13 @@ import net.minecraft.util.EnumChatFormatting;
public class PageCrusherRecipe extends BookletPage{
public CrusherRecipeManualRegistry.CrusherRecipe recipe;
public CrusherRecipeRegistry.CrusherRecipe recipe;
public PageCrusherRecipe(int id, CrusherRecipeManualRegistry.CrusherRecipe recipe){
private int inputPos;
private int outOnePos;
private int outTwoPos;
public PageCrusherRecipe(int id, CrusherRecipeRegistry.CrusherRecipe recipe){
super(id);
this.recipe = recipe;
InitBooklet.pagesWithItemStackData.add(this);
@ -37,6 +41,26 @@ public class PageCrusherRecipe extends BookletPage{
}
}
@Override
public void updateScreen(int ticksElapsed){
if(ticksElapsed%5 == 0){
if(this.inputPos+1 < this.recipe.getRecipeInputs().size()){
this.inputPos++;
}
else if(this.outOnePos+1 < this.recipe.getRecipeOutputOnes().size()){
this.outOnePos++;
}
else if(this.outTwoPos+1 < this.recipe.getRecipeOutputTwos().size()){
this.outTwoPos++;
}
else{
this.inputPos = 0;
this.outOnePos = 0;
this.outTwoPos = 0;
}
}
}
@SuppressWarnings("unchecked")
@Override
public void render(GuiBooklet gui, int mouseX, int mouseY, boolean mouseClick, int ticksElapsed){
@ -53,14 +77,25 @@ public class PageCrusherRecipe extends BookletPage{
gui.mc.fontRenderer.drawSplitString(text, gui.guiLeft+14, gui.guiTop+100, 115, 0);
}
if(recipe.secondChance > 0){
gui.mc.fontRenderer.drawString(recipe.secondChance+"%", gui.guiLeft+37+62, gui.guiTop+20+33, 0);
if(recipe.outputTwoChance > 0){
gui.mc.fontRenderer.drawString(recipe.outputTwoChance+"%", gui.guiLeft+37+62, gui.guiTop+20+33, 0);
}
if(recipe.firstOutput != null){
if(recipe.getRecipeOutputOnes() != null){
for(int i = 0; i < 2; i++){
for(int j = 0; j < 3; j++){
ItemStack stack = (j == 0 ? this.recipe.input : (j == 1 ? recipe.firstOutput : (j == 2 ? recipe.secondOutput : null)));
ItemStack stack;
switch(j){
case 0:
stack = this.recipe.getRecipeInputs().get(this.inputPos);
break;
case 1:
stack = this.recipe.getRecipeOutputOnes().get(this.outOnePos);
break;
default:
stack = this.recipe.getRecipeOutputTwos().get(this.outTwoPos);
break;
}
if(stack != null){
if(stack.getItemDamage() == Util.WILDCARD){
@ -87,6 +122,6 @@ public class PageCrusherRecipe extends BookletPage{
@Override
public ItemStack[] getItemStacksForPage(){
return this.recipe == null ? new ItemStack[0] : new ItemStack[]{this.recipe.firstOutput};
return this.recipe == null ? new ItemStack[0] : this.recipe.getRecipeOutputOnes().toArray(new ItemStack[this.recipe.getRecipeOutputOnes().size()]);
}
}

View file

@ -12,7 +12,6 @@ package ellpeck.actuallyadditions.communication;
import cpw.mods.fml.common.event.FMLInterModComms;
import ellpeck.actuallyadditions.items.ItemCoffee;
import ellpeck.actuallyadditions.recipe.CrusherRecipeManualRegistry;
import ellpeck.actuallyadditions.recipe.HairyBallHandler;
import ellpeck.actuallyadditions.recipe.TreasureChestHandler;
import ellpeck.actuallyadditions.util.ModUtil;
@ -26,7 +25,8 @@ public class InterModCommunications{
public static void processIMC(List<FMLInterModComms.IMCMessage> messages){
for(FMLInterModComms.IMCMessage message : messages){
if(message.key.equalsIgnoreCase("registerCrusherRecipe")){
//TODO This
/*if(message.key.equalsIgnoreCase("registerCrusherRecipe")){
NBTTagCompound compound = message.getNBTValue();
if(compound != null){
ItemStack input = ItemStack.loadItemStackFromNBT(compound.getCompoundTag("input"));
@ -42,7 +42,7 @@ public class InterModCommunications{
ModUtil.LOGGER.error("Crusher Recipe that was sent from Mod "+message.getSender()+" could not be registered: It's missing an Input or an Output!");
}
}
}
}*/
if(message.key.equalsIgnoreCase("registerCoffeeMachineRecipe")){
NBTTagCompound compound = message.getNBTValue();

View file

@ -30,7 +30,6 @@ public enum ConfigBoolValues{
EMERALD_SHARD_CROP("Emerald Shard", ConfigCategories.MOB_DROPS, true, "If the Emerald Shard drops from Mobs"),
DO_UPDATE_CHECK("Do Update Check", ConfigCategories.OTHER, true, "If Actually Additions should check for an Update on joining a World"),
DO_CRUSHER_SPAM("Crusher Debug", ConfigCategories.OTHER, false, "Print out Crusher Recipe Initializing Debug"),
DO_CAT_DROPS("Do Cat Drops", ConfigCategories.OTHER, true, "If Cats drop Hairy Balls on Occasion"),
TF_PAXELS("Thermal Foundation Paxels", ConfigCategories.OTHER, true, "If Paxels made of Thermal Foundation Materials should exist"),

View file

@ -11,16 +11,8 @@
package ellpeck.actuallyadditions.crafting;
import ellpeck.actuallyadditions.config.values.ConfigCrafting;
import ellpeck.actuallyadditions.items.InitItems;
import ellpeck.actuallyadditions.items.metalists.TheDusts;
import ellpeck.actuallyadditions.items.metalists.TheFoods;
import ellpeck.actuallyadditions.recipe.CrusherRecipeAutoRegistry;
import ellpeck.actuallyadditions.recipe.CrusherRecipeAutoRegistry.SearchCase;
import ellpeck.actuallyadditions.recipe.CrusherRecipeManualRegistry;
import ellpeck.actuallyadditions.recipe.CrusherRecipeRegistry;
import ellpeck.actuallyadditions.util.ModUtil;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
public class CrusherCrafting{
@ -28,48 +20,48 @@ public class CrusherCrafting{
ModUtil.LOGGER.info("Initializing Crusher Recipes...");
if(ConfigCrafting.REDSTONE.isEnabled()){
CrusherRecipeManualRegistry.registerRecipe(new ItemStack(Blocks.redstone_ore), new ItemStack(Items.redstone, 10));
CrusherRecipeRegistry.addRecipe("oreRedstone", "dustRedstone", 10);
}
if(ConfigCrafting.LAPIS.isEnabled()){
CrusherRecipeManualRegistry.registerRecipe(new ItemStack(Blocks.lapis_ore), new ItemStack(Items.dye, 12, 4));
CrusherRecipeRegistry.addRecipe("oreLapis", "gemLapis", 12);
}
if(ConfigCrafting.COAL.isEnabled()){
CrusherRecipeManualRegistry.registerRecipe(new ItemStack(Items.coal), new ItemStack(InitItems.itemDust, 1, TheDusts.COAL.ordinal()));
CrusherRecipeRegistry.addRecipe("coal", "dustCoal", 1);
}
if(ConfigCrafting.COAL_ORE.isEnabled()){
CrusherRecipeManualRegistry.registerRecipe(new ItemStack(Blocks.coal_ore), new ItemStack(Items.coal, 3));
CrusherRecipeRegistry.addRecipe("oreCoal", "coal", 3);
}
if(ConfigCrafting.COAL_BLOCKS.isEnabled()){
CrusherRecipeManualRegistry.registerRecipe(new ItemStack(Blocks.coal_block), new ItemStack(Items.coal, 9));
CrusherRecipeRegistry.addRecipe("blockCoal", "coal", 9);
}
if(ConfigCrafting.COBBLESTONE.isEnabled()){
CrusherRecipeManualRegistry.registerRecipe(new ItemStack(Blocks.cobblestone), new ItemStack(Blocks.sand));
CrusherRecipeRegistry.addRecipe("cobblestone", "sand", 1);
}
if(ConfigCrafting.GRAVEL.isEnabled()){
CrusherRecipeManualRegistry.registerRecipe(new ItemStack(Blocks.gravel), new ItemStack(Items.flint));
CrusherRecipeRegistry.addRecipe("gravel", "flint", 1);
}
if(ConfigCrafting.STONE.isEnabled()){
CrusherRecipeManualRegistry.registerRecipe(new ItemStack(Blocks.stone), new ItemStack(Blocks.cobblestone));
CrusherRecipeRegistry.addRecipe("stone", "cobblestone", 1);
}
if(ConfigCrafting.RICE_SUGAR.isEnabled()){
CrusherRecipeManualRegistry.registerRecipe(new ItemStack(InitItems.itemFoods, 1, TheFoods.RICE.ordinal()), new ItemStack(Items.sugar, 2));
CrusherRecipeRegistry.addRecipe("cropRice", "sugar", 2);
}
if(ConfigCrafting.NICKEL.isEnabled()){
CrusherRecipeManualRegistry.registerRecipe("oreNickel", "dustNickel", "dustPlatinum", 15, 2, 1);
CrusherRecipeRegistry.addRecipe("oreNickel", "dustNickel", 2, "dustPlatinum", 1, 15);
}
if(ConfigCrafting.IRON.isEnabled()){
CrusherRecipeManualRegistry.registerRecipe("oreIron", "dustIron", "dustGold", 20, 2, 1);
CrusherRecipeRegistry.addRecipe("oreIron", "dustIron", 2, "dustGold", 1, 20);
}
CrusherRecipeAutoRegistry.searchCases.add(new SearchCase("oreNether", 6));
CrusherRecipeAutoRegistry.searchCases.add(new SearchCase("orePoor", 4, "nugget"));
CrusherRecipeAutoRegistry.searchCases.add(new SearchCase("denseore", 8));
CrusherRecipeAutoRegistry.searchCases.add(new SearchCase("gem", 1));
CrusherRecipeAutoRegistry.searchCases.add(new SearchCase("ingot", 1));
CrusherRecipeAutoRegistry.searchCases.add(new SearchCase("ore", 2));
CrusherRecipeRegistry.searchCases.add(new CrusherRecipeRegistry.SearchCase("oreNether", 6));
CrusherRecipeRegistry.searchCases.add(new CrusherRecipeRegistry.SearchCase("orePoor", 4, "nugget"));
CrusherRecipeRegistry.searchCases.add(new CrusherRecipeRegistry.SearchCase("denseore", 8));
CrusherRecipeRegistry.searchCases.add(new CrusherRecipeRegistry.SearchCase("gem", 1));
CrusherRecipeRegistry.searchCases.add(new CrusherRecipeRegistry.SearchCase("ingot", 1));
CrusherRecipeRegistry.searchCases.add(new CrusherRecipeRegistry.SearchCase("ore", 2));
CrusherRecipeAutoRegistry.registerFinally();
CrusherRecipeRegistry.registerFinally();
}
}

View file

@ -11,7 +11,7 @@
package ellpeck.actuallyadditions.inventory;
import ellpeck.actuallyadditions.inventory.slot.SlotOutput;
import ellpeck.actuallyadditions.recipe.CrusherRecipeManualRegistry;
import ellpeck.actuallyadditions.recipe.CrusherRecipeRegistry;
import ellpeck.actuallyadditions.tile.TileEntityBase;
import ellpeck.actuallyadditions.tile.TileEntityGrinder;
import invtweaks.api.container.InventoryContainer;
@ -73,7 +73,7 @@ public class ContainerGrinder extends Container{
//Other Slots in Inventory excluded
else if(slot >= inventoryStart){
//Shift from Inventory
if(CrusherRecipeManualRegistry.getOutput(newStack, false) != null){
if(CrusherRecipeRegistry.getRecipeFromInput(newStack) != null){
if(!this.mergeItemStack(newStack, TileEntityGrinder.SLOT_INPUT_1, TileEntityGrinder.SLOT_INPUT_1+1, false)){
if(this.isDouble){
if(!this.mergeItemStack(newStack, TileEntityGrinder.SLOT_INPUT_2, TileEntityGrinder.SLOT_INPUT_2+1, false)){

View file

@ -11,13 +11,13 @@
package ellpeck.actuallyadditions.nei;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.NEIServerUtils;
import codechicken.nei.PositionedStack;
import codechicken.nei.recipe.RecipeInfo;
import codechicken.nei.recipe.TemplateRecipeHandler;
import ellpeck.actuallyadditions.blocks.InitBlocks;
import ellpeck.actuallyadditions.inventory.gui.GuiGrinder;
import ellpeck.actuallyadditions.recipe.CrusherRecipeManualRegistry;
import ellpeck.actuallyadditions.recipe.CrusherRecipeRegistry;
import ellpeck.actuallyadditions.util.ItemUtil;
import ellpeck.actuallyadditions.util.ModUtil;
import ellpeck.actuallyadditions.util.StringUtil;
import net.minecraft.client.gui.inventory.GuiContainer;
@ -48,9 +48,8 @@ public class CrusherRecipeHandler extends TemplateRecipeHandler implements INeiR
@Override
public void loadCraftingRecipes(String outputId, Object... results){
if(outputId.equals(this.getName()) && (getClass() == CrusherRecipeHandler.class || getClass() == CrusherDoubleRecipeHandler.class)){
ArrayList<CrusherRecipeManualRegistry.CrusherRecipe> recipes = CrusherRecipeManualRegistry.recipes;
for(CrusherRecipeManualRegistry.CrusherRecipe recipe : recipes){
arecipes.add(new CachedCrush(recipe.input, recipe.firstOutput, recipe.secondOutput, recipe.secondChance, this));
for(CrusherRecipeRegistry.CrusherRecipe recipe : CrusherRecipeRegistry.recipes){
arecipes.add(new CachedCrush(recipe.getRecipeInputs(), recipe.getRecipeOutputOnes(), recipe.getRecipeOutputTwos(), recipe.outputTwoChance, this));
}
}
else{
@ -60,20 +59,18 @@ public class CrusherRecipeHandler extends TemplateRecipeHandler implements INeiR
@Override
public void loadCraftingRecipes(ItemStack result){
ArrayList<CrusherRecipeManualRegistry.CrusherRecipe> recipes = CrusherRecipeManualRegistry.recipes;
for(CrusherRecipeManualRegistry.CrusherRecipe recipe : recipes){
if(NEIServerUtils.areStacksSameType(recipe.firstOutput, result) || NEIServerUtils.areStacksSameType(recipe.secondOutput, result)){
arecipes.add(new CachedCrush(recipe.input, recipe.firstOutput, recipe.secondOutput, recipe.secondChance, this));
for(CrusherRecipeRegistry.CrusherRecipe recipe : CrusherRecipeRegistry.recipes){
if(ItemUtil.contains(recipe.getRecipeOutputOnes(), result, true) || ItemUtil.contains(recipe.getRecipeOutputTwos(), result, true)){
arecipes.add(new CachedCrush(recipe.getRecipeInputs(), recipe.getRecipeOutputOnes(), recipe.getRecipeOutputTwos(), recipe.outputTwoChance, this));
}
}
}
@Override
public void loadUsageRecipes(ItemStack ingredient){
ArrayList<CrusherRecipeManualRegistry.CrusherRecipe> recipes = CrusherRecipeManualRegistry.recipes;
for(CrusherRecipeManualRegistry.CrusherRecipe recipe : recipes){
if(NEIServerUtils.areStacksSameTypeCrafting(recipe.input, ingredient)){
CachedCrush theRecipe = new CachedCrush(recipe.input, recipe.firstOutput, recipe.secondOutput, recipe.secondChance, this);
for(CrusherRecipeRegistry.CrusherRecipe recipe : CrusherRecipeRegistry.recipes){
if(ItemUtil.contains(recipe.getRecipeInputs(), ingredient, true)){
CachedCrush theRecipe = new CachedCrush(recipe.getRecipeInputs(), recipe.getRecipeOutputOnes(), recipe.getRecipeOutputTwos(), recipe.outputTwoChance, this);
theRecipe.setIngredientPermutation(Collections.singletonList(theRecipe.ingredient), ingredient);
arecipes.add(theRecipe);
}
@ -175,32 +172,32 @@ public class CrusherRecipeHandler extends TemplateRecipeHandler implements INeiR
public PositionedStack resultTwo;
public int secondChance;
public CachedCrush(ItemStack in, ItemStack resultOne, ItemStack resultTwo, int secondChance, CrusherRecipeHandler handler){
public CachedCrush(ArrayList<ItemStack> in, ArrayList<ItemStack> outOne, ArrayList<ItemStack> outTwo, int secondChance, CrusherRecipeHandler handler){
boolean isDouble = handler instanceof CrusherDoubleRecipeHandler;
in.stackSize = 1;
this.ingredient = new PositionedStack(in, isDouble ? 51 : 80, 21);
this.resultOne = new PositionedStack(resultOne, isDouble ? 38 : 66, 69);
if(resultTwo != null){
this.resultTwo = new PositionedStack(resultTwo, isDouble ? 63 : 94, 69);
this.resultOne = new PositionedStack(outOne, isDouble ? 38 : 66, 69);
if(outTwo != null && !outTwo.isEmpty()){
this.resultTwo = new PositionedStack(outTwo, isDouble ? 63 : 94, 69);
}
this.secondChance = secondChance;
}
@Override
public PositionedStack getResult(){
return resultOne;
return null;
}
@Override
public List<PositionedStack> getIngredients(){
return getCycledIngredients(cycleticks/48, Collections.singletonList(ingredient));
return this.getCycledIngredients(cycleticks/48, Collections.singletonList(this.ingredient));
}
@Override
public List<PositionedStack> getOtherStacks(){
ArrayList<PositionedStack> list = new ArrayList<PositionedStack>();
list.addAll(this.getCycledIngredients(cycleticks/48, Collections.singletonList(this.resultOne)));
if(this.resultTwo != null){
list.add(this.resultTwo);
list.addAll(this.getCycledIngredients(cycleticks/48, Collections.singletonList(this.resultTwo)));
}
return list;
}

View file

@ -32,6 +32,10 @@ public class InitOreDict{
//Vanilla Ores
addOre(Blocks.obsidian, "obsidian");
addOre(new ItemStack(Items.coal), "coal");
addOre(Items.flint, "flint");
addOre(Blocks.gravel, "gravel");
addOre(Items.sugar, "sugar");
//My Ores
addOre(InitItems.itemDust, TheDusts.IRON.ordinal(), "dustIron");

View file

@ -1,75 +0,0 @@
/*
* This file ("CrusherRecipeAutoRegistry.java") is part of the Actually Additions Mod for Minecraft.
* It is created and owned by Ellpeck and distributed
* under the Actually Additions License to be found at
* http://github.com/Ellpeck/ActuallyAdditions/blob/master/README.md
* View the source code at https://github.com/Ellpeck/ActuallyAdditions
*
* © 2015 Ellpeck
*/
package ellpeck.actuallyadditions.recipe;
import ellpeck.actuallyadditions.config.ConfigValues;
import net.minecraftforge.oredict.OreDictionary;
import java.util.ArrayList;
//TODO REDO COMPLETELY
public class CrusherRecipeAutoRegistry{
public static ArrayList<SearchCase> searchCases = new ArrayList<SearchCase>();
public static void registerFinally(){
String[] names = OreDictionary.getOreNames();
for(String inputName : names){
if(!hasException(inputName)){
int resultAmount = 1;
String inputNameWithoutPrefix = null;
String replacer = null;
for(SearchCase searchCase : searchCases){
String toSearch = searchCase.name;
if(inputName.length() > toSearch.length() && inputName.substring(0, toSearch.length()).equals(toSearch)){
inputNameWithoutPrefix = inputName.substring(toSearch.length());
resultAmount = searchCase.resultAmount;
replacer = searchCase.replacer;
break;
}
}
if(inputNameWithoutPrefix != null && replacer != null){
String inputWithDustPrefix = replacer+inputNameWithoutPrefix;
CrusherRecipeManualRegistry.registerRecipe(inputName, inputWithDustPrefix, resultAmount);
}
}
}
}
private static boolean hasException(String name){
for(String except : ConfigValues.crusherRecipeExceptions){
if(except.equals(name)){
return true;
}
}
return false;
}
public static class SearchCase{
public final String name;
public final int resultAmount;
public final String replacer;
public SearchCase(String name, int resultAmount){
this(name, resultAmount, "dust");
}
public SearchCase(String name, int resultAmount, String replacer){
this.name = name;
this.resultAmount = resultAmount;
this.replacer = replacer;
}
}
}

View file

@ -1,122 +0,0 @@
/*
* This file ("CrusherRecipeManualRegistry.java") is part of the Actually Additions Mod for Minecraft.
* It is created and owned by Ellpeck and distributed
* under the Actually Additions License to be found at
* http://github.com/Ellpeck/ActuallyAdditions/blob/master/README.md
* View the source code at https://github.com/Ellpeck/ActuallyAdditions
*
* © 2015 Ellpeck
*/
package ellpeck.actuallyadditions.recipe;
import ellpeck.actuallyadditions.config.values.ConfigBoolValues;
import ellpeck.actuallyadditions.util.ModUtil;
import ellpeck.actuallyadditions.util.Util;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
import java.util.ArrayList;
//TODO REDO COMPLETELY
public class CrusherRecipeManualRegistry{
public static ArrayList<CrusherRecipe> recipes = new ArrayList<CrusherRecipe>();
public static void registerRecipe(String input, String outputOne, int outputOneAmount){
registerRecipe(input, outputOne, "", 0, outputOneAmount, 0);
}
public static void registerRecipe(String input, String outputOne, String outputTwo, int secondChance, int outputOneAmount, int outputTwoAmount){
ArrayList<ItemStack> inputStacks = (ArrayList<ItemStack>)OreDictionary.getOres(input, false);
ArrayList<ItemStack> outputOneStacks = (ArrayList<ItemStack>)OreDictionary.getOres(outputOne, false);
ArrayList<ItemStack> outputTwoStacks = (outputTwo == null || outputTwo.isEmpty()) ? null : (ArrayList<ItemStack>)OreDictionary.getOres(outputTwo, false);
if(inputStacks != null && !inputStacks.isEmpty()){
for(ItemStack anInput : inputStacks){
ItemStack theInput = anInput.copy();
if(outputOneStacks != null && !outputOneStacks.isEmpty()){
for(ItemStack anOutputOne : outputOneStacks){
ItemStack theOutputOne = anOutputOne.copy();
theOutputOne.stackSize = outputOneAmount;
if(outputTwoStacks != null && !outputTwoStacks.isEmpty()){
for(ItemStack anOutputTwo : outputTwoStacks){
ItemStack theOutputTwo = anOutputTwo.copy();
theOutputTwo.stackSize = outputTwoAmount;
registerRecipe(theInput, theOutputOne, theOutputTwo, secondChance);
}
}
else{
registerRecipe(theInput, theOutputOne, null, 0);
}
}
}
else{
if(ConfigBoolValues.DO_CRUSHER_SPAM.isEnabled()){
ModUtil.LOGGER.warn("Couldn't register Crusher Recipe! An Item with OreDictionary Registry '"+outputOne+"' doesn't exist! It should be the output of '"+input+"'!");
}
}
}
}
else{
if(ConfigBoolValues.DO_CRUSHER_SPAM.isEnabled()){
ModUtil.LOGGER.warn("Couldn't register Crusher Recipe! Didn't find Items registered as '"+input+"'!");
}
}
}
public static void registerRecipe(ItemStack input, ItemStack outputOne, ItemStack outputTwo, int secondChance){
if(!hasRecipe(input, outputOne, outputTwo)){
recipes.add(new CrusherRecipe(input, outputOne, outputTwo, secondChance));
}
}
public static boolean hasRecipe(ItemStack input, ItemStack outputOne, ItemStack outputTwo){
for(CrusherRecipe recipe : recipes){
if(outputTwo == null || (recipe.secondOutput != null && recipe.secondOutput.isItemEqual(outputTwo))){
if(recipe.input.isItemEqual(input) && recipe.firstOutput.isItemEqual(outputOne) || (recipe.input.getItem() == input.getItem() && recipe.firstOutput.getItem() == outputOne.getItem() && recipe.input.getItemDamage() == Util.WILDCARD)){
return true;
}
}
}
return false;
}
public static void registerRecipe(ItemStack input, ItemStack outputOne){
registerRecipe(input, outputOne, null, 0);
}
public static ItemStack getOutput(ItemStack input, boolean wantSecond){
for(CrusherRecipe recipe : recipes){
if(recipe.input.isItemEqual(input) || (recipe.input.getItem() == input.getItem() && recipe.input.getItemDamage() == Util.WILDCARD)){
return wantSecond ? recipe.secondOutput : recipe.firstOutput;
}
}
return null;
}
public static int getSecondChance(ItemStack input){
for(CrusherRecipe recipe : recipes){
if(recipe.input.isItemEqual(input) || (recipe.input.getItem() == input.getItem() && recipe.input.getItemDamage() == Util.WILDCARD)){
return recipe.secondChance;
}
}
return 0;
}
public static class CrusherRecipe{
public final ItemStack input;
public final ItemStack firstOutput;
public final ItemStack secondOutput;
public final int secondChance;
public CrusherRecipe(ItemStack input, ItemStack firstOutput, ItemStack secondOutput, int secondChance){
this.input = input;
this.firstOutput = firstOutput;
this.secondOutput = secondOutput;
this.secondChance = secondChance;
}
}
}

View file

@ -0,0 +1,182 @@
/*
* This file ("CrusherRecipeRegistry.java") is part of the Actually Additions Mod for Minecraft.
* It is created and owned by Ellpeck and distributed
* under the Actually Additions License to be found at
* http://github.com/Ellpeck/ActuallyAdditions/blob/master/README.md
* View the source code at https://github.com/Ellpeck/ActuallyAdditions
*
* © 2015 Ellpeck
*/
package ellpeck.actuallyadditions.recipe;
import ellpeck.actuallyadditions.config.ConfigValues;
import ellpeck.actuallyadditions.util.ItemUtil;
import ellpeck.actuallyadditions.util.ModUtil;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
import java.util.ArrayList;
public class CrusherRecipeRegistry{
public static ArrayList<CrusherRecipe> recipes = new ArrayList<CrusherRecipe>();
public static ArrayList<SearchCase> searchCases = new ArrayList<SearchCase>();
public static void addRecipe(String input, String outputOne, int outputOneAmount, String outputTwo, int outputTwoAmount, int outputTwoChance){
recipes.add(new CrusherRecipe(input, outputOne, outputOneAmount, outputTwo, outputTwoAmount, outputTwoChance));
}
public static void addRecipe(String input, String outputOne, int outputOneAmount){
recipes.add(new CrusherRecipe(input, outputOne, outputOneAmount, "", 0, 0));
}
public static void registerFinally(){
ArrayList<String> oresNoResult = new ArrayList<String>();
int recipesAdded = 0;
int recipeStartedAt = recipes.size();
for(String ore : OreDictionary.getOreNames()){
if(!hasException(ore)){
for(SearchCase theCase : searchCases){
if(ore.length() > theCase.theCase.length()){
if(ore.substring(0, theCase.theCase.length()).equals(theCase.theCase)){
String output = theCase.resultPreString+ore.substring(theCase.theCase.length());
if(!hasRecipe(ore)){
if(!OreDictionary.getOres(output, false).isEmpty()){
addRecipe(ore, output, theCase.resultAmount);
recipesAdded++;
}
else{
oresNoResult.add(ore);
}
}
break;
}
}
}
}
}
ArrayList<String> addedRecipes = new ArrayList<String>();
for(int i = recipeStartedAt; i < recipes.size(); i++){
CrusherRecipe recipe = recipes.get(i);
addedRecipes.add(recipe.input+" -> "+recipe.outputOneAmount+"x "+recipe.outputOne);
}
ModUtil.LOGGER.info("Added "+recipesAdded+" Crusher Recipes automatically: "+addedRecipes.toString());
ModUtil.LOGGER.warn("Couldn't add "+oresNoResult.size()+" Crusher Recipes automatically because the inputs were missing outputs: "+oresNoResult.toString());
}
private static boolean hasException(String ore){
for(String conf : ConfigValues.crusherRecipeExceptions){
if(conf.equals(ore)){
return true;
}
}
return false;
}
public static boolean hasRecipe(String input){
for(CrusherRecipe recipe : recipes){
if(recipe.input.equals(input)){
return true;
}
}
return false;
}
public static CrusherRecipe getRecipeFromInput(ItemStack input){
for(CrusherRecipe recipe : recipes){
if(ItemUtil.contains(recipe.getRecipeInputs(), input, true)){
return recipe;
}
}
return null;
}
public static ArrayList<ItemStack> getOutputOnes(ItemStack input){
CrusherRecipe recipe = getRecipeFromInput(input);
return recipe == null ? null : recipe.getRecipeOutputOnes();
}
public static ArrayList<ItemStack> getOutputTwos(ItemStack input){
CrusherRecipe recipe = getRecipeFromInput(input);
return recipe == null ? null : recipe.getRecipeOutputTwos();
}
public static int getOutputTwoChance(ItemStack input){
CrusherRecipe recipe = getRecipeFromInput(input);
return recipe == null ? -1 : recipe.outputTwoChance;
}
public static class CrusherRecipe{
public String input;
public String outputOne;
public int outputOneAmount;
public String outputTwo;
public int outputTwoAmount;
public int outputTwoChance;
public CrusherRecipe(String input, String outputOne, int outputOneAmount, String outputTwo, int outputTwoAmount, int outputTwoChance){
this.input = input;
this.outputOne = outputOne;
this.outputOneAmount = outputOneAmount;
this.outputTwo = outputTwo;
this.outputTwoAmount = outputTwoAmount;
this.outputTwoChance = outputTwoChance;
}
public ArrayList<ItemStack> getRecipeOutputOnes(){
if(this.outputOne == null || this.outputOne.isEmpty()) return null;
ArrayList<ItemStack> stacks = OreDictionary.getOres(this.outputOne);
for(ItemStack stack : stacks){
stack.stackSize = this.outputOneAmount;
}
return stacks;
}
public ArrayList<ItemStack> getRecipeOutputTwos(){
if(this.outputTwo == null || this.outputTwo.isEmpty()) return null;
ArrayList<ItemStack> stacks = OreDictionary.getOres(this.outputTwo);
for(ItemStack stack : stacks){
stack.stackSize = this.outputTwoAmount;
}
return stacks;
}
public ArrayList<ItemStack> getRecipeInputs(){
if(this.input == null || this.input.isEmpty()) return null;
ArrayList<ItemStack> stacks = OreDictionary.getOres(this.input);
for(ItemStack stack : stacks){
stack.stackSize = 1;
}
return stacks;
}
}
public static class SearchCase{
String theCase;
int resultAmount;
String resultPreString;
public SearchCase(String theCase, int resultAmount, String resultPreString){
this.theCase = theCase;
this.resultAmount = resultAmount;
this.resultPreString = resultPreString;
}
public SearchCase(String theCase, int resultAmount){
this(theCase, resultAmount, "dust");
}
}
}

View file

@ -17,11 +17,12 @@ import cpw.mods.fml.relauncher.SideOnly;
import ellpeck.actuallyadditions.config.values.ConfigIntValues;
import ellpeck.actuallyadditions.network.sync.IPacketSyncerToClient;
import ellpeck.actuallyadditions.network.sync.PacketSyncerToClient;
import ellpeck.actuallyadditions.recipe.CrusherRecipeManualRegistry;
import ellpeck.actuallyadditions.recipe.CrusherRecipeRegistry;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import java.util.ArrayList;
import java.util.Random;
public class TileEntityGrinder extends TileEntityInventoryBase implements IEnergyReceiver, IPacketSyncerToClient{
@ -154,9 +155,11 @@ public class TileEntityGrinder extends TileEntityInventoryBase implements IEnerg
public boolean canCrushOn(int theInput, int theFirstOutput, int theSecondOutput){
if(this.slots[theInput] != null){
ItemStack outputOne = CrusherRecipeManualRegistry.getOutput(this.slots[theInput], false);
ItemStack outputTwo = CrusherRecipeManualRegistry.getOutput(this.slots[theInput], true);
if(this.slots[theInput] != null){
ArrayList<ItemStack> outputOnes = CrusherRecipeRegistry.getOutputOnes(this.slots[theInput]);
if(outputOnes != null && !outputOnes.isEmpty()){
ItemStack outputOne = outputOnes.get(0);
ArrayList<ItemStack> outputTwos = CrusherRecipeRegistry.getOutputTwos(this.slots[theInput]);
ItemStack outputTwo = outputTwos == null ? null : outputTwos.get(0);
if(outputOne != null){
if((this.slots[theFirstOutput] == null || (this.slots[theFirstOutput].isItemEqual(outputOne) && this.slots[theFirstOutput].stackSize <= this.slots[theFirstOutput].getMaxStackSize()-outputOne.stackSize)) && (outputTwo == null || (this.slots[theSecondOutput] == null || (this.slots[theSecondOutput].isItemEqual(outputTwo) && this.slots[theSecondOutput].stackSize <= this.slots[theSecondOutput].getMaxStackSize()-outputTwo.stackSize)))){
return true;
@ -176,26 +179,31 @@ public class TileEntityGrinder extends TileEntityInventoryBase implements IEnerg
}
public void finishCrushing(int theInput, int theFirstOutput, int theSecondOutput){
ItemStack outputOnFirst = CrusherRecipeManualRegistry.getOutput(this.slots[theInput], false);
if(outputOnFirst != null){
ArrayList<ItemStack> outputOnes = CrusherRecipeRegistry.getOutputOnes(this.slots[theInput]);
if(outputOnes != null){
ItemStack outputOne = outputOnes.get(0);
if(outputOne != null){
if(this.slots[theFirstOutput] == null){
this.slots[theFirstOutput] = outputOnFirst.copy();
this.slots[theFirstOutput] = outputOne.copy();
}
else if(this.slots[theFirstOutput].getItem() == outputOne.getItem()){
this.slots[theFirstOutput].stackSize += outputOne.stackSize;
}
else if(this.slots[theFirstOutput].getItem() == outputOnFirst.getItem()){
this.slots[theFirstOutput].stackSize += outputOnFirst.stackSize;
}
}
int chance = CrusherRecipeManualRegistry.getSecondChance(this.slots[theInput]);
ItemStack outputOnSecond = CrusherRecipeManualRegistry.getOutput(this.slots[theInput], true);
if(outputOnSecond != null){
ArrayList<ItemStack> outputTwos = CrusherRecipeRegistry.getOutputTwos(this.slots[theInput]);
if(outputTwos != null){
ItemStack outputTwo = outputTwos.get(0);
if(outputTwo != null){
int rand = new Random().nextInt(100)+1;
if(rand <= chance){
if(rand <= CrusherRecipeRegistry.getOutputTwoChance(this.slots[theInput])){
if(this.slots[theSecondOutput] == null){
this.slots[theSecondOutput] = outputOnSecond.copy();
this.slots[theSecondOutput] = outputTwo.copy();
}
else if(this.slots[theSecondOutput].getItem() == outputTwo.getItem()){
this.slots[theSecondOutput].stackSize += outputTwo.stackSize;
}
else if(this.slots[theSecondOutput].getItem() == outputOnSecond.getItem()){
this.slots[theSecondOutput].stackSize += outputOnSecond.stackSize;
}
}
}
@ -224,7 +232,7 @@ public class TileEntityGrinder extends TileEntityInventoryBase implements IEnerg
@Override
public boolean isItemValidForSlot(int i, ItemStack stack){
return (i == SLOT_INPUT_1 || i == SLOT_INPUT_2) && CrusherRecipeManualRegistry.getOutput(stack, false) != null;
return (i == SLOT_INPUT_1 || i == SLOT_INPUT_2) && CrusherRecipeRegistry.getRecipeFromInput(stack) != null;
}
@SideOnly(Side.CLIENT)

View file

@ -17,6 +17,8 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagList;
import java.util.List;
public class ItemUtil{
public static Item getItemFromName(String name){
@ -58,6 +60,13 @@ public class ItemUtil{
return true;
}
/**
* Returns true if list contains stack or if both contain null
*/
public static boolean contains(List<ItemStack> list, ItemStack stack, boolean checkWildcard){
return !(list == null || list.isEmpty()) && getPlaceAt(list.toArray(new ItemStack[list.size()]), stack, checkWildcard) != -1;
}
/**
* Returns true if array contains stack or if both contain null
*/