Added an option to toggle oredict subsitutions for patterns.

It adds a backward compatibility to convert current patterns to use
oredict by default, which should be removed with rv4 stable.

Closes #1156
This commit is contained in:
yueh 2015-09-22 00:24:40 +02:00
parent c14bc82a01
commit 24224a450b
13 changed files with 248 additions and 85 deletions

View file

@ -0,0 +1,30 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2015 AlgorithmX2
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.config;
public enum ItemSubstitution
{
ENABLED, DISABLED;
}

View file

@ -27,6 +27,7 @@ import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import appeng.api.config.ActionItems; import appeng.api.config.ActionItems;
import appeng.api.config.ItemSubstitution;
import appeng.api.config.Settings; import appeng.api.config.Settings;
import appeng.api.storage.ITerminalHost; import appeng.api.storage.ITerminalHost;
import appeng.client.gui.widgets.GuiImgButton; import appeng.client.gui.widgets.GuiImgButton;
@ -41,13 +42,20 @@ import appeng.core.sync.packets.PacketValueConfig;
public class GuiPatternTerm extends GuiMEMonitorable public class GuiPatternTerm extends GuiMEMonitorable
{ {
final ContainerPatternTerm container; private static final String SUBSITUTION_DISABLE = "0";
private static final String SUBSITUTION_ENABLE = "1";
GuiTabButton tabCraftButton; private static final String CRAFTMODE_CRFTING = "1";
GuiTabButton tabProcessButton; private static final String CRAFTMODE_PROCESSING = "0";
// GuiImgButton substitutionsBtn;
GuiImgButton encodeBtn; private final ContainerPatternTerm container;
GuiImgButton clearBtn;
private GuiTabButton tabCraftButton;
private GuiTabButton tabProcessButton;
private GuiImgButton substitutionsEnabledBtn;
private GuiImgButton substitutionsDisabledBtn;
private GuiImgButton encodeBtn;
private GuiImgButton clearBtn;
public GuiPatternTerm( final InventoryPlayer inventoryPlayer, final ITerminalHost te ) public GuiPatternTerm( final InventoryPlayer inventoryPlayer, final ITerminalHost te )
{ {
@ -66,7 +74,7 @@ public class GuiPatternTerm extends GuiMEMonitorable
if( this.tabCraftButton == btn || this.tabProcessButton == btn ) if( this.tabCraftButton == btn || this.tabProcessButton == btn )
{ {
NetworkHandler.instance.sendToServer( new PacketValueConfig( "PatternTerminal.CraftMode", this.tabProcessButton == btn ? "1" : "0" ) ); NetworkHandler.instance.sendToServer( new PacketValueConfig( "PatternTerminal.CraftMode", this.tabProcessButton == btn ? CRAFTMODE_CRFTING : CRAFTMODE_PROCESSING ) );
} }
if( this.encodeBtn == btn ) if( this.encodeBtn == btn )
@ -78,34 +86,43 @@ public class GuiPatternTerm extends GuiMEMonitorable
{ {
NetworkHandler.instance.sendToServer( new PacketValueConfig( "PatternTerminal.Clear", "1" ) ); NetworkHandler.instance.sendToServer( new PacketValueConfig( "PatternTerminal.Clear", "1" ) );
} }
if( this.substitutionsEnabledBtn == btn || this.substitutionsDisabledBtn == btn )
{
NetworkHandler.instance.sendToServer( new PacketValueConfig( "PatternTerminal.Substitute", this.substitutionsEnabledBtn == btn ? SUBSITUTION_DISABLE : SUBSITUTION_ENABLE ) );
}
} }
catch( final IOException e ) catch( final IOException e )
{ {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
// if ( substitutionsBtn == btn )
// {
// }
} }
@Override @Override
public void initGui() public void initGui()
{ {
super.initGui(); super.initGui();
this.buttonList.add( this.tabCraftButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.crafting_table ), GuiText.CraftingPattern.getLocal(), itemRender ) ); this.tabCraftButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.crafting_table ), GuiText.CraftingPattern.getLocal(), itemRender );
this.buttonList.add( this.tabProcessButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.furnace ), GuiText.ProcessingPattern.getLocal(), itemRender ) ); this.buttonList.add( this.tabCraftButton );
// buttonList.add( substitutionsBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, this.tabProcessButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.furnace ), GuiText.ProcessingPattern.getLocal(), itemRender );
// Settings.ACTIONS, ActionItems.SUBSTITUTION ) ); this.buttonList.add( this.tabProcessButton );
// substitutionsBtn.halfSize = true;
this.buttonList.add( this.clearBtn = new GuiImgButton( this.guiLeft + 74, this.guiTop + this.ySize - 163, Settings.ACTIONS, ActionItems.CLOSE ) ); this.substitutionsEnabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.ENABLED );
this.substitutionsEnabledBtn.halfSize = true;
this.buttonList.add( this.substitutionsEnabledBtn );
this.substitutionsDisabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.DISABLED );
this.substitutionsDisabledBtn.halfSize = true;
this.buttonList.add( this.substitutionsDisabledBtn );
this.clearBtn = new GuiImgButton( this.guiLeft + 74, this.guiTop + this.ySize - 163, Settings.ACTIONS, ActionItems.CLOSE );
this.clearBtn.halfSize = true; this.clearBtn.halfSize = true;
this.buttonList.add( this.clearBtn );
this.buttonList.add( this.encodeBtn = new GuiImgButton( this.guiLeft + 147, this.guiTop + this.ySize - 142, Settings.ACTIONS, ActionItems.ENCODE ) ); this.encodeBtn = new GuiImgButton( this.guiLeft + 147, this.guiTop + this.ySize - 142, Settings.ACTIONS, ActionItems.ENCODE );
this.buttonList.add( this.encodeBtn );
} }
@Override @Override
@ -122,6 +139,17 @@ public class GuiPatternTerm extends GuiMEMonitorable
this.tabProcessButton.visible = false; this.tabProcessButton.visible = false;
} }
if( this.container.substitute )
{
this.substitutionsEnabledBtn.visible = true;
this.substitutionsDisabledBtn.visible = false;
}
else
{
this.substitutionsEnabledBtn.visible = false;
this.substitutionsDisabledBtn.visible = true;
}
super.drawFG( offsetX, offsetY, mouseX, mouseY ); super.drawFG( offsetX, offsetY, mouseX, mouseY );
this.fontRendererObj.drawString( GuiText.PatternTerminal.getLocal(), 8, this.ySize - 96 + 2 - this.reservedSpace, 4210752 ); this.fontRendererObj.drawString( GuiText.PatternTerminal.getLocal(), 8, this.ySize - 96 + 2 - this.reservedSpace, 4210752 );
} }

View file

@ -34,6 +34,7 @@ import appeng.api.config.ActionItems;
import appeng.api.config.CondenserOutput; import appeng.api.config.CondenserOutput;
import appeng.api.config.FullnessMode; import appeng.api.config.FullnessMode;
import appeng.api.config.FuzzyMode; import appeng.api.config.FuzzyMode;
import appeng.api.config.ItemSubstitution;
import appeng.api.config.LevelType; import appeng.api.config.LevelType;
import appeng.api.config.OperationMode; import appeng.api.config.OperationMode;
import appeng.api.config.PowerUnits; import appeng.api.config.PowerUnits;
@ -129,7 +130,8 @@ public class GuiImgButton extends GuiButton implements ITooltip
this.registerApp( 6, Settings.ACTIONS, ActionItems.STASH, ButtonToolTips.Stash, ButtonToolTips.StashDesc ); this.registerApp( 6, Settings.ACTIONS, ActionItems.STASH, ButtonToolTips.Stash, ButtonToolTips.StashDesc );
this.registerApp( 8, Settings.ACTIONS, ActionItems.ENCODE, ButtonToolTips.Encode, ButtonToolTips.EncodeDescription ); this.registerApp( 8, Settings.ACTIONS, ActionItems.ENCODE, ButtonToolTips.Encode, ButtonToolTips.EncodeDescription );
this.registerApp( 4 + 3 * 16, Settings.ACTIONS, ActionItems.SUBSTITUTION, ButtonToolTips.Substitutions, ButtonToolTips.SubstitutionsDesc ); this.registerApp( 4 + 3 * 16, Settings.ACTIONS, ItemSubstitution.ENABLED, ButtonToolTips.Substitutions, ButtonToolTips.SubstitutionsDescEnabled );
this.registerApp( 7 + 3 * 16, Settings.ACTIONS, ItemSubstitution.DISABLED, ButtonToolTips.Substitutions, ButtonToolTips.SubstitutionsDescDisabled );
this.registerApp( 16, Settings.VIEW_MODE, ViewItems.STORED, ButtonToolTips.View, ButtonToolTips.StoredItems ); this.registerApp( 16, Settings.VIEW_MODE, ViewItems.STORED, ButtonToolTips.View, ButtonToolTips.StoredItems );
this.registerApp( 18, Settings.VIEW_MODE, ViewItems.ALL, ButtonToolTips.View, ButtonToolTips.StoredCraftable ); this.registerApp( 18, Settings.VIEW_MODE, ViewItems.ALL, ButtonToolTips.View, ButtonToolTips.StoredCraftable );

View file

@ -71,15 +71,17 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
{ {
public final PartPatternTerminal ct; public final PartPatternTerminal ct;
final AppEngInternalInventory cOut = new AppEngInternalInventory( null, 1 ); private final AppEngInternalInventory cOut = new AppEngInternalInventory( null, 1 );
final IInventory crafting; private final IInventory crafting;
final SlotFakeCraftingMatrix[] craftingSlots = new SlotFakeCraftingMatrix[9]; private final SlotFakeCraftingMatrix[] craftingSlots = new SlotFakeCraftingMatrix[9];
final OptionalSlotFake[] outputSlots = new OptionalSlotFake[3]; private final OptionalSlotFake[] outputSlots = new OptionalSlotFake[3];
final SlotPatternTerm craftSlot; private final SlotPatternTerm craftSlot;
final SlotRestrictedInput patternSlotIN; private final SlotRestrictedInput patternSlotIN;
final SlotRestrictedInput patternSlotOUT; private final SlotRestrictedInput patternSlotOUT;
@GuiSync( 97 ) @GuiSync( 97 )
public boolean craftingMode = true; public boolean craftingMode = true;
@GuiSync( 96 )
public boolean substitute = false;
public ContainerPatternTerm( final InventoryPlayer ip, final ITerminalHost monitorable ) public ContainerPatternTerm( final InventoryPlayer ip, final ITerminalHost monitorable )
{ {
@ -88,6 +90,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
final IInventory patternInv = this.ct.getInventoryByName( "pattern" ); final IInventory patternInv = this.ct.getInventoryByName( "pattern" );
final IInventory output = this.ct.getInventoryByName( "output" ); final IInventory output = this.ct.getInventoryByName( "output" );
this.crafting = this.ct.getInventoryByName( "crafting" ); this.crafting = this.ct.getInventoryByName( "crafting" );
for( int y = 0; y < 3; y++ ) for( int y = 0; y < 3; y++ )
@ -156,6 +159,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
public ItemStack getAndUpdateOutput() public ItemStack getAndUpdateOutput()
{ {
final InventoryCrafting ic = new InventoryCrafting( this, 3, 3 ); final InventoryCrafting ic = new InventoryCrafting( this, 3, 3 );
for( int x = 0; x < ic.getSizeInventory(); x++ ) for( int x = 0; x < ic.getSizeInventory(); x++ )
{ {
ic.setInventorySlotContents( x, this.crafting.getStackInSlot( x ) ); ic.setInventorySlotContents( x, this.crafting.getStackInSlot( x ) );
@ -238,6 +242,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
encodedValue.setTag( "in", tagIn ); encodedValue.setTag( "in", tagIn );
encodedValue.setTag( "out", tagOut ); encodedValue.setTag( "out", tagOut );
encodedValue.setBoolean( "crafting", this.craftingMode ); encodedValue.setBoolean( "crafting", this.craftingMode );
encodedValue.setBoolean( "substitute", this.substitute );
output.setTagCompound( encodedValue ); output.setTagCompound( encodedValue );
} }
@ -269,6 +274,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
if( this.craftingMode ) if( this.craftingMode )
{ {
final ItemStack out = this.getAndUpdateOutput(); final ItemStack out = this.getAndUpdateOutput();
if( out != null && out.stackSize > 0 ) if( out != null && out.stackSize > 0 )
{ {
return new ItemStack[] { out }; return new ItemStack[] { out };
@ -282,6 +288,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
for( final OptionalSlotFake outputSlot : this.outputSlots ) for( final OptionalSlotFake outputSlot : this.outputSlots )
{ {
final ItemStack out = outputSlot.getStack(); final ItemStack out = outputSlot.getStack();
if( out != null && out.stackSize > 0 ) if( out != null && out.stackSize > 0 )
{ {
list.add( out ); list.add( out );
@ -347,9 +354,9 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
if( packetPatternSlot.slotItem != null && this.cellInv != null ) if( packetPatternSlot.slotItem != null && this.cellInv != null )
{ {
final IAEItemStack out = packetPatternSlot.slotItem.copy(); final IAEItemStack out = packetPatternSlot.slotItem.copy();
InventoryAdaptor inv = new AdaptorPlayerHand( this.getPlayerInv().player ); InventoryAdaptor inv = new AdaptorPlayerHand( this.getPlayerInv().player );
final InventoryAdaptor playerInv = InventoryAdaptor.getAdaptor( this.getPlayerInv().player, ForgeDirection.UNKNOWN ); final InventoryAdaptor playerInv = InventoryAdaptor.getAdaptor( this.getPlayerInv().player, ForgeDirection.UNKNOWN );
if( packetPatternSlot.shift ) if( packetPatternSlot.shift )
{ {
inv = playerInv; inv = playerInv;
@ -376,6 +383,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 ); final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
final InventoryCrafting real = new InventoryCrafting( new ContainerNull(), 3, 3 ); final InventoryCrafting real = new InventoryCrafting( new ContainerNull(), 3, 3 );
for( int x = 0; x < 9; x++ ) for( int x = 0; x < 9; x++ )
{ {
ic.setInventorySlotContents( x, packetPatternSlot.pattern[x] == null ? null : packetPatternSlot.pattern[x].getItemStack() ); ic.setInventorySlotContents( x, packetPatternSlot.pattern[x] == null ? null : packetPatternSlot.pattern[x].getItemStack() );
@ -412,6 +420,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
for( int x = 0; x < real.getSizeInventory(); x++ ) for( int x = 0; x < real.getSizeInventory(); x++ )
{ {
final ItemStack failed = playerInv.addItems( real.getStackInSlot( x ) ); final ItemStack failed = playerInv.addItems( real.getStackInSlot( x ) );
if( failed != null ) if( failed != null )
{ {
p.dropPlayerItemWithRandomChoice( failed, false ); p.dropPlayerItemWithRandomChoice( failed, false );
@ -450,6 +459,8 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
this.craftingMode = this.ct.isCraftingRecipe(); this.craftingMode = this.ct.isCraftingRecipe();
this.updateOrderOfOutputSlots(); this.updateOrderOfOutputSlots();
} }
this.substitute = this.ct.isSubstitution();
} }
} }
@ -519,4 +530,12 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
{ {
return false; return false;
} }
public void toggleSubstitute()
{
this.substitute = !this.substitute;
this.detectAndSendChanges();
this.getAndUpdateOutput();
}
} }

View file

@ -54,7 +54,7 @@ public enum ButtonToolTips
LevelType, LevelType_Energy, LevelType_Item, InventoryTweaks, TerminalStyle, TerminalStyle_Full, TerminalStyle_Tall, TerminalStyle_Small, LevelType, LevelType_Energy, LevelType_Item, InventoryTweaks, TerminalStyle, TerminalStyle_Full, TerminalStyle_Tall, TerminalStyle_Small,
Stash, StashDesc, Encode, EncodeDescription, Substitutions, SubstitutionsOn, SubstitutionsOff, SubstitutionsDesc, CraftOnly, CraftEither, Stash, StashDesc, Encode, EncodeDescription, Substitutions, SubstitutionsOn, SubstitutionsOff, SubstitutionsDescEnabled, SubstitutionsDescDisabled, CraftOnly, CraftEither,
Craft, Mod, DoesntDespawn, EmitterMode, CraftViaRedstone, EmitWhenCrafting, ReportInaccessibleItems, ReportInaccessibleItemsYes, ReportInaccessibleItemsNo, Craft, Mod, DoesntDespawn, EmitterMode, CraftViaRedstone, EmitWhenCrafting, ReportInaccessibleItems, ReportInaccessibleItemsYes, ReportInaccessibleItemsNo,

View file

@ -47,9 +47,20 @@ public enum GuiText
// tunnel names // tunnel names
METunnel, ItemTunnel, RedstoneTunnel, EUTunnel, FluidTunnel, OCTunnel, LightTunnel, RFTunnel, PressureTunnel, METunnel, ItemTunnel, RedstoneTunnel, EUTunnel, FluidTunnel, OCTunnel, LightTunnel, RFTunnel, PressureTunnel,
StoredSize, CopyMode, CopyModeDesc, PatternTerminal, CraftingPattern, StoredSize, CopyMode, CopyModeDesc, PatternTerminal,
ProcessingPattern, Crafts, Creates, And, With, MolecularAssembler, // Pattern tooltips
CraftingPattern,
ProcessingPattern,
Crafts,
Creates,
And,
With,
Substitute,
Yes,
No,
MolecularAssembler,
StoredPower, MaxPower, RequiredPower, Efficiency, InWorldCrafting, StoredPower, MaxPower, RequiredPower, Efficiency, InWorldCrafting,

View file

@ -59,8 +59,8 @@ import appeng.helpers.IMouseWheelItem;
public class PacketValueConfig extends AppEngPacket public class PacketValueConfig extends AppEngPacket
{ {
public final String Name; private final String Name;
public final String Value; private final String Value;
// automatic. // automatic.
public PacketValueConfig( final ByteBuf stream ) throws IOException public PacketValueConfig( final ByteBuf stream ) throws IOException
@ -158,6 +158,10 @@ public class PacketValueConfig extends AppEngPacket
{ {
cpt.clear(); cpt.clear();
} }
else if( this.Name.equals( "PatternTerminal.Substitute" ) )
{
cpt.ct.setSubstitution( this.Value.equals( "1" ) );
}
} }
else if( this.Name.startsWith( "StorageBus." ) && c instanceof ContainerStorageBus ) else if( this.Name.startsWith( "StorageBus." ) && c instanceof ContainerStorageBus )
{ {

View file

@ -20,9 +20,12 @@ package appeng.crafting;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import com.google.common.collect.Lists;
import net.minecraft.world.World; import net.minecraft.world.World;
import appeng.api.AEApi; import appeng.api.AEApi;
@ -41,8 +44,8 @@ public class CraftingTreeNode
// what slot! // what slot!
final int slot; final int slot;
final CraftingJob job; private final CraftingJob job;
final IItemList<IAEItemStack> used = AEApi.instance().storage().createItemList(); private final IItemList<IAEItemStack> used = AEApi.instance().storage().createItemList();
// parent node. // parent node.
private final CraftingTreeProcess parent; private final CraftingTreeProcess parent;
private final World world; private final World world;
@ -50,14 +53,13 @@ public class CraftingTreeNode
private final IAEItemStack what; private final IAEItemStack what;
// what are the crafting patterns for this? // what are the crafting patterns for this?
private final ArrayList<CraftingTreeProcess> nodes = new ArrayList<CraftingTreeProcess>(); private final ArrayList<CraftingTreeProcess> nodes = new ArrayList<CraftingTreeProcess>();
int bytes = 0; private int bytes = 0;
boolean canEmit = false; private boolean canEmit = false;
boolean cannotUse = false; private boolean cannotUse = false;
long missing = 0; private long missing = 0;
long howManyEmitted = 0; private long howManyEmitted = 0;
boolean exhausted = false; private boolean exhausted = false;
private boolean sim;
boolean sim;
public CraftingTreeNode( final ICraftingGrid cc, final CraftingJob job, final IAEItemStack wat, final CraftingTreeProcess par, final int slot, final int depth ) public CraftingTreeNode( final ICraftingGrid cc, final CraftingJob job, final IAEItemStack wat, final CraftingTreeProcess par, final int slot, final int depth )
{ {
@ -69,6 +71,7 @@ public class CraftingTreeNode
this.sim = false; this.sim = false;
this.canEmit = cc.canEmitFor( this.what ); this.canEmit = cc.canEmitFor( this.what );
if( this.canEmit ) if( this.canEmit )
{ {
return; // if you can emit for something, you can't make it with patterns. return; // if you can emit for something, you can't make it with patterns.
@ -87,6 +90,7 @@ public class CraftingTreeNode
boolean notRecursive( final ICraftingPatternDetails details ) boolean notRecursive( final ICraftingPatternDetails details )
{ {
IAEItemStack[] o = details.getCondensedOutputs(); IAEItemStack[] o = details.getCondensedOutputs();
for( final IAEItemStack i : o ) for( final IAEItemStack i : o )
{ {
if( i.equals( this.what ) ) if( i.equals( this.what ) )
@ -96,6 +100,7 @@ public class CraftingTreeNode
} }
o = details.getCondensedInputs(); o = details.getCondensedInputs();
for( final IAEItemStack i : o ) for( final IAEItemStack i : o )
{ {
if( i.equals( this.what ) ) if( i.equals( this.what ) )
@ -121,12 +126,32 @@ public class CraftingTreeNode
this.what.setStackSize( l ); this.what.setStackSize( l );
if( this.slot >= 0 && this.parent != null && this.parent.details.isCraftable() ) if( this.slot >= 0 && this.parent != null && this.parent.details.isCraftable() )
{ {
for( IAEItemStack fuzz : inv.getItemList().findFuzzy( this.what, FuzzyMode.IGNORE_ALL ) ) final Collection<IAEItemStack> itemList;
final IItemList<IAEItemStack> inventoryList = inv.getItemList();
if( this.parent.details.canSubstitute() )
{
itemList = inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL );
}
else
{
itemList = Lists.newArrayList();
final IAEItemStack item = inventoryList.findPrecise( this.what );
if( item != null )
{
itemList.add( item );
}
}
for( IAEItemStack fuzz : itemList )
{ {
if( this.parent.details.isValidItemForSlot( this.slot, fuzz.getItemStack(), this.world ) ) if( this.parent.details.isValidItemForSlot( this.slot, fuzz.getItemStack(), this.world ) )
{ {
fuzz = fuzz.copy(); fuzz = fuzz.copy();
fuzz.setStackSize( l ); fuzz.setStackSize( l );
final IAEItemStack available = inv.extractItems( fuzz, Actionable.MODULATE, src ); final IAEItemStack available = inv.extractItems( fuzz, Actionable.MODULATE, src );
if( available != null ) if( available != null )
@ -134,6 +159,7 @@ public class CraftingTreeNode
if( !this.exhausted ) if( !this.exhausted )
{ {
final IAEItemStack is = this.job.checkUse( available ); final IAEItemStack is = this.job.checkUse( available );
if( is != null ) if( is != null )
{ {
thingsUsed.add( is.copy() ); thingsUsed.add( is.copy() );
@ -161,6 +187,7 @@ public class CraftingTreeNode
if( !this.exhausted ) if( !this.exhausted )
{ {
final IAEItemStack is = this.job.checkUse( available ); final IAEItemStack is = this.job.checkUse( available );
if( is != null ) if( is != null )
{ {
thingsUsed.add( is.copy() ); thingsUsed.add( is.copy() );
@ -202,6 +229,7 @@ public class CraftingTreeNode
pro.request( inv, pro.getTimes( l, madeWhat.getStackSize() ), src ); pro.request( inv, pro.getTimes( l, madeWhat.getStackSize() ), src );
madeWhat.setStackSize( l ); madeWhat.setStackSize( l );
final IAEItemStack available = inv.extractItems( madeWhat, Actionable.MODULATE, src ); final IAEItemStack available = inv.extractItems( madeWhat, Actionable.MODULATE, src );
if( available != null ) if( available != null )

View file

@ -23,6 +23,8 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import net.minecraft.inventory.InventoryCrafting; import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@ -45,20 +47,21 @@ import appeng.util.item.AEItemStack;
public class PatternHelper implements ICraftingPatternDetails, Comparable<PatternHelper> public class PatternHelper implements ICraftingPatternDetails, Comparable<PatternHelper>
{ {
final ItemStack patternItem; private final ItemStack patternItem;
final InventoryCrafting crafting = new InventoryCrafting( new ContainerNull(), 3, 3 ); private final InventoryCrafting crafting = new InventoryCrafting( new ContainerNull(), 3, 3 );
final InventoryCrafting testFrame = new InventoryCrafting( new ContainerNull(), 3, 3 ); private final InventoryCrafting testFrame = new InventoryCrafting( new ContainerNull(), 3, 3 );
final ItemStack correctOutput; private final ItemStack correctOutput;
final IRecipe standardRecipe; private final IRecipe standardRecipe;
final IAEItemStack[] condensedInputs; private final IAEItemStack[] condensedInputs;
final IAEItemStack[] condensedOutputs; private final IAEItemStack[] condensedOutputs;
final IAEItemStack[] inputs; private final IAEItemStack[] inputs;
final IAEItemStack[] outputs; private final IAEItemStack[] outputs;
final boolean isCrafting; private final boolean isCrafting;
final HashSet<TestLookup> failCache = new HashSet<TestLookup>(); private final boolean canSubstitute;
final HashSet<TestLookup> passCache = new HashSet<TestLookup>(); private final Set<TestLookup> failCache = new HashSet<TestLookup>();
private final Set<TestLookup> passCache = new HashSet<TestLookup>();
private final IAEItemStack pattern; private final IAEItemStack pattern;
public int priority = 0; private int priority = 0;
public PatternHelper( final ItemStack is, final World w ) public PatternHelper( final ItemStack is, final World w )
{ {
@ -72,6 +75,8 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
final NBTTagList inTag = encodedValue.getTagList( "in", 10 ); final NBTTagList inTag = encodedValue.getTagList( "in", 10 );
final NBTTagList outTag = encodedValue.getTagList( "out", 10 ); final NBTTagList outTag = encodedValue.getTagList( "out", 10 );
this.isCrafting = encodedValue.getBoolean( "crafting" ); this.isCrafting = encodedValue.getBoolean( "crafting" );
this.canSubstitute = encodedValue.getBoolean( "substitute" );
this.patternItem = is; this.patternItem = is;
this.pattern = AEItemStack.create( is ); this.pattern = AEItemStack.create( is );
@ -81,6 +86,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
for( int x = 0; x < inTag.tagCount(); x++ ) for( int x = 0; x < inTag.tagCount(); x++ )
{ {
final ItemStack gs = ItemStack.loadItemStackFromNBT( inTag.getCompoundTagAt( x ) ); final ItemStack gs = ItemStack.loadItemStackFromNBT( inTag.getCompoundTagAt( x ) );
this.crafting.setInventorySlotContents( x, gs ); this.crafting.setInventorySlotContents( x, gs );
if( gs != null && ( !this.isCrafting || !gs.hasTagCompound() ) ) if( gs != null && ( !this.isCrafting || !gs.hasTagCompound() ) )
@ -95,6 +101,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
if( this.isCrafting ) if( this.isCrafting )
{ {
this.standardRecipe = Platform.findMatchingRecipe( this.crafting, w ); this.standardRecipe = Platform.findMatchingRecipe( this.crafting, w );
if( this.standardRecipe != null ) if( this.standardRecipe != null )
{ {
this.correctOutput = this.standardRecipe.getCraftingResult( this.crafting ); this.correctOutput = this.standardRecipe.getCraftingResult( this.crafting );
@ -113,6 +120,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
for( int x = 0; x < outTag.tagCount(); x++ ) for( int x = 0; x < outTag.tagCount(); x++ )
{ {
final ItemStack gs = ItemStack.loadItemStackFromNBT( outTag.getCompoundTagAt( x ) ); final ItemStack gs = ItemStack.loadItemStackFromNBT( outTag.getCompoundTagAt( x ) );
if( gs != null ) if( gs != null )
{ {
out.add( AEApi.instance().storage().createItemStack( gs ) ); out.add( AEApi.instance().storage().createItemStack( gs ) );
@ -123,7 +131,8 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
this.outputs = out.toArray( new IAEItemStack[out.size()] ); this.outputs = out.toArray( new IAEItemStack[out.size()] );
this.inputs = in.toArray( new IAEItemStack[in.size()] ); this.inputs = in.toArray( new IAEItemStack[in.size()] );
final HashMap<IAEItemStack, IAEItemStack> tmpOutputs = new HashMap<IAEItemStack, IAEItemStack>(); final Map<IAEItemStack, IAEItemStack> tmpOutputs = new HashMap<IAEItemStack, IAEItemStack>();
for( final IAEItemStack io : this.outputs ) for( final IAEItemStack io : this.outputs )
{ {
if( io == null ) if( io == null )
@ -132,6 +141,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
} }
final IAEItemStack g = tmpOutputs.get( io ); final IAEItemStack g = tmpOutputs.get( io );
if( g == null ) if( g == null )
{ {
tmpOutputs.put( io, io.copy() ); tmpOutputs.put( io, io.copy() );
@ -142,7 +152,8 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
} }
} }
final HashMap<IAEItemStack, IAEItemStack> tmpInputs = new HashMap<IAEItemStack, IAEItemStack>(); final Map<IAEItemStack, IAEItemStack> tmpInputs = new HashMap<IAEItemStack, IAEItemStack>();
for( final IAEItemStack io : this.inputs ) for( final IAEItemStack io : this.inputs )
{ {
if( io == null ) if( io == null )
@ -151,6 +162,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
} }
final IAEItemStack g = tmpInputs.get( io ); final IAEItemStack g = tmpInputs.get( io );
if( g == null ) if( g == null )
{ {
tmpInputs.put( io, io.copy() ); tmpInputs.put( io, io.copy() );
@ -168,6 +180,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
this.condensedInputs = new IAEItemStack[tmpInputs.size()]; this.condensedInputs = new IAEItemStack[tmpInputs.size()];
int offset = 0; int offset = 0;
for( final IAEItemStack io : tmpInputs.values() ) for( final IAEItemStack io : tmpInputs.values() )
{ {
this.condensedInputs[offset] = io; this.condensedInputs[offset] = io;
@ -176,6 +189,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
offset = 0; offset = 0;
this.condensedOutputs = new IAEItemStack[tmpOutputs.size()]; this.condensedOutputs = new IAEItemStack[tmpOutputs.size()];
for( final IAEItemStack io : tmpOutputs.values() ) for( final IAEItemStack io : tmpOutputs.values() )
{ {
this.condensedOutputs[offset] = io; this.condensedOutputs[offset] = io;
@ -287,7 +301,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
@Override @Override
public boolean canSubstitute() public boolean canSubstitute()
{ {
return false; return this.canSubstitute;
} }
@Override @Override
@ -368,17 +382,38 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
return this.pattern.hashCode(); return this.pattern.hashCode();
} }
enum TestStatus @Override
public boolean equals( final Object obj )
{
if( obj == null )
{
return false;
}
if( this.getClass() != obj.getClass() )
{
return false;
}
final PatternHelper other = (PatternHelper) obj;
if( this.pattern != null && other.pattern != null )
{
return this.pattern.equals( other.pattern );
}
return false;
}
private enum TestStatus
{ {
ACCEPT, DECLINE, TEST ACCEPT, DECLINE, TEST
} }
static class TestLookup private static final class TestLookup
{ {
final int slot; private final int slot;
final int ref; private final int ref;
final int hash; private final int hash;
public TestLookup( final int slot, final ItemStack i ) public TestLookup( final int slot, final ItemStack i )
{ {
@ -407,6 +442,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
if( obj instanceof TestLookup ) if( obj instanceof TestLookup )
{ {
final TestLookup b = (TestLookup) obj; final TestLookup b = (TestLookup) obj;
equality = b.slot == this.slot && b.ref == this.ref; equality = b.slot == this.slot && b.ref == this.ref;
} }
else else
@ -417,23 +453,4 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
return equality; return equality;
} }
} }
@Override
public boolean equals( final Object obj )
{
if( obj == null )
{
return false;
}
if( this.getClass() != obj.getClass() )
{
return false;
}
final PatternHelper other = (PatternHelper) obj;
if( this.pattern != null && other.pattern != null )
{
return this.pattern.equals( other.pattern );
}
return false;
}
} }

View file

@ -113,6 +113,7 @@ public class ItemEncodedPattern extends AEBaseItem implements ICraftingPatternIt
} }
final boolean isCrafting = details.isCraftable(); final boolean isCrafting = details.isCraftable();
final boolean substitute = details.canSubstitute();
final IAEItemStack[] in = details.getCondensedInputs(); final IAEItemStack[] in = details.getCondensedInputs();
final IAEItemStack[] out = details.getCondensedOutputs(); final IAEItemStack[] out = details.getCondensedOutputs();
@ -144,6 +145,11 @@ public class ItemEncodedPattern extends AEBaseItem implements ICraftingPatternIt
lines.add( ( first ? with : and ) + anIn.getStackSize() + ' ' + Platform.getItemDisplayName( anIn ) ); lines.add( ( first ? with : and ) + anIn.getStackSize() + ' ' + Platform.getItemDisplayName( anIn ) );
first = false; first = false;
} }
final String substitutionLabel = GuiText.Substitute.getLocal() + " ";
final String canSubstitute = substitute ? GuiText.Yes.getLocal() : GuiText.No.getLocal();
lines.add( substitutionLabel + canSubstitute );
} }
@Override @Override

View file

@ -47,6 +47,7 @@ public class PartPatternTerminal extends AbstractPartTerminal
private final AppEngInternalInventory pattern = new AppEngInternalInventory( this, 2 ); private final AppEngInternalInventory pattern = new AppEngInternalInventory( this, 2 );
private boolean craftingMode = true; private boolean craftingMode = true;
private boolean substitute = false;
@Reflected @Reflected
public PartPatternTerminal( final ItemStack is ) public PartPatternTerminal( final ItemStack is )
@ -71,6 +72,7 @@ public class PartPatternTerminal extends AbstractPartTerminal
{ {
super.readFromNBT( data ); super.readFromNBT( data );
this.setCraftingRecipe( data.getBoolean( "craftingMode" ) ); this.setCraftingRecipe( data.getBoolean( "craftingMode" ) );
this.setSubstitution( data.getBoolean( "substitute" ) );
this.pattern.readFromNBT( data, "pattern" ); this.pattern.readFromNBT( data, "pattern" );
this.output.readFromNBT( data, "outputList" ); this.output.readFromNBT( data, "outputList" );
this.crafting.readFromNBT( data, "craftingGrid" ); this.crafting.readFromNBT( data, "craftingGrid" );
@ -81,6 +83,7 @@ public class PartPatternTerminal extends AbstractPartTerminal
{ {
super.writeToNBT( data ); super.writeToNBT( data );
data.setBoolean( "craftingMode", this.craftingMode ); data.setBoolean( "craftingMode", this.craftingMode );
data.setBoolean( "substitute", this.substitute );
this.pattern.writeToNBT( data, "pattern" ); this.pattern.writeToNBT( data, "pattern" );
this.output.writeToNBT( data, "outputList" ); this.output.writeToNBT( data, "outputList" );
this.crafting.writeToNBT( data, "craftingGrid" ); this.crafting.writeToNBT( data, "craftingGrid" );
@ -119,6 +122,7 @@ public class PartPatternTerminal extends AbstractPartTerminal
if( details != null ) if( details != null )
{ {
this.setCraftingRecipe( details.isCraftable() ); this.setCraftingRecipe( details.isCraftable() );
this.setSubstitution( details.canSubstitute() );
for( int x = 0; x < this.crafting.getSizeInventory() && x < details.getInputs().length; x++ ) for( int x = 0; x < this.crafting.getSizeInventory() && x < details.getInputs().length; x++ )
{ {
@ -168,6 +172,16 @@ public class PartPatternTerminal extends AbstractPartTerminal
this.fixCraftingRecipes(); this.fixCraftingRecipes();
} }
public boolean isSubstitution()
{
return this.substitute;
}
public void setSubstitution( boolean canSubstitute )
{
this.substitute = canSubstitute;
}
@Override @Override
public IInventory getInventoryByName( final String name ) public IInventory getInventoryByName( final String name )
{ {

View file

@ -177,6 +177,9 @@ gui.appliedenergistics2.Crafts=Crafts
gui.appliedenergistics2.And=and gui.appliedenergistics2.And=and
gui.appliedenergistics2.Creates=Creates gui.appliedenergistics2.Creates=Creates
gui.appliedenergistics2.With=with gui.appliedenergistics2.With=with
gui.appliedenergistics2.Substitute=Using Substitutions:
gui.appliedenergistics2.Yes=Yes
gui.appliedenergistics2.No=No
gui.appliedenergistics2.InWorldCrafting=AE2 In World Crafting gui.appliedenergistics2.InWorldCrafting=AE2 In World Crafting
gui.appliedenergistics2.inWorldFluix=Drop 1 Charged Certus Quartz + 1 Nether Quartz + Redstone Dust into a puddle next to one another and wait a moment to receive 2 Fluix Crystals. gui.appliedenergistics2.inWorldFluix=Drop 1 Charged Certus Quartz + 1 Nether Quartz + Redstone Dust into a puddle next to one another and wait a moment to receive 2 Fluix Crystals.
gui.appliedenergistics2.inWorldPurificationCertus=Drop a Certus Quartz Seed made from Certus Quartz Dust and Sand into a puddle of water; to make the process faster add Crystal Growth Accelerators. gui.appliedenergistics2.inWorldPurificationCertus=Drop a Certus Quartz Seed made from Certus Quartz Dust and Sand into a puddle of water; to make the process faster add Crystal Growth Accelerators.
@ -234,7 +237,8 @@ gui.appliedenergistics2.Nothing=Nothing
gui.tooltips.appliedenergistics2.Stash=Store Items gui.tooltips.appliedenergistics2.Stash=Store Items
gui.tooltips.appliedenergistics2.StashDesc=Return items on the crafting grid to network storage. gui.tooltips.appliedenergistics2.StashDesc=Return items on the crafting grid to network storage.
gui.tooltips.appliedenergistics2.Substitutions=Ore-Dict Substitutions gui.tooltips.appliedenergistics2.Substitutions=Ore-Dict Substitutions
gui.tooltips.appliedenergistics2.SubstitutionsDesc=Edit substitution options for input components. gui.tooltips.appliedenergistics2.SubstitutionsDescEnabled=Allow substitutions of input components.
gui.tooltips.appliedenergistics2.SubstitutionsDescDisabled=Prevent substitutions of input components.
gui.tooltips.appliedenergistics2.SubstitutionsOn=Substitutions Enabled gui.tooltips.appliedenergistics2.SubstitutionsOn=Substitutions Enabled
gui.tooltips.appliedenergistics2.SubstitutionsOff=Substitutions Disabled gui.tooltips.appliedenergistics2.SubstitutionsOff=Substitutions Disabled
gui.tooltips.appliedenergistics2.Encode=Encode Pattern gui.tooltips.appliedenergistics2.Encode=Encode Pattern

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB