Compare commits

...

53 Commits

Author SHA1 Message Date
PrototypeTrousers 9fc96295a8 0 2022-01-14 15:02:30 -03:00
PrototypeTrousers fd3349614d fix terminal crashing and not cleaning leftovers of larger recipe patterns 2022-01-11 11:23:40 -03:00
PrototypeTrousers 903f211044 fix crash while configuring fluid storage bus 2022-01-10 03:17:46 -03:00
PrototypeTrousers 78e1e26a11 Fix issues with the expanded pattern terminal and its patterns crafting 2022-01-05 21:36:49 -03:00
PrototypeTrousers 2a6de11597 update version 2022-01-04 17:08:55 -03:00
PrototypeTrousers cd2b53af85 Cherry-picked 5554ba903e74c2980b2e395c78555b40fc379e80
Be more lenient with extended block states being passed by other mods.
2022-01-04 17:01:55 -03:00
PrototypeTrousers 1c5565491a finish oredict storage bus 2022-01-03 13:16:27 -03:00
PrototypeTrousers 311cc5c6f6 more oredictbus work 2022-01-03 11:32:48 -03:00
PrototypeTrousers 41796449ed cache oredict filter list 2022-01-03 10:47:35 -03:00
PrototypeTrousers 9eef9d3840 partial implementation of oredict storage bus
missing proper GUI, text, item models, memorycard support.
logic works
2022-01-03 02:33:08 -03:00
PrototypeTrousers 13afa6908a implement expanded processing pattern terminal 2022-01-02 18:27:41 -03:00
PrototypeTrousers 103438f805 do full reset level emitter on stack update 2021-12-13 02:02:02 -03:00
PrototypeTrousers eaa01f7648 flip some boolean so craftables actually show up 2021-12-10 20:26:29 -03:00
PrototypeTrousers e81fb09599 when in off-hand, memory card wild paste as input 2021-12-10 14:02:56 -03:00
PrototypeTrousers 94d73aec7c wwww 2021-12-09 23:34:57 -03:00
PrototypeTrousers b51af43dba item/fluid count changes.. again 2021-12-07 21:10:04 -03:00
PrototypeTrousers 85dc8ae7c1 item costs/ghost fixes 2021-11-29 00:50:32 -03:00
PrototypeTrousers c34176f392 fix (?) item desync issues 2021-11-23 20:25:05 -03:00
PrototypeTrousers 76fe2175a0 moved p2p forge event to an upper class
add an extra update after the network has finished booting
2021-11-15 00:09:04 -03:00
PrototypeTrousers c5d33ed892 p2p fixes redton, light, items 2021-11-11 20:54:40 -03:00
PrototypeTrousers b423d99879 tweak crafting byte costs 2021-11-02 17:56:12 -03:00
PrototypeTrousers 81156b411d version 2021-11-02 15:34:45 -03:00
PrototypeTrousers 6be1660d41 Merge branch 'item-issues' into AE2-Omnifactory 2021-11-02 15:34:02 -03:00
PrototypeTrousers 304f394497 cut crafting tree earlier if the item is available
fix job byte size to 8 per crafting + 1 per item used/stored
2021-11-02 15:33:14 -03:00
PrototypeTrousers 50f21125c8 log if non-patterned items go missing before starting a craft 2021-11-02 02:00:01 -03:00
PrototypeTrousers 30b85bd239 potential fix for showing proper item names when failing to start craft 2021-11-01 23:23:45 -03:00
PrototypeTrousers 9ce00d338f only try to extract if its already in the cache 2021-10-29 17:04:24 -03:00
PrototypeTrousers 11f5b71089 update directly instead of relying on forge events 2021-10-29 15:14:33 -03:00
PrototypeTrousers e7da72163b backported #5349 2021-10-29 15:13:46 -03:00
PrototypeTrousers 6d7c65dd70 potential fix for an infinite loop while adding nodes 2021-10-29 14:09:19 -03:00
PrototypeTrousers 5e21101619 n-to-n p2p
network monitor checks nesting by action source
2021-10-28 23:49:16 -03:00
PrototypeTrousers 3db8d0185f fix security terminal and portable cell stored items not showing 2021-10-23 17:56:15 -03:00
PrototypeTrousers 2f5ecfe638 energy fixes 2021-10-22 15:37:08 -03:00
PrototypeTrousers 75843e802d WIP 2021-10-21 12:22:00 -03:00
PrototypeTrousers e41b6943aa fix swapping cells giving wrong item/fluid count 2021-09-28 23:29:52 -03:00
PrototypeTrousers 92347ad2f5 fix looping item count and hopefully energy issues 2021-09-26 22:07:16 -03:00
PrototypeTrousers 517bd77df7 yet another try at energy issues
fix requesters not being added to the energy grid


partially revert the energy 'fixes'


potential desync on item count


energy and items change
2021-09-17 00:09:49 -03:00
PrototypeTrousers 19f928a9a5 fluid pass 2021-09-13 04:22:52 -03:00
PrototypeTrousers 73251a0fe5 more item count changes.... 2021-09-13 02:10:28 -03:00
PrototypeTrousers 9335daff7d Revert "fixes item showing incorrect amounts"
This reverts commit 618e9390c6.
2021-09-11 22:48:45 -03:00
PrototypeTrousers cc5377d53b fluid storage bus handler cache tweaks and simplify energy cache 2021-09-06 23:51:32 -03:00
Salomão 059f20d801 yet another try at fixing power issues 2021-09-05 20:28:37 -03:00
Salomão d229570495 try to fix energy issues again
fix issue with voiding p2p parts when shift-right clicking with a memory card
2021-09-04 18:59:46 -03:00
PrototypeTrousers c284748b6c fix p2p not updating properly on memory card loading 2021-09-02 20:42:02 -03:00
PrototypeTrousers 880a9c8821 another case of wrong item count caused by weak reset logic overriding
a full reset needed
2021-09-01 16:11:45 -03:00
PrototypeTrousers c68c02ef3b more cases of wrong item counting fixed 2021-08-26 22:03:23 -03:00
PrototypeTrousers 89c4d2736c borrowed some fancy, colored, fluid rendering from gregicality
thank you @Yefancy
2021-08-23 22:35:26 -03:00
PrototypeTrousers 01778794e5 try to fix #51 2021-08-22 23:59:02 -03:00
PrototypeTrousers 8f2a06e457 fix #49. you can now actually clear storage and conversion monitors 2021-08-20 23:26:33 -03:00
PrototypeTrousers 2d71b75019 actually fix it 2021-08-17 07:46:47 -03:00
PrototypeTrousers 9f09cd04d4 enforce cache reset of storage bus attached to interfaces were configs
changed
2021-08-16 21:55:35 -03:00
PrototypeTrousers b041fae0d5 fix storage/monitors wrong item count and interactions 2021-08-16 19:26:25 -03:00
Salomão c466a0e00e fix items in level emitters with crafting cards not showing up 2021-08-14 09:44:47 -03:00
95 changed files with 4549 additions and 2525 deletions
+1 -1
View File
@@ -57,7 +57,7 @@ tasks.withType(JavaCompile) {
options.encoding = 'UTF-8' options.encoding = 'UTF-8'
} }
version = aeversion + "-" + aechannel + "-" + aebuild + " " + trousers version = trousers + "-" + aeversion + "-" + aechannel + "-" + aebuild + "-" + trousersversion
group = aegroup group = aegroup
archivesBaseName = aebasename archivesBaseName = aebasename
+2 -2
View File
@@ -3,8 +3,8 @@ aechannel=stable
aebuild=7 aebuild=7
aegroup=appeng aegroup=appeng
aebasename=appliedenergistics2 aebasename=appliedenergistics2
trousers=omni-fixes-v46e trousers=trousers_edition
trousersversion=v49t
######################################################### #########################################################
# Versions # # Versions #
######################################################### #########################################################
+1 -1
View File
@@ -31,7 +31,7 @@ repositories {
maven { maven {
name = "Tesla repo" name = "Tesla repo"
url "http://maven.mcmoddev.com" url "https://maven.mcmoddev.com"
} }
maven { maven {
@@ -58,6 +58,8 @@ public interface IParts
IItemDefinition storageBus(); IItemDefinition storageBus();
IItemDefinition oreDictStorageBus();
IItemDefinition importBus(); IItemDefinition importBus();
IItemDefinition exportBus(); IItemDefinition exportBus();
@@ -102,6 +104,8 @@ public interface IParts
IItemDefinition patternTerminal(); IItemDefinition patternTerminal();
IItemDefinition expandedProcessingPatternTerminal();
IItemDefinition craftingTerminal(); IItemDefinition craftingTerminal();
IItemDefinition terminal(); IItemDefinition terminal();
@@ -121,4 +121,8 @@ public interface IAEItemStack extends IAEStack<IAEItemStack>
*/ */
boolean equals(ItemStack is); boolean equals(ItemStack is);
ItemStack getCachedItemStack();
void setCachedItemStack(ItemStack is);
} }
@@ -104,7 +104,7 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngre
} }
if( doStart && GuiScreen.isShiftKeyDown() && Mouse.isButtonDown( 0 ) ) if( doStart && GuiScreen.isShiftKeyDown() && Mouse.isButtonDown( 0 ) )
{ {
if( gui instanceof GuiUpgradeable || gui instanceof GuiPatternTerm ) if( gui instanceof GuiUpgradeable || gui instanceof GuiPatternTerm || gui instanceof GuiExpandedProcessingPatternTerm )
{ {
IJEIGhostIngredients ghostGui = ( (IJEIGhostIngredients) gui ); IJEIGhostIngredients ghostGui = ( (IJEIGhostIngredients) gui );
for( Target<I> target : targets ) for( Target<I> target : targets )
@@ -21,6 +21,7 @@ package appeng.client.gui.implementations;
import java.io.IOException; import java.io.IOException;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@@ -123,6 +124,12 @@ public class GuiCraftAmount extends AEBaseGui
this.originalGui = GuiBridge.GUI_PATTERN_TERMINAL; this.originalGui = GuiBridge.GUI_PATTERN_TERMINAL;
} }
if( target instanceof PartExpandedProcessingPatternTerminal )
{
myIcon = parts.expandedProcessingPatternTerminal().maybeStack( 1 ).orElse( ItemStack.EMPTY );
this.originalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
}
if( this.originalGui != null && !myIcon.isEmpty() ) if( this.originalGui != null && !myIcon.isEmpty() )
{ {
this.buttonList.add( this.originalGuiBtn = new GuiTabButton( this.guiLeft + 154, this.guiTop, myIcon, myIcon.getDisplayName(), this.itemRender ) ); this.buttonList.add( this.originalGuiBtn = new GuiTabButton( this.guiLeft + 154, this.guiTop, myIcon, myIcon.getDisplayName(), this.itemRender ) );
@@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import org.lwjgl.input.Mouse; import org.lwjgl.input.Mouse;
@@ -104,6 +105,11 @@ public class GuiCraftConfirm extends AEBaseGui
{ {
this.OriginalGui = GuiBridge.GUI_PATTERN_TERMINAL; this.OriginalGui = GuiBridge.GUI_PATTERN_TERMINAL;
} }
if( te instanceof PartExpandedProcessingPatternTerminal )
{
this.OriginalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
}
} }
boolean isAutoStart() boolean isAutoStart()
@@ -25,6 +25,7 @@ package appeng.client.gui.implementations;
import java.io.IOException; import java.io.IOException;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import org.lwjgl.input.Mouse; import org.lwjgl.input.Mouse;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
@@ -95,6 +96,12 @@ public class GuiCraftingStatus extends GuiCraftingCPU
this.originalGui = GuiBridge.GUI_PATTERN_TERMINAL; this.originalGui = GuiBridge.GUI_PATTERN_TERMINAL;
} }
if( target instanceof PartExpandedProcessingPatternTerminal )
{
myIcon = parts.expandedProcessingPatternTerminal().maybeStack( 1 ).orElse( ItemStack.EMPTY );
this.originalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
}
} }
@Override @Override
@@ -0,0 +1,277 @@
package appeng.client.gui.implementations;
import appeng.api.config.ActionItems;
import appeng.api.config.ItemSubstitution;
import appeng.api.config.Settings;
import appeng.api.storage.ITerminalHost;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
import appeng.container.interfaces.IJEIGhostIngredients;
import appeng.container.slot.AppEngSlot;
import appeng.container.slot.SlotFake;
import appeng.core.AELog;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.helpers.InventoryAction;
import appeng.util.item.AEItemStack;
import mezz.jei.api.gui.IGhostIngredientHandler;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import java.awt.Rectangle;
import java.io.IOException;
import java.util.*;
public class GuiExpandedProcessingPatternTerm extends GuiMEMonitorable implements IJEIGhostIngredients
{
private static final String BACKGROUND_EXPANDED_PROCESSING_MODE = "guis/pattern_processing_expanded.png";
private static final String SUBSITUTION_DISABLE = "0";
private static final String SUBSITUTION_ENABLE = "1";
private static final String CRAFTMODE_CRFTING = "1";
private static final String CRAFTMODE_PROCESSING = "0";
private GuiTabButton tabCraftButton;
private GuiTabButton tabProcessButton;
private GuiImgButton substitutionsEnabledBtn;
private GuiImgButton substitutionsDisabledBtn;
private GuiImgButton encodeBtn;
private GuiImgButton clearBtn;
private GuiImgButton x2Btn;
private GuiImgButton x3Btn;
private GuiImgButton plusOneBtn;
private GuiImgButton divTwoBtn;
private GuiImgButton divThreeBtn;
private GuiImgButton minusOneBtn;
private GuiImgButton maxCountBtn;
public Map<IGhostIngredientHandler.Target<?>, Object> mapTargetSlot = new HashMap<>();
public GuiExpandedProcessingPatternTerm( final InventoryPlayer inventoryPlayer, final ITerminalHost te )
{
super( inventoryPlayer, te, new ContainerExpandedProcessingPatternTerm( inventoryPlayer, te ) );
this.setReservedSpace( 81 );
}
@Override
protected void actionPerformed( final GuiButton btn )
{
super.actionPerformed( btn );
try
{
if( this.tabCraftButton == btn || this.tabProcessButton == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.CraftMode", this.tabProcessButton == btn ? CRAFTMODE_CRFTING : CRAFTMODE_PROCESSING ) );
}
if( this.encodeBtn == btn )
{
if( isShiftKeyDown() )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Encode", "2" ) );
}
else
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Encode", "1" ) );
}
}
if( this.clearBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Clear", "1" ) );
}
if( this.x2Btn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.MultiplyByTwo", "1" ) );
}
if( this.x3Btn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.MultiplyByThree", "1" ) );
}
if( this.divTwoBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.DivideByTwo", "1" ) );
}
if( this.divThreeBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.DivideByThree", "1" ) );
}
if( this.plusOneBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.IncreaseByOne", "1" ) );
}
if( this.minusOneBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.DecreaseByOne", "1" ) );
}
if( this.maxCountBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.MaximizeCount", "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 )
{
AELog.error( e );
}
}
@Override
public void initGui()
{
super.initGui();
this.tabCraftButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.CRAFTING_TABLE ), GuiText.CraftingPattern.getLocal(), this.itemRender );
this.buttonList.add( this.tabCraftButton );
this.tabProcessButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.FURNACE ), GuiText.ProcessingPattern.getLocal(), this.itemRender );
this.buttonList.add( this.tabProcessButton );
this.substitutionsEnabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.ENABLED );
this.substitutionsEnabledBtn.setHalfSize( true );
this.buttonList.add( this.substitutionsEnabledBtn );
this.substitutionsDisabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.DISABLED );
this.substitutionsDisabledBtn.setHalfSize( true );
this.buttonList.add( this.substitutionsDisabledBtn );
this.clearBtn = new GuiImgButton( this.guiLeft + 74, this.guiTop + this.ySize - 163, Settings.ACTIONS, ActionItems.CLOSE );
this.clearBtn.setHalfSize( true );
this.buttonList.add( this.clearBtn );
this.x3Btn = new GuiImgButton( this.guiLeft + 131, this.guiTop + this.ySize - 158, Settings.ACTIONS, ActionItems.MULTIPLY_BY_THREE );
this.x3Btn.setHalfSize( true );
this.buttonList.add( this.x3Btn );
this.x2Btn = new GuiImgButton( this.guiLeft + 131, this.guiTop + this.ySize - 148, Settings.ACTIONS, ActionItems.MULTIPLY_BY_TWO );
this.x2Btn.setHalfSize( true );
this.buttonList.add( this.x2Btn );
this.plusOneBtn = new GuiImgButton( this.guiLeft + 131, this.guiTop + this.ySize - 110, Settings.ACTIONS, ActionItems.INCREASE_BY_ONE );
this.plusOneBtn.setHalfSize( true );
this.buttonList.add( this.plusOneBtn );
this.divThreeBtn = new GuiImgButton( this.guiLeft + 87, this.guiTop + this.ySize - 158, Settings.ACTIONS, ActionItems.DIVIDE_BY_THREE );
this.divThreeBtn.setHalfSize( true );
this.buttonList.add( this.divThreeBtn );
this.divTwoBtn = new GuiImgButton( this.guiLeft + 87, this.guiTop + this.ySize - 148, Settings.ACTIONS, ActionItems.DIVIDE_BY_TWO );
this.divTwoBtn.setHalfSize( true );
this.buttonList.add( this.divTwoBtn );
this.minusOneBtn = new GuiImgButton( this.guiLeft + 87, this.guiTop + this.ySize - 110, Settings.ACTIONS, ActionItems.DECREASE_BY_ONE );
this.minusOneBtn.setHalfSize( true );
this.buttonList.add( this.minusOneBtn );
//this.maxCountBtn = new GuiImgButton( this.guiLeft + 128, this.guiTop + this.ySize - 108, Settings.ACTIONS, ActionItems.MAX_COUNT );
//this.maxCountBtn.setHalfSize( true );
//this.buttonList.add( this.maxCountBtn );
this.encodeBtn = new GuiImgButton( this.guiLeft + 147, this.guiTop + this.ySize - 142, Settings.ACTIONS, ActionItems.ENCODE );
this.buttonList.add( this.encodeBtn );
}
@Override
public void drawFG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
{
this.tabCraftButton.visible = false;
this.tabProcessButton.visible = true;
this.substitutionsEnabledBtn.visible = false;
this.substitutionsDisabledBtn.visible = false;
this.x2Btn.visible = true;
this.x3Btn.visible = true;
this.divTwoBtn.visible = true;
this.divThreeBtn.visible = true;
this.plusOneBtn.visible = true;
this.minusOneBtn.visible = true;
//this.maxCountBtn.visible = true;
super.drawFG( offsetX, offsetY, mouseX, mouseY );
this.fontRenderer.drawString( GuiText.PatternTerminal.getLocal(), 8, this.ySize - 96 + 2 - this.getReservedSpace(), 4210752 );
}
@Override
protected String getBackground()
{
return BACKGROUND_EXPANDED_PROCESSING_MODE;
}
@Override
protected void repositionSlot( final AppEngSlot s )
{
final int offsetPlayerSide = s.isPlayerSide() ? 5 : 3;
s.yPos = s.getY() + this.ySize - 78 - offsetPlayerSide;
}
@Override
public List<IGhostIngredientHandler.Target<?>> getPhantomTargets( Object ingredient )
{
if( !( ingredient instanceof ItemStack ) )
{
return Collections.emptyList();
}
List<IGhostIngredientHandler.Target<?>> targets = new ArrayList<>();
for( Slot slot : this.inventorySlots.inventorySlots )
{
if( slot instanceof SlotFake )
{
ItemStack itemStack = (ItemStack) ingredient;
IGhostIngredientHandler.Target<Object> target = new IGhostIngredientHandler.Target<Object>()
{
@Override
public Rectangle getArea()
{
return new Rectangle( getGuiLeft() + slot.xPos, getGuiTop() + slot.yPos, 16, 16 );
}
@Override
public void accept( Object ingredient )
{
final PacketInventoryAction p;
try
{
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (SlotFake) slot, AEItemStack.fromItemStack( itemStack ) );
NetworkHandler.instance().sendToServer( p );
}
catch( IOException e )
{
e.printStackTrace();
}
}
};
targets.add( target );
mapTargetSlot.putIfAbsent( target, slot );
}
}
return targets;
}
@Override
public Map<IGhostIngredientHandler.Target<?>, Object> getFakeSlotTargetMap()
{
return mapTargetSlot;
}
}
@@ -0,0 +1,144 @@
package appeng.client.gui.implementations;
import appeng.api.config.ActionItems;
import appeng.api.config.Settings;
import appeng.client.gui.AEBaseGui;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.client.gui.widgets.MEGuiTextField;
import appeng.container.implementations.ContainerPartOreDictStorageBus;
import appeng.core.localization.GuiText;
import appeng.core.sync.GuiBridge;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketSwitchGuis;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.parts.misc.PartOreDicStorageBus;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
import java.io.IOException;
import java.util.regex.Pattern;
public class GuiPartOreDictStorageBus extends AEBaseGui
{
PartOreDicStorageBus part;
private GuiTabButton priority;
private GuiImgButton partition;
private static final Pattern ORE_DICTIONARY_FILTER = Pattern.compile( "\\*?[a-zA-Z0-9_|\\\\+(){,}?!=\\-\\[:\\]&^$]*\\*?" );
private MEGuiTextField searchFieldInputs;
public GuiPartOreDictStorageBus( final InventoryPlayer inventoryPlayer, final PartOreDicStorageBus te )
{
super( new ContainerPartOreDictStorageBus( inventoryPlayer, te ) );
part = te;
this.ySize = 84;
}
@Override
public void initGui()
{
super.initGui();
this.searchFieldInputs = new MEGuiTextField( this.fontRenderer, this.guiLeft + 3, this.guiTop + 22, 170, 12 );
this.searchFieldInputs.setEnableBackgroundDrawing( false );
this.searchFieldInputs.setMaxStringLength( 512 );
this.searchFieldInputs.setTextColor( 0xFFFFFF );
this.searchFieldInputs.setVisible( true );
this.searchFieldInputs.setFocused( false );
this.searchFieldInputs.setValidator( str -> ORE_DICTIONARY_FILTER.matcher( str ).matches() );
this.buttonList.add( this.priority = new GuiTabButton( this.guiLeft + 154, this.guiTop, 2 + 4 * 16, GuiText.Priority.getLocal(), this.itemRender ) );
this.buttonList.add( this.partition = new GuiImgButton( this.guiLeft - 18, this.guiTop + 28, Settings.ACTIONS, ActionItems.WRENCH ) );
try
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "OreDictStorageBus.getRegex", "1" ) );
}
catch( IOException e )
{
e.printStackTrace();
}
}
public void fillRegex( String regex )
{
this.searchFieldInputs.setText( regex );
}
@Override
protected void actionPerformed( final GuiButton btn ) throws IOException
{
super.actionPerformed( btn );
if( btn == this.priority )
{
NetworkHandler.instance().sendToServer( new PacketSwitchGuis( GuiBridge.GUI_PRIORITY ) );
}
if( btn == this.partition )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "StorageBus.Action", "Partition" ) );
try
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "OreDictStorageBus.getRegex", "1" ) );
}
catch( IOException e )
{
e.printStackTrace();
}
}
}
@Override
protected void mouseClicked( final int xCoord, final int yCoord, final int btn ) throws IOException
{
boolean wasFocused = this.searchFieldInputs.isFocused();
this.searchFieldInputs.mouseClicked( xCoord, yCoord, btn );
if( btn == 1 && this.searchFieldInputs.isMouseIn( xCoord, yCoord ) )
{
this.searchFieldInputs.setText( "" );
}
if( !searchFieldInputs.isFocused() && wasFocused )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "OreDictStorageBus.save", searchFieldInputs.getText() ) );
}
super.mouseClicked( xCoord, yCoord, btn );
}
@Override
protected void keyTyped( final char character, final int key ) throws IOException
{
if( !this.checkHotbarKeys( key ) )
{
if( !this.searchFieldInputs.textboxKeyTyped( character, key ) )
{
super.keyTyped( character, key );
}
}
}
@Override
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 );
}
@Override
public void drawBG( int offsetX, int offsetY, int mouseX, int mouseY )
{
this.bindTexture( "guis/oredictstoragebus.png" );
this.drawTexturedModalRect( offsetX, offsetY, 0, 0, 175, 85 );
if( this.searchFieldInputs != null )
{
this.searchFieldInputs.drawTextBox();
}
}
}
@@ -22,9 +22,10 @@ package appeng.client.render;
import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IAEFluidStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.RenderItem; import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
@@ -32,6 +33,7 @@ import appeng.api.storage.data.IAEItemStack;
import appeng.util.IWideReadableNumberConverter; import appeng.util.IWideReadableNumberConverter;
import appeng.util.ReadableNumberConverter; import appeng.util.ReadableNumberConverter;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import org.lwjgl.opengl.GL11;
/** /**
@@ -121,6 +123,49 @@ public class TesrRenderHelper
} }
} }
public static void renderFluid2d( FluidStack fluidStack, float scale )
{
if( fluidStack != null )
{
GlStateManager.pushMatrix();
int color = fluidStack.getFluid().getColor( fluidStack );
float r = ( color >> 16 & 255 ) / 255.0f;
float g = ( color >> 8 & 255 ) / 255.0f;
float b = ( color & 255 ) / 255.0f;
TextureAtlasSprite sprite = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite( fluidStack.getFluid().getStill( fluidStack ).toString() );
GlStateManager.enableBlend();
GlStateManager.blendFunc( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA );
GlStateManager.disableAlpha();
GlStateManager.disableLighting();
Minecraft.getMinecraft().getTextureManager().bindTexture( TextureMap.LOCATION_BLOCKS_TEXTURE );
Tessellator tess = Tessellator.getInstance();
BufferBuilder buf = tess.getBuffer();
float width = 0.4f;
float height = 0.4f;
float alpha = 1.0f;
float z = 0.0001f;
float x = -0.20f;
float y = -0.25f;
buf.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR );
double uMin = sprite.getInterpolatedU( 16D - width * 16D ), uMax = sprite.getInterpolatedU( width * 16D );
double vMin = sprite.getMinV(), vMax = sprite.getInterpolatedV( height * 16D );
buf.pos( x, y, z ).tex( uMin, vMin ).color( r, g, b, alpha ).endVertex();
buf.pos( x, y + height, z ).tex( uMin, vMax ).color( r, g, b, alpha ).endVertex();
buf.pos( x + width, y + height, z ).tex( uMax, vMax ).color( r, g, b, alpha ).endVertex();
buf.pos( x + width, y, z ).tex( uMax, vMin ).color( r, g, b, alpha ).endVertex();
tess.draw();
GlStateManager.enableLighting();
GlStateManager.enableAlpha();
GlStateManager.disableBlend();
GlStateManager.color( 1F, 1F, 1F, 1F );
GlStateManager.popMatrix();
}
}
/** /**
* Render an item in 2D and the given text below it. * Render an item in 2D and the given text below it.
* *
@@ -147,9 +192,9 @@ public class TesrRenderHelper
public static void renderFluid2dWithAmount( IAEFluidStack fluidStack, float scale, float spacing ) public static void renderFluid2dWithAmount( IAEFluidStack fluidStack, float scale, float spacing )
{ {
final ItemStack renderStack = fluidStack.asItemStackRepresentation(); final FluidStack renderStack = fluidStack.getFluidStack();
TesrRenderHelper.renderItem2d( renderStack, scale ); TesrRenderHelper.renderFluid2d( renderStack, scale );
final long stackSize = fluidStack.getStackSize() / 1000; final long stackSize = fluidStack.getStackSize() / 1000;
final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm( stackSize ) + "B"; final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm( stackSize ) + "B";
@@ -19,14 +19,9 @@
package appeng.client.render.model; package appeng.client.render.model;
import java.util.ArrayList; import appeng.block.storage.BlockDrive;
import java.util.List; import appeng.block.storage.DriveSlotState;
import java.util.Map; import appeng.block.storage.DriveSlotsState;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector3f;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.IBakedModel;
@@ -37,9 +32,12 @@ import net.minecraft.util.EnumFacing;
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad; import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState;
import appeng.block.storage.BlockDrive; import javax.annotation.Nullable;
import appeng.block.storage.DriveSlotState; import javax.vecmath.Matrix4f;
import appeng.block.storage.DriveSlotsState; import javax.vecmath.Vector3f;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class DriveBakedModel implements IBakedModel public class DriveBakedModel implements IBakedModel
@@ -57,13 +55,17 @@ public class DriveBakedModel implements IBakedModel
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand ) public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
{ {
List<BakedQuad> result = new ArrayList<>(); List<BakedQuad> result = new ArrayList<>( this.bakedBase.getQuads( state, side, rand ) );
result.addAll( this.bakedBase.getQuads( state, side, rand ) );
if( side == null && state instanceof IExtendedBlockState ) if( side == null && state instanceof IExtendedBlockState )
{ {
IExtendedBlockState extState = (IExtendedBlockState) state; IExtendedBlockState extState = (IExtendedBlockState) state;
if (!extState.getUnlistedNames().contains( BlockDrive.SLOTS_STATE ))
{
return result;
}
DriveSlotsState slotsState = extState.getValue( BlockDrive.SLOTS_STATE ); DriveSlotsState slotsState = extState.getValue( BlockDrive.SLOTS_STATE );
for( int row = 0; row < 5; row++ ) for( int row = 0; row < 5; row++ )
@@ -26,6 +26,7 @@ import java.util.concurrent.Future;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
@@ -345,11 +346,15 @@ public class ContainerCraftConfirm extends AEBaseContainer
originalGui = GuiBridge.GUI_PATTERN_TERMINAL; originalGui = GuiBridge.GUI_PATTERN_TERMINAL;
} }
if( ah instanceof PartExpandedProcessingPatternTerminal )
{
originalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
}
if( this.result != null && !this.isSimulation() ) if( this.result != null && !this.isSimulation() )
{ {
final ICraftingGrid cc = this.getGrid().getCache( ICraftingGrid.class ); final ICraftingGrid cc = this.getGrid().getCache( ICraftingGrid.class );
final ICraftingLink g = cc.submitJob( this.result, null, this.getSelectedCpu() == -1 ? null : this.cpus.get( this.getSelectedCpu() ).getCpu(), true, final ICraftingLink g = cc.submitJob( this.result, null, this.getSelectedCpu() == -1 ? null : this.cpus.get( this.getSelectedCpu() ).getCpu(), true, this.getActionSrc() );
this.getActionSrc() );
this.setAutoStart( false ); this.setAutoStart( false );
if( g != null && originalGui != null && this.getOpenContext() != null ) if( g != null && originalGui != null && this.getOpenContext() != null )
{ {
@@ -0,0 +1,528 @@
package appeng.container.implementations;
import appeng.api.AEApi;
import appeng.api.definitions.IDefinitions;
import appeng.api.storage.ITerminalHost;
import appeng.container.slot.*;
import appeng.helpers.IContainerCraftingPacket;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import appeng.util.Platform;
import appeng.util.inv.IAEAppEngInventory;
import appeng.util.inv.InvOperation;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.PlayerInvWrapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static appeng.helpers.PatternHelper.PROCESSING_INPUT_LIMIT;
import static appeng.helpers.PatternHelper.PROCESSING_OUTPUT_LIMIT;
public class ContainerExpandedProcessingPatternTerm extends ContainerMEMonitorable implements IAEAppEngInventory, IOptionalSlotHost, IContainerCraftingPacket
{
private final IItemHandler crafting;
private final SlotFakeCraftingMatrix[] gridSlots = new SlotFakeCraftingMatrix[PROCESSING_INPUT_LIMIT];
private final OptionalSlotFake[] outputSlots = new OptionalSlotFake[PROCESSING_OUTPUT_LIMIT];
private final SlotRestrictedInput patternSlotIN;
private final SlotRestrictedInput patternSlotOUT;
private final PartExpandedProcessingPatternTerminal expandedProcessingPatternTerminal;
public ContainerExpandedProcessingPatternTerm( InventoryPlayer ip, ITerminalHost monitorable )
{
super( ip, monitorable, false );
this.expandedProcessingPatternTerminal = (PartExpandedProcessingPatternTerminal) monitorable;
final IItemHandler patternInv = this.getExpandedPatternTerminal().getInventoryByName( "pattern" );
final IItemHandler output = this.getExpandedPatternTerminal().getInventoryByName( "output" );
this.crafting = this.getExpandedPatternTerminal().getInventoryByName( "crafting" );
for( int y = 0; y < 4; y++ )
{
for( int x = 0; x < 4; x++ )
{
this.addSlotToContainer( this.gridSlots[x + y * 4] = new SlotFakeCraftingMatrix( this.crafting, x + y * 4, 4 + x * 18, -85 + y * 18 ) );
}
}
for( int y = 0; y < 3; y++ )
{
for( int x = 0; x < 2; x++ )
{
this.addSlotToContainer( this.outputSlots[x + y * 2] = new SlotPatternOutputs( output, this, x + y * 2, 96 + x * 18, -76 + y * 18, 0, 0, 1 ) );
this.outputSlots[x + y * 2].setRenderDisabled( false );
this.outputSlots[x + y * 2].setIIcon( -1 );
}
}
this.addSlotToContainer( this.patternSlotIN = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.BLANK_PATTERN, patternInv, 0, 147, -72 - 9, this.getInventoryPlayer() ) );
this.addSlotToContainer( this.patternSlotOUT = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.ENCODED_PATTERN, patternInv, 1, 147, -72 + 34, this.getInventoryPlayer() ) );
this.patternSlotOUT.setStackLimit( 1 );
this.bindPlayerInventory( ip, 0, 0 );
}
@Override
public ItemStack transferStackInSlot( final EntityPlayer p, final int idx )
{
if( Platform.isClient() )
{
return ItemStack.EMPTY;
}
if( this.inventorySlots.get( idx ) instanceof SlotPlayerInv || this.inventorySlots.get( idx ) instanceof SlotPlayerHotBar )
{
final AppEngSlot clickSlot = (AppEngSlot) this.inventorySlots.get( idx ); // require AE SLots!
ItemStack itemStack = clickSlot.getStack();
if( AEApi.instance().definitions().materials().blankPattern().isSameAs( itemStack ) )
{
IItemHandler patternInv = this.getExpandedPatternTerminal().getInventoryByName( "pattern" );
ItemStack remainder = patternInv.insertItem( 0, itemStack, false );
clickSlot.putStack( remainder );
}
}
return super.transferStackInSlot( p, idx );
}
@Override
public void saveChanges()
{
}
@Override
public void onChangeInventory( final IItemHandler inv, final int slot, final InvOperation mc, final ItemStack removedStack, final ItemStack newStack )
{
}
public void encodeAndMoveToInventory()
{
encode();
ItemStack output = this.patternSlotOUT.getStack();
if( !output.isEmpty() )
{
if( !getPlayerInv().addItemStackToInventory( output ) )
{
getPlayerInv().player.dropItem( output, false );
}
this.patternSlotOUT.putStack( ItemStack.EMPTY );
}
}
public void encode()
{
ItemStack output = this.patternSlotOUT.getStack();
final ItemStack[] in = this.getInputs();
final ItemStack[] out = this.getOutputs();
// if there is no input, this would be silly.
if( in == null || out == null )
{
return;
}
// first check the output slots, should either be null, or a pattern
if( !output.isEmpty() && !this.isPattern( output ) )
{
return;
} // if nothing is there we should snag a new pattern.
else if( output.isEmpty() )
{
output = this.patternSlotIN.getStack();
if( output.isEmpty() || !this.isPattern( output ) )
{
return; // no blanks.
}
// remove one, and clear the input slot.
output.setCount( output.getCount() - 1 );
if( output.getCount() == 0 )
{
this.patternSlotIN.putStack( ItemStack.EMPTY );
}
// add a new encoded pattern.
Optional<ItemStack> maybePattern = AEApi.instance().definitions().items().encodedPattern().maybeStack( 1 );
if( maybePattern.isPresent() )
{
output = maybePattern.get();
this.patternSlotOUT.putStack( output );
}
}
// encode the slot.
final NBTTagCompound encodedValue = new NBTTagCompound();
final NBTTagList tagIn = new NBTTagList();
final NBTTagList tagOut = new NBTTagList();
for( final ItemStack i : in )
{
tagIn.appendTag( this.createItemTag( i ) );
}
for( final ItemStack i : out )
{
tagOut.appendTag( this.createItemTag( i ) );
}
encodedValue.setTag( "in", tagIn );
encodedValue.setTag( "out", tagOut );
encodedValue.setBoolean( "crafting", false );
encodedValue.setBoolean( "substitute", false );
output.setTagCompound( encodedValue );
}
boolean isPattern( final ItemStack output )
{
if( output.isEmpty() )
{
return false;
}
final IDefinitions definitions = AEApi.instance().definitions();
boolean isPattern = definitions.items().encodedPattern().isSameAs( output );
isPattern |= definitions.materials().blankPattern().isSameAs( output );
return isPattern;
}
NBTBase createItemTag( final ItemStack i )
{
final NBTTagCompound c = new NBTTagCompound();
if( !i.isEmpty() )
{
i.writeToNBT( c );
}
return c;
}
@Override
public boolean isSlotEnabled( final int idx )
{
return true;
}
protected ItemStack[] getInputs()
{
final ItemStack[] input = new ItemStack[16];
boolean hasValue = false;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() )
{
hasValue = true;
}
}
if( hasValue )
{
return input;
}
return null;
}
protected ItemStack[] getOutputs()
{
final List<ItemStack> list = new ArrayList<>( 3 );
boolean hasValue = false;
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( !out.isEmpty() && out.getCount() > 0 )
{
list.add( out );
hasValue = true;
}
}
if( hasValue )
{
return list.toArray( new ItemStack[0] );
}
return null;
}
public void clear()
{
for( final Slot s : this.gridSlots )
{
s.putStack( ItemStack.EMPTY );
}
for( final Slot s : this.outputSlots )
{
s.putStack( ItemStack.EMPTY );
}
this.detectAndSendChanges();
}
@Override
public IItemHandler getInventoryByName( final String name )
{
if( name.equals( "player" ) )
{
return new PlayerInvWrapper( this.getInventoryPlayer() );
}
return this.getExpandedPatternTerminal().getInventoryByName( name );
}
@Override
public boolean useRealItems()
{
return false;
}
public PartExpandedProcessingPatternTerminal getExpandedPatternTerminal()
{
return this.expandedProcessingPatternTerminal;
}
public void multiply( int multiple )
{
ItemStack[] input = new ItemStack[gridSlots.length];
boolean canMultiplyInputs = true;
boolean canMultiplyOutputs = true;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() && input[x].getCount() * multiple > input[x].getMaxStackSize() )
{
canMultiplyInputs = false;
}
}
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( !out.isEmpty() && out.getCount() * multiple > out.getMaxStackSize() )
{
canMultiplyOutputs = false;
}
}
if( canMultiplyInputs && canMultiplyOutputs )
{
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
{
ItemStack stack = craftingSlot.getStack();
if( !stack.isEmpty() )
{
craftingSlot.getStack().setCount( stack.getCount() * multiple );
}
}
for( OptionalSlotFake outputSlot : this.outputSlots )
{
ItemStack stack = outputSlot.getStack();
if( !stack.isEmpty() )
{
outputSlot.getStack().setCount( stack.getCount() * multiple );
}
}
}
}
public void divide( int divide )
{
ItemStack[] input = new ItemStack[gridSlots.length];
boolean canDivideInputs = true;
boolean canDivideOutputs = true;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() && input[x].getCount() % divide != 0 )
{
canDivideInputs = false;
}
}
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( !out.isEmpty() && out.getCount() % divide != 0 )
{
canDivideOutputs = false;
}
}
if( canDivideInputs && canDivideOutputs )
{
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
{
ItemStack stack = craftingSlot.getStack();
if( !stack.isEmpty() )
{
craftingSlot.getStack().setCount( stack.getCount() / divide );
}
}
for( OptionalSlotFake outputSlot : this.outputSlots )
{
ItemStack stack = outputSlot.getStack();
if( !stack.isEmpty() )
{
outputSlot.getStack().setCount( stack.getCount() / divide );
}
}
}
}
public void increase( int increase )
{
ItemStack[] input = new ItemStack[gridSlots.length];
boolean canIncreaseInputs = true;
boolean canIncreaseOutputs = true;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() && input[x].getCount() + increase > input[x].getMaxStackSize() )
{
canIncreaseInputs = false;
}
}
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( !out.isEmpty() && out.getCount() + increase > out.getMaxStackSize() )
{
canIncreaseOutputs = false;
}
}
if( canIncreaseInputs && canIncreaseOutputs )
{
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
{
ItemStack stack = craftingSlot.getStack();
if( !stack.isEmpty() )
{
craftingSlot.getStack().setCount( stack.getCount() + increase );
}
}
for( OptionalSlotFake outputSlot : this.outputSlots )
{
ItemStack stack = outputSlot.getStack();
if( !stack.isEmpty() )
{
outputSlot.getStack().setCount( stack.getCount() + increase );
}
}
}
}
public void decrease( int decrease )
{
ItemStack[] input = new ItemStack[gridSlots.length];
boolean canDecreaseInputs = true;
boolean canDecreaseOutputs = true;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() && input[x].getCount() - decrease < 1 )
{
canDecreaseInputs = false;
}
}
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( !out.isEmpty() && out.getCount() - decrease < 1 )
{
canDecreaseOutputs = false;
}
}
if( canDecreaseInputs && canDecreaseOutputs )
{
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
{
ItemStack stack = craftingSlot.getStack();
if( !stack.isEmpty() )
{
craftingSlot.getStack().setCount( stack.getCount() - decrease );
}
}
for( OptionalSlotFake outputSlot : this.outputSlots )
{
ItemStack stack = outputSlot.getStack();
if( !stack.isEmpty() )
{
outputSlot.getStack().setCount( stack.getCount() - decrease );
}
}
}
}
public void maximizeCount()
{
ItemStack[] input = new ItemStack[gridSlots.length];
boolean canGrowInputs = true;
boolean canGrowOutputs = true;
int maxInputStackGrowth = 0;
int maxOutputStackGrowth = 0;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() && input[x].getMaxStackSize() - input[x].getCount() > maxInputStackGrowth )
{
maxInputStackGrowth = input[x].getMaxStackSize() - input[x].getCount();
}
if( !input[x].isEmpty() && input[x].getCount() + maxInputStackGrowth > input[x].getMaxStackSize() )
{
canGrowInputs = false;
}
}
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
{
maxOutputStackGrowth = out.getMaxStackSize() - out.getCount();
}
if( !out.isEmpty() && out.getCount() + maxOutputStackGrowth > out.getMaxStackSize() )
{
canGrowOutputs = false;
}
}
if( canGrowInputs && canGrowOutputs )
{
int maxStackGrowth = Math.min( maxInputStackGrowth, maxOutputStackGrowth );
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
{
ItemStack stack = craftingSlot.getStack();
if( !stack.isEmpty() )
{
craftingSlot.getStack().setCount( stack.getCount() + maxStackGrowth );
}
}
for( OptionalSlotFake outputSlot : this.outputSlots )
{
ItemStack stack = outputSlot.getStack();
if( !stack.isEmpty() )
{
outputSlot.getStack().setCount( stack.getCount() + maxStackGrowth );
}
}
}
}
}
@@ -0,0 +1,113 @@
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;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class ContainerPartOreDictStorageBus extends AEBaseContainer
{
private final PartOreDicStorageBus part;
public ContainerPartOreDictStorageBus( final InventoryPlayer ip, final PartOreDicStorageBus anchor )
{
super( ip, anchor );
this.part = anchor;
this.bindPlayerInventory( ip, 14, 256 - /* height of player inventory */82 );
}
@Override
public void detectAndSendChanges()
{
if( Platform.isClient() )
{
return;
}
super.detectAndSendChanges();
}
public void partition()
{
final IMEInventory<IAEItemStack> cellInv = this.part.getInternalHandler();
Set<Integer> oreIDs = new HashSet<>();
for( IAEItemStack itemStack : cellInv.getAvailableItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList() ) )
{
OreReference ref = ( (AEItemStack) itemStack ).getOre().orElse( null );
if( ref != null )
{
oreIDs.addAll( ref.getOres() );
}
}
String oreMatch = "(";
String append = "";
for( Iterator<Integer> it = oreIDs.iterator(); it.hasNext(); )
{
int oreID = it.next();
if( it.hasNext() )
{
append = ")|(";
}
else
{
append = ")";
}
oreMatch = oreMatch.concat( OreDictionary.getOreName( oreID ) + append );
}
if( oreMatch.equals( "(" ) )
{
oreMatch = "";
}
part.saveOreMatch( oreMatch );
this.detectAndSendChanges();
}
public void saveOreMatch( String value )
{
part.saveOreMatch( value );
}
public void sendRegex()
{
try
{
NetworkHandler.instance().sendTo( new PacketValueConfig( "OreDictStorageBus.sendRegex", part.getOreMatch() ), (EntityPlayerMP) getInventoryPlayer().player );
}
catch( IOException e )
{
e.printStackTrace();
}
}
}
@@ -178,7 +178,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
this.getAndUpdateOutput(); this.getAndUpdateOutput();
} }
private ItemStack getAndUpdateOutput() protected ItemStack getAndUpdateOutput()
{ {
final World world = this.getPlayerInv().player.world; final World world = this.getPlayerInv().player.world;
final InventoryCrafting ic = new InventoryCrafting( this, 3, 3 ); final InventoryCrafting ic = new InventoryCrafting( this, 3, 3 );
@@ -505,7 +505,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
} }
} }
private ItemStack[] getInputs() protected ItemStack[] getInputs()
{ {
final ItemStack[] input = new ItemStack[9]; final ItemStack[] input = new ItemStack[9];
boolean hasValue = false; boolean hasValue = false;
@@ -527,7 +527,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
return null; return null;
} }
private ItemStack[] getOutputs() protected ItemStack[] getOutputs()
{ {
if( this.isCraftingMode() ) if( this.isCraftingMode() )
{ {
@@ -535,7 +535,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
if( !out.isEmpty() && out.getCount() > 0 ) if( !out.isEmpty() && out.getCount() > 0 )
{ {
return new ItemStack[] { out }; return new ItemStack[]{out};
} }
} }
else else
@@ -563,7 +563,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
return null; return null;
} }
private boolean isPattern( final ItemStack output ) boolean isPattern( final ItemStack output )
{ {
if( output.isEmpty() ) if( output.isEmpty() )
{ {
@@ -578,7 +578,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
return isPattern; return isPattern;
} }
private NBTBase createItemTag( final ItemStack i ) NBTBase createItemTag( final ItemStack i )
{ {
final NBTTagCompound c = new NBTTagCompound(); final NBTTagCompound c = new NBTTagCompound();
@@ -824,7 +824,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
return this.patternTerminal; return this.patternTerminal;
} }
private boolean isSubstitute() boolean isSubstitute()
{ {
return this.substitute; return this.substitute;
} }
@@ -52,6 +52,7 @@ public final class ApiParts implements IParts
private final IItemDefinition toggleBus; private final IItemDefinition toggleBus;
private final IItemDefinition invertedToggleBus; private final IItemDefinition invertedToggleBus;
private final IItemDefinition storageBus; private final IItemDefinition storageBus;
private final IItemDefinition oreDictStorageBus;
private final IItemDefinition importBus; private final IItemDefinition importBus;
private final IItemDefinition exportBus; private final IItemDefinition exportBus;
private final IItemDefinition iface; private final IItemDefinition iface;
@@ -77,6 +78,7 @@ public final class ApiParts implements IParts
private final IItemDefinition darkMonitor; private final IItemDefinition darkMonitor;
private final IItemDefinition interfaceTerminal; private final IItemDefinition interfaceTerminal;
private final IItemDefinition patternTerminal; private final IItemDefinition patternTerminal;
private final IItemDefinition expandedProcessingPatternTerminal;
private final IItemDefinition craftingTerminal; private final IItemDefinition craftingTerminal;
private final IItemDefinition terminal; private final IItemDefinition terminal;
private final IItemDefinition storageMonitor; private final IItemDefinition storageMonitor;
@@ -112,6 +114,7 @@ public final class ApiParts implements IParts
this.toggleBus = new DamagedItemDefinition( "part.toggle_bus", itemPart.createPart( PartType.TOGGLE_BUS ) ); this.toggleBus = new DamagedItemDefinition( "part.toggle_bus", itemPart.createPart( PartType.TOGGLE_BUS ) );
this.invertedToggleBus = new DamagedItemDefinition( "part.toggle_bus.inverted", itemPart.createPart( PartType.INVERTED_TOGGLE_BUS ) ); this.invertedToggleBus = new DamagedItemDefinition( "part.toggle_bus.inverted", itemPart.createPart( PartType.INVERTED_TOGGLE_BUS ) );
this.storageBus = new DamagedItemDefinition( "part.bus.storage", itemPart.createPart( PartType.STORAGE_BUS ) ); this.storageBus = new DamagedItemDefinition( "part.bus.storage", itemPart.createPart( PartType.STORAGE_BUS ) );
this.oreDictStorageBus = new DamagedItemDefinition( "part.bus.oredict_storage", itemPart.createPart( PartType.OREDICT_STORAGE_BUS ) );
this.importBus = new DamagedItemDefinition( "part.bus.import", itemPart.createPart( PartType.IMPORT_BUS ) ); this.importBus = new DamagedItemDefinition( "part.bus.import", itemPart.createPart( PartType.IMPORT_BUS ) );
this.exportBus = new DamagedItemDefinition( "part.bus.export", itemPart.createPart( PartType.EXPORT_BUS ) ); this.exportBus = new DamagedItemDefinition( "part.bus.export", itemPart.createPart( PartType.EXPORT_BUS ) );
this.iface = new DamagedItemDefinition( "part.interface", itemPart.createPart( PartType.INTERFACE ) ); this.iface = new DamagedItemDefinition( "part.interface", itemPart.createPart( PartType.INTERFACE ) );
@@ -139,6 +142,7 @@ public final class ApiParts implements IParts
this.darkMonitor = new DamagedItemDefinition( "part.monitor.dark", itemPart.createPart( PartType.DARK_MONITOR ) ); this.darkMonitor = new DamagedItemDefinition( "part.monitor.dark", itemPart.createPart( PartType.DARK_MONITOR ) );
this.interfaceTerminal = new DamagedItemDefinition( "part.terminal.interface", itemPart.createPart( PartType.INTERFACE_TERMINAL ) ); this.interfaceTerminal = new DamagedItemDefinition( "part.terminal.interface", itemPart.createPart( PartType.INTERFACE_TERMINAL ) );
this.patternTerminal = new DamagedItemDefinition( "part.terminal.pattern", itemPart.createPart( PartType.PATTERN_TERMINAL ) ); this.patternTerminal = new DamagedItemDefinition( "part.terminal.pattern", itemPart.createPart( PartType.PATTERN_TERMINAL ) );
this.expandedProcessingPatternTerminal = new DamagedItemDefinition( "part.terminal.expanded_processing_pattern", itemPart.createPart( PartType.EXPANDED_PROCESSING_PATTERN_TERMINAL ) );
this.craftingTerminal = new DamagedItemDefinition( "part.terminal.crafting", itemPart.createPart( PartType.CRAFTING_TERMINAL ) ); this.craftingTerminal = new DamagedItemDefinition( "part.terminal.crafting", itemPart.createPart( PartType.CRAFTING_TERMINAL ) );
this.terminal = new DamagedItemDefinition( "part.terminal", itemPart.createPart( PartType.TERMINAL ) ); this.terminal = new DamagedItemDefinition( "part.terminal", itemPart.createPart( PartType.TERMINAL ) );
this.storageMonitor = new DamagedItemDefinition( "part.monitor.storage", itemPart.createPart( PartType.STORAGE_MONITOR ) ); this.storageMonitor = new DamagedItemDefinition( "part.monitor.storage", itemPart.createPart( PartType.STORAGE_MONITOR ) );
@@ -245,6 +249,12 @@ public final class ApiParts implements IParts
return this.storageBus; return this.storageBus;
} }
@Override
public IItemDefinition oreDictStorageBus()
{
return this.oreDictStorageBus;
}
@Override @Override
public IItemDefinition importBus() public IItemDefinition importBus()
{ {
@@ -379,6 +389,12 @@ public final class ApiParts implements IParts
return this.patternTerminal; return this.patternTerminal;
} }
@Override
public IItemDefinition expandedProcessingPatternTerminal()
{
return this.expandedProcessingPatternTerminal;
}
@Override @Override
public IItemDefinition craftingTerminal() public IItemDefinition craftingTerminal()
{ {
@@ -70,6 +70,7 @@ public enum GuiText
EnergyDrain, EnergyDrain,
StorageBus, StorageBus,
OreDictStorageBus,
StorageBusFluids, StorageBusFluids,
Priority, Priority,
Security, Security,
@@ -31,8 +31,10 @@ public enum WailaText
DeviceMissingChannel, DeviceMissingChannel,
P2PUnlinked, P2PUnlinked,
P2PInputOneOutput, P2P_INPUT_ONE_OUTPUT,
P2PInputManyOutputs, P2P_INPUT_MANY_OUTPUTS,
P2P_OUTPUT_ONE_INPUT,
P2P_OUTPUT_MANY_INPUTS,
P2POutput, P2POutput,
Locked, Locked,
+7 -33
View File
@@ -21,6 +21,9 @@ package appeng.core.sync;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import appeng.container.implementations.*;
import appeng.parts.misc.PartOreDicStorageBus;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@@ -53,39 +56,6 @@ import appeng.client.gui.GuiNull;
import appeng.container.AEBaseContainer; import appeng.container.AEBaseContainer;
import appeng.container.ContainerNull; import appeng.container.ContainerNull;
import appeng.container.ContainerOpenContext; import appeng.container.ContainerOpenContext;
import appeng.container.implementations.ContainerCellWorkbench;
import appeng.container.implementations.ContainerChest;
import appeng.container.implementations.ContainerCondenser;
import appeng.container.implementations.ContainerCraftAmount;
import appeng.container.implementations.ContainerCraftConfirm;
import appeng.container.implementations.ContainerCraftingCPU;
import appeng.container.implementations.ContainerCraftingStatus;
import appeng.container.implementations.ContainerCraftingTerm;
import appeng.container.implementations.ContainerDrive;
import appeng.container.implementations.ContainerFormationPlane;
import appeng.container.implementations.ContainerGrinder;
import appeng.container.implementations.ContainerIOPort;
import appeng.container.implementations.ContainerInscriber;
import appeng.container.implementations.ContainerInterface;
import appeng.container.implementations.ContainerInterfaceTerminal;
import appeng.container.implementations.ContainerLevelEmitter;
import appeng.container.implementations.ContainerMAC;
import appeng.container.implementations.ContainerMEMonitorable;
import appeng.container.implementations.ContainerMEPortableCell;
import appeng.container.implementations.ContainerNetworkStatus;
import appeng.container.implementations.ContainerNetworkTool;
import appeng.container.implementations.ContainerPatternTerm;
import appeng.container.implementations.ContainerPriority;
import appeng.container.implementations.ContainerQNB;
import appeng.container.implementations.ContainerQuartzKnife;
import appeng.container.implementations.ContainerSecurityStation;
import appeng.container.implementations.ContainerSkyChest;
import appeng.container.implementations.ContainerSpatialIOPort;
import appeng.container.implementations.ContainerStorageBus;
import appeng.container.implementations.ContainerUpgradeable;
import appeng.container.implementations.ContainerVibrationChamber;
import appeng.container.implementations.ContainerWireless;
import appeng.container.implementations.ContainerWirelessTerm;
import appeng.fluids.container.ContainerFluidFormationPlane; import appeng.fluids.container.ContainerFluidFormationPlane;
import appeng.fluids.container.ContainerFluidIO; import appeng.fluids.container.ContainerFluidIO;
import appeng.fluids.container.ContainerFluidInterface; import appeng.fluids.container.ContainerFluidInterface;
@@ -171,6 +141,8 @@ public enum GuiBridge implements IGuiHandler
GUI_STORAGEBUS( ContainerStorageBus.class, PartStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ), GUI_STORAGEBUS( ContainerStorageBus.class, PartStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
GUI_OREDICTSTORAGEBUS( ContainerPartOreDictStorageBus.class, PartOreDicStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
GUI_STORAGEBUS_FLUID( ContainerFluidStorageBus.class, PartFluidStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ), GUI_STORAGEBUS_FLUID( ContainerFluidStorageBus.class, PartFluidStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
GUI_FORMATION_PLANE( ContainerFormationPlane.class, PartFormationPlane.class, GuiHostType.WORLD, SecurityPermissions.BUILD ), GUI_FORMATION_PLANE( ContainerFormationPlane.class, PartFormationPlane.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
@@ -185,6 +157,8 @@ public enum GuiBridge implements IGuiHandler
GUI_PATTERN_TERMINAL( ContainerPatternTerm.class, PartPatternTerminal.class, GuiHostType.WORLD, SecurityPermissions.CRAFT ), GUI_PATTERN_TERMINAL( ContainerPatternTerm.class, PartPatternTerminal.class, GuiHostType.WORLD, SecurityPermissions.CRAFT ),
GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL( ContainerExpandedProcessingPatternTerm.class, PartExpandedProcessingPatternTerminal.class, GuiHostType.WORLD, SecurityPermissions.CRAFT ),
GUI_FLUID_TERMINAL( ContainerFluidTerminal.class, ITerminalHost.class, GuiHostType.WORLD, SecurityPermissions.BUILD ), GUI_FLUID_TERMINAL( ContainerFluidTerminal.class, ITerminalHost.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
// extends (Container/Gui) + Bus // extends (Container/Gui) + Bus
@@ -192,7 +192,20 @@ public class PacketInventoryAction extends AppEngPacket
} }
else if( this.action == InventoryAction.PLACE_JEI_GHOST_ITEM ) else if( this.action == InventoryAction.PLACE_JEI_GHOST_ITEM )
{ {
if( sender.openContainer.inventorySlots.get( this.slot ) instanceof SlotFake ) if( sender.openContainer instanceof ContainerFluidConfigurable )
{
if( this.slotItem != null )
{
IAEFluidStack aefs = AEFluidStack.fromNBT( this.slotItem.getDefinition().getTagCompound() );
if( aefs != null )
{
aefs.setStackSize( 1000 );
( (ContainerFluidConfigurable) sender.openContainer ).getFluidConfigInventory().setFluidInSlot( this.slot, aefs );
NetworkHandler.instance().sendToServer( new PacketFluidSlot( Collections.singletonMap( this.slot, aefs ) ) );
}
}
}
else if( this.slot < sender.openContainer.inventorySlots.size() && sender.openContainer.inventorySlots.get( this.slot ) instanceof SlotFake )
{ {
if( this.slotItem != null ) if( this.slotItem != null )
{ {
@@ -217,20 +230,6 @@ public class PacketInventoryAction extends AppEngPacket
AELog.debug( e ); AELog.debug( e );
} }
} }
if( sender.openContainer instanceof ContainerFluidConfigurable )
{
if( this.slotItem != null )
{
IAEFluidStack aefs = AEFluidStack.fromNBT( this.slotItem.getDefinition().getTagCompound() );
if( aefs != null )
{
aefs.setStackSize( 1000 );
( (ContainerFluidConfigurable) sender.openContainer ).getFluidConfigInventory().setFluidInSlot( this.slot, aefs );
NetworkHandler.instance().sendToServer( new PacketFluidSlot( Collections.singletonMap( this.slot, aefs ) ) );
}
}
}
} }
else else
{ {
@@ -23,11 +23,12 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.List;
import appeng.api.config.FuzzyMode; import appeng.api.config.FuzzyMode;
import appeng.api.storage.data.IItemList; import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
import appeng.container.implementations.ContainerPatternTerm; import appeng.container.implementations.ContainerPatternTerm;
import gregtech.common.items.MetaTool; import gregtech.common.items.MetaTool;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
@@ -69,8 +70,9 @@ import appeng.util.prioritylist.IPartitionList;
public class PacketJEIRecipe extends AppEngPacket public class PacketJEIRecipe extends AppEngPacket
{ {
private ItemStack[][] recipe; private List<ItemStack[]> recipe;
private ItemStack[] output; private List<ItemStack> output;
static ItemStack[] emptyArray = {ItemStack.EMPTY};
// automatic. // automatic.
@@ -81,28 +83,35 @@ public class PacketJEIRecipe extends AppEngPacket
final NBTTagCompound comp = CompressedStreamTools.readCompressed( bytes ); final NBTTagCompound comp = CompressedStreamTools.readCompressed( bytes );
if( comp != null ) if( comp != null )
{ {
this.recipe = new ItemStack[9][]; this.recipe = new ArrayList<>();
for( int x = 0; x < this.recipe.length; x++ )
for( int x = 0; x < comp.getKeySet().size(); x++ )
{ {
final NBTTagList list = comp.getTagList( "#" + x, 10 ); if( comp.hasKey( "#" + x ) )
if( list.tagCount() > 0 )
{ {
this.recipe[x] = new ItemStack[list.tagCount()]; final NBTTagList list = comp.getTagList( "#" + x, 10 );
for( int y = 0; y < list.tagCount(); y++ ) if( list.tagCount() > 0 )
{ {
this.recipe[x][y] = new ItemStack( list.getCompoundTagAt( y ) ); this.recipe.add( new ItemStack[list.tagCount()] );
for( int y = 0; y < list.tagCount(); y++ )
{
this.recipe.get( x )[y] = new ItemStack( list.getCompoundTagAt( y ) );
}
}
else
{
this.recipe.add( emptyArray );
} }
} }
} }
if ( comp.hasKey("outputs") ) {
final NBTTagList outputList = comp.getTagList("outputs", 10); if( comp.hasKey( "outputs" ) )
this.output = new ItemStack[3]; {
for( int x = 0; x < this.output.length; x++ ) final NBTTagList outputList = comp.getTagList( "outputs", 10 );
this.output = new ArrayList<>();
for( int z = 0; z < outputList.tagCount(); z++ )
{ {
if( outputList.tagCount() > 0 ) this.output.add( new ItemStack( outputList.getCompoundTagAt( z ) ) );
{
this.output[x] = new ItemStack(outputList.getCompoundTagAt( x ));
}
} }
} }
} }
@@ -166,15 +175,22 @@ public class PacketJEIRecipe extends AppEngPacket
{ {
ItemStack currentItem = craftMatrix.getStackInSlot( x ); ItemStack currentItem = craftMatrix.getStackInSlot( x );
if (x >= this.recipe.size()) {
currentItem = ItemStack.EMPTY;
}
// prepare slots // prepare slots
if( !currentItem.isEmpty() ) if( !currentItem.isEmpty() )
{ {
// already the correct item? // already the correct item?
ItemStack newItem = this.canUseInSlot( x, currentItem ); ItemStack newItem = this.canUseInSlot( x, currentItem );
if ( !cct.useRealItems() && this.recipe[x] != null ) { if( !cct.useRealItems() && this.recipe.get( x ) != null )
if (this.recipe[x].length > 0 ) {
currentItem.setCount( recipe[x][0].getCount() ); if( this.recipe.get( x ).length > 0 )
{
currentItem.setCount( recipe.get( x )[0].getCount() );
}
} }
// put away old item // put away old item
@@ -193,12 +209,12 @@ public class PacketJEIRecipe extends AppEngPacket
} }
} }
if( currentItem.isEmpty() && this.recipe[x] != null ) if( currentItem.isEmpty() && recipe.size() > x && recipe.get( x ) != null )
{ {
// for each variant // for each variant
for( int y = 0; y < this.recipe[x].length && currentItem.isEmpty(); y++ ) for( int y = 0; y < this.recipe.get( x ).length && currentItem.isEmpty(); y++ )
{ {
final IAEItemStack request = AEItemStack.fromItemStack( this.recipe[x][y] ); final IAEItemStack request = AEItemStack.fromItemStack( this.recipe.get( x )[y] );
if( request != null ) if( request != null )
{ {
// try ae // try ae
@@ -247,7 +263,7 @@ public class PacketJEIRecipe extends AppEngPacket
{ {
if (!cct.useRealItems()) if (!cct.useRealItems())
{ {
out.setStackSize( recipe[x][y].getCount() ); out.setStackSize( recipe.get( x )[y].getCount() );
} }
currentItem = out.createItemStack(); currentItem = out.createItemStack();
} }
@@ -260,20 +276,20 @@ public class PacketJEIRecipe extends AppEngPacket
if( cct.useRealItems() ) if( cct.useRealItems() )
{ {
currentItem = ad.removeSimilarItems(1, this.recipe[x][y],FuzzyMode.IGNORE_ALL, null ); currentItem = ad.removeSimilarItems( 1, this.recipe.get( x )[y], FuzzyMode.IGNORE_ALL, null );
} }
else else
{ {
currentItem = ad.simulateSimilarRemove(recipe[x][y].getCount(), this.recipe[x][y],FuzzyMode.IGNORE_ALL, null ); currentItem = ad.simulateSimilarRemove( recipe.get( x )[y].getCount(), this.recipe.get( x )[y], FuzzyMode.IGNORE_ALL, null );
} }
} }
} }
} }
if (!cct.useRealItems()) if (!cct.useRealItems())
{ {
if( currentItem.isEmpty() && this.recipe[x] != null ) if( currentItem.isEmpty() && recipe.size() > x && this.recipe.get( x ) != null )
{ {
currentItem = this.recipe[x][0].copy(); currentItem = this.recipe.get( x )[0].copy();
} }
} }
} }
@@ -282,14 +298,19 @@ public class PacketJEIRecipe extends AppEngPacket
con.onCraftMatrixChanged( new WrapperInvItemHandler( craftMatrix ) ); con.onCraftMatrixChanged( new WrapperInvItemHandler( craftMatrix ) );
if( this.output != null && con instanceof ContainerPatternTerm && !( (ContainerPatternTerm) con ).isCraftingMode() ) if( this.output != null && ( ( con instanceof ContainerPatternTerm && !( (ContainerPatternTerm) con ).isCraftingMode() ) || con instanceof ContainerExpandedProcessingPatternTerm ) )
{ {
IItemHandler outputSlots = cct.getInventoryByName( "output" ); IItemHandler outputSlots = cct.getInventoryByName( "output" );
for( int i = 0; i < this.output.length; ++i )
for( int i = 0; i < this.output.size(); ++i )
{ {
if( this.output[i] == null ) continue; if( this.output.get( i ) == null )
ItemHandlerUtil.setStackInSlot( outputSlots, i, this.output[i] ); {
continue;
}
ItemHandlerUtil.setStackInSlot( outputSlots, i, this.output.get( i ) );
} }
} }
} }
} }
@@ -302,9 +323,9 @@ public class PacketJEIRecipe extends AppEngPacket
*/ */
private ItemStack canUseInSlot( int slot, ItemStack is ) private ItemStack canUseInSlot( int slot, ItemStack is )
{ {
if( this.recipe[slot] != null ) if( this.recipe.get( slot ) != null )
{ {
for( ItemStack option : this.recipe[slot] ) for( ItemStack option : this.recipe.get( slot ) )
{ {
if( ItemStack.areItemStacksEqual( is, option ) ) if( ItemStack.areItemStacksEqual( is, option ) )
{ {
@@ -24,6 +24,8 @@ import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import appeng.client.gui.implementations.GuiPartOreDictStorageBus;
import appeng.container.implementations.*;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
@@ -40,17 +42,6 @@ import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject; import appeng.api.util.IConfigurableObject;
import appeng.client.gui.implementations.GuiCraftingCPU; import appeng.client.gui.implementations.GuiCraftingCPU;
import appeng.container.AEBaseContainer; import appeng.container.AEBaseContainer;
import appeng.container.implementations.ContainerCellWorkbench;
import appeng.container.implementations.ContainerCraftConfirm;
import appeng.container.implementations.ContainerCraftingCPU;
import appeng.container.implementations.ContainerCraftingStatus;
import appeng.container.implementations.ContainerLevelEmitter;
import appeng.container.implementations.ContainerNetworkTool;
import appeng.container.implementations.ContainerPatternTerm;
import appeng.container.implementations.ContainerPriority;
import appeng.container.implementations.ContainerQuartzKnife;
import appeng.container.implementations.ContainerSecurityStation;
import appeng.container.implementations.ContainerStorageBus;
import appeng.core.sync.AppEngPacket; import appeng.core.sync.AppEngPacket;
import appeng.core.sync.network.INetworkInfo; import appeng.core.sync.network.INetworkInfo;
import appeng.fluids.container.ContainerFluidLevelEmitter; import appeng.fluids.container.ContainerFluidLevelEmitter;
@@ -166,58 +157,109 @@ public class PacketValueConfig extends AppEngPacket
final ContainerFluidLevelEmitter lvc = (ContainerFluidLevelEmitter) c; final ContainerFluidLevelEmitter lvc = (ContainerFluidLevelEmitter) c;
lvc.setLevel( Long.parseLong( this.Value ), player ); lvc.setLevel( Long.parseLong( this.Value ), player );
} }
else if( this.Name.startsWith( "PatternTerminal." ) && c instanceof ContainerPatternTerm ) else if( this.Name.startsWith( "PatternTerminal." ) )
{ {
final ContainerPatternTerm cpt = (ContainerPatternTerm) c; if( c instanceof ContainerPatternTerm )
if( this.Name.equals( "PatternTerminal.CraftMode" ) )
{ {
cpt.getPatternTerminal().setCraftingRecipe( this.Value.equals( "1" ) ); final ContainerPatternTerm cpt = (ContainerPatternTerm) c;
} if( this.Name.equals( "PatternTerminal.CraftMode" ) )
else if( this.Name.equals( "PatternTerminal.Encode" ) )
{
if (this.Value.equals( "2" )) {
cpt.encodeAndMoveToInventory();
}
else
{ {
cpt.encode(); cpt.getPatternTerminal().setCraftingRecipe( this.Value.equals( "1" ) );
}
else if( this.Name.equals( "PatternTerminal.Encode" ) )
{
if( this.Value.equals( "2" ) )
{
cpt.encodeAndMoveToInventory();
}
else
{
cpt.encode();
}
}
else if( this.Name.equals( "PatternTerminal.Clear" ) )
{
cpt.clear();
}
else if( this.Name.equals( "PatternTerminal.MultiplyByTwo" ) )
{
cpt.multiply( 2 );
}
else if( this.Name.equals( "PatternTerminal.MultiplyByThree" ) )
{
cpt.multiply( 3 );
}
else if( this.Name.equals( "PatternTerminal.DivideByTwo" ) )
{
cpt.divide( 2 );
}
else if( this.Name.equals( "PatternTerminal.DivideByThree" ) )
{
cpt.divide( 3 );
}
else if( this.Name.equals( "PatternTerminal.IncreaseByOne" ) )
{
cpt.increase( 1 );
}
else if( this.Name.equals( "PatternTerminal.DecreaseByOne" ) )
{
cpt.decrease( 1 );
}
else if( this.Name.equals( "PatternTerminal.MaximizeCount" ) )
{
cpt.maximizeCount();
}
else if( this.Name.equals( "PatternTerminal.Substitute" ) )
{
cpt.getPatternTerminal().setSubstitution( this.Value.equals( "1" ) );
} }
} }
else if( this.Name.equals( "PatternTerminal.Clear" ) ) else if( c instanceof ContainerExpandedProcessingPatternTerm )
{ {
cpt.clear(); final ContainerExpandedProcessingPatternTerm cept = (ContainerExpandedProcessingPatternTerm) c;
} if( this.Name.equals( "PatternTerminal.Encode" ) )
else if( this.Name.equals( "PatternTerminal.MultiplyByTwo" ) ) {
{ if( this.Value.equals( "2" ) )
cpt.multiply(2); {
} cept.encodeAndMoveToInventory();
else if( this.Name.equals( "PatternTerminal.MultiplyByThree" ) ) }
{ else
cpt.multiply(3); {
} cept.encode();
else if( this.Name.equals( "PatternTerminal.DivideByTwo" ) ) }
{ }
cpt.divide(2); else if( this.Name.equals( "PatternTerminal.Clear" ) )
} {
else if( this.Name.equals( "PatternTerminal.DivideByThree" ) ) cept.clear();
{ }
cpt.divide(3); else if( this.Name.equals( "PatternTerminal.MultiplyByTwo" ) )
} {
else if( this.Name.equals( "PatternTerminal.IncreaseByOne" ) ) cept.multiply( 2 );
{ }
cpt.increase(1); else if( this.Name.equals( "PatternTerminal.MultiplyByThree" ) )
} {
else if( this.Name.equals( "PatternTerminal.DecreaseByOne" ) ) cept.multiply( 3 );
{ }
cpt.decrease(1); else if( this.Name.equals( "PatternTerminal.DivideByTwo" ) )
} {
else if( this.Name.equals( "PatternTerminal.MaximizeCount" ) ) cept.divide( 2 );
{ }
cpt.maximizeCount(); else if( this.Name.equals( "PatternTerminal.DivideByThree" ) )
} {
else if( this.Name.equals( "PatternTerminal.Substitute" ) ) cept.divide( 3 );
{ }
cpt.getPatternTerminal().setSubstitution( this.Value.equals( "1" ) ); else if( this.Name.equals( "PatternTerminal.IncreaseByOne" ) )
{
cept.increase( 1 );
}
else if( this.Name.equals( "PatternTerminal.DecreaseByOne" ) )
{
cept.decrease( 1 );
}
else if( this.Name.equals( "PatternTerminal.MaximizeCount" ) )
{
cept.maximizeCount();
}
} }
} }
else if( this.Name.startsWith( "StorageBus." ) ) else if( this.Name.startsWith( "StorageBus." ) )
@@ -234,6 +276,10 @@ public class PacketValueConfig extends AppEngPacket
{ {
( (ContainerFluidStorageBus) c ).partition(); ( (ContainerFluidStorageBus) c ).partition();
} }
else if( c instanceof ContainerPartOreDictStorageBus )
{
( (ContainerPartOreDictStorageBus) c ).partition();
}
} }
else if( this.Value.equals( "Clear" ) ) else if( this.Value.equals( "Clear" ) )
{ {
@@ -248,6 +294,20 @@ public class PacketValueConfig extends AppEngPacket
} }
} }
} }
else if( this.Name.startsWith( "OreDictStorageBus" ) )
{
if( c instanceof ContainerPartOreDictStorageBus )
{
if( this.Name.equals( "OreDictStorageBus.save" ) )
{
( (ContainerPartOreDictStorageBus) c ).saveOreMatch( this.Value );
}
if( this.Name.equals( "OreDictStorageBus.getRegex" ) )
{
( (ContainerPartOreDictStorageBus) c ).sendRegex();
}
}
}
else if( this.Name.startsWith( "CellWorkbench." ) && c instanceof ContainerCellWorkbench ) else if( this.Name.startsWith( "CellWorkbench." ) && c instanceof ContainerCellWorkbench )
{ {
final ContainerCellWorkbench ccw = (ContainerCellWorkbench) c; final ContainerCellWorkbench ccw = (ContainerCellWorkbench) c;
@@ -324,6 +384,14 @@ public class PacketValueConfig extends AppEngPacket
( (GuiCraftingCPU) gs ).clearItems(); ( (GuiCraftingCPU) gs ).clearItems();
} }
} }
else if( this.Name.equals( "OreDictStorageBus.sendRegex" ) )
{
final GuiScreen gs = Minecraft.getMinecraft().currentScreen;
if( gs instanceof GuiPartOreDictStorageBus )
{
( (GuiPartOreDictStorageBus) gs ).fillRegex( this.Value );
}
}
else if( c instanceof IConfigurableObject ) else if( c instanceof IConfigurableObject )
{ {
final IConfigManager cm = ( (IConfigurableObject) c ).getConfigManager(); final IConfigManager cm = ( (IConfigurableObject) c ).getConfigManager();
@@ -25,6 +25,7 @@ import java.util.List;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World; import net.minecraft.world.World;
import appeng.api.AEApi; import appeng.api.AEApi;
@@ -123,18 +124,43 @@ public class CraftingTreeNode
final List<IAEItemStack> thingsUsed = new ArrayList<>(); final List<IAEItemStack> thingsUsed = new ArrayList<>();
this.what.setStackSize( l ); this.what.setStackSize( l );
if( this.getSlot() >= 0 && this.parent != null && this.parent.details.isCraftable() ) IAEItemStack available = inv.extractItems( this.what, Actionable.MODULATE, src );
if( available != null )
{
if( !this.exhausted )
{
final IAEItemStack is = this.job.checkUse( available );
if( is != null )
{
thingsUsed.add( is.copy() );
this.used.add( is );
}
}
this.bytes += available.getStackSize();
l -= available.getStackSize();
if( l == 0 )
{
return available;
}
}
else if( this.getSlot() >= 0 && this.parent != null && this.parent.details.isCraftable() )
{ {
final Collection<IAEItemStack> itemList; final Collection<IAEItemStack> itemList;
final IItemList<IAEItemStack> inventoryList = inv.getItemList(); final IItemList<IAEItemStack> inventoryList = inv.getItemList();
if( this.parent.details.canSubstitute() ) if( this.parent.details.canSubstitute() )
{ {
final List<IAEItemStack> substitutes = this.parent.details.getSubstituteInputs(this.slot); final List<IAEItemStack> substitutes = this.parent.details.getSubstituteInputs( this.slot );
itemList = new ArrayList<>(substitutes.size()); itemList = new ArrayList<>( substitutes.size() );
for (IAEItemStack stack : substitutes) { for( IAEItemStack stack : substitutes )
itemList.addAll(inventoryList.findFuzzy(stack, FuzzyMode.IGNORE_ALL)); {
itemList.addAll( inventoryList.findFuzzy( stack, FuzzyMode.IGNORE_ALL ) );
} }
} }
else else
@@ -156,7 +182,7 @@ public class CraftingTreeNode
fuzz = fuzz.copy(); fuzz = fuzz.copy();
fuzz.setStackSize( l ); fuzz.setStackSize( l );
final IAEItemStack available = inv.extractItems( fuzz, Actionable.MODULATE, src ); available = inv.extractItems( fuzz, Actionable.MODULATE, src );
if( available != null ) if( available != null )
{ {
@@ -182,32 +208,6 @@ public class CraftingTreeNode
} }
} }
} }
else
{
final IAEItemStack available = inv.extractItems( this.what, Actionable.MODULATE, src );
if( available != null )
{
if( !this.exhausted )
{
final IAEItemStack is = this.job.checkUse( available );
if( is != null )
{
thingsUsed.add( is.copy() );
this.used.add( is );
}
}
this.bytes += available.getStackSize();
l -= available.getStackSize();
if( l == 0 )
{
return available;
}
}
}
if( this.canEmit ) if( this.canEmit )
{ {
@@ -226,7 +226,7 @@ public class CraftingTreeNode
{ {
final CraftingTreeProcess pro = this.nodes.get( 0 ); final CraftingTreeProcess pro = this.nodes.get( 0 );
while( pro.possible && l > 0 ) while ( pro.possible && l > 0 )
{ {
final IAEItemStack madeWhat = pro.getAmountCrafted( this.what ); final IAEItemStack madeWhat = pro.getAmountCrafted( this.what );
@@ -234,7 +234,7 @@ public class CraftingTreeNode
madeWhat.setStackSize( l ); madeWhat.setStackSize( l );
final IAEItemStack available = inv.extractItems( madeWhat, Actionable.MODULATE, src ); available = inv.extractItems( madeWhat, Actionable.MODULATE, src );
if( available != null ) if( available != null )
{ {
@@ -258,13 +258,13 @@ public class CraftingTreeNode
{ {
try try
{ {
while( pro.possible && l > 0 ) while ( pro.possible && l > 0 )
{ {
final MECraftingInventory subInv = new MECraftingInventory( inv, true, true, true ); final MECraftingInventory subInv = new MECraftingInventory( inv, true, true, true );
pro.request( subInv, 1, src ); pro.request( subInv, 1, src );
this.what.setStackSize( l ); this.what.setStackSize( l );
final IAEItemStack available = subInv.extractItems( this.what, Actionable.MODULATE, src ); available = subInv.extractItems( this.what, Actionable.MODULATE, src );
if( available != null ) if( available != null )
{ {
@@ -321,7 +321,7 @@ public class CraftingTreeNode
} }
// missing = 0; // missing = 0;
job.addBytes( 8 + this.bytes ); job.addBytes( this.bytes );
for( final CraftingTreeProcess pro : this.nodes ) for( final CraftingTreeProcess pro : this.nodes )
{ {
@@ -358,6 +358,10 @@ public class CraftingTreeNode
if( ex == null || ex.getStackSize() != i.getStackSize() ) if( ex == null || ex.getStackSize() != i.getStackSize() )
{ {
if( src.player().isPresent() )
{
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + i.getStackSize() + " " + i.getDefinition().getItem().getItemStackDisplayName( i.getDefinition() ) + " available but could not extract anything" ), false );
}
throw new CraftBranchFailure( i, i.getStackSize() ); throw new CraftBranchFailure( i, i.getStackSize() );
} }
@@ -241,7 +241,6 @@ public class CraftingTreeProcess
o.setStackSize( o.getStackSize() * i ); o.setStackSize( o.getStackSize() * i );
inv.injectItems( o, Actionable.MODULATE, src ); inv.injectItems( o, Actionable.MODULATE, src );
} }
this.crafts += i; this.crafts += i;
} }
@@ -253,7 +252,7 @@ public class CraftingTreeProcess
pro.dive( job ); pro.dive( job );
} }
job.addBytes( 8 + this.crafts + this.bytes ); job.addBytes( this.crafts + 8 + this.bytes );
} }
IAEItemStack getAmountCrafted( IAEItemStack what2 ) IAEItemStack getAmountCrafted( IAEItemStack what2 )
@@ -305,7 +304,7 @@ public class CraftingTreeProcess
void getPlan( final IItemList<IAEItemStack> plan ) void getPlan( final IItemList<IAEItemStack> plan )
{ {
for( IAEItemStack i : this.details.getCondensedOutputs() ) for( IAEItemStack i : this.details.getOutputs() )
{ {
i = i.copy(); i = i.copy();
i.setCountRequestable( i.getStackSize() * this.crafts ); i.setCountRequestable( i.getStackSize() * this.crafts );
@@ -312,9 +312,13 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
if( src.player().isPresent() ) if( src.player().isPresent() )
{ {
if( result == null ) if( result == null )
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could not extract anything" ), false ); {
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getItem().getItemStackDisplayName( extra.getDefinition() ) + " available but could not extract anything" ), false );
}
else else
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could only extract " + result.getStackSize() ), false ); {
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getItem().getItemStackDisplayName( extra.getDefinition() ) + " available but could only extract " + result.getStackSize() ), false );
}
} }
failed = true; failed = true;
if( !src.player().isPresent() ) break; if( !src.player().isPresent() ) break;
@@ -91,12 +91,10 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
private int isWorking = -1; private int isWorking = -1;
private int priority; private int priority;
private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance() private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
.storage() private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) );
.getStorageChannel( IItemStorageChannel.class ) ); private boolean resetConfigCache = true;
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance() private IMEMonitor<IAEFluidStack> configCachedHandler;
.storage()
.getStorageChannel( IFluidStorageChannel.class ) );
public DualityFluidInterface( final AENetworkProxy networkProxy, final IFluidInterfaceHost ih ) public DualityFluidInterface( final AENetworkProxy networkProxy, final IFluidInterfaceHost ih )
{ {
@@ -119,15 +117,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
public IUpgradeableHost getHost() public IUpgradeableHost getHost()
{ {
if( this.iHost instanceof IUpgradeableHost ) return this.iHost;
{
return this.iHost;
}
if( this.iHost instanceof IUpgradeableHost )
{
return this.iHost;
}
return null;
} }
@Override @Override
@@ -146,7 +136,12 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
{ {
if( this.hasConfig() ) if( this.hasConfig() )
{ {
return (IMEMonitor<T>) new InterfaceInventory( this ); if( resetConfigCache )
{
resetConfigCache = false;
configCachedHandler = new InterfaceInventory( this );
}
return (IMEMonitor<T>) configCachedHandler;
} }
return (IMEMonitor<T>) this.fluids; return (IMEMonitor<T>) this.fluids;
@@ -383,7 +378,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
{ {
changed = true; changed = true;
} }
else else if( this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ).getStorageList().findPrecise( work ) != null )
{ {
final IAEFluidStack acquired = Platform.poweredExtraction( src, dest, work, this.interfaceRequestSource ); final IAEFluidStack acquired = Platform.poweredExtraction( src, dest, work, this.interfaceRequestSource );
if( acquired != null ) if( acquired != null )
@@ -450,7 +445,13 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
if( inventory == this.config ) if( inventory == this.config )
{ {
boolean cfg = hasConfig();
this.readConfig(); this.readConfig();
if( cfg != hasConfig )
{
resetConfigCache = true;
this.notifyNeighbors();
}
} }
else if( inventory == this.tanks ) else if( inventory == this.tanks )
{ {
@@ -555,7 +556,6 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
InterfaceInventory( final DualityFluidInterface tileInterface ) InterfaceInventory( final DualityFluidInterface tileInterface )
{ {
super( tileInterface.tanks ); super( tileInterface.tanks );
this.setActionSource( new MachineSource( tileInterface.iHost ) );
} }
@Override @Override
@@ -232,18 +232,11 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
for( IFluidTankProperties tankProperty : tankProperties ) for( IFluidTankProperties tankProperty : tankProperties )
{ {
FluidStack newFS = tankProperty.getContents(); if( this.mode == StorageFilter.EXTRACTABLE_ONLY && this.fluidHandler.drain( 1, false ) == null )
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && newFS != null )
{ {
if( this.fluidHandler.drain( 1, false ) == null ) continue;
{
newFS = null;
}
}
if( newFS != null )
{
currentlyOnStorage.add( AEFluidStack.fromFluidStack( newFS ) );
} }
currentlyOnStorage.add( AEFluidStack.fromFluidStack( tankProperty.getContents() ) );
} }
for ( final IAEFluidStack is : currentlyCached ) for ( final IAEFluidStack is : currentlyCached )
@@ -178,8 +178,9 @@ public class PartFluidFormationPlane extends PartAbstractFormationPlane<IAEFluid
this.stateChanged(); this.stateChanged();
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void updateChannels( final MENetworkChannelsChanged changedChannels ) public void chanRender( final MENetworkChannelsChanged changedChannels )
{ {
this.stateChanged(); this.stateChanged();
} }
@@ -90,14 +90,16 @@ public class PartFluidInterface extends PartBasicState implements IGridTickable,
return this.duality; return this.duality;
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void stateChange( final MENetworkChannelsChanged c ) public void chanRender( final MENetworkChannelsChanged c )
{ {
this.duality.notifyNeighbors(); this.duality.notifyNeighbors();
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void stateChange( final MENetworkPowerStatusChange c ) public void powerRender( final MENetworkPowerStatusChange c )
{ {
this.duality.notifyNeighbors(); this.duality.notifyNeighbors();
} }
@@ -4,7 +4,6 @@ package appeng.fluids.parts;
import java.util.Random; import java.util.Random;
import appeng.api.networking.events.MENetworkChannelChanged;
import appeng.api.storage.data.IItemList; import appeng.api.storage.data.IItemList;
import appeng.fluids.helper.IConfigurableFluidInventory; import appeng.fluids.helper.IConfigurableFluidInventory;
import appeng.me.cache.NetworkMonitor; import appeng.me.cache.NetworkMonitor;
@@ -116,9 +115,9 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
@Override @Override
public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan ) public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan )
{ {
if( chan == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) && diffStack.equals( this.config.getFluidInSlot( 0 ) ) ) if( chan == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) && fullStack.equals( this.config.getFluidInSlot( 0 ) ) )
{ {
this.lastReportedValue += diffStack.getStackSize(); this.lastReportedValue = fullStack.getStackSize();
this.updateState(); this.updateState();
} }
} }
@@ -129,8 +128,9 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
this.configureWatchers(); this.configureWatchers();
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void powerStatusChange( final MENetworkPowerStatusChange powerEvent ) public void powerRender( final MENetworkPowerStatusChange powerEvent )
{ {
if (this.getProxy().isActive()) if (this.getProxy().isActive())
{ {
@@ -139,8 +139,9 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
this.updateState(); this.updateState();
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void channelChanged( final MENetworkChannelsChanged c ) public void chanRender( final MENetworkChannelsChanged c )
{ {
if (this.getProxy().isActive()) if (this.getProxy().isActive())
{ {
File diff suppressed because it is too large Load Diff
@@ -23,7 +23,6 @@ import java.util.*;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import appeng.api.definitions.IItemDefinition;
import appeng.integration.modules.gregtech.GTCEInventoryAdaptor; import appeng.integration.modules.gregtech.GTCEInventoryAdaptor;
import appeng.util.*; import appeng.util.*;
import appeng.util.inv.*; import appeng.util.inv.*;
@@ -35,7 +34,6 @@ import gregtech.api.metatileentity.MetaTileEntity;
import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.metatileentity.MetaTileEntityHolder;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Items; import net.minecraft.init.Items;
import net.minecraft.inventory.InventoryCrafting; import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@@ -142,15 +140,17 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private int isWorking = -1; private int isWorking = -1;
private final Accessor accessor = new Accessor(); private final Accessor accessor = new Accessor();
private EnumSet<EnumFacing> visitedFaces = EnumSet.noneOf( EnumFacing.class ); private EnumSet<EnumFacing> visitedFaces = EnumSet.noneOf( EnumFacing.class );
private EnumMap<EnumFacing,List<ItemStack>> waitingToSendFacing = new EnumMap<>(EnumFacing.class); private EnumMap<EnumFacing, List<ItemStack>> waitingToSendFacing = new EnumMap<>( EnumFacing.class );
private GTCEInventoryAdaptor GTad; private GTCEInventoryAdaptor GTad;
private boolean resetConfigCache = true;
private IMEMonitor<IAEItemStack> configCachedHandler;
public DualityInterface( final AENetworkProxy networkProxy, final IInterfaceHost ih ) public DualityInterface( final AENetworkProxy networkProxy, final IInterfaceHost ih )
{ {
this.gridProxy = networkProxy; this.gridProxy = networkProxy;
this.gridProxy.setFlags( GridFlags.REQUIRE_CHANNEL ); this.gridProxy.setFlags( GridFlags.REQUIRE_CHANNEL );
this.upgrades = new StackUpgradeInventory( this.gridProxy.getMachineRepresentation(), this, 4); this.upgrades = new StackUpgradeInventory( this.gridProxy.getMachineRepresentation(), this, 4 );
this.cm.registerSetting( Settings.BLOCK, YesNo.NO ); this.cm.registerSetting( Settings.BLOCK, YesNo.NO );
this.cm.registerSetting( Settings.INTERFACE_TERMINAL, YesNo.YES ); this.cm.registerSetting( Settings.INTERFACE_TERMINAL, YesNo.YES );
@@ -178,9 +178,15 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{ {
return; return;
} }
if( inv == this.config ) if( inv == this.config && ( !removed.isEmpty() || !added.isEmpty() ) )
{ {
boolean cfg = hasConfig();
this.readConfig(); this.readConfig();
if( cfg != hasConfig )
{
resetConfigCache = true;
this.notifyNeighbors();
}
} }
else if( inv == this.patterns && ( !removed.isEmpty() || !added.isEmpty() ) ) else if( inv == this.patterns && ( !removed.isEmpty() || !added.isEmpty() ) )
{ {
@@ -851,19 +857,26 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
throw new GridAccessException(); throw new GridAccessException();
} }
final IAEItemStack acquired = Platform.poweredExtraction( src, this.destination, itemStack, this.interfaceRequestSource ); IAEItemStack storedStack = this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findPrecise( itemStack );
if( acquired != null ) if( storedStack != null )
{ {
changed = true; if( storedStack.getStackSize() > 0 )
final ItemStack issue = adaptor.addItems( acquired.createItemStack() );
if( !issue.isEmpty() )
{ {
throw new IllegalStateException( "bad attempt at managing inventory. ( addItems )" ); final IAEItemStack acquired = Platform.poweredExtraction( src, this.destination, itemStack, this.interfaceRequestSource );
if( acquired != null )
{
changed = true;
final ItemStack issue = adaptor.addItems( acquired.createItemStack() );
if( !issue.isEmpty() )
{
throw new IllegalStateException( "bad attempt at managing inventory. ( addItems )" );
}
}
}
else if( storedStack.isCraftable() )
{
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
} }
}
else
{
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
} }
} }
else if( itemStack.getStackSize() < 0 ) else if( itemStack.getStackSize() < 0 )
@@ -975,7 +988,12 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{ {
if( this.hasConfig() ) if( this.hasConfig() )
{ {
return (IMEMonitor<T>) new InterfaceInventory( this ); if( resetConfigCache )
{
resetConfigCache = false;
configCachedHandler = new InterfaceInventory( this );
}
return (IMEMonitor<T>) configCachedHandler;
} }
return (IMEMonitor<T>) this.items; return (IMEMonitor<T>) this.items;
@@ -1583,7 +1601,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
public InterfaceInventory( final DualityInterface tileInterface ) public InterfaceInventory( final DualityInterface tileInterface )
{ {
super( new AdaptorItemHandler( tileInterface.storage ) ); super( new AdaptorItemHandler( tileInterface.storage ) );
this.setActionSource( new MachineSource( DualityInterface.this.iHost ) );
} }
@Override @Override
+14 -12
View File
@@ -20,7 +20,6 @@ package appeng.helpers;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import net.minecraft.inventory.InventoryCrafting; import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@@ -38,9 +37,6 @@ import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEItemStack;
import appeng.container.ContainerNull; import appeng.container.ContainerNull;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.core.features.AEFeature;
import appeng.util.Platform; import appeng.util.Platform;
import appeng.util.item.AEItemStack; import appeng.util.item.AEItemStack;
import net.minecraftforge.common.crafting.IShapedRecipe; import net.minecraftforge.common.crafting.IShapedRecipe;
@@ -50,13 +46,16 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
{ {
private static final int CRAFTING_GRID_DIMENSION = 3; private static final int CRAFTING_GRID_DIMENSION = 3;
private static final int ALL_INPUT_LIMIT = CRAFTING_GRID_DIMENSION * CRAFTING_GRID_DIMENSION; private static final int CRAFTING_INPUT_LIMIT = CRAFTING_GRID_DIMENSION * CRAFTING_GRID_DIMENSION;
public static final int PROCESSING_INPUT_HEIGHT = 4;
public static final int PROCESSING_INPUT_WIDTH = 4;
public static final int PROCESSING_INPUT_LIMIT = PROCESSING_INPUT_HEIGHT * PROCESSING_INPUT_WIDTH;
private static final int CRAFTING_OUTPUT_LIMIT = 1; private static final int CRAFTING_OUTPUT_LIMIT = 1;
private static final int PROCESSING_OUTPUT_LIMIT = 3; public static final int PROCESSING_OUTPUT_LIMIT = 6;
private final ItemStack patternItem; private final ItemStack patternItem;
private final InventoryCrafting crafting = new InventoryCrafting( new ContainerNull(), 3, 3 ); private final InventoryCrafting crafting;
private final InventoryCrafting testFrame = new InventoryCrafting( new ContainerNull(), 3, 3 ); private final InventoryCrafting testFrame;
private final ItemStack correctOutput; private final ItemStack correctOutput;
private final IRecipe standardRecipe; private final IRecipe standardRecipe;
private final IAEItemStack[] condensedInputs; private final IAEItemStack[] condensedInputs;
@@ -84,6 +83,9 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
final NBTTagList outTag = encodedValue.getTagList( "out", 10 ); final NBTTagList outTag = encodedValue.getTagList( "out", 10 );
this.isCrafting = encodedValue.getBoolean( "crafting" ); this.isCrafting = encodedValue.getBoolean( "crafting" );
crafting = new InventoryCrafting( new ContainerNull(), isCrafting ? 3 : 4, isCrafting ? 3 : 4 );
testFrame = new InventoryCrafting( new ContainerNull(), isCrafting ? 3 : 4, isCrafting ? 3 : 4 );
this.canSubstitute = this.isCrafting && encodedValue.getBoolean( "substitute" ); this.canSubstitute = this.isCrafting && encodedValue.getBoolean( "substitute" );
this.patternItem = is; this.patternItem = is;
this.pattern = AEItemStack.fromItemStack( is ); this.pattern = AEItemStack.fromItemStack( is );
@@ -147,11 +149,11 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
} }
} }
} }
final int outputLength = this.isCrafting ? CRAFTING_OUTPUT_LIMIT : PROCESSING_OUTPUT_LIMIT; final int outputLength = out.size();
this.inputs = in.toArray(new IAEItemStack[ALL_INPUT_LIMIT]); this.inputs = in.toArray( new IAEItemStack[isCrafting ? CRAFTING_INPUT_LIMIT : PROCESSING_INPUT_LIMIT] );
this.outputs = out.toArray(new IAEItemStack[outputLength]); this.outputs = out.toArray( new IAEItemStack[outputLength] );
this.substituteInputs = new HashMap<>(ALL_INPUT_LIMIT); this.substituteInputs = new HashMap<>( CRAFTING_INPUT_LIMIT );
final Map<IAEItemStack, IAEItemStack> tmpOutputs = new HashMap<>(); final Map<IAEItemStack, IAEItemStack> tmpOutputs = new HashMap<>();
@@ -26,6 +26,7 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import appeng.client.gui.AEGuiHandler; import appeng.client.gui.AEGuiHandler;
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@@ -90,16 +91,13 @@ public class JEIPlugin implements IModPlugin
this.registerDescriptions( definitions, registry ); this.registerDescriptions( definitions, registry );
// Allow recipe transfer from JEI to crafting and pattern terminal // Allow recipe transfer from JEI to crafting and pattern terminal
registry.getRecipeTransferRegistry() registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerCraftingTerm.class ), VanillaRecipeCategoryUid.CRAFTING );
.addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerCraftingTerm.class ), registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ), Constants.UNIVERSAL_RECIPE_TRANSFER_UID );
VanillaRecipeCategoryUid.CRAFTING ); registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerExpandedProcessingPatternTerm.class ), Constants.UNIVERSAL_RECIPE_TRANSFER_UID );
registry.getRecipeTransferRegistry()
.addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ),
Constants.UNIVERSAL_RECIPE_TRANSFER_UID );
aeGuiHandler = new AEGuiHandler(); aeGuiHandler = new AEGuiHandler();
registry.addAdvancedGuiHandlers(aeGuiHandler); registry.addAdvancedGuiHandlers( aeGuiHandler );
registry.addGhostIngredientHandler( aeGuiHandler.getGuiContainerClass(), aeGuiHandler); registry.addGhostIngredientHandler( aeGuiHandler.getGuiContainerClass(), aeGuiHandler );
} }
private void registerDescriptions( IDefinitions definitions, IModRegistry registry ) private void registerDescriptions( IDefinitions definitions, IModRegistry registry )
@@ -35,6 +35,8 @@ public enum TheOneProbeText
P2P_UNLINKED, P2P_UNLINKED,
P2P_INPUT_ONE_OUTPUT, P2P_INPUT_ONE_OUTPUT,
P2P_INPUT_MANY_OUTPUTS, P2P_INPUT_MANY_OUTPUTS,
P2P_OUTPUT_ONE_INPUT,
P2P_OUTPUT_MANY_INPUTS,
P2P_OUTPUT, P2P_OUTPUT,
P2P_FREQUENCY, P2P_FREQUENCY,
@@ -57,11 +57,11 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
// The default state // The default state
int state = STATE_UNLINKED; int state = STATE_UNLINKED;
int outputCount = 0; int outputCount = getOutputCount( tunnel );
int inputCount = getInputCount( tunnel );
if( !tunnel.isOutput() ) if( !tunnel.isOutput() )
{ {
outputCount = getOutputCount( tunnel );
if( outputCount > 0 ) if( outputCount > 0 )
{ {
// Only set it to INPUT if we know there are any outputs // Only set it to INPUT if we know there are any outputs
@@ -70,8 +70,7 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
} }
else else
{ {
final PartP2PTunnel input = tunnel.getInput(); if( inputCount > 0 )
if( input != null )
{ {
state = STATE_OUTPUT; state = STATE_OUTPUT;
} }
@@ -83,7 +82,7 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
probeInfo.text( TheOneProbeText.P2P_UNLINKED.getLocal() ); probeInfo.text( TheOneProbeText.P2P_UNLINKED.getLocal() );
break; break;
case STATE_OUTPUT: case STATE_OUTPUT:
probeInfo.text( TheOneProbeText.P2P_OUTPUT.getLocal() ); probeInfo.text( getInputText( inputCount ) );
break; break;
case STATE_INPUT: case STATE_INPUT:
probeInfo.text( getOutputText( outputCount ) ); probeInfo.text( getOutputText( outputCount ) );
@@ -110,6 +109,19 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
} }
} }
private static int getInputCount( PartP2PTunnel tunnel )
{
try
{
return Iterators.size( tunnel.getInputs().iterator() );
}
catch( GridAccessException e )
{
// Well... unknown size it is!
return 0;
}
}
private static String getOutputText( int outputs ) private static String getOutputText( int outputs )
{ {
if( outputs <= 1 ) if( outputs <= 1 )
@@ -122,4 +134,16 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
} }
} }
private static String getInputText( int inputs )
{
if( inputs <= 1 )
{
return TheOneProbeText.P2P_OUTPUT_ONE_INPUT.getLocal();
}
else
{
return String.format( TheOneProbeText.P2P_OUTPUT_MANY_INPUTS.getLocal(), inputs );
}
}
} }
@@ -21,6 +21,7 @@ package appeng.integration.modules.waila.part;
import java.util.List; import java.util.List;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
import com.google.common.collect.Iterators; import com.google.common.collect.Iterators;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
@@ -117,11 +118,11 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
// The default state // The default state
int state = STATE_UNLINKED; int state = STATE_UNLINKED;
int outputCount = 0; int outputCount = getOutputCount( tunnel );
int inputCount = getInputCount( tunnel );
if( !tunnel.isOutput() ) if( !tunnel.isOutput() )
{ {
outputCount = getOutputCount( tunnel );
if( outputCount > 0 ) if( outputCount > 0 )
{ {
// Only set it to INPUT if we know there are any outputs // Only set it to INPUT if we know there are any outputs
@@ -130,8 +131,7 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
} }
else else
{ {
PartP2PTunnel input = tunnel.getInput(); if( inputCount > 0 )
if( input != null )
{ {
state = STATE_OUTPUT; state = STATE_OUTPUT;
} }
@@ -160,15 +160,40 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
} }
} }
private static int getInputCount( PartP2PTunnel tunnel )
{
try
{
return Iterators.size( tunnel.getInputs().iterator() );
}
catch( GridAccessException e )
{
// Well... unknown size it is!
return 0;
}
}
private static String getOutputText( int outputs ) private static String getOutputText( int outputs )
{ {
if( outputs <= 1 ) if( outputs <= 1 )
{ {
return WailaText.P2PInputOneOutput.getLocal(); return WailaText.P2P_INPUT_ONE_OUTPUT.getLocal();
} }
else else
{ {
return String.format( WailaText.P2PInputManyOutputs.getLocal(), outputs ); return String.format( WailaText.P2P_INPUT_MANY_OUTPUTS.getLocal(), outputs );
}
}
private static String getInputText( int inputs )
{
if( inputs <= 1 )
{
return WailaText.P2P_OUTPUT_ONE_INPUT.getLocal();
}
else
{
return String.format( WailaText.P2P_OUTPUT_MANY_INPUTS.getLocal(), inputs );
} }
} }
@@ -19,6 +19,7 @@
package appeng.items.contents; package appeng.items.contents;
import appeng.api.networking.security.IActionSource;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
@@ -42,6 +43,8 @@ import appeng.me.helpers.MEMonitorHandler;
import appeng.util.ConfigManager; import appeng.util.ConfigManager;
import appeng.util.Platform; import appeng.util.Platform;
import java.util.Collections;
public class PortableCellViewer extends MEMonitorHandler<IAEItemStack> implements IPortableCell, IInventorySlotAware public class PortableCellViewer extends MEMonitorHandler<IAEItemStack> implements IPortableCell, IInventorySlotAware
{ {
@@ -83,6 +86,34 @@ public class PortableCellViewer extends MEMonitorHandler<IAEItemStack> implement
return usePowerMultiplier.divide( this.ips.extractAEPower( this.target, amt, Actionable.MODULATE ) ); return usePowerMultiplier.divide( this.ips.extractAEPower( this.target, amt, Actionable.MODULATE ) );
} }
@Override
public IAEItemStack injectItems( IAEItemStack input, Actionable mode, IActionSource src )
{
final long size = input.getStackSize();
final IAEItemStack injected = super.injectItems( input, mode, src );
if( mode == Actionable.MODULATE && ( injected == null || injected.getStackSize() != size ) )
{
this.notifyListenersOfChange( Collections.singletonList( input.copy().setStackSize( input.getStackSize() - ( injected == null ? 0 : injected.getStackSize() ) ) ), null);
}
return injected;
}
@Override
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
{
final IAEItemStack extractable = super.extractItems( request, mode, src );
if( mode == Actionable.MODULATE && extractable != null )
{
this.notifyListenersOfChange( Collections.singletonList( request.copy().setStackSize( -extractable.getStackSize() ) ), null );
}
return extractable;
}
@Override @Override
public <T extends IAEStack<T>> IMEMonitor<T> getInventory( IStorageChannel<T> channel ) public <T extends IAEStack<T>> IMEMonitor<T> getInventory( IStorageChannel<T> channel )
{ {
@@ -225,7 +225,7 @@ public class ItemEncodedPattern extends AEBaseItem implements ICraftingPatternIt
final ICraftingPatternDetails details = this.getPatternForItem( item, w ); final ICraftingPatternDetails details = this.getPatternForItem( item, w );
out = details != null ? details.getCondensedOutputs()[0].createItemStack() : ItemStack.EMPTY; out = details != null ? details.getOutputs()[0].createItemStack() : ItemStack.EMPTY;
SIMPLE_CACHE.put( item, out ); SIMPLE_CACHE.put( item, out );
return out; return out;
+59 -83
View File
@@ -28,6 +28,8 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import appeng.parts.misc.*;
import appeng.parts.reporting.*;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.block.model.ModelResourceLocation;
@@ -57,11 +59,6 @@ import appeng.parts.automation.PartFormationPlane;
import appeng.parts.automation.PartIdentityAnnihilationPlane; import appeng.parts.automation.PartIdentityAnnihilationPlane;
import appeng.parts.automation.PartImportBus; import appeng.parts.automation.PartImportBus;
import appeng.parts.automation.PartLevelEmitter; import appeng.parts.automation.PartLevelEmitter;
import appeng.parts.misc.PartCableAnchor;
import appeng.parts.misc.PartInterface;
import appeng.parts.misc.PartInvertedToggleBus;
import appeng.parts.misc.PartStorageBus;
import appeng.parts.misc.PartToggleBus;
import appeng.parts.networking.PartCableCovered; import appeng.parts.networking.PartCableCovered;
import appeng.parts.networking.PartCableGlass; import appeng.parts.networking.PartCableGlass;
import appeng.parts.networking.PartCableSmart; import appeng.parts.networking.PartCableSmart;
@@ -75,15 +72,6 @@ import appeng.parts.p2p.PartP2PItems;
import appeng.parts.p2p.PartP2PLight; import appeng.parts.p2p.PartP2PLight;
import appeng.parts.p2p.PartP2PRedstone; import appeng.parts.p2p.PartP2PRedstone;
import appeng.parts.p2p.PartP2PTunnelME; import appeng.parts.p2p.PartP2PTunnelME;
import appeng.parts.reporting.PartConversionMonitor;
import appeng.parts.reporting.PartCraftingTerminal;
import appeng.parts.reporting.PartDarkPanel;
import appeng.parts.reporting.PartInterfaceTerminal;
import appeng.parts.reporting.PartPanel;
import appeng.parts.reporting.PartPatternTerminal;
import appeng.parts.reporting.PartSemiDarkPanel;
import appeng.parts.reporting.PartStorageMonitor;
import appeng.parts.reporting.PartTerminal;
import appeng.util.Platform; import appeng.util.Platform;
@@ -193,14 +181,13 @@ public enum PartType
MONITOR( 160, "monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartPanel.class, "itemIlluminatedPanel" ), MONITOR( 160, "monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartPanel.class, "itemIlluminatedPanel" ),
SEMI_DARK_MONITOR( 180, "semi_dark_monitor", EnumSet.of( AEFeature.PANELS ), EnumSet SEMI_DARK_MONITOR( 180, "semi_dark_monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartSemiDarkPanel.class, "itemIlluminatedPanel" ),
.noneOf( IntegrationType.class ), PartSemiDarkPanel.class, "itemIlluminatedPanel" ),
DARK_MONITOR( 200, "dark_monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartDarkPanel.class, "itemIlluminatedPanel" ), DARK_MONITOR( 200, "dark_monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartDarkPanel.class, "itemIlluminatedPanel" ),
STORAGE_BUS( 220, "storage_bus", EnumSet.of( AEFeature.STORAGE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartStorageBus.class ), STORAGE_BUS( 220, "storage_bus", EnumSet.of( AEFeature.STORAGE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartStorageBus.class ),
FLUID_STORAGE_BUS( 221, "fluid_storage_bus", EnumSet.of( AEFeature.FLUID_STORAGE_BUS ), EnumSet FLUID_STORAGE_BUS( 221, "fluid_storage_bus", EnumSet.of( AEFeature.FLUID_STORAGE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartFluidStorageBus.class ),
.noneOf( IntegrationType.class ), PartFluidStorageBus.class ), OREDICT_STORAGE_BUS( 222, "oredict_storage_bus", EnumSet.of( AEFeature.STORAGE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartOreDicStorageBus.class ),
IMPORT_BUS( 240, "import_bus", EnumSet.of( AEFeature.IMPORT_BUS ), EnumSet.noneOf( IntegrationType.class ), PartImportBus.class ), IMPORT_BUS( 240, "import_bus", EnumSet.of( AEFeature.IMPORT_BUS ), EnumSet.noneOf( IntegrationType.class ), PartImportBus.class ),
@@ -211,94 +198,83 @@ public enum PartType
FLUID_EXPORT_BUS( 261, "fluid_export_bus", EnumSet.of( AEFeature.FLUID_EXPORT_BUS ), EnumSet.noneOf( IntegrationType.class ), PartFluidExportBus.class ), FLUID_EXPORT_BUS( 261, "fluid_export_bus", EnumSet.of( AEFeature.FLUID_EXPORT_BUS ), EnumSet.noneOf( IntegrationType.class ), PartFluidExportBus.class ),
LEVEL_EMITTER( 280, "level_emitter", EnumSet.of( AEFeature.LEVEL_EMITTER ), EnumSet.noneOf( IntegrationType.class ), PartLevelEmitter.class ), LEVEL_EMITTER( 280, "level_emitter", EnumSet.of( AEFeature.LEVEL_EMITTER ), EnumSet.noneOf( IntegrationType.class ), PartLevelEmitter.class ),
FLUID_LEVEL_EMITTER( 281, "fluid_level_emitter", EnumSet.of( AEFeature.FLUID_LEVEL_EMITTER ), EnumSet FLUID_LEVEL_EMITTER( 281, "fluid_level_emitter", EnumSet.of( AEFeature.FLUID_LEVEL_EMITTER ), EnumSet.noneOf( IntegrationType.class ), PartFluidLevelEmitter.class ),
.noneOf( IntegrationType.class ), PartFluidLevelEmitter.class ),
ANNIHILATION_PLANE( 300, "annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE ), EnumSet ANNIHILATION_PLANE( 300, "annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartAnnihilationPlane.class ),
.noneOf( IntegrationType.class ), PartAnnihilationPlane.class ),
IDENTITY_ANNIHILATION_PLANE( 301, "identity_annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE, AEFeature.IDENTITY_ANNIHILATION_PLANE ), EnumSet IDENTITY_ANNIHILATION_PLANE( 301, "identity_annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE, AEFeature.IDENTITY_ANNIHILATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartIdentityAnnihilationPlane.class ),
.noneOf( IntegrationType.class ), PartIdentityAnnihilationPlane.class ),
FLUID_ANNIHILATION_PLANE( 302, "fluid_annihilation_plane", EnumSet.of( AEFeature.FLUID_ANNIHILATION_PLANE ), EnumSet FLUID_ANNIHILATION_PLANE( 302, "fluid_annihilation_plane", EnumSet.of( AEFeature.FLUID_ANNIHILATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartFluidAnnihilationPlane.class ),
.noneOf( IntegrationType.class ), PartFluidAnnihilationPlane.class ),
FORMATION_PLANE( 320, "formation_plane", EnumSet.of( AEFeature.FORMATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartFormationPlane.class ), FORMATION_PLANE( 320, "formation_plane", EnumSet.of( AEFeature.FORMATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartFormationPlane.class ),
FLUID_FORMATION_PLANE( 321, "fluid_formation_plane", EnumSet.of( AEFeature.FLUID_FORMATION_PLANE ), EnumSet FLUID_FORMATION_PLANE( 321, "fluid_formation_plane", EnumSet.of( AEFeature.FLUID_FORMATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartFluidFormationPlane.class ),
.noneOf( IntegrationType.class ), PartFluidFormationPlane.class ),
PATTERN_TERMINAL( 340, "pattern_terminal", EnumSet.of( AEFeature.PATTERNS ), EnumSet.noneOf( IntegrationType.class ), PartPatternTerminal.class ), PATTERN_TERMINAL( 340, "pattern_terminal", EnumSet.of( AEFeature.PATTERNS ), EnumSet.noneOf( IntegrationType.class ), PartPatternTerminal.class ),
CRAFTING_TERMINAL( 360, "crafting_terminal", EnumSet.of( AEFeature.CRAFTING_TERMINAL ), EnumSet EXPANDED_PROCESSING_PATTERN_TERMINAL( 341, "expanded_processing_pattern_terminal", EnumSet.of( AEFeature.PATTERNS ), EnumSet.noneOf( IntegrationType.class ), PartExpandedProcessingPatternTerminal.class ),
.noneOf( IntegrationType.class ), PartCraftingTerminal.class ),
CRAFTING_TERMINAL( 360, "crafting_terminal", EnumSet.of( AEFeature.CRAFTING_TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartCraftingTerminal.class ),
TERMINAL( 380, "terminal", EnumSet.of( AEFeature.TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartTerminal.class ), TERMINAL( 380, "terminal", EnumSet.of( AEFeature.TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartTerminal.class ),
STORAGE_MONITOR( 400, "storage_monitor", EnumSet.of( AEFeature.STORAGE_MONITOR ), EnumSet.noneOf( IntegrationType.class ), PartStorageMonitor.class ), STORAGE_MONITOR( 400, "storage_monitor", EnumSet.of( AEFeature.STORAGE_MONITOR ), EnumSet.noneOf( IntegrationType.class ), PartStorageMonitor.class ),
CONVERSION_MONITOR( 420, "conversion_monitor", EnumSet.of( AEFeature.PART_CONVERSION_MONITOR ), EnumSet CONVERSION_MONITOR( 420, "conversion_monitor", EnumSet.of( AEFeature.PART_CONVERSION_MONITOR ), EnumSet.noneOf( IntegrationType.class ), PartConversionMonitor.class ),
.noneOf( IntegrationType.class ), PartConversionMonitor.class ),
INTERFACE( 440, "interface", EnumSet.of( AEFeature.INTERFACE ), EnumSet.noneOf( IntegrationType.class ), PartInterface.class ), INTERFACE( 440, "interface", EnumSet.of( AEFeature.INTERFACE ), EnumSet.noneOf( IntegrationType.class ), PartInterface.class ),
FLUID_INTERFACE( 441, "fluid_interface", EnumSet.of( AEFeature.FLUID_INTERFACE ), EnumSet.noneOf( IntegrationType.class ), PartFluidInterface.class ), FLUID_INTERFACE( 441, "fluid_interface", EnumSet.of( AEFeature.FLUID_INTERFACE ), EnumSet.noneOf( IntegrationType.class ), PartFluidInterface.class ),
P2P_TUNNEL_ME( 460, "p2p_tunnel_me", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ME ), EnumSet P2P_TUNNEL_ME( 460, "p2p_tunnel_me", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ME ), EnumSet.noneOf( IntegrationType.class ), PartP2PTunnelME.class, GuiText.METunnel )
.noneOf( IntegrationType.class ), PartP2PTunnelME.class, GuiText.METunnel ) {
{ @Override
@Override String getUnlocalizedName()
String getUnlocalizedName() {
{ return "p2p_tunnel";
return "p2p_tunnel"; }
} },
},
P2P_TUNNEL_REDSTONE( 461, "p2p_tunnel_redstone", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_REDSTONE ), EnumSet P2P_TUNNEL_REDSTONE( 461, "p2p_tunnel_redstone", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_REDSTONE ), EnumSet.noneOf( IntegrationType.class ), PartP2PRedstone.class, GuiText.RedstoneTunnel )
.noneOf( IntegrationType.class ), PartP2PRedstone.class, GuiText.RedstoneTunnel ) {
{ @Override
@Override String getUnlocalizedName()
String getUnlocalizedName() {
{ return "p2p_tunnel";
return "p2p_tunnel"; }
} },
},
P2P_TUNNEL_ITEMS( 462, "p2p_tunnel_items", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ITEMS ), EnumSet P2P_TUNNEL_ITEMS( 462, "p2p_tunnel_items", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ITEMS ), EnumSet.noneOf( IntegrationType.class ), PartP2PItems.class, GuiText.ItemTunnel )
.noneOf( IntegrationType.class ), PartP2PItems.class, GuiText.ItemTunnel ) {
{ @Override
@Override String getUnlocalizedName()
String getUnlocalizedName() {
{ return "p2p_tunnel";
return "p2p_tunnel"; }
} },
},
P2P_TUNNEL_FLUIDS( 463, "p2p_tunnel_fluids", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_FLUIDS ), EnumSet P2P_TUNNEL_FLUIDS( 463, "p2p_tunnel_fluids", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_FLUIDS ), EnumSet.noneOf( IntegrationType.class ), PartP2PFluids.class, GuiText.FluidTunnel )
.noneOf( IntegrationType.class ), PartP2PFluids.class, GuiText.FluidTunnel ) {
{ @Override
@Override String getUnlocalizedName()
String getUnlocalizedName() {
{ return "p2p_tunnel";
return "p2p_tunnel"; }
} },
},
P2P_TUNNEL_IC2( 465, "p2p_tunnel_ic2", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_EU ), EnumSet P2P_TUNNEL_IC2( 465, "p2p_tunnel_ic2", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_EU ), EnumSet.of( IntegrationType.IC2 ), PartP2PIC2Power.class, GuiText.EUTunnel )
.of( IntegrationType.IC2 ), PartP2PIC2Power.class, GuiText.EUTunnel ) {
{ @Override
@Override String getUnlocalizedName()
String getUnlocalizedName() {
{ return "p2p_tunnel";
return "p2p_tunnel"; }
} },
},
P2P_TUNNEL_LIGHT( 467, "p2p_tunnel_light", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_LIGHT ), EnumSet P2P_TUNNEL_LIGHT( 467, "p2p_tunnel_light", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_LIGHT ), EnumSet.noneOf( IntegrationType.class ), PartP2PLight.class, GuiText.LightTunnel )
.noneOf( IntegrationType.class ), PartP2PLight.class, GuiText.LightTunnel ) {
{ @Override
@Override String getUnlocalizedName()
String getUnlocalizedName() {
{
return "p2p_tunnel"; return "p2p_tunnel";
} }
}, },
@@ -403,7 +403,7 @@ public class ToolMatterCannon extends AEBasePoweredItem implements IStorageCell<
} }
else if( pos.entityHit.attackEntityFrom( dmgSrc, dmg ) ) else if( pos.entityHit.attackEntityFrom( dmgSrc, dmg ) )
{ {
hasDestroyed = true; hasDestroyed = pos.entityHit.isEntityAlive();
} }
} }
else if( pos.typeOfHit == RayTraceResult.Type.BLOCK ) else if( pos.typeOfHit == RayTraceResult.Type.BLOCK )
+9 -2
View File
@@ -59,6 +59,7 @@ import appeng.me.cache.CraftingGridCache;
import appeng.me.pathfinding.IPathItem; import appeng.me.pathfinding.IPathItem;
import appeng.util.IWorldCallable; import appeng.util.IWorldCallable;
import appeng.util.ReadOnlyCollection; import appeng.util.ReadOnlyCollection;
import net.minecraftforge.common.util.Constants;
public class GridNode implements IGridNode, IPathItem public class GridNode implements IGridNode, IPathItem
@@ -333,7 +334,11 @@ public class GridNode implements IGridNode, IPathItem
@Override @Override
public void loadFromNBT( final String name, final NBTTagCompound nodeData ) public void loadFromNBT( final String name, final NBTTagCompound nodeData )
{ {
if( this.myGrid == null ) if( this.myGrid != null )
{
throw new IllegalStateException( "Loading data after part of a grid, this is invalid." );
}
if( nodeData.hasKey( name, 10 ) )
{ {
final NBTTagCompound node = nodeData.getCompoundTag( name ); final NBTTagCompound node = nodeData.getCompoundTag( name );
this.playerID = node.getInteger( "p" ); this.playerID = node.getInteger( "p" );
@@ -345,7 +350,9 @@ public class GridNode implements IGridNode, IPathItem
} }
else else
{ {
throw new IllegalStateException( "Loading data after part of a grid, this is invalid." ); this.playerID = -1; // Unknown owner
setLastSecurityKey( -1 );
setGridStorage( null );
} }
} }
+32 -4
View File
@@ -35,7 +35,6 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
import appeng.api.storage.data.IAEFluidStack;
import com.google.common.collect.HashMultimap; import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@@ -272,6 +271,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
} }
final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = new Object2ObjectOpenHashMap<>(this.craftableItems); final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = new Object2ObjectOpenHashMap<>(this.craftableItems);
final Set<IAEItemStack> oldEmitableItems = new HashSet<>(this.emitableItems);
// erase list. // erase list.
this.craftingMethods.clear(); this.craftingMethods.clear();
@@ -289,7 +289,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
// new craftables! // new craftables!
for( final ICraftingPatternDetails details : this.craftingMethods.keySet() ) for( final ICraftingPatternDetails details : this.craftingMethods.keySet() )
{ {
for( IAEItemStack out : details.getCondensedOutputs() ) for( IAEItemStack out : details.getOutputs() )
{ {
out = out.copy(); out = out.copy();
out.reset(); out.reset();
@@ -317,14 +317,42 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> i = oldItems.entrySet(); ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> i = oldItems.entrySet();
for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : i) { for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : i) {
if (!this.craftableItems.containsKey( ais.getKey() )) { if (!this.craftableItems.containsKey( ais.getKey() )) {
craftablesChanged.put( ais.getKey().setCraftable( false ), ais.getValue() ); IAEItemStack changedStack = ais.getKey().copy();
changedStack.reset();
changedStack.setCraftable( false );
craftablesChanged.put( changedStack, ais.getValue() );
} }
} }
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> j = this.craftableItems.entrySet(); ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> j = this.craftableItems.entrySet();
for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : j) { for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : j) {
if (!oldItems.containsKey( ais )){ if (!oldItems.containsKey( ais )){
craftablesChanged.put( ais.getKey().setCraftable( true ), ais.getValue() ); IAEItemStack changedStack = ais.getKey().copy();
changedStack.reset();
changedStack.setCraftable( true );
craftablesChanged.put( changedStack, ais.getValue() );
}
}
for( final IAEItemStack st : oldEmitableItems )
{
if( !emitableItems.contains( st ) )
{
IAEItemStack changedStack = st.copy();
changedStack.reset();
changedStack.setCraftable( false );
craftablesChanged.put( changedStack, null );
}
}
for( final IAEItemStack st : this.emitableItems )
{
if( !oldEmitableItems.contains( st ) )
{
IAEItemStack changedStack = st.copy();
changedStack.reset();
changedStack.setCraftable( true );
craftablesChanged.put( changedStack, null );
} }
} }
+115 -138
View File
@@ -19,10 +19,21 @@
package appeng.me.cache; package appeng.me.cache;
import java.util.*; import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.NavigableSet;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.*; import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
import com.google.common.collect.Sets;
import appeng.api.config.AccessRestriction; import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
@@ -54,11 +65,9 @@ public class EnergyGridCache implements IEnergyGrid
{ {
private static final double MAX_BUFFER_STORAGE = 800; private static final double MAX_BUFFER_STORAGE = 800;
private static final Comparator<IEnergyGridProvider> COMPARATOR_HIGHEST_AMOUNT_STORED_FIRST = ( o1, o2 ) -> Double.compare( o2.getProviderStoredEnergy(), private static final Comparator<IEnergyGridProvider> COMPARATOR_HIGHEST_AMOUNT_STORED_FIRST = ( o1, o2 ) -> Double.compare( o2.getProviderStoredEnergy(), o1.getProviderStoredEnergy() );
o1.getProviderStoredEnergy() );
private static final Comparator<IEnergyGridProvider> COMPARATOR_LOWEST_PERCENTAGE_FIRST = ( o1, o2 ) -> private static final Comparator<IEnergyGridProvider> COMPARATOR_LOWEST_PERCENTAGE_FIRST = ( o1, o2 ) -> {
{
final double percent1 = ( o1.getProviderStoredEnergy() + 1 ) / ( o1.getProviderMaxEnergy() + 1 ); final double percent1 = ( o1.getProviderStoredEnergy() + 1 ) / ( o1.getProviderMaxEnergy() + 1 );
final double percent2 = ( o2.getProviderStoredEnergy() + 1 ) / ( o2.getProviderMaxEnergy() + 1 ); final double percent2 = ( o2.getProviderStoredEnergy() + 1 ) / ( o2.getProviderMaxEnergy() + 1 );
@@ -70,7 +79,7 @@ public class EnergyGridCache implements IEnergyGrid
// Should only be modified from the add/remove methods below to guard against // Should only be modified from the add/remove methods below to guard against
// concurrent modifications // concurrent modifications
private final double averageLength = 40.0; private final double averageLength = 40.0;
private final Multimap<Integer,IAEPowerStorage> providers = HashMultimap.create(); private final Set<IAEPowerStorage> providers = new LinkedHashSet<>();
// Used to track whether an extraction is currently in progress, to fail fast // Used to track whether an extraction is currently in progress, to fail fast
// when something externally // when something externally
// modifies the energy grid. // modifies the energy grid.
@@ -78,7 +87,7 @@ public class EnergyGridCache implements IEnergyGrid
// Should only be modified from the add/remove methods below to guard against // Should only be modified from the add/remove methods below to guard against
// concurrent modifications // concurrent modifications
private final Multimap<Integer,IAEPowerStorage> requesters = HashMultimap.create(); private final Set<IAEPowerStorage> requesters = new LinkedHashSet<>();
// Used to track whether an injection is currently in progress, to fail fast // Used to track whether an injection is currently in progress, to fail fast
// when something externally // when something externally
// modifies the energy grid. // modifies the energy grid.
@@ -115,16 +124,16 @@ public class EnergyGridCache implements IEnergyGrid
private double lastStoredPower = -1; private double lastStoredPower = -1;
private final GridPowerStorage localStorage = new GridPowerStorage(); private final GridPowerStorage localStorage = new GridPowerStorage();
private Set<IAEPowerStorage> providersToRemove = new HashSet<>(); private Set<IAEPowerStorage> providerToRemove = new HashSet<>();
private Set<IAEPowerStorage> requestersToRemove = new HashSet<>(); private Set<IAEPowerStorage> requesterToRemove = new HashSet<>();
private Set<IAEPowerStorage> providersToAdd = new HashSet<>(); private Set<IAEPowerStorage> providersToAdd = new HashSet<>();
private Set<IAEPowerStorage> requestersToAdd = new HashSet<>(); private Set<IAEPowerStorage> requesterToAdd = new HashSet<>();
public EnergyGridCache( final IGrid g ) public EnergyGridCache( final IGrid g )
{ {
this.myGrid = g; this.myGrid = g;
this.requesters.put( 0, this.localStorage ); this.requesters.add( this.localStorage );
this.providers.put( 1, this.localStorage ); this.providers.add( this.localStorage );
} }
@MENetworkEventSubscribe @MENetworkEventSubscribe
@@ -152,34 +161,33 @@ public class EnergyGridCache implements IEnergyGrid
{ {
if( ev.storage.isAEPublicPowerStorage() ) if( ev.storage.isAEPublicPowerStorage() )
{ {
switch ( ev.type ) if( ev.type == PowerEventType.PROVIDE_POWER )
{ {
case PROVIDE_POWER: if( ev.storage.getPowerFlow() != AccessRestriction.WRITE )
if( ev.storage.getPowerFlow() != AccessRestriction.WRITE ) {
if( !ongoingExtractOperation )
{ {
if( !ongoingExtractOperation ) addProvider( ev.storage );
{
addProvider( ev.storage );
}
else
{
this.providersToAdd.add( ev.storage );
}
} }
break; else
case REQUEST_POWER:
if( ev.storage.getPowerFlow() != AccessRestriction.READ )
{ {
if( !ongoingInjectOperation ) this.providersToAdd.add( ev.storage );
{
addRequester( ev.storage );
}
else
{
this.requestersToAdd.add( ev.storage );
}
} }
break; }
}
else if( ev.type == PowerEventType.REQUEST_POWER )
{
if( ev.storage.getPowerFlow() != AccessRestriction.READ )
{
if( !ongoingInjectOperation )
{
addRequester( ev.storage );
}
else
{
this.requesterToAdd.add( ev.storage );
}
}
} }
} }
else else
@@ -307,7 +315,7 @@ public class EnergyGridCache implements IEnergyGrid
{ {
this.availableTicksSinceUpdate = 0; this.availableTicksSinceUpdate = 0;
this.globalAvailablePower = 0; this.globalAvailablePower = 0;
for( final IAEPowerStorage p : this.providers.values() ) for( final IAEPowerStorage p : this.providers )
{ {
this.globalAvailablePower += p.getAECurrentPower(); this.globalAvailablePower += p.getAECurrentPower();
} }
@@ -324,50 +332,57 @@ public class EnergyGridCache implements IEnergyGrid
{ {
double extractedPower = 0; double extractedPower = 0;
providersToAdd.forEach( provider -> { this.providers.addAll( providersToAdd );
if( provider instanceof GridPowerStorage )
{
providers.put( 1, provider );
}
else
{
providers.put( 0, provider );
}
} );
providersToAdd.clear(); providersToAdd.clear();
providers.removeIf( providerToRemove::contains );
this.providerToRemove.clear();
final Iterator<IAEPowerStorage> it = this.providers.values().iterator(); final Iterator<IAEPowerStorage> it = this.providers.iterator();
ongoingExtractOperation = true; ongoingExtractOperation = true;
boolean ls = false;
try try
{ {
while ( extractedPower < amt && it.hasNext() ) while ( extractedPower < amt && it.hasNext() )
{ {
final IAEPowerStorage node = it.next(); final IAEPowerStorage node = it.next();
if( node != null )
{
if( node == localStorage && mode == Actionable.MODULATE )
{
ls = true;
continue;
}
final double req = amt - extractedPower; final double req = amt - extractedPower;
final double newPower = node.extractAEPower( req, mode, PowerMultiplier.ONE ); final double newPower = node.extractAEPower( req, mode, PowerMultiplier.ONE );
extractedPower += newPower; extractedPower += newPower;
if( newPower < req && mode == Actionable.MODULATE ) if( newPower < req && mode == Actionable.MODULATE )
{
it.remove();
}
}
else
{ {
it.remove(); it.remove();
} }
} }
} finally } finally
{ {
providersToRemove.forEach( provider -> {
if( provider instanceof GridPowerStorage )
{
providers.remove( 1, provider );
}
else
{
providers.remove( 0, provider );
}
} );
this.providersToRemove.clear();
ongoingExtractOperation = false; ongoingExtractOperation = false;
if( ls && extractedPower < amt )
{
final double req = amt - extractedPower;
final double newPower = localStorage.extractAEPower( req, mode, PowerMultiplier.ONE );
extractedPower += newPower;
if( newPower < req )
{
providers.remove( localStorage );
}
}
} }
final double result = Math.min( extractedPower, amt ); final double result = Math.min( extractedPower, amt );
@@ -391,19 +406,12 @@ public class EnergyGridCache implements IEnergyGrid
{ {
final double originalAmount = amt; final double originalAmount = amt;
requestersToAdd.forEach( requester -> { this.requesters.addAll( requesterToAdd );
if( requester instanceof GridPowerStorage ) requesterToAdd.clear();
{ requesters.removeIf( requesterToRemove::contains );
requesters.put( 0, requester ); this.requesterToRemove.clear();
}
else
{
requesters.put( 1, requester );
}
} );
requestersToAdd.clear();
final Iterator<IAEPowerStorage> it = this.requesters.values().iterator(); final Iterator<IAEPowerStorage> it = this.requesters.iterator();
ongoingInjectOperation = true; ongoingInjectOperation = true;
try try
@@ -412,26 +420,22 @@ public class EnergyGridCache implements IEnergyGrid
{ {
final IAEPowerStorage node = it.next(); final IAEPowerStorage node = it.next();
amt = node.injectAEPower( amt, mode ); if( node != null )
{
amt = node.injectAEPower( amt, mode );
if( amt > 0 && mode == Actionable.MODULATE ) if( amt > 0 && mode == Actionable.MODULATE )
{
it.remove();
}
}
else
{ {
it.remove(); it.remove();
} }
} }
} finally } finally
{ {
requestersToRemove.forEach( requester -> {
if( requester instanceof GridPowerStorage )
{
requesters.remove( 0, requester );
}
else
{
requesters.remove( 1, requester );
}
} );
this.requestersToRemove.clear();
ongoingInjectOperation = false; ongoingInjectOperation = false;
} }
@@ -450,8 +454,8 @@ public class EnergyGridCache implements IEnergyGrid
{ {
double required = 0; double required = 0;
final Iterator<IAEPowerStorage> it = this.requesters.values().iterator(); final Iterator<IAEPowerStorage> it = this.requesters.iterator();
while( required < maxRequired && it.hasNext() ) while ( required < maxRequired && it.hasNext() )
{ {
final IAEPowerStorage node = it.next(); final IAEPowerStorage node = it.next();
if( node.getPowerFlow() != AccessRestriction.READ ) if( node.getPowerFlow() != AccessRestriction.READ )
@@ -591,7 +595,7 @@ public class EnergyGridCache implements IEnergyGrid
} }
else else
{ {
this.providersToRemove.add( ps ); this.providerToRemove.add( ps );
} }
if( !ongoingInjectOperation ) if( !ongoingInjectOperation )
{ {
@@ -599,7 +603,7 @@ public class EnergyGridCache implements IEnergyGrid
} }
else else
{ {
this.requestersToRemove.add( ps ); this.requesterToRemove.add( ps );
} }
} }
} }
@@ -616,58 +620,31 @@ public class EnergyGridCache implements IEnergyGrid
} }
} }
private void addRequester(IAEPowerStorage requester) { private void addRequester( IAEPowerStorage requester )
Preconditions.checkState(!ongoingInjectOperation, {
"Cannot modify energy requesters while energy is being injected."); Preconditions.checkState( !ongoingInjectOperation, "Cannot modify energy requesters while energy is being injected." );
if( requester instanceof GridPowerStorage ) this.requesters.add( requester );
{
requesters.put( 0, requester );
}
else
{
requesters.put( 1, requester );
}
} }
private void removeRequester(IAEPowerStorage requester) { private void removeRequester( IAEPowerStorage requester )
Preconditions.checkState(!ongoingInjectOperation, {
"Cannot modify energy requesters while energy is being injected."); Preconditions.checkState( !ongoingInjectOperation, "Cannot modify energy requesters while energy is being injected." );
if( requester instanceof GridPowerStorage ) this.requesters.remove( requester );
{
requesters.remove( 0, requester );
}
else
{
requesters.remove( 1, requester );
}
} }
private void addProvider(IAEPowerStorage provider) { private void addProvider( IAEPowerStorage provider )
Preconditions.checkState(!ongoingExtractOperation,
"Cannot modify energy providers while energy is being extracted.");
if( provider instanceof GridPowerStorage )
{
providers.put( 1, provider );
}
else
{
providers.put( 0, provider );
}
}
private void removeProvider(IAEPowerStorage provider)
{ {
Preconditions.checkState( !ongoingExtractOperation, "Cannot modify energy providers while energy is being extracted." ); Preconditions.checkState( !ongoingExtractOperation, "Cannot modify energy providers while energy is being extracted." );
if( provider instanceof GridPowerStorage ) this.providers.add( provider );
{
providers.remove( 1, provider );
}
else
{
providers.remove( 0, provider );
}
} }
private void removeProvider( IAEPowerStorage provider )
{
Preconditions.checkState( !ongoingExtractOperation, "Cannot modify energy providers while energy is being extracted." );
this.providers.remove( provider );
}
@Override @Override
public void addNode( final IGridNode node, final IGridHost machine ) public void addNode( final IGridNode node, final IGridHost machine )
{ {
@@ -717,7 +694,7 @@ public class EnergyGridCache implements IEnergyGrid
} }
else else
{ {
this.requestersToAdd.add( ps ); this.requesterToAdd.add( ps );
} }
} }
} }
@@ -845,4 +822,4 @@ public class EnergyGridCache implements IEnergyGrid
} }
} }
} }
} }
+9 -6
View File
@@ -94,7 +94,7 @@ public class GridStorageCache implements IStorageGrid
this.removeCellProvider( cc, tracker ); this.removeCellProvider( cc, tracker );
this.inactiveCellProviders.remove( cc ); this.inactiveCellProviders.remove( cc );
this.getGrid().postEvent( new MENetworkCellArrayUpdate() ); cellUpdate( null );
tracker.applyChanges(); tracker.applyChanges();
} }
@@ -119,7 +119,7 @@ public class GridStorageCache implements IStorageGrid
final ICellContainer cc = (ICellContainer) machine; final ICellContainer cc = (ICellContainer) machine;
this.inactiveCellProviders.add( cc ); this.inactiveCellProviders.add( cc );
this.getGrid().postEvent( new MENetworkCellArrayUpdate() ); cellUpdate( null );
if( node.isActive() ) if( node.isActive() )
{ {
@@ -177,8 +177,7 @@ public class GridStorageCache implements IStorageGrid
final IActionSource actionSrc = cc instanceof IActionHost ? new MachineSource( (IActionHost) cc ) : new BaseActionSource(); final IActionSource actionSrc = cc instanceof IActionHost ? new MachineSource( (IActionHost) cc ) : new BaseActionSource();
this.storageMonitors.forEach( ( channel, monitor ) -> this.storageMonitors.forEach( ( channel, monitor ) -> {
{
for( final IMEInventoryHandler<?> h : cc.getCellArray( channel ) ) for( final IMEInventoryHandler<?> h : cc.getCellArray( channel ) )
{ {
tracker.postChanges( channel, 1, h, actionSrc ); tracker.postChanges( channel, 1, h, actionSrc );
@@ -247,8 +246,9 @@ public class GridStorageCache implements IStorageGrid
this.removeCellProvider( cc, tracker ); this.removeCellProvider( cc, tracker );
} }
} }
tracker.applyChanges(); tracker.applyChanges();
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.setForceUpdate( true ) );
} }
private <T extends IAEStack<T>, C extends IStorageChannel<T>> void postChangesToNetwork( final C chan, final int upOrDown, final IItemList<T> availableItems, final IActionSource src ) private <T extends IAEStack<T>, C extends IStorageChannel<T>> void postChangesToNetwork( final C chan, final int upOrDown, final IItemList<T> availableItems, final IActionSource src )
@@ -328,7 +328,10 @@ public class GridStorageCache implements IStorageGrid
public void applyChanges() public void applyChanges()
{ {
GridStorageCache.this.postChangesToNetwork( this.channel, this.up_or_down, this.list, this.src ); if( !this.list.isEmpty() )
{
GridStorageCache.this.postChangesToNetwork( this.channel, this.up_or_down, this.list, this.src );
}
} }
} }
+116 -32
View File
@@ -19,7 +19,6 @@
package appeng.me.cache; package appeng.me.cache;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import appeng.api.AEApi; import appeng.api.AEApi;
@@ -36,20 +35,21 @@ import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEStack; import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList; import appeng.api.storage.data.IItemList;
import appeng.me.storage.ItemWatcher; import appeng.me.storage.ItemWatcher;
import com.google.common.collect.Queues;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import java.util.Collection; import java.util.*;
import java.util.Deque;
import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T> public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
{ {
@Nonnull @Nonnull
private static final Deque<NetworkMonitor<?>> GLOBAL_DEPTH = Queues.newArrayDeque(); private static final HashMap<IActionSource, LinkedList<NetworkMonitor<?>>> src2MonitorsMap = new HashMap<>();
private static final Set<IActionSource> nestingSources = new HashSet<>();
protected boolean wasNested = false;
protected boolean isNested = false;
@Nonnull @Nonnull
private final GridStorageCache myGridCache; private final GridStorageCache myGridCache;
@@ -61,10 +61,9 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
private final Object2ObjectMap<IMEMonitorHandlerReceiver<T>, Object> listeners; private final Object2ObjectMap<IMEMonitorHandlerReceiver<T>, Object> listeners;
private boolean sendEvent = false; private boolean sendEvent = false;
@Nonnegative
private int localDepthSemaphore = 0;
private long gridItemCount; private long gridItemCount;
private long gridFluidCount; private long gridFluidCount;
public boolean forceUpdate;
public NetworkMonitor( final GridStorageCache cache, final IStorageChannel<T> chan ) public NetworkMonitor( final GridStorageCache cache, final IStorageChannel<T> chan )
{ {
@@ -135,17 +134,16 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
return 0; return 0;
} }
public long incGridCurrentCount(long count) public void incGridCurrentCount( long count )
{ {
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{ {
return gridItemCount += count; gridItemCount += count;
} }
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ) else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
{ {
return gridFluidCount += count; gridFluidCount += count;
} }
return 0;
} }
@Nonnull @Nonnull
@@ -198,6 +196,7 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
{ {
final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next(); final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
final IMEMonitorHandlerReceiver<T> receiver = o.getKey(); final IMEMonitorHandlerReceiver<T> receiver = o.getKey();
if( receiver.isValid( o.getValue() ) ) if( receiver.isValid( o.getValue() ) )
{ {
receiver.postChange( this, diff, src ); receiver.postChange( this, diff, src );
@@ -214,47 +213,52 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
for( final T changedItem : input ) for( final T changedItem : input )
{ {
if (changedItem.isCraftable()) { if (changedItem.isCraftable()) {
this.cachedList.add( changedItem.copy().setCraftable( true ) ); this.cachedList.add( changedItem );
} }
else else
{ {
this.cachedList.findPrecise( changedItem ).setCraftable( false ); T i = this.cachedList.findPrecise( changedItem );
if (i != null)
i.setCraftable( false );
} }
} }
} }
protected void postChange( final boolean add, final Iterable<T> changes, final IActionSource src ) protected void postChange( final boolean add, final Iterable<T> changes, final IActionSource src )
{ {
if( GLOBAL_DEPTH.contains( this ) ) src2MonitorsMap.putIfAbsent( src, new LinkedList<>() );
if( src2MonitorsMap.get( src ).contains( this ) )
{ {
nestingSources.add( src );
return; return;
} }
src2MonitorsMap.get( src ).add( this );
GLOBAL_DEPTH.push( this );
this.sendEvent = true; this.sendEvent = true;
for( final T changedItem : changes ) for( final T change : changes )
{ {
if( !add && changedItem != null ) //T change = changed;
if( !add && change != null )
{ {
changedItem.setStackSize( -changedItem.getStackSize() ); //change = changed.copy();
change.setStackSize( -change.getStackSize() );
} }
incGridCurrentCount( changedItem.getStackSize() ); incGridCurrentCount( change.getStackSize() );
this.cachedList.add( changedItem ); this.cachedList.addStorage( change );
if( this.myGridCache.getInterestManager().containsKey( changedItem ) ) if( this.myGridCache.getInterestManager().containsKey( change ) )
{ {
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( changedItem ); final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( change );
if( !list.isEmpty() ) if( !list.isEmpty() )
{ {
IAEStack<T> fullStack = this.getStorageList().findPrecise( changedItem ); IAEStack<T> fullStack = this.getStorageList().findPrecise( change );
if( fullStack == null ) if( fullStack == null )
{ {
fullStack = changedItem.copy(); fullStack = change.copy();
fullStack.setStackSize( 0 ); fullStack.setStackSize( 0 );
} }
@@ -262,7 +266,7 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
for( final ItemWatcher iw : list ) for( final ItemWatcher iw : list )
{ {
iw.getHost().onStackChange( this.getStorageList(), fullStack, changedItem, src, this.getChannel() ); iw.getHost().onStackChange( this.getStorageList(), fullStack, change, src, this.getChannel() );
} }
this.myGridCache.getInterestManager().disableTransactions(); this.myGridCache.getInterestManager().disableTransactions();
@@ -272,21 +276,101 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
this.notifyListenersOfChange( changes, src ); this.notifyListenersOfChange( changes, src );
final NetworkMonitor<?> last = GLOBAL_DEPTH.pop(); if( src2MonitorsMap.get( src ).getFirst() == this )
if( last != this )
{ {
throw new IllegalStateException( "Invalid Access to Networked Storage API detected." ); boolean nested = nestingSources.contains( src );
src2MonitorsMap.get( src ).forEach( networkMonitor -> networkMonitor.isNested = nested );
src2MonitorsMap.get( src ).forEach( networkMonitor -> {
if( networkMonitor.isNested != networkMonitor.wasNested )
{
networkMonitor.wasNested = networkMonitor.isNested;
networkMonitor.setForceUpdate( true );
}
} );
src2MonitorsMap.remove( src );
nestingSources.remove( src );
}
}
public void setForceUpdate( boolean forceUpdate )
{
this.forceUpdate = forceUpdate;
}
void forceUpdate()
{
forceUpdate = false;
this.cachedList.resetStatus();
this.getAvailableItems( this.cachedList );
long count = 0;
for( T stack : this.cachedList )
{
count += stack.getStackSize();
if( this.myGridCache.getInterestManager().containsKey( stack ) )
{
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( stack );
if( !list.isEmpty() )
{
IAEStack<T> fullStack = this.getStorageList().findPrecise( stack );
if( fullStack == null )
{
fullStack = stack.copy();
fullStack.setStackSize( 0 );
}
this.myGridCache.getInterestManager().enableTransactions();
for ( final ItemWatcher iw : list )
{
iw.getHost().onStackChange( this.getStorageList(), fullStack, stack, null, this.getChannel() );
}
this.myGridCache.getInterestManager().disableTransactions();
}
}
}
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
gridItemCount = count;
}
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
{
gridFluidCount = count;
}
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
while ( i.hasNext() )
{
final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
final IMEMonitorHandlerReceiver<T> receiver = o.getKey();
if( receiver.isValid( o.getValue() ) )
{
receiver.onListUpdate();
}
else
{
i.remove();
}
} }
} }
void onTick() void onTick()
{ {
if( forceUpdate )
{
forceUpdate();
}
if( this.sendEvent ) if( this.sendEvent )
{ {
this.sendEvent = false; this.sendEvent = false;
this.myGridCache.getGrid().postEvent( new MENetworkStorageEvent( this, this.myChannel ) ); this.myGridCache.getGrid().postEvent( new MENetworkStorageEvent( this, this.myChannel ) );
} }
} }
} }
+56 -17
View File
@@ -19,7 +19,7 @@
package appeng.me.cache; package appeng.me.cache;
import java.util.HashMap; import java.util.Collection;
import java.util.Random; import java.util.Random;
import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.LinkedHashMultimap;
@@ -46,7 +46,7 @@ public class P2PCache implements IGridCache
private static final TunnelCollection<PartP2PTunnel> NULL_COLLECTION = new TunnelCollection<PartP2PTunnel>( null, null ); private static final TunnelCollection<PartP2PTunnel> NULL_COLLECTION = new TunnelCollection<PartP2PTunnel>( null, null );
private final IGrid myGrid; private final IGrid myGrid;
private final HashMap<Short, PartP2PTunnel> inputs = new HashMap<>(); private final Multimap<Short, PartP2PTunnel> inputs = LinkedHashMultimap.create();
private final Multimap<Short, PartP2PTunnel> outputs = LinkedHashMultimap.create(); private final Multimap<Short, PartP2PTunnel> outputs = LinkedHashMultimap.create();
private final Random frequencyGenerator; private final Random frequencyGenerator;
@@ -110,10 +110,19 @@ public class P2PCache implements IGridCache
} }
else else
{ {
this.inputs.remove( t.getFrequency() ); this.inputs.remove( t.getFrequency(), t );
} }
this.updateTunnel( t.getFrequency(), !t.isOutput(), false ); if( this.inputs.get( t.getFrequency() ).isEmpty() )
{
this.inputs.removeAll( t.getFrequency() );
}
if( this.outputs.get( t.getFrequency() ).isEmpty() )
{
this.outputs.removeAll( t.getFrequency() );
}
this.updateTunnel( t.getFrequency(), t.isOutput(), false );
} }
} }
@@ -142,7 +151,7 @@ public class P2PCache implements IGridCache
this.inputs.put( t.getFrequency(), t ); this.inputs.put( t.getFrequency(), t );
} }
this.updateTunnel( t.getFrequency(), !t.isOutput(), false ); this.updateTunnel( t.getFrequency(), t.isOutput(), false );
} }
} }
@@ -164,6 +173,20 @@ public class P2PCache implements IGridCache
} }
public void removeTunnel( final PartP2PTunnel t, short freq )
{
this.outputs.remove( freq, t );
this.inputs.remove( freq, t );
if( this.inputs.get( t.getFrequency() ).isEmpty() )
{
this.inputs.removeAll( t.getFrequency() );
}
if( this.outputs.get( t.getFrequency() ).isEmpty() )
{
this.outputs.removeAll( t.getFrequency() );
}
}
private void updateTunnel( final short freq, final boolean updateOutputs, final boolean configChange ) private void updateTunnel( final short freq, final boolean updateOutputs, final boolean configChange )
{ {
for( final PartP2PTunnel p : this.outputs.get( freq ) ) for( final PartP2PTunnel p : this.outputs.get( freq ) )
@@ -175,8 +198,7 @@ public class P2PCache implements IGridCache
p.onTunnelNetworkChange(); p.onTunnelNetworkChange();
} }
final PartP2PTunnel in = this.inputs.get( freq ); for( final PartP2PTunnel in : this.inputs.get( freq ) )
if( in != null )
{ {
if( configChange ) if( configChange )
{ {
@@ -195,7 +217,7 @@ public class P2PCache implements IGridCache
if( this.inputs.containsValue( t ) ) if( this.inputs.containsValue( t ) )
{ {
this.inputs.remove( t.getFrequency() ); this.inputs.remove( t.getFrequency(), t );
} }
t.setFrequency( newFrequency ); t.setFrequency( newFrequency );
@@ -211,7 +233,6 @@ public class P2PCache implements IGridCache
// AELog.info( "update-" + (t.output ? "output: " : "input: ") + t.freq ); // AELog.info( "update-" + (t.output ? "output: " : "input: ") + t.freq );
this.updateTunnel( t.getFrequency(), t.isOutput(), true ); this.updateTunnel( t.getFrequency(), t.isOutput(), true );
this.updateTunnel( t.getFrequency(), !t.isOutput(), true );
} }
public short newFrequency() public short newFrequency()
@@ -236,25 +257,43 @@ public class P2PCache implements IGridCache
public TunnelCollection<PartP2PTunnel> getOutputs( final short freq, final Class<? extends PartP2PTunnel> c ) public TunnelCollection<PartP2PTunnel> getOutputs( final short freq, final Class<? extends PartP2PTunnel> c )
{ {
final PartP2PTunnel in = this.inputs.get( freq ); Collection<PartP2PTunnel> in = this.inputs.get( freq );
if( in == null ) if( in == null )
{ {
return NULL_COLLECTION; return NULL_COLLECTION;
} }
final TunnelCollection<PartP2PTunnel> out = this.inputs.get( freq ).getCollection( this.outputs.get( freq ), c ); TunnelCollection<PartP2PTunnel> out;
for( PartP2PTunnel part : this.inputs.get( freq ) )
{
out = part.getCollection( this.outputs.get( freq ), c );
if( out != null )
{
return out;
}
}
return NULL_COLLECTION;
}
public TunnelCollection<PartP2PTunnel> getInputs( final short freq, final Class<? extends PartP2PTunnel> c )
{
Collection<PartP2PTunnel> out = this.outputs.get( freq );
if( out == null ) if( out == null )
{ {
return NULL_COLLECTION; return NULL_COLLECTION;
} }
return out; TunnelCollection<PartP2PTunnel> in;
} for( PartP2PTunnel part : this.outputs.get( freq ) )
{
public PartP2PTunnel getInput( final short freq ) in = part.getCollection( this.inputs.get( freq ), c );
{ if( in != null )
return this.inputs.get( freq ); {
return in;
}
}
return NULL_COLLECTION;
} }
} }
@@ -25,6 +25,7 @@ import java.util.stream.Collectors;
import appeng.api.config.Upgrades; import appeng.api.config.Upgrades;
import appeng.helpers.DualityInterface; import appeng.helpers.DualityInterface;
import appeng.helpers.PatternHelper;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@@ -742,24 +743,35 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{ {
continue; continue;
} }
if( details.isCraftable() )
{
ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
}
else
{
ic = new InventoryCrafting( new ContainerNull(), PatternHelper.PROCESSING_INPUT_WIDTH, PatternHelper.PROCESSING_INPUT_HEIGHT );
}
ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
boolean found = false; boolean found = false;
for (int x = 0; x < input.length; x++) { for( int x = 0; x < input.length; x++ )
if (input[x] != null) { {
if( input[x] != null )
{
found = false; found = false;
if (details.isCraftable()) { if( details.isCraftable() )
{
final Collection<IAEItemStack> itemList; final Collection<IAEItemStack> itemList;
if (details.canSubstitute()) { if( details.canSubstitute() )
final List<IAEItemStack> substitutes = details.getSubstituteInputs(x); {
itemList = new ArrayList<>(substitutes.size()); final List<IAEItemStack> substitutes = details.getSubstituteInputs( x );
itemList = new ArrayList<>( substitutes.size() );
for (IAEItemStack stack : substitutes) { for( IAEItemStack stack : substitutes )
itemList.addAll(this.inventory.getItemList().findFuzzy(stack, {
FuzzyMode.IGNORE_ALL)); itemList.addAll( this.inventory.getItemList().findFuzzy( stack, FuzzyMode.IGNORE_ALL ) );
} }
} else { } else {
itemList = new ArrayList<>(1); itemList = new ArrayList<>(1);
@@ -23,11 +23,10 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import appeng.api.config.FuzzyMode;
import appeng.api.storage.data.IAEStack;
import appeng.util.item.AEItemStack;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import appeng.api.storage.data.IAEStack;
public class GenericInterestManager<T> public class GenericInterestManager<T>
{ {
@@ -102,30 +101,12 @@ public class GenericInterestManager<T>
public boolean containsKey( final IAEStack stack ) public boolean containsKey( final IAEStack stack )
{ {
if( stack.isItem() && ( ( AEItemStack ) stack ).getItem().isDamageable() )
{
return this.container.keySet().stream().filter( s -> s.isItem() )
.anyMatch( s -> s.fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) );
}
return this.container.containsKey( stack ); return this.container.containsKey( stack );
} }
public Collection<T> get( final IAEStack stack ) public Collection<T> get( final IAEStack stack )
{ {
Collection<T> watchers = new ArrayList<>(); return this.container.get( stack );
if( stack.isItem() && ( ( AEItemStack ) stack ).getItem().isDamageable() )
{
this.container.keySet().stream().filter( s -> s.isItem() )
.filter( k -> k.fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) )
.forEach( key ->
watchers.addAll( this.container.get( key ) )
);
}
else
{
return this.container.get( stack );
}
return watchers;
} }
private class SavedTransactions private class SavedTransactions
@@ -142,4 +123,4 @@ public class GenericInterestManager<T>
this.iw = watcher; this.iw = watcher;
} }
} }
} }
@@ -28,8 +28,6 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
import com.google.common.collect.ImmutableList;
import appeng.api.config.AccessRestriction; import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
import appeng.api.networking.security.IActionSource; import appeng.api.networking.security.IActionSource;
@@ -85,11 +83,7 @@ public class MEMonitorHandler<T extends IAEStack<T>> implements IMEMonitor<T>
@Override @Override
public T injectItems( final T input, final Actionable mode, final IActionSource src ) public T injectItems( final T input, final Actionable mode, final IActionSource src )
{ {
if( mode == Actionable.SIMULATE ) return this.getHandler().injectItems( input, mode, src );
{
return this.getHandler().injectItems( input, mode, src );
}
return this.monitorDifference( input.copy(), this.getHandler().injectItems( input, mode, src ), false, src );
} }
protected IMEInventoryHandler<T> getHandler() protected IMEInventoryHandler<T> getHandler()
@@ -97,28 +91,7 @@ public class MEMonitorHandler<T extends IAEStack<T>> implements IMEMonitor<T>
return this.internalHandler; return this.internalHandler;
} }
private T monitorDifference( final T original, final T leftOvers, final boolean extraction, final IActionSource src ) public void postChangesToListeners( final Iterable<T> changes, final IActionSource src )
{
final T diff = original.copy();
if( extraction )
{
diff.setStackSize( leftOvers == null ? 0 : -leftOvers.getStackSize() );
}
else if( leftOvers != null )
{
diff.decStackSize( leftOvers.getStackSize() );
}
if( diff.getStackSize() != 0 )
{
this.postChangesToListeners( ImmutableList.of( diff ), src );
}
return leftOvers;
}
protected void postChangesToListeners( final Iterable<T> changes, final IActionSource src )
{ {
this.notifyListenersOfChange( changes, src ); this.notifyListenersOfChange( changes, src );
} }
@@ -150,11 +123,7 @@ public class MEMonitorHandler<T extends IAEStack<T>> implements IMEMonitor<T>
@Override @Override
public T extractItems( final T request, final Actionable mode, final IActionSource src ) public T extractItems( final T request, final Actionable mode, final IActionSource src )
{ {
if( mode == Actionable.SIMULATE ) return this.getHandler().extractItems( request, mode, src );
{
return this.getHandler().extractItems( request, mode, src );
}
return this.monitorDifference( request.copy(), this.getHandler().extractItems( request, mode, src ), true, src );
} }
@Override @Override
@@ -19,6 +19,7 @@
package appeng.me.helpers; package appeng.me.helpers;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
@@ -55,4 +56,24 @@ public class MachineSource implements IActionSource
return Optional.empty(); return Optional.empty();
} }
@Override
public boolean equals( Object o )
{
if( this == o )
{
return true;
}
if( o == null || getClass() != o.getClass() )
{
return false;
}
MachineSource that = (MachineSource) o;
return via.equals( that.via );
}
@Override
public int hashCode()
{
return Objects.hash( via );
}
} }
@@ -19,19 +19,20 @@
package appeng.me.storage; package appeng.me.storage;
import appeng.core.features.registries.cell.CreativeCellHandler;
import appeng.me.GridAccessException; import appeng.me.GridAccessException;
import appeng.me.helpers.MachineSource; import appeng.me.helpers.MachineSource;
import appeng.tile.storage.TileDrive; import appeng.tile.storage.TileDrive;
import com.google.common.collect.ImmutableList;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.api.networking.security.IActionSource; import appeng.api.networking.security.IActionSource;
import appeng.api.storage.ICellHandler; import appeng.api.storage.ICellHandler;
import appeng.api.storage.ICellInventoryHandler; import appeng.api.storage.ICellInventoryHandler;
import appeng.api.storage.data.IAEStack; import appeng.api.storage.data.IAEStack;
import java.util.Collections;
public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T> public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
{ {
@@ -39,16 +40,16 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
private int oldStatus = 0; private int oldStatus = 0;
private final ItemStack is; private final ItemStack is;
private final ICellHandler handler; private final ICellHandler handler;
private final IChestOrDrive cord; private final TileDrive drive;
private IActionSource source; private IActionSource source;
public DriveWatcher( final ICellInventoryHandler<T> i, final ItemStack is, final ICellHandler han, final IChestOrDrive cod ) public DriveWatcher( final ICellInventoryHandler<T> i, final ItemStack is, final ICellHandler han, final TileDrive drive )
{ {
super( i, i.getChannel() ); super( i, i.getChannel() );
this.is = is; this.is = is;
this.handler = han; this.handler = han;
this.cord = cod; this.drive = drive;
this.source = new MachineSource( cod ); this.source = new MachineSource( drive );
} }
public int getStatus() public int getStatus()
@@ -61,55 +62,58 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
{ {
final long size = input.getStackSize(); final long size = input.getStackSize();
final T a = super.injectItems( input, type, src ); final T remainder = super.injectItems( input, type, src );
if( type == Actionable.MODULATE && ( a == null || a.getStackSize() != size ) ) if( type == Actionable.MODULATE && ( remainder == null || remainder.getStackSize() != size ) )
{ {
final int newStatus = this.getStatus(); final int newStatus = this.getStatus();
if( newStatus != this.oldStatus ) if( newStatus != this.oldStatus )
{ {
this.cord.blinkCell( this.getSlot() ); this.drive.blinkCell( this.getSlot() );
this.oldStatus = newStatus; this.oldStatus = newStatus;
} }
try if (this.drive.getProxy().isActive() && !(handler instanceof CreativeCellHandler))
{ {
( (TileDrive) this.cord ).getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), ImmutableList.of( input.copy().setStackSize( input.getStackSize() - ( a == null ? 0 : a.getStackSize() ) ) ), this.source ); try
} {
catch( GridAccessException e ) this.drive.getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), Collections.singletonList( input.copy().setStackSize( input.getStackSize() - ( remainder == null ? 0 : remainder.getStackSize() ) ) ), this.source );
{ } catch ( GridAccessException e )
e.printStackTrace(); {
e.printStackTrace();
}
} }
} }
return a; return remainder;
} }
@Override @Override
public T extractItems( final T request, final Actionable type, final IActionSource src ) public T extractItems( final T request, final Actionable type, final IActionSource src )
{ {
final T a = super.extractItems( request, type, src ); final T extractable = super.extractItems( request, type, src );
if( type == Actionable.MODULATE && a != null ) if( type == Actionable.MODULATE && extractable != null )
{ {
final int newStatus = this.getStatus(); final int newStatus = this.getStatus();
if( newStatus != this.oldStatus ) if( newStatus != this.oldStatus )
{ {
this.cord.blinkCell( this.getSlot() ); this.drive.blinkCell( this.getSlot() );
this.oldStatus = newStatus; this.oldStatus = newStatus;
} }
if (this.drive.getProxy().isActive() && !(handler instanceof CreativeCellHandler ))
try
{ {
( (TileDrive) this.cord ).getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), ImmutableList.of( request.copy().setStackSize( -a.getStackSize() ) ), this.source ); try
} {
catch( GridAccessException e ) this.drive.getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), Collections.singletonList( request.copy().setStackSize( -extractable.getStackSize() ) ), this.source );
{ } catch ( GridAccessException e )
e.printStackTrace(); {
e.printStackTrace();
}
} }
} }
return a; return extractable;
} }
} }
@@ -19,14 +19,11 @@
package appeng.me.storage; package appeng.me.storage;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListMap;
import appeng.fluids.util.AEFluidStack;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidTankProperties; import net.minecraftforge.fluids.capability.IFluidTankProperties;
@@ -48,16 +45,14 @@ import appeng.api.storage.data.IItemList;
public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITickingMonitor public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITickingMonitor
{ {
private final IFluidHandler handler; private final IFluidHandler handler;
private final IItemList<IAEFluidStack> list = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList(); private IItemList<IAEFluidStack> cache = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
private final HashMap<IMEMonitorHandlerReceiver<IAEFluidStack>, Object> listeners = new HashMap<>(); private final HashMap<IMEMonitorHandlerReceiver<IAEFluidStack>, Object> listeners = new HashMap<>();
private final NavigableMap<Integer, CachedFluidStack> memory;
private IActionSource mySource; private IActionSource mySource;
private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY; private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
public MEMonitorIFluidHandler( final IFluidHandler handler ) public MEMonitorIFluidHandler( final IFluidHandler handler )
{ {
this.handler = handler; this.handler = handler;
this.memory = new ConcurrentSkipListMap<>();
} }
@Override @Override
@@ -82,11 +77,6 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
return input.copy(); return input.copy();
} }
if( type == Actionable.MODULATE )
{
this.onTick();
}
if( filled == input.getStackSize() ) if( filled == input.getStackSize() )
{ {
return null; return null;
@@ -94,6 +84,15 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
final IAEFluidStack o = input.copy(); final IAEFluidStack o = input.copy();
o.setStackSize( input.getStackSize() - filled ); o.setStackSize( input.getStackSize() - filled );
if( type == Actionable.MODULATE )
{
IAEFluidStack added = o.copy();
this.cache.add( added );
this.postDifference( Collections.singletonList( added ) );
this.onTick();
}
return o; return o;
} }
@@ -107,13 +106,18 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
return null; return null;
} }
if( type == Actionable.MODULATE )
{
this.onTick();
}
final IAEFluidStack o = request.copy(); final IAEFluidStack o = request.copy();
o.setStackSize( removed.amount ); o.setStackSize( removed.amount );
if( type == Actionable.MODULATE )
{
IAEFluidStack cachedStack = this.cache.findPrecise( request );
if( cachedStack != null )
{
cachedStack.decStackSize( o.getStackSize() );
this.postDifference( Collections.singletonList( o.copy().setStackSize( -o.getStackSize() ) ) );
}
}
return o; return o;
} }
@@ -126,111 +130,51 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
@Override @Override
public TickRateModulation onTick() public TickRateModulation onTick()
{ {
final List<IAEFluidStack> changes = new ArrayList<>();
this.list.resetStatus();
int high = 0;
boolean changed = false; boolean changed = false;
final IFluidTankProperties[] props = this.handler.getTankProperties(); final List<IAEFluidStack> changes = new ArrayList<>();
for( int slot = 0; slot < this.handler.getTankProperties().length; ++slot ) final IFluidTankProperties[] tankProperties = this.handler.getTankProperties();
IItemList<IAEFluidStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
for( IFluidTankProperties tankProperty : tankProperties )
{ {
final CachedFluidStack old = this.memory.get( slot ); if( this.mode == StorageFilter.EXTRACTABLE_ONLY && this.handler.drain( 1, false ) == null )
high = Math.max( high, slot );
final FluidStack newIS = !props[slot].canDrain() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? null : props[slot].getContents();
final FluidStack oldIS = old == null ? null : old.fluidStack;
if( isDifferent( newIS, oldIS ) )
{ {
final CachedFluidStack cis = new CachedFluidStack( newIS ); continue;
this.memory.put( slot, cis );
if( old != null && old.aeStack != null )
{
old.aeStack.setStackSize( -old.aeStack.getStackSize() );
changes.add( old.aeStack );
}
if( cis.aeStack != null )
{
changes.add( cis.aeStack );
this.list.add( cis.aeStack );
}
changed = true;
} }
else currentlyOnStorage.add( AEFluidStack.fromFluidStack( tankProperty.getContents() ) );
}
for( final IAEFluidStack is : cache )
{
is.setStackSize( -is.getStackSize() );
}
for( final IAEFluidStack is : currentlyOnStorage )
{
cache.add( is );
}
for( final IAEFluidStack is : cache )
{
if( is.getStackSize() != 0 )
{ {
final int newSize = newIS == null ? 0 : newIS.amount; changes.add( is );
final int diff = newSize - ( oldIS == null ? 0 : oldIS.amount );
IAEFluidStack stack = null;
if( newIS != null )
{
stack = ( old == null || old.aeStack == null ? AEApi.instance()
.storage()
.getStorageChannel( IFluidStorageChannel.class )
.createStack( newIS ) : old.aeStack.copy() );
}
if( stack != null )
{
stack.setStackSize( newSize );
this.list.add( stack );
}
if( diff != 0 && stack != null )
{
final CachedFluidStack cis = new CachedFluidStack( newIS );
this.memory.put( slot, cis );
final IAEFluidStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
changed = true;
}
} }
} }
// detect dropped items; should fix non IISided Inventory Changes. cache = currentlyOnStorage;
final NavigableMap<Integer, CachedFluidStack> end = this.memory.tailMap( high, false );
if( !end.isEmpty() )
{
for( final CachedFluidStack cis : end.values() )
{
if( cis != null && cis.aeStack != null )
{
final IAEFluidStack a = cis.aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
changed = true;
}
}
end.clear();
}
if( !changes.isEmpty() ) if( !changes.isEmpty() )
{ {
this.postDifference( changes ); this.postDifference( changes );
changed = true;
} }
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER; return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
} }
private static boolean isDifferent( FluidStack a, FluidStack b )
{
if( a == b )
{
return false;
}
if( a == null || b == null )
{
return true;
}
return !a.getFluid().equals( b.getFluid() );
}
private void postDifference( final Iterable<IAEFluidStack> a ) private void postDifference( final Iterable<IAEFluidStack> a )
{ {
if( a != null ) if( a != null )
@@ -291,9 +235,9 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
@Override @Override
public IItemList<IAEFluidStack> getAvailableItems( final IItemList out ) public IItemList<IAEFluidStack> getAvailableItems( final IItemList out )
{ {
for( final CachedFluidStack is : this.memory.values() ) for( final IAEFluidStack fs : cache )
{ {
out.addStorage( is.aeStack ); out.addStorage( fs );
} }
return out; return out;
@@ -302,7 +246,7 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
@Override @Override
public IItemList<IAEFluidStack> getStorageList() public IItemList<IAEFluidStack> getStorageList()
{ {
return this.list; return this.cache;
} }
private StorageFilter getMode() private StorageFilter getMode()
@@ -326,24 +270,4 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
this.mySource = mySource; this.mySource = mySource;
} }
private static class CachedFluidStack
{
private final FluidStack fluidStack;
private final IAEFluidStack aeStack;
CachedFluidStack( final FluidStack is )
{
if( is == null )
{
this.fluidStack = null;
this.aeStack = null;
}
else
{
this.fluidStack = is.copy();
this.aeStack = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createStack( is );
}
}
}
} }
@@ -19,12 +19,8 @@
package appeng.me.storage; package appeng.me.storage;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListMap;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@@ -50,16 +46,15 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
{ {
private final InventoryAdaptor adaptor; private final InventoryAdaptor adaptor;
private final IItemList<IAEItemStack> list = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList(); private IItemList<IAEItemStack> cache = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>(); private final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
private final NavigableMap<Integer, CachedItemStack> memory;
private IActionSource mySource; private IActionSource mySource;
private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY; private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
public MEMonitorIInventory( final InventoryAdaptor adaptor ) public MEMonitorIInventory( final InventoryAdaptor adaptor )
{ {
this.adaptor = adaptor; this.adaptor = adaptor;
this.memory = new ConcurrentSkipListMap<>();
} }
@Override @Override
@@ -88,11 +83,6 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
out = this.adaptor.addItems( input.createItemStack() ); out = this.adaptor.addItems( input.createItemStack() );
} }
if( type == Actionable.MODULATE )
{
this.onTick();
}
if( out.isEmpty() ) if( out.isEmpty() )
{ {
return null; return null;
@@ -101,6 +91,15 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
// better then doing construction from scratch :3 // better then doing construction from scratch :3
final IAEItemStack o = input.copy(); final IAEItemStack o = input.copy();
o.setStackSize( out.getCount() ); o.setStackSize( out.getCount() );
if( type == Actionable.MODULATE )
{
IAEItemStack added = o.copy();
this.cache.add( added );
this.postDifference( Collections.singletonList( added ) );
this.onTick();
}
return o; return o;
} }
@@ -129,6 +128,12 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
if( type == Actionable.MODULATE ) if( type == Actionable.MODULATE )
{ {
IAEItemStack cachedStack = this.cache.findPrecise( request );
if( cachedStack != null )
{
cachedStack.decStackSize( o.getStackSize() );
this.postDifference( Collections.singletonList( o.copy().setStackSize( -o.getStackSize() ) ) );
}
this.onTick(); this.onTick();
} }
@@ -144,110 +149,52 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
@Override @Override
public TickRateModulation onTick() public TickRateModulation onTick()
{ {
boolean changed = false;
final List<IAEItemStack> changes = new ArrayList<>(); final List<IAEItemStack> changes = new ArrayList<>();
this.list.resetStatus(); IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
int high = 0;
boolean changed = false; for( final ItemSlot is : adaptor )
for( final ItemSlot is : this.adaptor )
{ {
final CachedItemStack old = this.memory.get( is.getSlot() ); if( this.mode == StorageFilter.EXTRACTABLE_ONLY && !is.isExtractable() )
high = Math.max( high, is.getSlot() );
final ItemStack newIS = !is.isExtractable() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? ItemStack.EMPTY : is.getItemStack();
final ItemStack oldIS = old == null ? ItemStack.EMPTY : old.itemStack;
if( this.isDifferent( newIS, oldIS ) )
{ {
final CachedItemStack cis = new CachedItemStack( is.getItemStack() ); continue;
this.memory.put( is.getSlot(), cis );
if( old != null && old.aeStack != null )
{
old.aeStack.setStackSize( -old.aeStack.getStackSize() );
changes.add( old.aeStack );
}
if( cis.aeStack != null )
{
changes.add( cis.aeStack );
this.list.add( cis.aeStack );
}
changed = true;
} }
else currentlyOnStorage.add( is.getAEItemStack() );
}
for( final IAEItemStack is : cache )
{
is.setStackSize( -is.getStackSize() );
}
for( final IAEItemStack is : currentlyOnStorage )
{
cache.add( is );
}
for( final IAEItemStack is : cache )
{
if( is.getStackSize() != 0 )
{ {
final int newSize = ( newIS.isEmpty() ? 0 : newIS.getCount() ); changes.add( is );
final int diff = newSize - ( oldIS.isEmpty() ? 0 : oldIS.getCount() );
final IAEItemStack stack = ( old == null || old.aeStack == null ? AEApi.instance()
.storage()
.getStorageChannel( IItemStorageChannel.class )
.createStack( newIS ) : old.aeStack.copy() );
if( stack != null )
{
stack.setStackSize( newSize );
this.list.add( stack );
}
if( diff != 0 && stack != null )
{
final CachedItemStack cis = new CachedItemStack( is.getItemStack() );
this.memory.put( is.getSlot(), cis );
final IAEItemStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
changed = true;
}
} }
} }
// detect dropped items; should fix non IISided Inventory Changes. cache = currentlyOnStorage;
final NavigableMap<Integer, CachedItemStack> end = this.memory.tailMap( high, false );
if( !end.isEmpty() )
{
for( final CachedItemStack cis : end.values() )
{
if( cis != null && cis.aeStack != null )
{
final IAEItemStack a = cis.aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
changed = true;
}
}
end.clear();
}
if( !changes.isEmpty() ) if( !changes.isEmpty() )
{ {
this.postDifference( changes ); this.postDifference( changes );
changed = true;
} }
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER; return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
} }
private boolean isDifferent( final ItemStack a, final ItemStack b )
{
if( a == b && b.isEmpty() )
{
return false;
}
if( ( a.isEmpty() && !b.isEmpty() ) || ( !a.isEmpty() && b.isEmpty() ) )
{
return true;
}
return !Platform.itemComparisons().isSameItem( a, b );
}
private void postDifference( final Iterable<IAEItemStack> a ) private void postDifference( final Iterable<IAEItemStack> a )
{ {
// AELog.info( a.getItemStack().getUnlocalizedName() + " @ " + a.getStackSize() );
if( a != null ) if( a != null )
{ {
final Iterator<Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator(); final Iterator<Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
@@ -306,9 +253,9 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
@Override @Override
public IItemList<IAEItemStack> getAvailableItems( final IItemList out ) public IItemList<IAEItemStack> getAvailableItems( final IItemList out )
{ {
for( final CachedItemStack is : this.memory.values() ) for( IAEItemStack is : cache )
{ {
out.addStorage( is.aeStack ); out.addStorage( is );
} }
return out; return out;
@@ -317,7 +264,7 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
@Override @Override
public IItemList<IAEItemStack> getStorageList() public IItemList<IAEItemStack> getStorageList()
{ {
return this.list; return this.cache;
} }
private StorageFilter getMode() private StorageFilter getMode()
@@ -341,24 +288,4 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
this.mySource = mySource; this.mySource = mySource;
} }
private static class CachedItemStack
{
private final ItemStack itemStack;
private final IAEItemStack aeStack;
public CachedItemStack( final ItemStack is )
{
if( is.isEmpty() )
{
this.itemStack = ItemStack.EMPTY;
this.aeStack = null;
}
else
{
this.itemStack = is.copy();
this.aeStack = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( is );
}
}
}
} }
@@ -171,4 +171,5 @@ public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T
{ {
this.changeSource = changeSource; this.changeSource = changeSource;
} }
} }
@@ -19,6 +19,8 @@
package appeng.me.storage; package appeng.me.storage;
import appeng.me.helpers.MEMonitorHandler;
import appeng.me.helpers.MachineSource;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import appeng.api.AEApi; import appeng.api.AEApi;
@@ -35,16 +37,20 @@ import appeng.api.storage.data.IItemList;
import appeng.me.GridAccessException; import appeng.me.GridAccessException;
import appeng.tile.misc.TileSecurityStation; import appeng.tile.misc.TileSecurityStation;
import java.util.Collections;
public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStack> public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStack>
{ {
private final IItemList<IAEItemStack> storedItems = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList(); private final IItemList<IAEItemStack> storedItems = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final TileSecurityStation securityTile; private final TileSecurityStation securityTile;
private final MachineSource src;
public SecurityStationInventory( final TileSecurityStation ts ) public SecurityStationInventory( final TileSecurityStation ts )
{ {
this.securityTile = ts; this.securityTile = ts;
this.src = new MachineSource( securityTile );
} }
@Override @Override
@@ -61,6 +67,11 @@ public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStac
return null; return null;
} }
if( securityTile.getProxy().isActive() )
{
( ( MEMonitorHandler<IAEItemStack> ) securityTile.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) ).postChangesToListeners( Collections.singletonList( input.copy() ), this.src );
}
this.getStoredItems().add( input ); this.getStoredItems().add( input );
this.securityTile.inventoryChanged(); this.securityTile.inventoryChanged();
return null; return null;
@@ -101,6 +112,11 @@ public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStac
return output; return output;
} }
if( securityTile.getProxy().isActive() )
{
( ( MEMonitorHandler<IAEItemStack> ) securityTile.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) ).postChangesToListeners( Collections.singletonList( target.copy().setStackSize( -target.getStackSize() ) ), this.src );
}
target.setStackSize( 0 ); target.setStackSize( 0 );
this.securityTile.inventoryChanged(); this.securityTile.inventoryChanged();
return output; return output;
@@ -27,6 +27,7 @@ import net.minecraft.item.ItemStack;
import appeng.api.implementations.IPowerChannelState; import appeng.api.implementations.IPowerChannelState;
import appeng.api.networking.GridFlags; import appeng.api.networking.GridFlags;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkChannelsChanged; import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe; import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange; import appeng.api.networking.events.MENetworkPowerStatusChange;
@@ -59,6 +60,12 @@ public abstract class PartBasicState extends AEBasePart implements IPowerChannel
this.getHost().markForUpdate(); this.getHost().markForUpdate();
} }
@MENetworkEventSubscribe
public void bootingRender( final MENetworkBootingStatusChange bs )
{
this.getHost().markForUpdate();
}
@Override @Override
public void writeToStream( final ByteBuf data ) throws IOException public void writeToStream( final ByteBuf data ) throws IOException
{ {
@@ -187,8 +187,9 @@ public class PartFormationPlane extends PartAbstractFormationPlane<IAEItemStack>
this.stateChanged(); this.stateChanged();
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void updateChannels( final MENetworkChannelsChanged changedChannels ) public void chanRender( final MENetworkChannelsChanged changedChannels )
{ {
this.stateChanged(); this.stateChanged();
} }
@@ -184,8 +184,9 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
return flipState ? this.reportingValue >= this.lastReportedValue + 1 : this.reportingValue < this.lastReportedValue + 1; return flipState ? this.reportingValue >= this.lastReportedValue + 1 : this.reportingValue < this.lastReportedValue + 1;
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void powerStatusChange( final MENetworkPowerStatusChange powerEvent ) public void powerRender( final MENetworkPowerStatusChange powerEvent )
{ {
if (this.getProxy().isActive()) if (this.getProxy().isActive())
{ {
@@ -194,8 +195,9 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
this.updateState(); this.updateState();
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void channelChanged( final MENetworkChannelsChanged c ) public void chanRender( final MENetworkChannelsChanged c )
{ {
if (this.getProxy().isActive()) if (this.getProxy().isActive())
{ {
@@ -288,37 +290,24 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
try try
{ {
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 || myStack == null )
if( myStack == null )
{ {
this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).addListener( this, this.getProxy().getGrid() ); this.getProxy()
.getStorage()
.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
.addListener( this,
this.getProxy().getGrid() );
} }
else else
{ {
this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).removeListener( this ); this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).removeListener( this );
if( this.myWatcher != null ) if( this.myWatcher != null )
{ {
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 ) this.myWatcher.add( myStack );
{
Optional<OreReference> ores = OreHelper.INSTANCE.getOre( myStack.getDefinition() );
if( ores.isPresent() )
{
for( IAEItemStack iaeItemStack : ores.get().getAEEquivalents() )
{
this.myWatcher.add( iaeItemStack );
}
}
else
{
this.myWatcher.add( myStack );
}
}
else
{
this.myWatcher.add( myStack );
}
} }
} }
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) ); this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
} }
catch( final GridAccessException e ) catch( final GridAccessException e )
@@ -363,23 +352,11 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
} }
@Override @Override
public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan ) public void onStackChange( final IItemList o, final IAEStack fullStack, final IAEStack diffStack, final IActionSource src, final IStorageChannel chan )
{ {
if( chan == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) if( chan == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) && fullStack.equals( this.config.getAEStackInSlot( 0 ) ) && this.getInstalledUpgrades( Upgrades.FUZZY ) == 0 )
{ {
IAEItemStack myStack = this.config.getAEStackInSlot( 0 ); this.lastReportedValue = fullStack.getStackSize();
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
{
final FuzzyMode fzMode = (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE );
if( Platform.itemComparisons().isFuzzyEqualItem( myStack.getDefinition(), ( (IAEItemStack) diffStack ).getDefinition(), fzMode ) )
{
this.lastReportedValue += diffStack.getStackSize();
}
}
else if( diffStack.equals( myStack ) )
{
this.lastReportedValue += diffStack.getStackSize();
}
this.updateState(); this.updateState();
} }
} }
@@ -507,6 +484,7 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
public void upgradesChanged() public void upgradesChanged()
{ {
this.configureWatchers(); this.configureWatchers();
this.updateState();
} }
@Override @Override
@@ -62,8 +62,6 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
private StorageFilter mode; private StorageFilter mode;
private AccessRestriction access; private AccessRestriction access;
private ItemStack stackCache = null;
ItemHandlerAdapter( IItemHandler itemHandler, IGridProxyable proxy ) ItemHandlerAdapter( IItemHandler itemHandler, IGridProxyable proxy )
{ {
this.itemHandler = itemHandler; this.itemHandler = itemHandler;
@@ -82,8 +80,8 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src ) public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
{ {
// Try to reuse the cached stack // Try to reuse the cached stack
@Nullable ItemStack currentCached = stackCache; @Nullable ItemStack currentCached = iox.getCachedItemStack();
stackCache = null; iox.setCachedItemStack(null);
ItemStack orgInput; ItemStack orgInput;
int slotCount = this.itemHandler.getSlots(); int slotCount = this.itemHandler.getSlots();
@@ -108,9 +106,9 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
} }
// Store the stack in the cache for next time. // Store the stack in the cache for next time.
if( !remaining.isEmpty() && remaining != orgInput ) if( !remaining.isEmpty() )
{ {
stackCache = remaining; iox.setCachedItemStack( remaining );
} }
// At this point, we still have some items left... // At this point, we still have some items left...
@@ -320,13 +318,13 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList(); IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
for ( final ItemSlot is : this ) for( final ItemSlot is : this )
{ {
final ItemStack newIS = !is.isExtractable() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? ItemStack.EMPTY : is.getItemStack(); if( this.mode == StorageFilter.EXTRACTABLE_ONLY && !is.isExtractable() )
if( !newIS.isEmpty() )
{ {
currentlyOnStorage.add( is.getAEItemStack() ); continue;
} }
currentlyOnStorage.add( is.getAEItemStack() );
} }
for ( final IAEItemStack is : currentlyCached ) for ( final IAEItemStack is : currentlyCached )
@@ -95,14 +95,16 @@ public class PartInterface extends PartBasicState implements IGridTickable, ISto
super( is ); super( is );
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void stateChange( final MENetworkChannelsChanged c ) public void chanRender( final MENetworkChannelsChanged c )
{ {
this.duality.notifyNeighbors(); this.duality.notifyNeighbors();
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void stateChange( final MENetworkPowerStatusChange c ) public void powerRender( final MENetworkPowerStatusChange c )
{ {
this.duality.notifyNeighbors(); this.duality.notifyNeighbors();
} }
@@ -0,0 +1,215 @@
package appeng.parts.misc;
import appeng.api.AEApi;
import appeng.api.config.*;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.networking.ticking.ITickManager;
import appeng.api.parts.IPartModel;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.core.AppEng;
import appeng.core.sync.GuiBridge;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
import appeng.me.cache.GridStorageCache;
import appeng.me.storage.ITickingMonitor;
import appeng.me.storage.MEInventoryHandler;
import appeng.parts.PartModel;
import appeng.util.ConfigManager;
import appeng.util.Platform;
import appeng.util.item.OreHelper;
import appeng.util.prioritylist.OreDictPriorityList;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d;
public class PartOreDicStorageBus extends PartStorageBus
{
public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/oredict_storage_bus_base" );
@PartModels
public static final IPartModel MODELS_OFF = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_off" ) );
@PartModels
public static final IPartModel MODELS_ON = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_on" ) );
@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;
OreDictPriorityList<IAEItemStack> priorityList;
public PartOreDicStorageBus( ItemStack is )
{
super( is );
}
@Override
public void readFromNBT( NBTTagCompound data )
{
super.readFromNBT( data );
this.oreMatch = data.getString( "oreMatch" );
this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreMatch ), oreMatch );
}
@Override
public void writeToNBT( NBTTagCompound data )
{
super.writeToNBT( data );
data.setString( "oreMatch", getOreMatch() );
}
@Override
public boolean onPartActivate( final EntityPlayer player, final EnumHand hand, final Vec3d pos )
{
if( Platform.isServer() )
{
Platform.openGUI( player, this.getHost().getTile(), this.getSide(), GuiBridge.GUI_OREDICTSTORAGEBUS );
}
return true;
}
@Override
public GuiBridge getGuiBridge()
{
return GuiBridge.GUI_OREDICTSTORAGEBUS;
}
@Override
public MEInventoryHandler<IAEItemStack> getInternalHandler()
{
if( this.cached )
{
return this.handler;
}
final boolean wasSleeping = this.monitor == null;
this.cached = true;
final TileEntity self = this.getHost().getTile();
final TileEntity target = self.getWorld().getTileEntity( self.getPos().offset( this.getSide().getFacing() ) );
final int newHandlerHash = this.createHandlerHash( target );
if( newHandlerHash != 0 && newHandlerHash == this.handlerHash )
{
return this.handler;
}
this.handlerHash = newHandlerHash;
this.handler = null;
if( this.monitor != null )
{
( (IBaseMonitor<IAEItemStack>) monitor ).removeListener( this );
}
this.monitor = null;
if( target != null )
{
IMEInventory<IAEItemStack> inv = this.getInventoryWrapper( target );
if( inv instanceof ITickingMonitor )
{
this.monitor = (ITickingMonitor) inv;
this.monitor.setActionSource( mySrc );
this.monitor.setMode( (StorageFilter) this.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
}
if( inv != null )
{
this.handler = new MEInventoryHandler<>( inv, AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
this.handler.setBaseAccess( (AccessRestriction) this.getConfigManager().getSetting( Settings.ACCESS ) );
this.handler.setWhitelist( this.getInstalledUpgrades( Upgrades.INVERTER ) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST );
this.handler.setPriority( this.priority );
this.handler.setPartitionList( priorityList );
if( inv instanceof IBaseMonitor )
{
if( ( (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS ) ).hasPermission( AccessRestriction.READ ) )
{
( (IBaseMonitor<IAEItemStack>) inv ).addListener( this, this.handler );
}
}
}
}
// update sleep state...
if( wasSleeping != ( this.monitor == null ) )
{
try
{
final ITickManager tm = this.getProxy().getTick();
if( this.monitor == null )
{
tm.sleepDevice( this.getProxy().getNode() );
}
else
{
tm.wakeDevice( this.getProxy().getNode() );
}
}
catch( final GridAccessException e )
{
// :(
}
}
try
{
// force grid to update handlers...
( (GridStorageCache) this.getProxy().getGrid().getCache( IStorageGrid.class ) ).cellUpdate( null );
}
catch( final GridAccessException e )
{
// :3
}
return this.handler;
}
public String getOreMatch()
{
if( this.oreMatch == null )
{
return "";
}
return oreMatch;
}
public void saveOreMatch( String oreMatch )
{
if( !this.oreMatch.equals( oreMatch ) )
{
this.oreMatch = oreMatch;
this.priorityList = new OreDictPriorityList<>( OreHelper.INSTANCE.getMatchingOre( oreMatch ), oreMatch );
if( this.handler != null )
{
handler.setPartitionList( this.priorityList );
}
this.getHost().markForSave();
}
}
@Override
public IPartModel getStaticModels()
{
if( this.isActive() && this.isPowered() )
{
return MODELS_HAS_CHANNEL;
}
else if( this.isPowered() )
{
return MODELS_ON;
}
else
{
return MODELS_OFF;
}
}
}
@@ -1,201 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2018, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.parts.misc;
import java.util.Collections;
import java.util.List;
import appeng.api.config.AccessRestriction;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import appeng.api.AEApi;
import appeng.api.networking.events.MENetworkCellArrayUpdate;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.storage.ICellContainer;
import appeng.api.storage.ICellInventory;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.util.AECableType;
import appeng.api.util.IConfigManager;
import appeng.helpers.IPriorityHost;
import appeng.me.GridAccessException;
import appeng.parts.automation.PartUpgradeable;
/**
* @author BrockWS
* @version rv6 - 22/05/2018
* @since rv6 22/05/2018
*/
public abstract class PartSharedStorageBus extends PartUpgradeable implements IGridTickable, ICellContainer, IPriorityHost
{
private boolean wasActive = false;
private int priority = 0;
protected boolean accessChanged;
public PartSharedStorageBus( ItemStack is )
{
super( is );
}
protected void updateStatus()
{
final boolean currentActive = this.getProxy().isActive();
if( this.wasActive != currentActive )
{
this.wasActive = currentActive;
try
{
this.getProxy().getGrid().postEvent( new MENetworkCellArrayUpdate() );
this.getHost().markForUpdate();
}
catch( final GridAccessException ignore )
{
// :P
}
}
}
@MENetworkEventSubscribe
public void updateChannels( final MENetworkChannelsChanged changedChannels )
{
this.updateStatus();
}
/**
* Helper method to get this parts storage channel
*
* @return Storage channel
*/
public IStorageChannel getStorageChannel()
{
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
}
protected abstract void resetCache();
protected abstract void resetCache( boolean fullReset );
@Override
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
{
return Collections.emptyList();
}
@Override
public void blinkCell( int slot )
{
}
@Override
public void saveChanges( ICellInventory<?> cellInventory )
{
}
@Override
public int getPriority()
{
return this.priority;
}
@Override
public void setPriority( final int newValue )
{
this.priority = newValue;
this.getHost().markForSave();
this.resetCache( true );
}
@Override
@MENetworkEventSubscribe
public void powerRender( final MENetworkPowerStatusChange c )
{
this.updateStatus();
}
@Override
public void upgradesChanged()
{
super.upgradesChanged();
this.resetCache( true );
}
@Override
public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue )
{
if( settingName instanceof AccessRestriction )
{
this.accessChanged = true;
}
this.resetCache( true );
this.getHost().markForSave();
}
@Override
public void onNeighborChanged( IBlockAccess w, BlockPos pos, BlockPos neighbor )
{
if( pos.offset( this.getSide().getFacing() ).equals( neighbor ) )
{
this.resetCache( false );
}
}
@Override
public void readFromNBT( final NBTTagCompound data )
{
super.readFromNBT( data );
this.priority = data.getInteger( "priority" );
}
@Override
public void writeToNBT( final NBTTagCompound data )
{
super.writeToNBT( data );
data.setInteger( "priority", this.priority );
}
@Override
public void getBoxes( final IPartCollisionHelper bch )
{
bch.addBox( 3, 3, 15, 13, 13, 16 );
bch.addBox( 2, 2, 14, 14, 14, 15 );
bch.addBox( 5, 5, 12, 11, 11, 14 );
}
@Override
protected int getUpgradeSlots()
{
return 5;
}
@Override
public float getCableConnectionLength( AECableType cable )
{
return 4;
}
}
File diff suppressed because it is too large Load Diff
@@ -83,10 +83,19 @@ public class PartP2PFluids extends PartP2PTunnel<PartP2PFluids> implements IFlui
if( this.isOutput() ) if( this.isOutput() )
{ {
final PartP2PFluids in = this.getInput(); try
if( in != null )
{ {
in.onTunnelNetworkChange(); for( PartP2PFluids in : this.getInputs() )
{
if( in != null )
{
in.onTunnelNetworkChange();
}
}
}
catch( GridAccessException e )
{
e.printStackTrace();
} }
} }
} }
@@ -124,13 +133,21 @@ public class PartP2PFluids extends PartP2PTunnel<PartP2PFluids> implements IFlui
{ {
if( !this.isOutput() ) if( !this.isOutput() )
{ {
final PartP2PFluids tun = this.getInput(); try
if( tun != null )
{ {
return ACTIVE_TANK; for( PartP2PFluids tun : this.getInputs() )
{
if( tun != null )
{
return ACTIVE_TANK;
}
}
}
catch( GridAccessException e )
{
e.printStackTrace();
} }
} }
return INACTIVE_TANK; return INACTIVE_TANK;
} }
@@ -33,10 +33,6 @@ import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.EmptyHandler; import net.minecraftforge.items.wrapper.EmptyHandler;
import appeng.api.networking.IGridNode; import appeng.api.networking.IGridNode;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.ticking.IGridTickable; import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation; import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest; import appeng.api.networking.ticking.TickingRequest;
@@ -74,10 +70,22 @@ public class PartP2PItems extends PartP2PTunnel<PartP2PItems> implements IItemHa
public void onNeighborChanged( IBlockAccess w, BlockPos pos, BlockPos neighbor ) public void onNeighborChanged( IBlockAccess w, BlockPos pos, BlockPos neighbor )
{ {
this.cachedInv = null; this.cachedInv = null;
final PartP2PItems input = this.getInput(); try
if( input != null && this.isOutput() )
{ {
input.onTunnelNetworkChange(); if( this.isOutput() )
{
for( PartP2PItems input : this.getInputs() )
{
if( input != null )
{
input.onTunnelNetworkChange();
}
}
}
}
catch( GridAccessException e )
{
e.printStackTrace();
} }
} }
@@ -162,51 +170,6 @@ public class PartP2PItems extends PartP2PTunnel<PartP2PItems> implements IItemHa
return wasReq ? TickRateModulation.FASTER : TickRateModulation.SLOWER; return wasReq ? TickRateModulation.FASTER : TickRateModulation.SLOWER;
} }
@MENetworkEventSubscribe
public void changeStateA( final MENetworkBootingStatusChange bs )
{
if( !this.isOutput() )
{
this.cachedInv = null;
final int olderSize = this.oldSize;
this.oldSize = this.getDestination().getSlots();
if( olderSize != this.oldSize )
{
this.getHost().notifyNeighbors();
}
}
}
@MENetworkEventSubscribe
public void changeStateB( final MENetworkChannelsChanged bs )
{
if( !this.isOutput() )
{
this.cachedInv = null;
final int olderSize = this.oldSize;
this.oldSize = this.getDestination().getSlots();
if( olderSize != this.oldSize )
{
this.getHost().notifyNeighbors();
}
}
}
@MENetworkEventSubscribe
public void changeStateC( final MENetworkPowerStatusChange bs )
{
if( !this.isOutput() )
{
this.cachedInv = null;
final int olderSize = this.oldSize;
this.oldSize = this.getDestination().getSlots();
if( olderSize != this.oldSize )
{
this.getHost().notifyNeighbors();
}
}
}
@Override @Override
public void onTunnelNetworkChange() public void onTunnelNetworkChange()
{ {
@@ -222,10 +185,19 @@ public class PartP2PItems extends PartP2PTunnel<PartP2PItems> implements IItemHa
} }
else else
{ {
final PartP2PItems input = this.getInput(); try
if( input != null )
{ {
input.getHost().notifyNeighbors(); for( PartP2PItems input : this.getInputs() )
{
if( input != null )
{
input.getHost().notifyNeighbors();
}
}
}
catch( GridAccessException e )
{
e.printStackTrace();
} }
} }
} }
@@ -32,8 +32,6 @@ import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import appeng.api.networking.IGridNode; import appeng.api.networking.IGridNode;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.ticking.IGridTickable; import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation; import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest; import appeng.api.networking.ticking.TickingRequest;
@@ -62,20 +60,6 @@ public class PartP2PLight extends PartP2PTunnel<PartP2PLight> implements IGridTi
super( is ); super( is );
} }
@Override
public void chanRender( final MENetworkChannelsChanged c )
{
this.onTunnelNetworkChange();
super.chanRender( c );
}
@Override
public void powerRender( final MENetworkPowerStatusChange c )
{
this.onTunnelNetworkChange();
super.powerRender( c );
}
@Override @Override
public void writeToStream( final ByteBuf data ) throws IOException public void writeToStream( final ByteBuf data ) throws IOException
{ {
@@ -115,9 +99,17 @@ public class PartP2PLight extends PartP2PTunnel<PartP2PLight> implements IGridTi
this.lastValue = newLevel; this.lastValue = newLevel;
try try
{ {
int light = 0;
for( PartP2PLight src : this.getInputs() )
{
if( src != null && src.getProxy().isActive() )
{
light = Math.max( light, src.lastValue );
}
}
for( final PartP2PLight out : this.getOutputs() ) for( final PartP2PLight out : this.getOutputs() )
{ {
out.setLightLevel( this.lastValue ); out.setLightLevel( light );
} }
} }
catch( final GridAccessException e ) catch( final GridAccessException e )
@@ -196,15 +188,23 @@ public class PartP2PLight extends PartP2PTunnel<PartP2PLight> implements IGridTi
{ {
if( this.isOutput() ) if( this.isOutput() )
{ {
final PartP2PLight src = this.getInput(); try
if( src != null && src.getProxy().isActive() )
{
this.setLightLevel( src.lastValue );
}
else
{ {
int light = 0;
for( PartP2PLight src : this.getInputs() )
{
if( src != null && src.getProxy().isActive() )
{
light = Math.max( light, src.lastValue );
}
}
this.setLightLevel( light );
this.getHost().markForUpdate(); this.getHost().markForUpdate();
} }
catch( GridAccessException e )
{
e.printStackTrace();
}
} }
else else
{ {
@@ -31,10 +31,6 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess; import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.parts.IPartModel; import appeng.api.parts.IPartModel;
import appeng.items.parts.PartModels; import appeng.items.parts.PartModels;
import appeng.me.GridAccessException; import appeng.me.GridAccessException;
@@ -60,20 +56,25 @@ public class PartP2PRedstone extends PartP2PTunnel<PartP2PRedstone>
super( is ); super( is );
} }
@MENetworkEventSubscribe
public void changeStateA( final MENetworkBootingStatusChange bs )
{
this.setNetworkReady();
}
private void setNetworkReady() private void setNetworkReady()
{ {
if( this.isOutput() ) if( this.isOutput() )
{ {
final PartP2PRedstone in = this.getInput(); try
if( in != null )
{ {
this.putInput( in.power ); int power = 0;
for( PartP2PRedstone in : this.getInputs() )
{
if( in != null )
{
power = Math.max( power, in.power );
}
}
this.putInput( power );
}
catch( GridAccessException e )
{
e.printStackTrace();
} }
} }
} }
@@ -86,12 +87,20 @@ public class PartP2PRedstone extends PartP2PTunnel<PartP2PRedstone>
} }
this.recursive = true; this.recursive = true;
if( this.isOutput() && this.getProxy().isActive() ) if( this.isOutput() )
{ {
final int newPower = (Integer) o; if( this.getProxy().isActive() )
if( this.power != newPower )
{ {
this.power = newPower; final int newPower = (Integer) o;
if( this.power != newPower )
{
this.power = newPower;
this.notifyNeighbors();
}
}
else
{
this.power = 0;
this.notifyNeighbors(); this.notifyNeighbors();
} }
} }
@@ -111,18 +120,6 @@ public class PartP2PRedstone extends PartP2PTunnel<PartP2PRedstone>
} }
} }
@MENetworkEventSubscribe
public void changeStateB( final MENetworkChannelsChanged bs )
{
this.setNetworkReady();
}
@MENetworkEventSubscribe
public void changeStateC( final MENetworkPowerStatusChange bs )
{
this.setNetworkReady();
}
@Override @Override
public void readFromNBT( final NBTTagCompound tag ) public void readFromNBT( final NBTTagCompound tag )
{ {
@@ -167,7 +164,22 @@ public class PartP2PRedstone extends PartP2PTunnel<PartP2PRedstone>
this.power = b.getWeakPower( state, this.getTile().getWorld(), target, srcSide ); this.power = b.getWeakPower( state, this.getTile().getWorld(), target, srcSide );
this.power = Math.max( this.power, b.getWeakPower( state, this.getTile().getWorld(), target, srcSide ) ); this.power = Math.max( this.power, b.getWeakPower( state, this.getTile().getWorld(), target, srcSide ) );
this.sendToOutput( this.power ); int powerOut = this.power;
try
{
for( PartP2PRedstone in : this.getInputs() )
{
if( in != null )
{
powerOut = Math.max( in.power, powerOut );
}
}
}
catch( GridAccessException e )
{
e.printStackTrace();
}
this.sendToOutput( powerOut );
} }
else else
{ {
+108 -27
View File
@@ -24,6 +24,10 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Optional; import java.util.Optional;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
@@ -53,6 +57,7 @@ import appeng.me.cache.P2PCache;
import appeng.me.cache.helpers.TunnelCollection; import appeng.me.cache.helpers.TunnelCollection;
import appeng.parts.PartBasicState; import appeng.parts.PartBasicState;
import appeng.util.Platform; import appeng.util.Platform;
import org.lwjgl.input.Keyboard;
public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicState public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicState
@@ -77,26 +82,13 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
return null; return null;
} }
public T getInput() public TunnelCollection<T> getInputs() throws GridAccessException
{ {
if( this.getFrequency() == 0 ) if( this.getProxy().isActive() && this.getFrequency() != 0 )
{ {
return null; return (TunnelCollection<T>) this.getProxy().getP2P().getInputs( this.getFrequency(), this.getClass() );
} }
return new TunnelCollection( new ArrayList(), this.getClass() );
try
{
final PartP2PTunnel tunnel = this.getProxy().getP2P().getInput( this.getFrequency() );
if( this.getClass().isInstance( tunnel ) )
{
return (T) tunnel;
}
}
catch( final GridAccessException e )
{
// :P
}
return null;
} }
public TunnelCollection<T> getOutputs() throws GridAccessException public TunnelCollection<T> getOutputs() throws GridAccessException
@@ -164,6 +156,30 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
super.writeToStream( data ); super.writeToStream( data );
data.writeShort( this.getFrequency() ); data.writeShort( this.getFrequency() );
} }
@Override
@MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged c )
{
this.onTunnelNetworkChange();
super.chanRender( c );
}
@Override
@MENetworkEventSubscribe
public void powerRender( final MENetworkPowerStatusChange c )
{
this.onTunnelNetworkChange();
super.powerRender( c );
}
@Override
@MENetworkEventSubscribe
public void bootingRender( final MENetworkBootingStatusChange bs )
{
this.onTunnelNetworkChange();
super.bootingRender( bs );
}
@Override @Override
public float getCableConnectionLength( AECableType cable ) public float getCableConnectionLength( AECableType cable )
@@ -189,8 +205,13 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
{ {
return false; return false;
} }
final ItemStack is = player.getHeldItem( hand ); boolean pasteAsOutput = true;
ItemStack is = player.getHeldItem( hand );
if (is.isEmpty()) {
pasteAsOutput = false;
is = player.getHeldItemOffhand();
}
// UniqueIdentifier id = GameRegistry.findUniqueIdentifierFor( is.getItem() ); // UniqueIdentifier id = GameRegistry.findUniqueIdentifierFor( is.getItem() );
// AELog.info( "ID:" + id.toString() + " : " + is.getItemDamage() ); // AELog.info( "ID:" + id.toString() + " : " + is.getItemDamage() );
@@ -211,14 +232,29 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
final IPart testPart = ( (IPartItem) newType.getItem() ).createPartFromItemStack( newType ); final IPart testPart = ( (IPartItem) newType.getItem() ).createPartFromItemStack( newType );
if( testPart instanceof PartP2PTunnel ) if( testPart instanceof PartP2PTunnel )
{ {
try
{
this.getProxy().getP2P().removeTunnel( this, this.getFrequency() );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
this.getHost().removePart( this.getSide(), true ); this.getHost().removePart( this.getSide(), true );
final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand ); final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand );
final IPart newBus = this.getHost().getPart( dir ); final IPart newBus = this.getHost().getPart( dir );
if( newBus instanceof PartP2PTunnel ) if( newBus instanceof PartP2PTunnel )
{ {
final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus; final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus;
newTunnel.setOutput( true );
if( pasteAsOutput )
{
newTunnel.setOutput( true );
}
try try
{ {
@@ -295,7 +331,17 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
final boolean oldOutput = this.isOutput(); final boolean oldOutput = this.isOutput();
final short myFreq = this.getFrequency(); final short myFreq = this.getFrequency();
try
{
this.getProxy().getP2P().removeTunnel( this, this.getFrequency() );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
this.getHost().removePart( this.getSide(), false ); this.getHost().removePart( this.getSide(), false );
final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand ); final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand );
final IPart newBus = this.getHost().getPart( dir ); final IPart newBus = this.getHost().getPart( dir );
@@ -303,7 +349,6 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
{ {
final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus; final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus;
newTunnel.setOutput( oldOutput ); newTunnel.setOutput( oldOutput );
newTunnel.onTunnelNetworkChange();
try try
{ {
@@ -314,9 +359,10 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
{ {
// :P // :P
} }
newTunnel.onTunnelNetworkChange();
} }
Platform.notifyBlocksOfNeighbors( this.getTile().getWorld(), this.getTile().getPos() );
return true; return true;
} }
} }
@@ -350,9 +396,38 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
if( needsNewFrequency ) if( needsNewFrequency )
{ {
newFreq = this.getProxy().getP2P().newFrequency(); newFreq = this.getProxy().getP2P().newFrequency();
}
this.getProxy().getP2P().updateFreq( this, newFreq ); final ItemStack newType = this.getHost().getPart( this.getSide() ).getItemStack( PartItemStack.WRENCH );
try
{
this.getProxy().getP2P().removeTunnel( this, this.getFrequency() );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
this.getHost().removePart( this.getSide(), false );
final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand );
final IPart newBus = this.getHost().getPart( dir );
if( newBus instanceof PartP2PTunnel )
{
final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus;
newTunnel.setOutput( false );
newTunnel.getProxy().getP2P().updateFreq( newTunnel, newFreq );
newTunnel.onTunnelNetworkChange();
}
}
else
{
this.getProxy().getP2P().updateFreq( this, newFreq );
this.onTunnelNetworkChange();
}
Platform.notifyBlocksOfNeighbors( this.getTile().getWorld(), this.getTile().getPos() );
} }
catch( final GridAccessException e ) catch( final GridAccessException e )
{ {
@@ -365,10 +440,17 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
final String type = p2pItem.getUnlocalizedName(); final String type = p2pItem.getUnlocalizedName();
p2pItem.writeToNBT( data ); p2pItem.writeToNBT( data );
data.setShort( "freq", this.getFrequency() ); if( needsNewFrequency )
{
data.setShort( "freq", newFreq );
}
else
{
data.setShort( "freq", this.getFrequency() );
}
final AEColor[] colors = Platform.p2p().toColors( this.getFrequency() ); final AEColor[] colors = Platform.p2p().toColors( this.getFrequency() );
final int[] colorCode = new int[] { final int[] colorCode = new int[]{
colors[0].ordinal(), colors[0].ordinal(), colors[1].ordinal(), colors[1].ordinal(), colors[0].ordinal(), colors[0].ordinal(), colors[1].ordinal(), colors[1].ordinal(),
colors[2].ordinal(), colors[2].ordinal(), colors[3].ordinal(), colors[3].ordinal(), colors[2].ordinal(), colors[2].ordinal(), colors[3].ordinal(), colors[3].ordinal(),
}; };
@@ -395,7 +477,6 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
public void onTunnelNetworkChange() public void onTunnelNetworkChange()
{ {
} }
protected void queueTunnelDrain( final PowerUnits unit, final double f ) protected void queueTunnelDrain( final PowerUnits unit, final double f )
@@ -82,6 +82,7 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
private IAEItemStack configuredItem; private IAEItemStack configuredItem;
private IAEFluidStack configuredFluid; private IAEFluidStack configuredFluid;
private long configuredAmount;
private String lastHumanReadableText; private String lastHumanReadableText;
private boolean isLocked; private boolean isLocked;
private IStackWatcher myWatcher; private IStackWatcher myWatcher;
@@ -208,14 +209,21 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
fluidInTank = fluidHandlerItem.drain( Integer.MAX_VALUE, false ); fluidInTank = fluidHandlerItem.drain( Integer.MAX_VALUE, false );
} }
if (fluidInTank == null) if( fluidInTank == null )
{ {
this.configuredFluid = null; this.configuredFluid = null;
this.configuredItem = AEItemStack.fromItemStack( eq ); if( !eq.isEmpty() )
{
this.configuredItem = AEItemStack.fromItemStack( eq ).setStackSize( 0 );
}
else
{
this.configuredItem = null;
}
} }
else if( fluidInTank.amount > 0 ) else if( fluidInTank.amount > 0 )
{ {
this.configuredFluid = AEFluidStack.fromFluidStack( fluidInTank ); this.configuredFluid = AEFluidStack.fromFluidStack( fluidInTank ).setStackSize( 0 );
this.configuredItem = null; this.configuredItem = null;
} }
@@ -299,30 +307,31 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
private <T extends IAEStack<T>> void updateReportingValue ( final IMEMonitor<T> monitor ) private <T extends IAEStack<T>> void updateReportingValue ( final IMEMonitor<T> monitor )
{ {
if( this.configuredItem != null) if( this.configuredItem != null)
{ {
final IAEItemStack result = (IAEItemStack) monitor.getStorageList().findPrecise( (T) this.configuredItem ); final IAEItemStack result = (IAEItemStack) monitor.getStorageList().findPrecise( (T) this.configuredItem );
if( result == null ) if( result == null )
{ {
this.configuredItem.setStackSize( 0 ); this.configuredAmount = 0;
} }
else else
{ {
this.configuredItem.setStackSize( result.getStackSize() ); this.configuredAmount = result.getStackSize();
} }
this.configuredItem.setStackSize( this.configuredAmount );
} }
else if( this.configuredFluid != null) else if( this.configuredFluid != null)
{ {
final IAEFluidStack result = (IAEFluidStack) monitor.getStorageList().findPrecise( (T) this.configuredFluid ); final IAEFluidStack result = (IAEFluidStack) monitor.getStorageList().findPrecise( (T) this.configuredFluid );
if( result == null ) if( result == null )
{ {
this.configuredFluid.setStackSize( 0 ); this.configuredAmount = 0;
} }
else else
{ {
this.configuredFluid.setStackSize( result.getStackSize() ); this.configuredAmount = result.getStackSize();
} }
this.configuredFluid.setStackSize( this.configuredAmount );
} }
} }
@@ -390,108 +399,35 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void powerStatusChange( final MENetworkPowerStatusChange ev ) public void powerStatusChange( final MENetworkPowerStatusChange ev )
{ {
if( !this.getProxy().isPowered() ) if( this.getProxy().isPowered() )
{ {
if( this.myWatcher != null ) this.configureWatchers();
{
if( this.configuredItem != null )
{
this.configuredItem.setStackSize( 0 );
}
if( this.configuredFluid != null )
{
this.configuredFluid.setStackSize( 0 );
}
}
}
else
{
try
{
if( this.configuredItem != null )
{
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
}
if( this.configuredFluid != null )
{
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ) );
}
}
catch( final GridAccessException e )
{
// ;P
}
} }
} }
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void channelChanged( final MENetworkChannelsChanged c ) public void channelChanged( final MENetworkChannelsChanged c )
{ {
if( !this.getProxy().isPowered() ) if( this.getProxy().isPowered() )
{ {
if( this.myWatcher != null ) this.configureWatchers();
{
if( this.configuredItem != null )
{
this.configuredItem.setStackSize( 0 );
}
if( this.configuredFluid != null )
{
this.configuredFluid.setStackSize( 0 );
}
}
}
else
{
try
{
if( this.configuredItem != null )
{
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
}
if( this.configuredFluid != null )
{
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ) );
}
}
catch( final GridAccessException e )
{
// ;P
}
} }
} }
@Override @Override
public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan ) public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan )
{ {
this.configuredAmount = fullStack.getStackSize();
if( this.configuredItem != null ) if( this.configuredItem != null )
{ {
long diff = this.configuredItem.getStackSize() + diffStack.getStackSize(); this.configuredItem.setStackSize( this.configuredAmount );
this.configuredItem.setStackSize( diff >= 0 ? this.configuredItem.getStackSize() + diffStack.getStackSize() : 0 );
final long stackSize = this.configuredItem.getStackSize();
final String humanReadableText = NUMBER_CONVERTER.toWideReadableForm( stackSize );
if( !humanReadableText.equals( this.lastHumanReadableText ) )
{
this.lastHumanReadableText = humanReadableText;
this.getHost().markForUpdate();
}
} }
else if( this.configuredFluid != null ) else if( this.configuredFluid != null )
{ {
long diff = this.configuredFluid.getStackSize() + diffStack.getStackSize(); this.configuredFluid.setStackSize( this.configuredAmount );
this.configuredFluid.setStackSize( diff >= 0 ? this.configuredFluid.getStackSize() + diffStack.getStackSize() : 0 );
final long stackSize = this.configuredFluid.getStackSize() / 1000;
final String humanReadableText = NUMBER_CONVERTER.toWideReadableForm( stackSize ) + "B";
if( !humanReadableText.equals( this.lastHumanReadableText ) )
{
this.lastHumanReadableText = humanReadableText;
this.getHost().markForUpdate();
}
} }
this.getHost().markForUpdate();
} }
@Override @Override
@@ -137,14 +137,10 @@ public class PartConversionMonitor extends AbstractPartMonitor
{ {
this.insertItem( player, hand, false ); this.insertItem( player, hand, false );
} }
} }
//If its a fluid container, grab its fluidstack. if its empty pass its itemstack; //If its a fluid container, grab its fluidstack. if its empty pass its itemstack;
if (eq.isEmpty()){
return super.onPartActivate( player, hand, pos );
}
if( fluidInTank != null && fluidInTank.amount > 0 ) if( fluidInTank != null && fluidInTank.amount > 0 )
{ {
if( getDisplayed() instanceof IAEItemStack || getDisplayed() == null ) if( getDisplayed() instanceof IAEItemStack || getDisplayed() == null )
@@ -155,23 +151,16 @@ public class PartConversionMonitor extends AbstractPartMonitor
{ {
this.drainFluidContainer( player, hand ); this.drainFluidContainer( player, hand );
} }
else { else
{
return super.onPartActivate( player, hand, pos ); return super.onPartActivate( player, hand, pos );
} }
} }
else else if( this.getDisplayed() != null && this.getDisplayed().equals( player.getHeldItem( hand ) ) )
{ {
if( getDisplayed() instanceof IAEFluidStack || getDisplayed() == null ) this.insertItem( player, hand, false );
{
return super.onPartActivate( player, hand, pos );
}
if( ( (IAEItemStack) this.getDisplayed() ).equals( eq ) )
{
this.insertItem( player, hand, false );
}
} }
return super.onPartActivate( player, hand, pos );
return true;
} }
@Override @Override
@@ -192,7 +181,6 @@ public class PartConversionMonitor extends AbstractPartMonitor
return false; return false;
} }
ItemStack eq = player.getHeldItem( hand );
if( this.getDisplayed() != null && this.getDisplayed() instanceof IAEItemStack ) if( this.getDisplayed() != null && this.getDisplayed() instanceof IAEItemStack )
{ {
this.extractItem( player, ( (IAEItemStack) this.getDisplayed() ).getDefinition().getMaxStackSize() ); this.extractItem( player, ( (IAEItemStack) this.getDisplayed() ).getDefinition().getMaxStackSize() );
@@ -282,7 +270,7 @@ public class PartConversionMonitor extends AbstractPartMonitor
{ {
if (!(this.getDisplayed() instanceof IAEItemStack)) if (!(this.getDisplayed() instanceof IAEItemStack))
return; return;
final IAEItemStack input = (IAEItemStack) this.getDisplayed(); final IAEItemStack input = (IAEItemStack) this.getDisplayed().copy();
if( input != null ) if( input != null )
{ {
try try
@@ -0,0 +1,138 @@
package appeng.parts.reporting;
import appeng.api.implementations.ICraftingPatternItem;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.parts.IPartModel;
import appeng.api.storage.data.IAEItemStack;
import appeng.core.AppEng;
import appeng.core.sync.GuiBridge;
import appeng.helpers.Reflected;
import appeng.items.parts.PartModels;
import appeng.parts.PartModel;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.inv.InvOperation;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.items.IItemHandler;
import static appeng.helpers.PatternHelper.PROCESSING_INPUT_LIMIT;
import static appeng.helpers.PatternHelper.PROCESSING_OUTPUT_LIMIT;
public class PartExpandedProcessingPatternTerminal extends AbstractPartTerminal
{
@PartModels
public static final ResourceLocation MODEL_OFF = new ResourceLocation( AppEng.MOD_ID, "part/expanded_processing_pattern_terminal_off" );
@PartModels
public static final ResourceLocation MODEL_ON = new ResourceLocation( AppEng.MOD_ID, "part/expanded_processing_pattern_terminal_on" );
public static final IPartModel MODELS_OFF = new PartModel( MODEL_BASE, MODEL_OFF, MODEL_STATUS_OFF );
public static final IPartModel MODELS_ON = new PartModel( MODEL_BASE, MODEL_ON, MODEL_STATUS_ON );
public static final IPartModel MODELS_HAS_CHANNEL = new PartModel( MODEL_BASE, MODEL_ON, MODEL_STATUS_HAS_CHANNEL );
private final AppEngInternalInventory crafting = new AppEngInternalInventory( this, PROCESSING_INPUT_LIMIT );
private final AppEngInternalInventory output = new AppEngInternalInventory( this, PROCESSING_OUTPUT_LIMIT );
private final AppEngInternalInventory pattern = new AppEngInternalInventory( this, 2 );
@Reflected
public PartExpandedProcessingPatternTerminal( final ItemStack is )
{
super( is );
}
@Override
public void readFromNBT( NBTTagCompound data )
{
super.readFromNBT( data );
this.crafting.readFromNBT( data, "processingGrid" );
this.pattern.readFromNBT( data, "pattern" );
this.output.readFromNBT( data, "outputList" );
}
@Override
public void writeToNBT( NBTTagCompound data )
{
super.writeToNBT( data );
this.crafting.writeToNBT( data, "processingGrid" );
this.pattern.writeToNBT( data, "pattern" );
this.output.writeToNBT( data, "outputList" );
}
@Override
public GuiBridge getGui( final EntityPlayer p )
{
int x = (int) p.posX;
int y = (int) p.posY;
int z = (int) p.posZ;
if( this.getHost().getTile() != null )
{
x = this.getTile().getPos().getX();
y = this.getTile().getPos().getY();
z = this.getTile().getPos().getZ();
}
if( GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL.hasPermissions( this.getHost().getTile(), x, y, z, this.getSide(), p ) )
{
return GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
}
return GuiBridge.GUI_ME;
}
@Override
public void onChangeInventory( final IItemHandler inv, final int slot, final InvOperation mc, final ItemStack removedStack, final ItemStack newStack )
{
if( inv == this.pattern && slot == 1 )
{
final ItemStack is = this.pattern.getStackInSlot( 1 );
if( !is.isEmpty() && is.getItem() instanceof ICraftingPatternItem )
{
final ICraftingPatternItem pattern = (ICraftingPatternItem) is.getItem();
final ICraftingPatternDetails details = pattern.getPatternForItem( is, this.getHost().getTile().getWorld() );
if( details != null )
{
for( int x = 0; x < this.crafting.getSlots() && x < details.getInputs().length; x++ )
{
final IAEItemStack item = details.getInputs()[x];
this.crafting.setStackInSlot( x, item == null ? ItemStack.EMPTY : item.createItemStack() );
}
for( int x = 0; x < this.output.getSlots() && x < details.getOutputs().length; x++ )
{
final IAEItemStack item = details.getOutputs()[x];
this.output.setStackInSlot( x, item == null ? ItemStack.EMPTY : item.createItemStack() );
}
}
}
}
this.getHost().markForSave();
}
@Override
public IItemHandler getInventoryByName( final String name )
{
if( name.equals( "crafting" ) )
{
return this.crafting;
}
if( name.equals( "output" ) )
{
return this.output;
}
if( name.equals( "pattern" ) )
{
return this.pattern;
}
return super.getInventoryByName( name );
}
@Override
public IPartModel getStaticModels()
{
return this.selectModel( MODELS_OFF, MODELS_ON, MODELS_HAS_CHANNEL );
}
}
@@ -123,7 +123,7 @@ public class AppEngInternalInventory extends ItemStackHandler implements Iterabl
ItemStack oldStack = this.previousStack; ItemStack oldStack = this.previousStack;
InvOperation op = InvOperation.SET; InvOperation op = InvOperation.SET;
if( newStack.isEmpty() || oldStack.isEmpty() || ItemStack.areItemsEqual( newStack, oldStack ) ) if( newStack.isEmpty() || oldStack.isEmpty() || ( oldStack.getCount() < oldStack.getMaxStackSize() && oldStack.getCount() < this.getSlotLimit( slot ) && ItemStack.areItemsEqual( newStack, oldStack ) ) )
{ {
if( newStack.getCount() > oldStack.getCount() ) if( newStack.getCount() > oldStack.getCount() )
{ {
@@ -155,7 +155,7 @@ public class TileEnergyCell extends AENetworkTile implements IAEPowerStorage
return 0; return 0;
} }
if( this.internalCurrentPower < 0.01 && amt > 0.01 ) if( this.internalCurrentPower < 0.01 && amt > 0 )
{ {
this.getProxy().getNode().getGrid().postEvent( new MENetworkPowerStorage( this, PowerEventType.PROVIDE_POWER ) ); this.getProxy().getNode().getGrid().postEvent( new MENetworkPowerStorage( this, PowerEventType.PROVIDE_POWER ) );
} }
@@ -217,7 +217,7 @@ public class TileEnergyCell extends AENetworkTile implements IAEPowerStorage
final boolean wasFull = this.internalCurrentPower >= this.getInternalMaxPower() - 0.001; final boolean wasFull = this.internalCurrentPower >= this.getInternalMaxPower() - 0.001;
if( wasFull && amt > 0.001 ) if( wasFull && amt > 0 )
{ {
try try
{ {
@@ -26,6 +26,8 @@ import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import appeng.me.storage.BasicCellInventoryHandler;
import appeng.me.storage.CreativeCellInventory;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
@@ -493,13 +495,15 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
try try
{ {
if( this.getProxy().isActive() )
{
final IStorageGrid gs = this.getProxy().getStorage();
Platform.postChanges( gs, removed, added, this.mySrc );
}
this.getProxy().getGrid().postEvent( new MENetworkCellArrayUpdate() ); this.getProxy().getGrid().postEvent( new MENetworkCellArrayUpdate() );
final IStorageGrid gs = this.getProxy().getStorage();
Platform.postChanges( gs, removed, added, this.mySrc );
} }
catch( final GridAccessException ignored ) catch( final GridAccessException ignored )
{ {
} }
// update the neighbors // update the neighbors
@@ -733,7 +737,15 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
{ {
return input; return input;
} }
return super.injectItems( input, mode, src ); T injected = super.injectItems( input, mode, src );
if (mode == Actionable.MODULATE && ( injected == null || injected.getStackSize() != input.getStackSize() ))
{
if( TileChest.this.getProxy().isActive() && this.getInternalHandler().getCellInv() != null )
{
TileChest.this.cellHandler.postChangesToListeners(Collections.singletonList( input.copy().setStackSize( input.getStackSize() - ( injected == null ? 0 : injected.getStackSize() ) ) ), TileChest.this.mySrc );
}
}
return injected;
} }
private boolean securityCheck( final EntityPlayer player, final SecurityPermissions requiredPermission ) private boolean securityCheck( final EntityPlayer player, final SecurityPermissions requiredPermission )
@@ -777,7 +789,15 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
{ {
return null; return null;
} }
return super.extractItems( request, mode, src ); T extracted = super.extractItems( request, mode, src );
if( mode == Actionable.MODULATE && extracted != null )
{
if( TileChest.this.getProxy().isActive() && this.getInternalHandler().getCellInv() != null )
{
TileChest.this.cellHandler.postChangesToListeners(Collections.singletonList( request.copy().setStackSize( -extracted.getStackSize() ) ), TileChest.this.mySrc );
}
}
return extracted;
} }
} }
@@ -263,10 +263,12 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior
try try
{ {
if( this.getProxy().isActive() )
{
final IStorageGrid gs = this.getProxy().getStorage();
Platform.postChanges( gs, removed, added, this.mySrc );
}
this.getProxy().getGrid().postEvent( new MENetworkCellArrayUpdate() ); this.getProxy().getGrid().postEvent( new MENetworkCellArrayUpdate() );
final IStorageGrid gs = this.getProxy().getStorage();
Platform.postChanges( gs, removed, added, this.mySrc );
} }
catch( final GridAccessException ignored ) catch( final GridAccessException ignored )
{ {
@@ -53,6 +53,7 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
private String displayName; private String displayName;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
private List<String> tooltip; private List<String> tooltip;
private ItemStack cachedItemStack;
private AEItemStack(final AEItemStack is) { private AEItemStack(final AEItemStack is) {
this.setStackSize(is.getStackSize()); this.setStackSize(is.getStackSize());
@@ -250,6 +251,18 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
return this.isSameType(is); return this.isSameType(is);
} }
@Override
public ItemStack getCachedItemStack()
{
return this.cachedItemStack;
}
@Override
public void setCachedItemStack( ItemStack is )
{
this.cachedItemStack = is;
}
@Override @Override
public String toString() { public String toString() {
return this.getStackSize() + "x" + this.getDefinition().getItem().getRegistryName(); return this.getStackSize() + "x" + this.getDefinition().getItem().getRegistryName();
+50 -10
View File
@@ -19,13 +19,8 @@
package appeng.util.item; package appeng.util.item;
import java.util.Collection; import java.util.*;
import java.util.HashMap; import java.util.concurrent.ConcurrentMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
@@ -116,7 +111,7 @@ public class OreHelper
boolean sameOre( final AEItemStack aeItemStack, final IAEItemStack is ) boolean sameOre( final AEItemStack aeItemStack, final IAEItemStack is )
{ {
final OreReference a = aeItemStack.getOre().orElse( null ); final OreReference a = aeItemStack.getOre().orElse( null );
final OreReference b = aeItemStack.getOre().orElse( null ); final OreReference b = ( (AEItemStack) is ).getOre().orElse( null );
return this.sameOre( a, b ); return this.sameOre( a, b );
} }
@@ -160,8 +155,53 @@ public class OreHelper
} }
} }
return false; return false;
} ) } ).orElse( false );
.orElse( false ); }
public Set<Integer> getMatchingOre( String allow )
{
List<String> matchingOres = new ArrayList<>();
ConcurrentMap<String, List<ItemStack>> oreKeys = oreDictCache.asMap();
oreKeys.forEach( ( s, l ) -> {
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 );
}
}
} );
Set<Integer> oreIDs = new HashSet<>();
for( String matchingOre : matchingOres )
{
oreIDs.add( OreDictionary.getOreID( matchingOre ) );
}
return oreIDs;
} }
List<ItemStack> getCachedOres( final String oreName ) List<ItemStack> getCachedOres( final String oreName )
@@ -65,8 +65,8 @@ public class OreReference
return this.aeOtherOptions; return this.aeOtherOptions;
} }
Collection<Integer> getOres() public Collection<Integer> getOres()
{ {
return this.ores; return this.ores;
} }
} }
@@ -0,0 +1,51 @@
package appeng.util.prioritylist;
import appeng.api.storage.data.IAEStack;
import appeng.util.item.AEItemStack;
import appeng.util.item.OreReference;
import java.util.ArrayList;
import java.util.Set;
public class OreDictPriorityList<T extends IAEStack<T>> implements IPartitionList<T>
{
private final Set<Integer> oreIDs;
private final String oreMatch;
public OreDictPriorityList( Set<Integer> oreIDs, String oreMatch )
{
this.oreIDs = oreIDs;
this.oreMatch = oreMatch;
}
@Override
public boolean isListed( final T input )
{
OreReference or = ( (AEItemStack) input ).getOre().orElse( null );
if( or != null )
{
for( Integer oreID : or.getOres() )
{
if( this.oreIDs.contains( oreID ) )
{
return true;
}
}
}
return false;
}
@Override
public boolean isEmpty()
{
return oreMatch.equals( "" );
}
@Override
public Iterable<T> getItems()
{
return new ArrayList<>();
}
}
@@ -133,6 +133,7 @@ gui.appliedenergistics2.SecurityCardEditor=Biometric Card Editor
gui.appliedenergistics2.Encoded=Encoded gui.appliedenergistics2.Encoded=Encoded
gui.appliedenergistics2.Priority=Priority gui.appliedenergistics2.Priority=Priority
gui.appliedenergistics2.StorageBus=Storage Bus gui.appliedenergistics2.StorageBus=Storage Bus
gui.appliedenergistics2.OreDictStorageBus=Ore Dictionary Storage Bus
gui.appliedenergistics2.StorageBusFluids=Fluid Storage Bus gui.appliedenergistics2.StorageBusFluids=Fluid Storage Bus
gui.appliedenergistics2.EnergyDrain=Passive Drain gui.appliedenergistics2.EnergyDrain=Passive Drain
gui.appliedenergistics2.Installed=Installed gui.appliedenergistics2.Installed=Installed
@@ -405,8 +406,10 @@ waila.appliedenergistics2.Showing=Showing
waila.appliedenergistics2.Contains=Contains waila.appliedenergistics2.Contains=Contains
waila.appliedenergistics2.Channels=%1$d of %2$d Channels waila.appliedenergistics2.Channels=%1$d of %2$d Channels
waila.appliedenergistics2.P2PUnlinked=Unlinked waila.appliedenergistics2.P2PUnlinked=Unlinked
waila.appliedenergistics2.P2PInputOneOutput=Linked (Input Side) waila.appliedenergistics2.p2p_input_one_output=Linked (Input Side) - 1 Output
waila.appliedenergistics2.P2PInputManyOutputs=Linked (Input Side) - %d Outputs waila.appliedenergistics2.p2p_input_many_outputs=Linked (Input Side) - %d Outputs
waila.appliedenergistics2.p2p_output_one_input=Linked (Output Side) - 1 Input
waila.appliedenergistics2.p2p_output_many_inputs=Linked (Output Side) - %d Inputs
waila.appliedenergistics2.P2POutput=Linked (Output Side) waila.appliedenergistics2.P2POutput=Linked (Output Side)
// TheOneProbe // TheOneProbe
@@ -420,8 +423,10 @@ theoneprobe.appliedenergistics2.showing=Showing
theoneprobe.appliedenergistics2.contains=Contains theoneprobe.appliedenergistics2.contains=Contains
theoneprobe.appliedenergistics2.channels=%1$d of %2$d Channels theoneprobe.appliedenergistics2.channels=%1$d of %2$d Channels
theoneprobe.appliedenergistics2.p2p_unlinked=Unlinked theoneprobe.appliedenergistics2.p2p_unlinked=Unlinked
theoneprobe.appliedenergistics2.p2p_input_one_output=Linked (Input Side) theoneprobe.appliedenergistics2.p2p_input_one_output=Linked (Input Side) - 1 Output
theoneprobe.appliedenergistics2.p2p_input_many_outputs=Linked (Input Side) - %d Outputs theoneprobe.appliedenergistics2.p2p_input_many_outputs=Linked (Input Side) - %d Outputs
theoneprobe.appliedenergistics2.p2p_output_one_input=Linked (Output Side) - 1 Input
theoneprobe.appliedenergistics2.p2p_output_many_inputs=Linked (Output Side) - %d Inputs
theoneprobe.appliedenergistics2.p2p_output=Linked (Output Side) theoneprobe.appliedenergistics2.p2p_output=Linked (Output Side)
theoneprobe.appliedenergistics2.p2p_frequency=Frequency: %1$s theoneprobe.appliedenergistics2.p2p_frequency=Frequency: %1$s
theoneprobe.appliedenergistics2.stored_energy=%1$d / %2$d theoneprobe.appliedenergistics2.stored_energy=%1$d / %2$d
@@ -531,8 +536,10 @@ item.appliedenergistics2.multi_part.level_emitter.name=ME Level Emitter
item.appliedenergistics2.multi_part.fluid_level_emitter.name=ME Fluid Level Emitter item.appliedenergistics2.multi_part.fluid_level_emitter.name=ME Fluid Level Emitter
item.appliedenergistics2.multi_part.p2p_tunnel.name=P2P Tunnel item.appliedenergistics2.multi_part.p2p_tunnel.name=P2P Tunnel
item.appliedenergistics2.multi_part.pattern_terminal.name=ME Pattern Terminal item.appliedenergistics2.multi_part.pattern_terminal.name=ME Pattern Terminal
item.appliedenergistics2.multi_part.expanded_processing_pattern_terminal.name=ME Extended Processing Pattern Terminal
item.appliedenergistics2.multi_part.quartz_fiber.name=Quartz Fiber item.appliedenergistics2.multi_part.quartz_fiber.name=Quartz Fiber
item.appliedenergistics2.multi_part.storage_bus.name=ME Storage Bus item.appliedenergistics2.multi_part.storage_bus.name=ME Storage Bus
item.appliedenergistics2.multi_part.oredict_storage_bus.name=ME OreDict Storage Bus
item.appliedenergistics2.multi_part.fluid_storage_bus.name=ME Fluid Storage Bus item.appliedenergistics2.multi_part.fluid_storage_bus.name=ME Fluid Storage Bus
item.appliedenergistics2.multi_part.terminal.name=ME Terminal item.appliedenergistics2.multi_part.terminal.name=ME Terminal
item.appliedenergistics2.multi_part.inverted_toggle_bus.name=ME Inverted Toggle Bus item.appliedenergistics2.multi_part.inverted_toggle_bus.name=ME Inverted Toggle Bus
@@ -0,0 +1,9 @@
{
"parent": "appliedenergistics2:item/part/display",
"textures": {
"front": "appliedenergistics2:items/part/expanded_processing_pattern_terminal",
"front_bright": "appliedenergistics2:parts/expanded_processing_pattern_terminal_bright",
"front_medium": "appliedenergistics2:parts/expanded_processing_pattern_terminal_medium",
"front_dark": "appliedenergistics2:parts/pattern_terminal_dark"
}
}
@@ -0,0 +1,106 @@
{
"parent": "appliedenergistics2:item/part/part",
"textures": {
"sides": "appliedenergistics2:parts/storage_bus_sides",
"back": "appliedenergistics2:parts/storage_bus_back",
"front": "appliedenergistics2:items/part/oredict_storage_bus"
},
"elements": [
{
"from": [
3,
3,
6
],
"to": [
13,
13,
7
],
"faces": {
"north": {
"texture": "#front"
},
"south": {
"texture": "#back"
},
"east": {
"texture": "#sides"
},
"west": {
"texture": "#sides"
},
"up": {
"texture": "#sides"
},
"down": {
"texture": "#sides"
}
}
},
{
"from": [
2,
2,
7
],
"to": [
14,
14,
8
],
"faces": {
"north": {
"texture": "#front"
},
"south": {
"texture": "#back"
},
"east": {
"texture": "#sides"
},
"west": {
"texture": "#sides"
},
"up": {
"texture": "#sides"
},
"down": {
"texture": "#sides"
}
}
},
{
"from": [
5,
5,
8
],
"to": [
11,
11,
10
],
"faces": {
"north": {
"texture": "#front"
},
"south": {
"texture": "#back"
},
"east": {
"texture": "#sides"
},
"west": {
"texture": "#sides"
},
"up": {
"texture": "#sides"
},
"down": {
"texture": "#sides"
}
}
}
]
}
@@ -0,0 +1,8 @@
{
"parent": "appliedenergistics2:part/display_off",
"textures": {
"lightsBright": "appliedenergistics2:parts/expanded_processing_pattern_terminal_bright",
"lightsMedium": "appliedenergistics2:parts/expanded_processing_pattern_terminal_medium",
"lightsDark": "appliedenergistics2:parts/pattern_terminal_dark"
}
}
@@ -0,0 +1,76 @@
{
"ae2_uvl_marker": true,
"textures": {
"lightsBright": "appliedenergistics2:parts/expanded_processing_pattern_terminal_bright",
"lightsMedium": "appliedenergistics2:parts/expanded_processing_pattern_terminal_medium",
"lightsDark": "appliedenergistics2:parts/pattern_terminal_dark"
},
"elements": [
{
"from": [
2,
2,
0
],
"to": [
14,
14,
2
],
"faces": {
"north": {
"texture": "#lightsBright",
"tintindex": 3,
"uvlightmap": {
"sky": 0.007,
"block": 0.007
}
}
}
},
{
"from": [
2,
2,
0
],
"to": [
14,
14,
2
],
"faces": {
"north": {
"texture": "#lightsMedium",
"tintindex": 2,
"uvlightmap": {
"sky": 0.007,
"block": 0.007
}
}
}
},
{
"from": [
2,
2,
0
],
"to": [
14,
14,
2
],
"faces": {
"north": {
"texture": "#lightsDark",
"tintindex": 1,
"uvlightmap": {
"sky": 0.007,
"block": 0.007
}
}
}
}
]
}
@@ -0,0 +1,130 @@
{
"textures": {
"sides": "appliedenergistics2:parts/storage_bus_sides",
"sidesStatus": "appliedenergistics2:parts/monitor_sides_status",
"back": "appliedenergistics2:parts/storage_bus_back",
"front": "appliedenergistics2:items/part/oredict_storage_bus",
"particle": "appliedenergistics2:parts/storage_bus_back"
},
"elements": [
{
"from": [
3,
3,
0
],
"to": [
13,
13,
1
],
"faces": {
"down": {
"texture": "#sides"
},
"up": {
"texture": "#sides"
},
"south": {
"texture": "#back"
},
"east": {
"texture": "#sides"
},
"north": {
"texture": "#front"
},
"west": {
"texture": "#sides"
}
}
},
{
"from": [
2,
2,
1
],
"to": [
14,
14,
2
],
"faces": {
"down": {
"texture": "#sides"
},
"up": {
"texture": "#sides"
},
"south": {
"texture": "#back"
},
"east": {
"texture": "#sides"
},
"north": {
"texture": "#front"
},
"west": {
"texture": "#sides"
}
}
},
{
"from": [
5,
5,
3
],
"to": [
11,
11,
4
],
"faces": {
"down": {
"texture": "#sides"
},
"up": {
"texture": "#sides"
},
"south": {
"texture": "#back"
},
"east": {
"texture": "#sides"
},
"west": {
"texture": "#sides"
}
}
},
{
"from": [
5,
5,
2
],
"to": [
11,
11,
3
],
"faces": {
"down": {
"texture": "#sides"
},
"up": {
"texture": "#sides"
},
"east": {
"texture": "#sides"
},
"west": {
"texture": "#sides"
}
}
}
]
}
@@ -0,0 +1,41 @@
{
"conditions": [
{
"type": "forge:and",
"values": [
{
"type": "appliedenergistics2:part_exists",
"part": "part.pattern_terminal"
},
{
"type": "appliedenergistics2:material_exists",
"material": "material.calculation_processor"
}
]
}
],
"result": {
"type": "appliedenergistics2:part",
"part": "part.expanded_processing_pattern_terminal"
},
"type": "appliedenergistics2:part_shaped",
"pattern": [
"c c",
"tft",
"c c"
],
"key": {
"f": {
"type": "appliedenergistics2:part",
"part": "cable_glass.fluix"
},
"t": {
"type": "appliedenergistics2:part",
"part": "part.pattern_terminal"
},
"c": {
"type": "appliedenergistics2:part",
"part": "material.calculation_processor"
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B