diff --git a/gradle/scripts/dependencies.gradle b/gradle/scripts/dependencies.gradle index dc21c0dbe..693942a09 100644 --- a/gradle/scripts/dependencies.gradle +++ b/gradle/scripts/dependencies.gradle @@ -80,6 +80,7 @@ configurations { } dependencies { + compileOnly "gregtechce:gregtech:1.12.2:1.15.1.735" // installable runtime dependencies mods "mcp.mobius.waila:Hwyla:${hwyla_version}" mods "net.industrial-craft:industrialcraft-2:${ic2_version}:dev" diff --git a/src/main/java/appeng/client/gui/implementations/GuiPartOreDictStorageBus.java b/src/main/java/appeng/client/gui/implementations/GuiPartOreDictStorageBus.java index 298b77cf9..10ac22ff9 100644 --- a/src/main/java/appeng/client/gui/implementations/GuiPartOreDictStorageBus.java +++ b/src/main/java/appeng/client/gui/implementations/GuiPartOreDictStorageBus.java @@ -13,6 +13,7 @@ import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.packets.PacketSwitchGuis; import appeng.core.sync.packets.PacketValueConfig; import appeng.parts.misc.PartOreDicStorageBus; +import appeng.util.item.OreDictFilterMatcher; import net.minecraft.client.gui.GuiButton; import net.minecraft.entity.player.InventoryPlayer; @@ -26,7 +27,7 @@ public class GuiPartOreDictStorageBus extends AEBaseGui private GuiTabButton priority; private GuiImgButton partition; - private static final Pattern ORE_DICTIONARY_FILTER = Pattern.compile( "\\*?[a-zA-Z0-9_|\\\\+(){,}?!=\\-\\[:\\]&^$]*\\*?" ); + private static final Pattern ORE_DICTIONARY_FILTER = Pattern.compile( "[(!]* *[0-9a-zA-Z*]* *\\)*( *[&|^]? *[(!]* *[0-9a-zA-Z*]* *\\)*)*" ); private MEGuiTextField searchFieldInputs; public GuiPartOreDictStorageBus( final InventoryPlayer inventoryPlayer, final PartOreDicStorageBus te ) @@ -103,6 +104,7 @@ public class GuiPartOreDictStorageBus extends AEBaseGui if( !searchFieldInputs.isFocused() && wasFocused ) { + searchFieldInputs.setText( OreDictFilterMatcher.validateExp( searchFieldInputs.getText() ) ); NetworkHandler.instance().sendToServer( new PacketValueConfig( "OreDictStorageBus.save", searchFieldInputs.getText() ) ); } @@ -125,8 +127,11 @@ public class GuiPartOreDictStorageBus extends AEBaseGui public void drawFG( int offsetX, int offsetY, int mouseX, int mouseY ) { this.fontRenderer.drawString( this.getGuiDisplayName( GuiText.OreDictStorageBus.getLocal() ), 8, 6, 4210752 ); - this.fontRenderer.drawString( this.searchFieldInputs.getText().length() + " / " + this.searchFieldInputs.getMaxStringLength(), 8, 36, 4210752 ); - this.fontRenderer.drawSplitString( "Supports regex. Or use * as a wildcard", 6, 48, 174, 4210752 ); + this.fontRenderer.drawString( this.searchFieldInputs.getText().length() + " / " + this.searchFieldInputs.getMaxStringLength(), 120, 36, 4210752 ); + this.fontRenderer.drawString( "& = AND " + "| = OR", 8, 36, 4210752 ); + this.fontRenderer.drawString( "^ = XOR " + "! = NOT", 8, 48, 4210752 ); + this.fontRenderer.drawString( "() for priority " + "* for wildcard", 8, 60, 4210752 ); + this.fontRenderer.drawString( "Ex.: *Redstone*&!dustRedstone", 8, 72, 4210752 ); } @Override diff --git a/src/main/java/appeng/container/implementations/ContainerPartOreDictStorageBus.java b/src/main/java/appeng/container/implementations/ContainerPartOreDictStorageBus.java index edba3f14d..a9c02c7c7 100644 --- a/src/main/java/appeng/container/implementations/ContainerPartOreDictStorageBus.java +++ b/src/main/java/appeng/container/implementations/ContainerPartOreDictStorageBus.java @@ -1,27 +1,18 @@ package appeng.container.implementations; import appeng.api.AEApi; -import appeng.api.config.AccessRestriction; -import appeng.api.config.FuzzyMode; -import appeng.api.config.Settings; -import appeng.api.config.StorageFilter; import appeng.api.storage.IMEInventory; import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.data.IAEItemStack; -import appeng.api.storage.data.IItemList; import appeng.container.AEBaseContainer; import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.packets.PacketValueConfig; import appeng.parts.misc.PartOreDicStorageBus; import appeng.util.Platform; -import appeng.util.helpers.ItemHandlerUtil; import appeng.util.item.AEItemStack; import appeng.util.item.OreReference; -import appeng.util.iterators.NullIterator; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.item.ItemStack; -import net.minecraftforge.items.IItemHandler; import net.minecraftforge.oredict.OreDictionary; import java.io.IOException; @@ -103,7 +94,7 @@ public class ContainerPartOreDictStorageBus extends AEBaseContainer { try { - NetworkHandler.instance().sendTo( new PacketValueConfig( "OreDictStorageBus.sendRegex", part.getOreMatch() ), (EntityPlayerMP) getInventoryPlayer().player ); + NetworkHandler.instance().sendTo( new PacketValueConfig( "OreDictStorageBus.sendRegex", part.getOreExp() ), (EntityPlayerMP) getInventoryPlayer().player ); } catch( IOException e ) { diff --git a/src/main/java/appeng/parts/misc/PartOreDicStorageBus.java b/src/main/java/appeng/parts/misc/PartOreDicStorageBus.java index f38d1f209..4c02365de 100644 --- a/src/main/java/appeng/parts/misc/PartOreDicStorageBus.java +++ b/src/main/java/appeng/parts/misc/PartOreDicStorageBus.java @@ -40,8 +40,7 @@ public class PartOreDicStorageBus extends PartStorageBus @PartModels public static final IPartModel MODELS_HAS_CHANNEL = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_has_channel" ) ); - - public String oreMatch; + public String oreExp = ""; OreDictPriorityList priorityList; public PartOreDicStorageBus( ItemStack is ) @@ -53,15 +52,15 @@ public class PartOreDicStorageBus extends PartStorageBus public void readFromNBT( NBTTagCompound data ) { super.readFromNBT( data ); - this.oreMatch = data.getString( "oreMatch" ); - this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreMatch ), oreMatch ); + this.oreExp = data.getString( "oreMatch" ); + this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreExp ), oreExp ); } @Override public void writeToNBT( NBTTagCompound data ) { super.writeToNBT( data ); - data.setString( "oreMatch", getOreMatch() ); + data.setString( "oreMatch", getOreExp() ); } @Override @@ -172,21 +171,22 @@ public class PartOreDicStorageBus extends PartStorageBus return this.handler; } - public String getOreMatch() + public String getOreExp() { - if( this.oreMatch == null ) + if( this.oreExp == null ) { return ""; } - return oreMatch; + return oreExp; } public void saveOreMatch( String oreMatch ) { - if( !this.oreMatch.equals( oreMatch ) ) + if( !this.oreExp.equals( oreMatch ) ) { - this.oreMatch = oreMatch; - this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreMatch ), oreMatch ); + this.oreExp = oreMatch; + + this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreExp ), oreExp ); if( this.handler != null ) { handler.setPartitionList( this.priorityList ); diff --git a/src/main/java/appeng/util/item/OreDictFilterMatcher.java b/src/main/java/appeng/util/item/OreDictFilterMatcher.java new file mode 100644 index 000000000..62b80a661 --- /dev/null +++ b/src/main/java/appeng/util/item/OreDictFilterMatcher.java @@ -0,0 +1,383 @@ +package appeng.util.item; + +import java.util.ArrayList; +import java.util.List; + + +/** + * @author brachy84 + * @butcherer PrototypeTrousers + */ +public class OreDictFilterMatcher +{ + + /** + * Parses the given expression and creates a List. + * + * @param expression expr to parse + * @return match rule list + */ + public static List parseExpression( String expression ) + { + List rules = new ArrayList<>(); + parseExpression( rules, expression ); + return rules; + } + + /** + * Parses the given expression and puts them into the given list. + * + * @param rules list to fill + * @param expression expr to parse + * @return the position of the expr. Is only relevant for sub rules + */ + public static int parseExpression( List rules, String expression ) + { + rules.clear(); + + StringBuilder builder = new StringBuilder(); + for( int i = 0; i < expression.length(); i++ ) + { + char c = expression.charAt( i ); + if( c == ' ' ) + { + continue; + } + if( c == '(' ) + { + List subRules = new ArrayList<>(); + i = parseExpression( subRules, expression.substring( i + 1 ) ) + i + 1; + rules.add( MatchRule.group( subRules, builder.toString() ) ); + builder = new StringBuilder(); + } + else + { + switch ( c ) + { + case '&': + rules.add( new MatchRule( builder.toString() ) ); + rules.add( new MatchRule( MatchLogic.AND ) ); + builder = new StringBuilder(); + break; + case '|': + rules.add( new MatchRule( builder.toString() ) ); + rules.add( new MatchRule( MatchLogic.OR ) ); + builder = new StringBuilder(); + break; + case '^': + rules.add( new MatchRule( builder.toString() ) ); + rules.add( new MatchRule( MatchLogic.XOR ) ); + builder = new StringBuilder(); + break; + case ')': + rules.add( new MatchRule( builder.toString() ) ); + return i + 1; + default: + builder.append( c ); + } + } + } + if( builder.length() > 0 ) + { + rules.add( new MatchRule( builder.toString() ) ); + } + return expression.length(); + } + + /** + * Matches the given string against a list of rules. + * The string does not have to be an oreDict. + * + * @param rules to check against + * @param oreDict string to check + * @return if the string matches the rules + */ + public static boolean matches( List rules, String oreDict ) + { + boolean first = true; + boolean lastResult = false; + MatchLogic lastLogic = null; + for( MatchRule rule : rules ) + { + if( lastLogic == null ) + { + if( rule.logic == MatchLogic.AND || rule.logic == MatchLogic.OR || rule.logic == MatchLogic.XOR ) + { + lastLogic = rule.logic; + continue; + } + } + if( lastLogic != null || first ) + { + if( lastLogic != null ) + { + switch ( lastLogic ) + { + case AND: + { + if( !lastResult ) + { + return false; + } + break; + } + case OR: + { + if( lastResult ) + { + return true; + } + break; + } + } + } + + boolean newResult; + if( rule.isGroup() ) + { + newResult = rule.logic == MatchLogic.NOT ^ matches( rule.subRules, oreDict ); + } + else + { + newResult = matches( rule, oreDict ); + } + + if( lastLogic == MatchLogic.XOR ) + { + if( lastResult == newResult ) + { + return false; + } + } + + lastLogic = null; + lastResult = newResult; + first = false; + } + + } + + return lastResult; + } + + private static boolean matches( MatchRule rule, String oreDict ) + { + String filter = rule.expression; + + if( filter.equals( "*" ) ) + { + return true; + } + + boolean startWild = filter.startsWith( "*" ), endWild = filter.endsWith( "*" ); + if( startWild ) + { + filter = filter.substring( 1 ); + } + + String[] parts = filter.split( "\\*+" ); + + return ( rule.logic == MatchLogic.NOT ) ^ matches( parts, oreDict, startWild, endWild ); + } + + private static boolean matches( String[] filter, String oreDict, boolean startWild, boolean endWild ) + { + String lastlastPart = filter[0]; + String lastPart = filter[0]; + int index = oreDict.indexOf( lastPart ); + if( ( !startWild && index != 0 ) || index < 0 ) + { + return false; + } + boolean didGoBack = false; + + for( int i = 1; i < filter.length; i++ ) + { + String part = filter[i]; + int newIndex = oreDict.indexOf( part, index + lastPart.length() ); + if( newIndex < 0 ) + { + if( i > 1 && !didGoBack ) + { + i -= 2; + lastPart = lastlastPart; + didGoBack = true; + continue; + } + return false; + } + lastlastPart = lastPart; + lastPart = part; + index = newIndex; + if( didGoBack ) + { + didGoBack = false; + } + } + + if( endWild || lastPart.length() + index == oreDict.length() ) + { + return true; + } + + for( int i = filter.length - 1; i < filter.length; i++ ) + { + String part = filter[i]; + int newIndex = oreDict.indexOf( part, index + lastPart.length() ); + if( newIndex < 0 ) + { + if( i > 1 && !didGoBack ) + { + i -= 2; + lastPart = lastlastPart; + didGoBack = true; + continue; + } + return false; + } + lastlastPart = lastPart; + lastPart = part; + index = newIndex; + if( didGoBack ) + { + didGoBack = false; + } + } + return lastPart.length() + index == oreDict.length(); + } + + public static String validateExp( String input ) + { + // remove all operators that are double + input = input.replaceAll( "\\*{2,}", "*" ); + input = input.replaceAll( "&{2,}", "&" ); + input = input.replaceAll( "\\|{2,}", "|" ); + input = input.replaceAll( "!{2,}", "!" ); + input = input.replaceAll( "\\^{2,}", "^" ); + input = input.replaceAll( " {2,}", " " ); + // move ( and ) so it doesn't create invalid expressions f.e. xxx (& yyy) => xxx & (yyy) + // append or prepend ( and ) if the amount is not equal + StringBuilder builder = new StringBuilder(); + int unclosed = 0; + char last = ' '; + for( int i = 0; i < input.length(); i++ ) + { + char c = input.charAt( i ); + if( c == ' ' ) + { + if( last != '(' ) + { + builder.append( " " ); + } + continue; + } + if( c == '(' ) + { + unclosed++; + } + else if( c == ')' ) + { + unclosed--; + if( last == '&' || last == '|' || last == '^' ) + { + int l = builder.lastIndexOf( " " + last ); + int l2 = builder.lastIndexOf( "" + last ); + builder.insert( l == l2 - 1 ? l : l2, ")" ); + continue; + } + if( i > 0 && builder.charAt( builder.length() - 1 ) == ' ' ) + { + builder.deleteCharAt( builder.length() - 1 ); + } + } + else if( ( c == '&' || c == '|' || c == '^' ) && last == '(' ) + { + builder.deleteCharAt( builder.lastIndexOf( "(" ) ); + builder.append( c ).append( " (" ); + continue; + } + + builder.append( c ); + last = c; + } + if( unclosed > 0 ) + { + for( int i = 0; i < unclosed; i++ ) + { + builder.append( ")" ); + } + } + else if( unclosed < 0 ) + { + unclosed = -unclosed; + for( int i = 0; i < unclosed; i++ ) + { + builder.insert( 0, "(" ); + } + } + input = builder.toString(); + input = input.replaceAll( " {2,}", " " ); + return input; + } + + + public static class MatchRule + { + public final MatchLogic logic; + public final String expression; + private final List subRules; + + private MatchRule( MatchLogic logic, String expression, List subRules ) + { + if( expression.startsWith( "!" ) ) + { + logic = MatchLogic.NOT; + expression = expression.substring( 1 ); + } + this.logic = logic; + this.expression = expression; + this.subRules = subRules; + } + + public MatchRule( MatchLogic logic, String expression ) + { + this( logic, expression, null ); + } + + public MatchRule( MatchLogic logic ) + { + this( logic, "" ); + } + + public MatchRule( String expression ) + { + this( MatchLogic.ANY, expression ); + } + + public static MatchRule not( String expression, boolean not ) + { + return new MatchRule( not ? MatchLogic.NOT : MatchLogic.ANY, expression ); + } + + public static MatchRule group( List subRules, String expression ) + { + MatchLogic logic = expression.startsWith( "!" ) ? MatchLogic.NOT : MatchLogic.ANY; + return new MatchRule( logic, "", subRules ); + } + + public boolean isGroup() + { + return subRules != null; + } + } + + + public enum MatchLogic + { + OR, + AND, + XOR, + NOT, + ANY + } +} \ No newline at end of file diff --git a/src/main/java/appeng/util/item/OreHelper.java b/src/main/java/appeng/util/item/OreHelper.java index fcfcd3952..8b926a691 100644 --- a/src/main/java/appeng/util/item/OreHelper.java +++ b/src/main/java/appeng/util/item/OreHelper.java @@ -19,244 +19,208 @@ package appeng.util.item; -import java.util.*; -import java.util.concurrent.ConcurrentMap; - +import appeng.api.storage.data.IAEItemStack; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; - import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraftforge.oredict.OreDictionary; -import appeng.api.storage.data.IAEItemStack; +import java.util.*; public class OreHelper { - public static final OreHelper INSTANCE = new OreHelper(); + public static final OreHelper INSTANCE = new OreHelper(); - /** - * A local cache to speed up OreDictionary lookups. - */ - private final LoadingCache> oreDictCache = CacheBuilder.newBuilder().build( new CacheLoader>() - { - @Override - public List load( final String oreName ) - { - return OreDictionary.getOres( oreName ); - } - } ); + /** + * A local cache to speed up OreDictionary lookups. + */ + private final LoadingCache> oreDictCache = CacheBuilder.newBuilder().build( new CacheLoader>() + { + @Override + public List load( final String oreName ) + { + return OreDictionary.getOres( oreName ); + } + } ); - private final Map references = new HashMap<>(); + private final Map references = new HashMap<>(); - /** - * Test if the passed {@link ItemStack} is an ore. - * - * @param itemStack the itemstack to test - * - * @return true if an ore entry exists, false otherwise - */ - public Optional getOre( final ItemStack itemStack ) - { - final ItemRef ir = new ItemRef( itemStack ); + /** + * Test if the passed {@link ItemStack} is an ore. + * + * @param itemStack the itemstack to test + * @return true if an ore entry exists, false otherwise + */ + public Optional getOre( final ItemStack itemStack ) + { + final ItemRef ir = new ItemRef( itemStack ); - if( !this.references.containsKey( ir ) ) - { - final OreReference ref = new OreReference(); - final Collection ores = ref.getOres(); - final Collection set = ref.getEquivalents(); + if( !this.references.containsKey( ir ) ) + { + final OreReference ref = new OreReference(); + final Collection ores = ref.getOres(); + final Collection set = ref.getEquivalents(); - final Set toAdd = new HashSet<>(); + final Set toAdd = new HashSet<>(); - for( final String ore : OreDictionary.getOreNames() ) - { - // skip ore if it is a match already or null. - if( ore == null || toAdd.contains( ore ) ) - { - continue; - } + for( final String ore : OreDictionary.getOreNames() ) + { + // skip ore if it is a match already or null. + if( ore == null || toAdd.contains( ore ) ) + { + continue; + } - for( final ItemStack oreItem : this.oreDictCache.getUnchecked( ore ) ) - { - if( OreDictionary.itemMatches( oreItem, itemStack, false ) ) - { - toAdd.add( ore ); - break; - } - } - } + for( final ItemStack oreItem : this.oreDictCache.getUnchecked( ore ) ) + { + if( OreDictionary.itemMatches( oreItem, itemStack, false ) ) + { + toAdd.add( ore ); + break; + } + } + } - for( final String ore : toAdd ) - { - set.add( ore ); - ores.add( OreDictionary.getOreID( ore ) ); - } + for( final String ore : toAdd ) + { + set.add( ore ); + ores.add( OreDictionary.getOreID( ore ) ); + } - if( !set.isEmpty() ) - { - this.references.put( ir, ref ); - } - else - { - this.references.put( ir, null ); - } - } + if( !set.isEmpty() ) + { + this.references.put( ir, ref ); + } + else + { + this.references.put( ir, null ); + } + } - return Optional.ofNullable( this.references.get( ir ) ); - } + return Optional.ofNullable( this.references.get( ir ) ); + } - boolean sameOre( final AEItemStack aeItemStack, final IAEItemStack is ) - { - final OreReference a = aeItemStack.getOre().orElse( null ); - final OreReference b = ( (AEItemStack) is ).getOre().orElse( null ); + boolean sameOre( final AEItemStack aeItemStack, final IAEItemStack is ) + { + final OreReference a = aeItemStack.getOre().orElse( null ); + final OreReference b = ( (AEItemStack) is ).getOre().orElse( null ); - return this.sameOre( a, b ); - } + return this.sameOre( a, b ); + } - public boolean sameOre( final OreReference a, final OreReference b ) - { - if( a == null || b == null ) - { - return false; - } + public boolean sameOre( final OreReference a, final OreReference b ) + { + if( a == null || b == null ) + { + return false; + } - if( a == b ) - { - return true; - } + if( a == b ) + { + return true; + } - final Collection bOres = b.getOres(); - for( final Integer ore : a.getOres() ) - { - if( bOres.contains( ore ) ) - { - return true; - } - } + final Collection bOres = b.getOres(); + for( final Integer ore : a.getOres() ) + { + if( bOres.contains( ore ) ) + { + return true; + } + } - return false; - } + return false; + } - boolean sameOre( final AEItemStack aeItemStack, final ItemStack o ) - { - return aeItemStack.getOre().map( a -> - { - for( final String oreName : a.getEquivalents() ) - { - for( final ItemStack oreItem : this.oreDictCache.getUnchecked( oreName ) ) - { - if( OreDictionary.itemMatches( oreItem, o, false ) ) - { - return true; - } - } - } - return false; - } ).orElse( false ); - } + boolean sameOre( final AEItemStack aeItemStack, final ItemStack o ) + { + return aeItemStack.getOre().map( a -> { + for( final String oreName : a.getEquivalents() ) + { + for( final ItemStack oreItem : this.oreDictCache.getUnchecked( oreName ) ) + { + if( OreDictionary.itemMatches( oreItem, o, false ) ) + { + return true; + } + } + } + return false; + } ).orElse( false ); + } - public Set getMatchingOre( String allow ) - { - List matchingOres = new ArrayList<>(); - ConcurrentMap> oreKeys = oreDictCache.asMap(); + public Set getMatchingOre( String oreExp ) + { + Set matchingIds = new HashSet<>(); - oreKeys.forEach( ( s, l ) -> { + List rulesList = OreDictFilterMatcher.parseExpression( oreExp ); + for( String ore : OreDictionary.getOreNames() ) + { + if( OreDictFilterMatcher.matches( rulesList, ore ) ) + { + matchingIds.add( OreDictionary.getOreID( ore ) ); + } + } + return matchingIds; + } - if( allow.startsWith( "*" ) && allow.endsWith( "*" ) ) - { - if( s.contains( allow.substring( 1, allow.length() - 1 ) ) ) - { - matchingOres.add( s ); - } - } - else if( allow.startsWith( "*" ) ) - { - if( s.endsWith( allow.substring( 1 ) ) ) - { - matchingOres.add( s ); - } - } - else if( allow.endsWith( "*" ) ) - { - if( s.startsWith( allow.substring( 0, allow.length() - 1 ) ) ) - { - matchingOres.add( s ); - } - } - else - { - if( s.matches( allow ) ) - { - matchingOres.add( s ); - } - } - } ); + public List getCachedOres( final String oreName ) + { + return this.oreDictCache.getUnchecked( oreName ); + } - Set oreIDs = new HashSet<>(); - for( String matchingOre : matchingOres ) - { - oreIDs.add( OreDictionary.getOreID( matchingOre ) ); - } + private static class ItemRef + { - return oreIDs; - } + private final Item ref; + private final int damage; + private final int hash; - public List getCachedOres( final String oreName ) - { - return this.oreDictCache.getUnchecked( oreName ); - } + ItemRef( final ItemStack stack ) + { + this.ref = stack.getItem(); - private static class ItemRef - { + if( stack.getItem().isDamageable() ) + { + this.damage = 0; // IGNORED + } + else + { + this.damage = stack.getItemDamage(); // might be important... + } - private final Item ref; - private final int damage; - private final int hash; + this.hash = this.ref.hashCode() ^ this.damage; + } - ItemRef( final ItemStack stack ) - { - this.ref = stack.getItem(); + @Override + public int hashCode() + { + return this.hash; + } - if( stack.getItem().isDamageable() ) - { - this.damage = 0; // IGNORED - } - else - { - this.damage = stack.getItemDamage(); // might be important... - } + @Override + public boolean equals( final Object obj ) + { + if( obj == null ) + { + return false; + } + if( this.getClass() != obj.getClass() ) + { + return false; + } + final ItemRef other = (ItemRef) obj; + return this.damage == other.damage && this.ref == other.ref; + } - this.hash = this.ref.hashCode() ^ this.damage; - } - - @Override - public int hashCode() - { - return this.hash; - } - - @Override - public boolean equals( final Object obj ) - { - if( obj == null ) - { - return false; - } - if( this.getClass() != obj.getClass() ) - { - return false; - } - final ItemRef other = (ItemRef) obj; - return this.damage == other.damage && this.ref == other.ref; - } - - @Override - public String toString() - { - return "ItemRef [ref=" + this.ref.getUnlocalizedName() + ", damage=" + this.damage + ", hash=" + this.hash + ']'; - } - } + @Override + public String toString() + { + return "ItemRef [ref=" + this.ref.getUnlocalizedName() + ", damage=" + this.damage + ", hash=" + this.hash + ']'; + } + } } \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/recipes/network/parts/oredict_storage_bus.json b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/oredict_storage_bus.json new file mode 100644 index 000000000..22d001e4e --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/oredict_storage_bus.json @@ -0,0 +1,36 @@ +{ + "conditions": [ + { + "type": "forge:and", + "values": [ + { + "type": "appliedenergistics2:part_exists", + "part": "part.storage_bus" + }, + { + "type": "minecraft:item_exists", + "item": "appliedenergistics2:interface" + } + ] + } + ], + "result": { + "type": "appliedenergistics2:part", + "part": "part.oredict_storage_bus" + }, + "type": "appliedenergistics2:part_shapeless", + "ingredients": [ + { + "item": "minecraft:sticky_piston" + }, + { + "item": "#appliedenergistics2:interface" + }, + { + "item": "minecraft:piston" + }, + { + "item": "minecraft:book" + } + ] +} diff --git a/src/main/resources/assets/appliedenergistics2/recipes/network/parts/oredict_storage_bus_alt.json b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/oredict_storage_bus_alt.json new file mode 100644 index 000000000..47d7a5e1e --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/oredict_storage_bus_alt.json @@ -0,0 +1,31 @@ +{ + "conditions": [ + { + "type": "forge:and", + "values": [ + { + "type": "appliedenergistics2:part_exists", + "part": "part.storage_bus" + }, + { + "type": "minecraft:item_exists", + "item": "appliedenergistics2:interface" + } + ] + } + ], + "result": { + "type": "appliedenergistics2:part", + "part": "part.oredict_storage_bus" + }, + "type": "appliedenergistics2:part_shapeless", + "ingredients": [ + { + "type": "appliedenergistics2:part", + "part": "part.storage_bus" + }, + { + "item": "minecraft:book" + } + ] +}