diff --git a/src/api/java/appeng/api/features/IGrinderEntry.java b/src/api/java/appeng/api/features/IGrinderRecipe.java similarity index 68% rename from src/api/java/appeng/api/features/IGrinderEntry.java rename to src/api/java/appeng/api/features/IGrinderRecipe.java index 1667f12c..2a2cd442 100644 --- a/src/api/java/appeng/api/features/IGrinderEntry.java +++ b/src/api/java/appeng/api/features/IGrinderRecipe.java @@ -24,13 +24,17 @@ package appeng.api.features; +import java.util.Optional; + +import javax.annotation.Nonnull; + import net.minecraft.item.ItemStack; /** * Registration Records for {@link IGrinderRegistry} */ -public interface IGrinderEntry +public interface IGrinderRecipe { /** @@ -38,66 +42,40 @@ public interface IGrinderEntry * * @return input that the grinder will accept. */ + @Nonnull ItemStack getInput(); - /** - * lets you change the grinder recipe by changing its input. - * - * @param input input item - */ - void setInput( ItemStack input ); - /** * gets the current output * * @return output that the grinder will produce */ + @Nonnull ItemStack getOutput(); /** - * allows you to change the output. + * gets the current output * - * @param output output item + * @return output that the grinder will produce */ - void setOutput( ItemStack output ); + @Nonnull + Optional getOptionalOutput(); /** * gets the current output * * @return output that the grinder will produce */ - ItemStack getOptionalOutput(); - - /** - * gets the current output - * - * @return output that the grinder will produce - */ - ItemStack getSecondOptionalOutput(); - - /** - * stack, and 0.0-1.0 chance that it will be generated. - * - * @param output output item - * @param chance generation chance - */ - void setOptionalOutput( ItemStack output, float chance ); + Optional getSecondOptionalOutput(); /** * 0.0 - 1.0 the chance that the optional output will be generated. * * @return chance of optional output */ + @Nonnull float getOptionalChance(); - /** - * stack, and 0.0-1.0 chance that it will be generated. - * - * @param output second optional output item - * @param chance second optional output chance - */ - void setSecondOptionalOutput( ItemStack output, float chance ); - /** * 0.0 - 1.0 the chance that the optional output will be generated. * @@ -106,16 +84,10 @@ public interface IGrinderEntry float getSecondOptionalChance(); /** - * Energy cost, in turns. + * Amount of turns required to process the item. * * @return number of turns it takes to produce the output from the input. */ - int getEnergyCost(); + int getRequiredTurns(); - /** - * Allows you to adjust the number of turns - * - * @param c number of turns to produce output. - */ - void setEnergyCost( int c ); } diff --git a/src/api/java/appeng/api/features/IGrinderRegistry.java b/src/api/java/appeng/api/features/IGrinderRegistry.java index e263c915..2a5e8d15 100644 --- a/src/api/java/appeng/api/features/IGrinderRegistry.java +++ b/src/api/java/appeng/api/features/IGrinderRegistry.java @@ -24,7 +24,10 @@ package appeng.api.features; -import java.util.List; +import java.util.Collection; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import net.minecraft.item.ItemStack; @@ -36,51 +39,90 @@ public interface IGrinderRegistry { /** - * Current list of registered recipes, you can modify this if you want too. + * An immutable list of the currently registered recipes. * * @return currentlyRegisteredRecipes */ - List getRecipes(); + @Nonnull + Collection getRecipes(); /** - * add a new recipe the easy way, in → out, how many turns., duplicates will not be added. + * Add a new recipe with a single input and output and how many turns it requires. + * + * Will ignore duplicate recipes with the same input item. * - * @param in input - * @param out output - * @param turns amount of turns to turn the input into the output + * @param in The {@link ItemStack} to grind. + * @param out The {@link ItemStack} to output. + * @param turns Amount of turns to turn the input into the output, with turns > 0. */ - void addRecipe( ItemStack in, ItemStack out, int turns ); + void addRecipe( @Nonnull ItemStack in, @Nonnull ItemStack out, int turns ); + + /** + * Add a new recipe with an input, output and a single optional output. + * + * Will ignore duplicate recipes with the same input item. + * + * @param in The {@link ItemStack} to grind. + * @param out The {@link ItemStack} to output. + * @param optional The optional {@link ItemStack} to output of a certain chance. + * @param chance Chance to get the optional output within 0.0 - 1.0 + * @param turns Amount of turns to turn the input into the output, with turns > 0. + */ + void addRecipe( @Nonnull ItemStack in, @Nonnull ItemStack out, @Nonnull ItemStack optional, float chance, int turns ); /** * add a new recipe with optional outputs, duplicates will not be added. + * + * Will ignore duplicate recipes with the same input item. * - * @param in input - * @param out output - * @param optional optional output - * @param chance chance to get the optional output within 0.0 - 1.0 - * @param turns amount of turns to turn the input into the outputs - */ - void addRecipe( ItemStack in, ItemStack out, ItemStack optional, float chance, int turns ); - - /** - * add a new recipe with optional outputs, duplicates will not be added. - * - * @param in input - * @param out output - * @param optional optional output - * @param chance chance to get the optional output within 0.0 - 1.0 - * @param optional2 second optional output + * @param in The {@link ItemStack} to grind. + * @param out The {@link ItemStack} to output. + * @param optional The first optional {@link ItemStack} to output of a certain chance. + * @param chance Chance to get the first optional output within 0.0 - 1.0 + * @param optional2 The second optional {@link ItemStack} to output of a certain chance. * @param chance2 chance to get the second optional output within 0.0 - 1.0 - * @param turns amount of turns to turn the input into the outputs + * @param turns Amount of turns to turn the input into the output, with turns > 0. + * */ - void addRecipe( ItemStack in, ItemStack out, ItemStack optional, float chance, ItemStack optional2, float chance2, int turns ); + void addRecipe( @Nonnull ItemStack in, @Nonnull ItemStack out, @Nonnull ItemStack optional, float chance, @Nonnull ItemStack optional2, float chance2, int turns ); + + /** + * Remove the specific from the recipe list. + * + * @param recipe The recipe to be removed. + * @return true, if it was removed + */ + boolean removeRecipe( @Nonnull IGrinderRecipe recipe ); /** * Searches for a recipe for a given input, and returns it. * - * @param input input + * @param input The {@link ItemStack} to be grinded. * * @return identified recipe or null */ - IGrinderEntry getRecipeForInput( ItemStack input ); + @Nullable + IGrinderRecipe getRecipeForInput( @Nonnull ItemStack input ); + + /** + * Allows do add a custom ratio from an ore to dust when being grinded. + * + * The default ratio is 1 ore to 2 dusts. + * + * These have to be added before any recipe is registered. Otherwise it will use the default value. + * + * @param oredictName The name of the ore; + * @param ratio The amount, must be > 0; + */ + void addDustRatio( @Nonnull String oredictName, int ratio ); + + /** + * Remove a custom ratio for a specific ore name. + * + * Will use the default of 2 value afterwards. + * + * @param oredictName The name of the ore; + */ + boolean removeDustRatio( @Nonnull String oredictName ); + } diff --git a/src/main/java/appeng/core/AEConfig.java b/src/main/java/appeng/core/AEConfig.java index ebef88b0..1fac9c96 100644 --- a/src/main/java/appeng/core/AEConfig.java +++ b/src/main/java/appeng/core/AEConfig.java @@ -24,8 +24,11 @@ import java.util.Arrays; import java.util.Collection; import java.util.EnumSet; import java.util.List; +import java.util.Set; import java.util.stream.Stream; +import com.google.common.collect.Sets; + import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.config.Configuration; import net.minecraftforge.common.config.Property; @@ -99,6 +102,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject // Grindstone private String[] grinderOres = Stream.of( ORES_VANILLA, ORES_AE, ORES_COMMON, ORES_MISC ).flatMap( Stream::of ).toArray( String[]::new ); + private Set grinderBlackList; private double oreDoublePercentage = 90.0; // Batteries @@ -153,8 +157,16 @@ public final class AEConfig extends Configuration implements IConfigurableObject this.removeCrashingItemsOnLoad = this.get( "general", "removeCrashingItemsOnLoad", false, "Will auto-remove items that crash when being loaded from storage. This will destroy those items instead of crashing the game!" ).getBoolean(); - this.grinderOres = this.get( "GrindStone", "grinderOres", this.grinderOres ).getStringList(); - this.oreDoublePercentage = this.get( "GrindStone", "oreDoublePercentage", this.oreDoublePercentage ).getDouble( this.oreDoublePercentage ); + this.setCategoryComment( "GrindStone", + "Creates recipe of the following pattern automatically: '1 oreTYPE => 2 dustTYPE' and '(1 ingotTYPE or 1 crystalTYPE or 1 gemTYPE) => 1 dustTYPE'" ); + this.grinderOres = this.get( "GrindStone", "grinderOres", this.grinderOres, "The list of types to handle. Specify without a prefix like ore or dust." ) + .getStringList(); + this.grinderBlackList = Sets.newHashSet( + this.get( "GrindStone", "blacklist", new String[] {}, "Blacklists the exact oredict name from being handled by any recipe." ) + .getStringList() ); + this.oreDoublePercentage = this + .get( "GrindStone", "oreDoublePercentage", this.oreDoublePercentage, "Chance to actually get an output with stacksize > 1." ) + .getDouble( this.oreDoublePercentage ); this.settings.registerSetting( Settings.SEARCH_TOOLTIPS, YesNo.YES ); this.settings.registerSetting( Settings.TERMINAL_STYLE, TerminalStyle.TALL ); @@ -632,6 +644,11 @@ public final class AEConfig extends Configuration implements IConfigurableObject return grinderOres; } + public Set getGrinderBlackList() + { + return this.grinderBlackList; + } + public double getOreDoublePercentage() { return oreDoublePercentage; diff --git a/src/main/java/appeng/core/AELog.java b/src/main/java/appeng/core/AELog.java index 1de2d033..217e4ba4 100644 --- a/src/main/java/appeng/core/AELog.java +++ b/src/main/java/appeng/core/AELog.java @@ -290,11 +290,11 @@ public final class AELog * * @param message String to be logged */ - public static void grinder( @Nonnull final String message ) + public static void grinder( @Nonnull final String message, final Object... params ) { if( AEConfig.instance().isFeatureEnabled( AEFeature.GRINDER_LOGGING ) ) { - log( Level.DEBUG, "grinder: " + message ); + log( Level.DEBUG, "grinder: " + message, params ); } } diff --git a/src/main/java/appeng/core/features/registries/GrinderRecipeManager.java b/src/main/java/appeng/core/features/registries/GrinderRecipeManager.java index 57d995af..adcdd034 100644 --- a/src/main/java/appeng/core/features/registries/GrinderRecipeManager.java +++ b/src/main/java/appeng/core/features/registries/GrinderRecipeManager.java @@ -19,17 +19,20 @@ package appeng.core.features.registries; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; +import java.util.Collection; +import java.util.Collections; import java.util.Map; import java.util.Map.Entry; +import com.google.common.base.Preconditions; +import com.google.common.collect.Maps; + import net.minecraft.init.Blocks; import net.minecraft.init.Items; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import appeng.api.features.IGrinderEntry; +import appeng.api.features.IGrinderRecipe; import appeng.api.features.IGrinderRegistry; import appeng.core.AEConfig; import appeng.core.AELog; @@ -41,17 +44,23 @@ import appeng.util.Platform; public final class GrinderRecipeManager implements IGrinderRegistry, IOreListener { - private final List recipes; + private final Map recipes; private final Map ores; private final Map ingots; private final Map dusts; + private final Map dustToOreRatio; public GrinderRecipeManager() { - this.recipes = new ArrayList(); - this.ores = new HashMap(); - this.ingots = new HashMap(); - this.dusts = new HashMap(); + this.recipes = Maps.newHashMap(); + this.ores = Maps.newHashMap(); + this.ingots = Maps.newHashMap(); + this.dusts = Maps.newHashMap(); + this.dustToOreRatio = Maps.newHashMap(); + + this.addDustRatio( "Obsidian", 1 ); + this.addDustRatio( "Charcoal", 1 ); + this.addDustRatio( "Coal", 1 ); this.addOre( "Coal", new ItemStack( Items.COAL ) ); this.addOre( "Charcoal", new ItemStack( Items.COAL, 1, 1 ) ); @@ -76,62 +85,147 @@ public final class GrinderRecipeManager implements IGrinderRegistry, IOreListene } @Override - public List getRecipes() + public Collection getRecipes() { - this.log( "API - getRecipes" ); - return this.recipes; + return Collections.unmodifiableCollection( this.recipes.values() ); } @Override public void addRecipe( final ItemStack in, final ItemStack out, final int cost ) { - if( in == null || out == null ) - { - this.log( "Invalid Grinder Recipe Specified." ); - return; - } + Preconditions.checkNotNull( in, "Null is not accepted as input itemstack." ); + Preconditions.checkNotNull( out, "Null is not accepted as output itemstack." ); + Preconditions.checkArgument( cost > 0, "Turns must be > 0" ); + + this.log( "Allow Grinding of '%1$s' to '%2$s' for %3$d turn", Platform.getItemDisplayName( in ), Platform.getItemDisplayName( out ), cost ); - this.log( "Allow Grinding of " + Platform.getItemDisplayName( in ) + " to " + Platform.getItemDisplayName( out ) + " for " + cost ); this.injectRecipe( new AppEngGrinderRecipe( this.copy( in ), this.copy( out ), cost ) ); } @Override public void addRecipe( final ItemStack in, final ItemStack out, final ItemStack optional, final float chance, final int cost ) { - if( in == null || ( optional == null && out == null ) ) - { - this.log( "Invalid Grinder Recipe Specified." ); - return; - } + Preconditions.checkNotNull( in, "Null is not accepted as input itemstack." ); + Preconditions.checkNotNull( out, "Null is not accepted as output itemstack." ); + Preconditions.checkNotNull( optional, "Null is not accepted as optional itemstack." ); + Preconditions.checkArgument( chance >= 0.0 && chance <= 1.0, "chance must be within 0.0 - 1.0." ); + Preconditions.checkArgument( cost > 0, "Turns must be > 0" ); + + this.log( "Allow Grinding of '%1$s' to '%2$s' with optional '%3$s' @ %4$.2f for %5$d", Platform.getItemDisplayName( in ), + Platform.getItemDisplayName( out ), Platform.getItemDisplayName( optional ), chance, cost ); - this.log( "Allow Grinding of " + Platform.getItemDisplayName( in ) + " to " + Platform.getItemDisplayName( out ) + " with optional " + Platform.getItemDisplayName( optional ) + " for " + cost ); this.injectRecipe( new AppEngGrinderRecipe( this.copy( in ), this.copy( out ), this.copy( optional ), chance, cost ) ); } @Override - public void addRecipe( final ItemStack in, final ItemStack out, final ItemStack optional, final float chance, final ItemStack optional2, final float chance2, final int cost ) + public void addRecipe( final ItemStack in, final ItemStack out, final ItemStack optional1, final float chance1, final ItemStack optional2, final float chance2, final int cost ) { - if( in == null || ( optional == null && out == null && optional2 == null ) ) + Preconditions.checkNotNull( in, "Null is not accepted as input itemstack." ); + Preconditions.checkNotNull( out, "Null is not accepted as output itemstack." ); + Preconditions.checkNotNull( optional1, "Null is not accepted as optional itemstack." ); + Preconditions.checkArgument( chance1 >= 0.0 && chance1 <= 1.0, "chance must be within 0.0 - 1.0." ); + Preconditions.checkNotNull( optional2, "Null is not accepted as optional2 itemstack." ); + Preconditions.checkArgument( chance2 >= 0.0 && chance2 <= 1.0, "chance2 must be within 0.0 - 1.0." ); + Preconditions.checkArgument( cost > 0, "Turns must be > 0" ); + + this.log( "Allow Grinding of '%1$s' to '%2$s' with optional '%3$s' @ %4$.2f and optional2 '%5$s' @ %6$.2f for %7$d", Platform.getItemDisplayName( in ), + Platform.getItemDisplayName( out ), Platform.getItemDisplayName( optional1 ), chance1, Platform.getItemDisplayName( optional2 ), chance2, + cost ); + + this.injectRecipe( + new AppEngGrinderRecipe( this.copy( in ), this.copy( out ), this.copy( optional1 ), this.copy( optional2 ), chance1, chance2, cost ) ); + } + + @Override + public boolean removeRecipe( IGrinderRecipe recipe ) + { + Preconditions.checkNotNull( recipe, "Cannot remove null as recipe." ); + + final CacheKey key = new CacheKey( recipe.getInput() ); + final IGrinderRecipe removedRecipe = this.recipes.remove( key ); + + this.log( "Removed Grinding of '%1%s'", Platform.getItemDisplayName( recipe.getInput() ) ); + + return removedRecipe != null; + } + + @Override + public IGrinderRecipe getRecipeForInput( final ItemStack input ) + { + this.log( "Looking up recipe for '%1$s'", Platform.getItemDisplayName( input ) ); + + if( input == null ) { - this.log( "Invalid Grinder Recipe Specified." ); - return; + return null; } - this.log( "Allow Grinding of " + Platform.getItemDisplayName( in ) + " to " + Platform.getItemDisplayName( out ) + " with optional " + Platform.getItemDisplayName( optional ) + " for " + cost ); - this.injectRecipe( new AppEngGrinderRecipe( this.copy( in ), this.copy( out ), this.copy( optional ), this.copy( optional2 ), chance, chance2, cost ) ); + final IGrinderRecipe recipe = this.recipes.get( new CacheKey( input ) ); + + if( recipe == null ) + { + return null; + } + + this.log( "Recipe for '%1$s' found '%2$s'", input.getUnlocalizedName(), Platform.getItemDisplayName( recipe.getOutput() ) ); + return recipe; + } + + @Override + public void addDustRatio( String oredictName, int ratio ) + { + Preconditions.checkNotNull( oredictName ); + Preconditions.checkArgument( ratio > 0 ); + + this.log( "Added ratio for '%1$s' of %2$d", oredictName, ratio ); + + this.dustToOreRatio.put( oredictName, ratio ); + } + + @Override + public boolean removeDustRatio( String oredictName ) + { + Preconditions.checkNotNull( oredictName ); + + this.log( "Removed ratio for '%1$s'", oredictName ); + + return this.dustToOreRatio.remove( oredictName ) != null; + } + + @Override + public void oreRegistered( final String name, final ItemStack item ) + { + if( !AEConfig.instance().getGrinderBlackList().contains( name ) && ( name.startsWith( "ore" ) || name.startsWith( "crystal" ) || name + .startsWith( "gem" ) || name.startsWith( "ingot" ) || name.startsWith( "dust" ) ) ) + { + for( final String ore : AEConfig.instance().getGrinderOres() ) + { + if( name.equals( "ore" + ore ) ) + { + this.addOre( ore, item ); + } + else if( name.equals( "crystal" + ore ) || name.equals( "ingot" + ore ) || name.equals( "gem" + ore ) ) + { + this.addIngot( ore, item ); + } + else if( name.equals( "dust" + ore ) ) + { + this.addDust( ore, item ); + } + } + } } private void injectRecipe( final AppEngGrinderRecipe appEngGrinderRecipe ) { - for( final IGrinderEntry gr : this.recipes ) + final CacheKey cacheKey = new CacheKey( appEngGrinderRecipe.getInput() ); + + if( this.recipes.containsKey( cacheKey ) ) { - if( Platform.itemComparisons().isSameItem( gr.getInput(), appEngGrinderRecipe.getInput() ) ) - { - return; - } + this.log( "Tried to add duplicate recipe for '%1$s'", Platform.getItemDisplayName( appEngGrinderRecipe.getInput() ) ); + return; } - this.recipes.add( appEngGrinderRecipe ); + this.recipes.put( cacheKey, appEngGrinderRecipe ); } private ItemStack copy( final ItemStack is ) @@ -143,47 +237,9 @@ public final class GrinderRecipeManager implements IGrinderRegistry, IOreListene return null; } - @Override - public IGrinderEntry getRecipeForInput( final ItemStack input ) - { - this.log( "Looking up recipe for " + Platform.getItemDisplayName( input ) ); - if( input != null ) - { - for( final IGrinderEntry r : this.recipes ) - { - if( Platform.itemComparisons().isEqualItem( input, r.getInput() ) ) - { - this.log( "Recipe for " + input.getUnlocalizedName() + " found " + Platform.getItemDisplayName( r.getOutput() ) ); - return r; - } - } - - this.log( "Could not find recipe for " + Platform.getItemDisplayName( input ) ); - } - - return null; - } - - private void log( final String o ) - { - AELog.grinder( o ); - } - private int getDustToOreRatio( final String name ) { - if( name.equals( "Obsidian" ) ) - { - return 1; - } - if( name.equals( "Charcoal" ) ) - { - return 1; - } - if( name.equals( "Coal" ) ) - { - return 1; - } - return 2; + return this.dustToOreRatio.getOrDefault( name, 2 ); } private void addOre( final String name, final ItemStack item ) @@ -192,7 +248,7 @@ public final class GrinderRecipeManager implements IGrinderRegistry, IOreListene { return; } - this.log( "Adding Ore - " + name + " : " + Platform.getItemDisplayName( item ) ); + this.log( "Adding Ore: '%1$s'", Platform.getItemDisplayName( item ) ); this.ores.put( item, name ); @@ -219,7 +275,7 @@ public final class GrinderRecipeManager implements IGrinderRegistry, IOreListene { return; } - this.log( "Adding Ingot - " + name + " : " + Platform.getItemDisplayName( item ) ); + this.log( "Adding Ingot: '%1$s'", Platform.getItemDisplayName( item ) ); this.ingots.put( item, name ); @@ -237,11 +293,11 @@ public final class GrinderRecipeManager implements IGrinderRegistry, IOreListene } if( this.dusts.containsKey( name ) ) { - this.log( "Rejecting Dust - " + name + " : " + Platform.getItemDisplayName( item ) ); + this.log( "Rejecting Dust: '%1$s'", Platform.getItemDisplayName( item ) ); return; } - this.log( "Adding Dust - " + name + " : " + Platform.getItemDisplayName( item ) ); + this.log( "Adding Dust: '%1$s'", Platform.getItemDisplayName( item ) ); this.dusts.put( name, item ); @@ -274,26 +330,68 @@ public final class GrinderRecipeManager implements IGrinderRegistry, IOreListene } } - @Override - public void oreRegistered( final String name, final ItemStack item ) + private void log( final String o, Object... params ) { - if( name.startsWith( "ore" ) || name.startsWith( "crystal" ) || name.startsWith( "gem" ) || name.startsWith( "ingot" ) || name.startsWith( "dust" ) ) + AELog.grinder( o, params ); + } + + private static class CacheKey + { + private final Item item; + private final int damage; + + CacheKey( ItemStack input ) { - for( final String ore : AEConfig.instance().getGrinderOres() ) + Preconditions.checkNotNull( input ); + Preconditions.checkNotNull( input.getItem() ); + + this.item = input.getItem(); + this.damage = input.getItemDamage(); + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + damage; + result = prime * result + ( ( item == null ) ? 0 : item.hashCode() ); + return result; + } + + @Override + public boolean equals( Object obj ) + { + if( this == obj ) { - if( name.equals( "ore" + ore ) ) + return true; + } + if( obj == null || getClass() != obj.getClass() ) + { + return false; + } + + CacheKey other = (CacheKey) obj; + + if( damage != other.damage ) + { + return false; + } + + if( item == null ) + { + if( other.item != null ) { - this.addOre( ore, item ); - } - else if( name.equals( "crystal" + ore ) || name.equals( "ingot" + ore ) || name.equals( "gem" + ore ) ) - { - this.addIngot( ore, item ); - } - else if( name.equals( "dust" + ore ) ) - { - this.addDust( ore, item ); + return false; } } + else if( item != other.item ) + { + return false; + } + + return true; } + } } diff --git a/src/main/java/appeng/core/features/registries/entries/AppEngGrinderRecipe.java b/src/main/java/appeng/core/features/registries/entries/AppEngGrinderRecipe.java index 67d96612..9d615b72 100644 --- a/src/main/java/appeng/core/features/registries/entries/AppEngGrinderRecipe.java +++ b/src/main/java/appeng/core/features/registries/entries/AppEngGrinderRecipe.java @@ -19,55 +19,49 @@ package appeng.core.features.registries.entries; +import java.util.Optional; + import net.minecraft.item.ItemStack; -import appeng.api.features.IGrinderEntry; +import appeng.api.features.IGrinderRecipe; -public class AppEngGrinderRecipe implements IGrinderEntry +public class AppEngGrinderRecipe implements IGrinderRecipe { - private ItemStack in; - private ItemStack out; + private final ItemStack in; + private final ItemStack out; - private float optionalChance; - private ItemStack optionalOutput; + private final float optionalChance; + private final Optional optionalOutput; - private float optionalChance2; - private ItemStack optionalOutput2; + private final float optionalChance2; + private final Optional optionalOutput2; - private int energy; + private final int turns; - public AppEngGrinderRecipe( final ItemStack a, final ItemStack b, final int cost ) + public AppEngGrinderRecipe( final ItemStack input, final ItemStack output, final int cost ) { - this.in = a; - this.out = b; - this.energy = cost; + this( input, output, null, null, 0, 0, cost ); } - public AppEngGrinderRecipe( final ItemStack a, final ItemStack b, final ItemStack c, final float chance, final int cost ) + public AppEngGrinderRecipe( final ItemStack input, final ItemStack output, final ItemStack optional, final float chance, final int cost ) { - this.in = a; - this.out = b; - - this.optionalOutput = c; - this.optionalChance = chance; - - this.energy = cost; + this( input, output, optional, null, chance, 0, cost ); } - public AppEngGrinderRecipe( final ItemStack a, final ItemStack b, final ItemStack c, final ItemStack d, final float chance, final float chance2, final int cost ) + public AppEngGrinderRecipe( final ItemStack input, final ItemStack output, final ItemStack optional1, final ItemStack optional2, final float chance1, final float chance2, final int cost ) { - this.in = a; - this.out = b; + this.in = input; + this.out = output; - this.optionalOutput = c; - this.optionalChance = chance; + this.optionalOutput = Optional.ofNullable( optional1 ); + this.optionalChance = chance1; - this.optionalOutput2 = d; + this.optionalOutput2 = Optional.ofNullable( optional2 ); this.optionalChance2 = chance2; - this.energy = cost; + this.turns = cost; } @Override @@ -76,12 +70,6 @@ public class AppEngGrinderRecipe implements IGrinderEntry return this.in; } - @Override - public void setInput( final ItemStack i ) - { - this.in = i.copy(); - } - @Override public ItemStack getOutput() { @@ -89,43 +77,23 @@ public class AppEngGrinderRecipe implements IGrinderEntry } @Override - public void setOutput( final ItemStack o ) - { - this.out = o.copy(); - } - - @Override - public ItemStack getOptionalOutput() + public Optional getOptionalOutput() { return this.optionalOutput; } @Override - public ItemStack getSecondOptionalOutput() + public Optional getSecondOptionalOutput() { return this.optionalOutput2; } - @Override - public void setOptionalOutput( final ItemStack output, final float chance ) - { - this.optionalOutput = output.copy(); - this.optionalChance = chance; - } - @Override public float getOptionalChance() { return this.optionalChance; } - @Override - public void setSecondOptionalOutput( final ItemStack output, final float chance ) - { - this.optionalChance2 = chance; - this.optionalOutput2 = output.copy(); - } - @Override public float getSecondOptionalChance() { @@ -133,14 +101,8 @@ public class AppEngGrinderRecipe implements IGrinderEntry } @Override - public int getEnergyCost() + public int getRequiredTurns() { - return this.energy; - } - - @Override - public void setEnergyCost( final int c ) - { - this.energy = c; + return this.turns; } } diff --git a/src/main/java/appeng/integration/modules/jei/GrinderRecipeHandler.java b/src/main/java/appeng/integration/modules/jei/GrinderRecipeHandler.java index 6d1721dc..8b499e4b 100644 --- a/src/main/java/appeng/integration/modules/jei/GrinderRecipeHandler.java +++ b/src/main/java/appeng/integration/modules/jei/GrinderRecipeHandler.java @@ -22,16 +22,16 @@ package appeng.integration.modules.jei; import mezz.jei.api.recipe.IRecipeHandler; import mezz.jei.api.recipe.IRecipeWrapper; -import appeng.api.features.IGrinderEntry; +import appeng.api.features.IGrinderRecipe; -class GrinderRecipeHandler implements IRecipeHandler +class GrinderRecipeHandler implements IRecipeHandler { @Override - public Class getRecipeClass() + public Class getRecipeClass() { - return IGrinderEntry.class; + return IGrinderRecipe.class; } @Override @@ -41,19 +41,19 @@ class GrinderRecipeHandler implements IRecipeHandler } @Override - public String getRecipeCategoryUid( IGrinderEntry recipe ) + public String getRecipeCategoryUid( IGrinderRecipe recipe ) { return GrinderRecipeCategory.UID; } @Override - public IRecipeWrapper getRecipeWrapper( IGrinderEntry recipe ) + public IRecipeWrapper getRecipeWrapper( IGrinderRecipe recipe ) { return new GrinderRecipeWrapper( recipe ); } @Override - public boolean isRecipeValid( IGrinderEntry recipe ) + public boolean isRecipeValid( IGrinderRecipe recipe ) { return true; } diff --git a/src/main/java/appeng/integration/modules/jei/GrinderRecipeWrapper.java b/src/main/java/appeng/integration/modules/jei/GrinderRecipeWrapper.java index 6b60f998..78fe8f90 100644 --- a/src/main/java/appeng/integration/modules/jei/GrinderRecipeWrapper.java +++ b/src/main/java/appeng/integration/modules/jei/GrinderRecipeWrapper.java @@ -31,15 +31,15 @@ import net.minecraft.item.ItemStack; import mezz.jei.api.ingredients.IIngredients; import mezz.jei.api.recipe.BlankRecipeWrapper; -import appeng.api.features.IGrinderEntry; +import appeng.api.features.IGrinderRecipe; class GrinderRecipeWrapper extends BlankRecipeWrapper { - private final IGrinderEntry recipe; + private final IGrinderRecipe recipe; - GrinderRecipeWrapper( IGrinderEntry recipe ) + GrinderRecipeWrapper( IGrinderRecipe recipe ) { this.recipe = recipe; } @@ -50,14 +50,8 @@ class GrinderRecipeWrapper extends BlankRecipeWrapper ingredients.setInput( ItemStack.class, recipe.getInput() ); List outputs = new ArrayList<>( 3 ); outputs.add( recipe.getOutput() ); - if( recipe.getOptionalOutput() != null ) - { - outputs.add( recipe.getOptionalOutput() ); - } - if( recipe.getSecondOptionalOutput() != null ) - { - outputs.add( recipe.getSecondOptionalOutput() ); - } + recipe.getOptionalOutput().ifPresent( outputs::add ); + recipe.getSecondOptionalOutput().ifPresent( outputs::add ); ingredients.setOutputs( ItemStack.class, outputs ); } diff --git a/src/main/java/appeng/integration/modules/jei/JEIPlugin.java b/src/main/java/appeng/integration/modules/jei/JEIPlugin.java index bf8a4dac..e0f8f2b2 100644 --- a/src/main/java/appeng/integration/modules/jei/JEIPlugin.java +++ b/src/main/java/appeng/integration/modules/jei/JEIPlugin.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Optional; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -70,8 +71,10 @@ public class JEIPlugin extends BlankModPlugin registerDescriptions( definitions, registry ); // Allow recipe transfer from JEI to crafting and pattern terminal - registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerCraftingTerm.class ), VanillaRecipeCategoryUid.CRAFTING ); - registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ), VanillaRecipeCategoryUid.CRAFTING ); + registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerCraftingTerm.class ), + VanillaRecipeCategoryUid.CRAFTING ); + registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ), + VanillaRecipeCategoryUid.CRAFTING ); } private void registerDescriptions( IDefinitions definitions, IModRegistry registry ) @@ -130,7 +133,7 @@ public class JEIPlugin extends BlankModPlugin return; } - registry.addRecipes( AEApi.instance().registries().grinder().getRecipes() ); + registry.addRecipes( Lists.newArrayList( AEApi.instance().registries().grinder().getRecipes() ) ); registry.addRecipeHandlers( new GrinderRecipeHandler() ); registry.addRecipeCategories( new GrinderRecipeCategory( registry.getJeiHelpers().getGuiHelper() ) ); registry.addRecipeCategoryCraftingItem( grindstone, GrinderRecipeCategory.UID ); diff --git a/src/main/java/appeng/tile/grindstone/TileGrinder.java b/src/main/java/appeng/tile/grindstone/TileGrinder.java index ac152ede..0d0bee0e 100644 --- a/src/main/java/appeng/tile/grindstone/TileGrinder.java +++ b/src/main/java/appeng/tile/grindstone/TileGrinder.java @@ -28,7 +28,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; import appeng.api.AEApi; -import appeng.api.features.IGrinderEntry; +import appeng.api.features.IGrinderRecipe; import appeng.api.implementations.tiles.ICrankable; import appeng.tile.AEBaseInvTile; import appeng.tile.inventory.AppEngInternalInventory; @@ -108,7 +108,7 @@ public class TileGrinder extends AEBaseInvTile implements ICrankable continue; } - final IGrinderEntry r = AEApi.instance().registries().grinder().getRecipeForInput( item ); + final IGrinderRecipe r = AEApi.instance().registries().grinder().getRecipeForInput( item ); if( r != null ) { if( item.stackSize >= r.getInput().stackSize ) @@ -144,10 +144,10 @@ public class TileGrinder extends AEBaseInvTile implements ICrankable this.points++; final ItemStack processing = this.getStackInSlot( 6 ); - final IGrinderEntry r = AEApi.instance().registries().grinder().getRecipeForInput( processing ); + final IGrinderRecipe r = AEApi.instance().registries().grinder().getRecipeForInput( processing ); if( r != null ) { - if( r.getEnergyCost() > this.points ) + if( r.getRequiredTurns() > this.points ) { return; } @@ -157,17 +157,25 @@ public class TileGrinder extends AEBaseInvTile implements ICrankable this.addItem( sia, r.getOutput() ); - float chance = ( Platform.getRandomInt() % 2000 ) / 2000.0f; - if( chance <= r.getOptionalChance() ) + r.getOptionalOutput().ifPresent( itemStack -> { - this.addItem( sia, r.getOptionalOutput() ); - } + final float chance = ( Platform.getRandomInt() % 2000 ) / 2000.0f; - chance = ( Platform.getRandomInt() % 2000 ) / 2000.0f; - if( chance <= r.getSecondOptionalChance() ) + if( chance <= r.getOptionalChance() ) + { + this.addItem( sia, itemStack ); + } + } ); + + r.getSecondOptionalOutput().ifPresent( itemStack -> { - this.addItem( sia, r.getSecondOptionalOutput() ); - } + final float chance = ( Platform.getRandomInt() % 2000 ) / 2000.0f; + + if( chance <= r.getSecondOptionalChance() ) + { + this.addItem( sia, itemStack ); + } + } ); this.setInventorySlotContents( 6, null ); }