Compare commits
116 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9fc96295a8 | |||
| fd3349614d | |||
| 903f211044 | |||
| 78e1e26a11 | |||
| 2a6de11597 | |||
| cd2b53af85 | |||
| 1c5565491a | |||
| 311cc5c6f6 | |||
| 41796449ed | |||
| 9eef9d3840 | |||
| 13afa6908a | |||
| 103438f805 | |||
| eaa01f7648 | |||
| e81fb09599 | |||
| 94d73aec7c | |||
| b51af43dba | |||
| 85dc8ae7c1 | |||
| c34176f392 | |||
| 76fe2175a0 | |||
| c5d33ed892 | |||
| b423d99879 | |||
| 81156b411d | |||
| 6be1660d41 | |||
| 304f394497 | |||
| 50f21125c8 | |||
| 30b85bd239 | |||
| 9ce00d338f | |||
| 11f5b71089 | |||
| e7da72163b | |||
| 6d7c65dd70 | |||
| 5e21101619 | |||
| 3db8d0185f | |||
| 2f5ecfe638 | |||
| 75843e802d | |||
| e41b6943aa | |||
| 92347ad2f5 | |||
| 517bd77df7 | |||
| 19f928a9a5 | |||
| 73251a0fe5 | |||
| 9335daff7d | |||
| cc5377d53b | |||
| 059f20d801 | |||
| d229570495 | |||
| c284748b6c | |||
| 880a9c8821 | |||
| c68c02ef3b | |||
| 89c4d2736c | |||
| 01778794e5 | |||
| 8f2a06e457 | |||
| 2d71b75019 | |||
| 9f09cd04d4 | |||
| b041fae0d5 | |||
| c466a0e00e | |||
| 618e9390c6 | |||
| 9a71bfb0f0 | |||
| 9680123906 | |||
| 87730894e9 | |||
| 71c944daea | |||
| e96b4a698a | |||
| 1d5465a4b8 | |||
| 09cbfe96d6 | |||
| cbdad7c58e | |||
| 6be96956a9 | |||
| e376e002e9 | |||
| 0b9df31d4e | |||
| cef6dbf0d7 | |||
| e4af7b1947 | |||
| 6eadb8f861 | |||
| b6b6a83563 | |||
| 32ab4c6af4 | |||
| fda8c87410 | |||
| 389e060707 | |||
| 0942a90ef4 | |||
| 8cef06512a | |||
| 8e4658be20 | |||
| 0bd2bd6b5a | |||
| db2c4c4325 | |||
| ac793ee847 | |||
| 6404f26cca | |||
| ced6ad865c | |||
| 24750f00b1 | |||
| df08ce0513 | |||
| f9c274fb48 | |||
| 3582582e3f | |||
| 6de48f8541 | |||
| 5a2c2d06d3 | |||
| 98d3cafdfd | |||
| 904de49543 | |||
| b0772bf94c | |||
| aa5d5e3623 | |||
| 42f4ef2855 | |||
| 3eb2582f29 | |||
| 307f86ded8 | |||
| 56f57e18a5 | |||
| eab695b692 | |||
| 0fb393820b | |||
| 01fe5c7a8b | |||
| 8468b47443 | |||
| 6cb583c918 | |||
| d69395a117 | |||
| 59effe8131 | |||
| 6f42876963 | |||
| 08952b48dd | |||
| e3c9c4ce65 | |||
| 7b91da58c0 | |||
| 26c06bca15 | |||
| 4458bd28ab | |||
| df3f00d978 | |||
| 18ae994ee4 | |||
| 47888b5546 | |||
| e18593feb5 | |||
| af4c3de55e | |||
| bea29331a3 | |||
| 9b9579b358 | |||
| 52da4f9528 | |||
| 50aac2c768 |
+13
-2
@@ -15,6 +15,10 @@ Fixes:
|
|||||||
- Exclusive Blocking mode for GTCE ( shapes, molds and configured circuits do not block GTCE machines )
|
- Exclusive Blocking mode for GTCE ( shapes, molds and configured circuits do not block GTCE machines )
|
||||||
- Blocking modes default to block on any item in the iventory the entity exposes
|
- Blocking modes default to block on any item in the iventory the entity exposes
|
||||||
- Fuzzy includes items that report that they're damageable, but report a maxDamage of 0 ( auto-crafting of basic capacitors -> resonant capacitors is now possible ) <- Broken item implementation.
|
- Fuzzy includes items that report that they're damageable, but report a maxDamage of 0 ( auto-crafting of basic capacitors -> resonant capacitors is now possible ) <- Broken item implementation.
|
||||||
|
- Fix CME exceptions on the energy grid
|
||||||
|
- Fix AE going offline even with enough power by extracting from the local buffer always last
|
||||||
|
- Fix IO-Port copying craftable flag into items
|
||||||
|
- Fix NBT of old items not clearing on drives that reached 64 types once
|
||||||
|
|
||||||
Performance:
|
Performance:
|
||||||
|
|
||||||
@@ -24,6 +28,9 @@ Performance:
|
|||||||
- Count items set in interfaces before queuing crafting for them needlessly
|
- Count items set in interfaces before queuing crafting for them needlessly
|
||||||
- Backported b7ca98d ( Avoid copying items on simulated item extraction )
|
- Backported b7ca98d ( Avoid copying items on simulated item extraction )
|
||||||
- Cache some level emitters functions
|
- Cache some level emitters functions
|
||||||
|
- Reduced import bus insert simulation to 1 before real insertion (if possible)
|
||||||
|
- Backported itemlist re-implementation along with pattern changes to avoid CraftingManager fallback issues
|
||||||
|
- Instead of recalculating all the content of the network on every change, track the changes properly and apply them to the cached list of items
|
||||||
|
|
||||||
QOL:
|
QOL:
|
||||||
|
|
||||||
@@ -31,7 +38,7 @@ QOL:
|
|||||||
- Added bar on the interface terminal that search by inputs ( The one on the LEFT, also searchs by interface name )
|
- Added bar on the interface terminal that search by inputs ( The one on the LEFT, also searchs by interface name )
|
||||||
- Shortcut to molecular assemblers with free slots on the terminal interface by @Theisyat
|
- Shortcut to molecular assemblers with free slots on the terminal interface by @Theisyat
|
||||||
- Toggle button on interface terminal to hide full interfaces
|
- Toggle button on interface terminal to hide full interfaces
|
||||||
- JEI "U""R" and "A" (Usages/Recipes/Bookmark) now work on the Crafting Status GUI. ( the one that shows the total items to craft, and whats missing)
|
- JEI "U", "R" and "A" (Usages/Recipes/Bookmark) now work on the Crafting Status GUI. ( the one that shows the total items to craft, and whats missing)
|
||||||
- Patterns can now be made with items currently showing on JEI. ( This is overriden by Just Enough Energistics. )
|
- Patterns can now be made with items currently showing on JEI. ( This is overriden by Just Enough Energistics. )
|
||||||
- Added multiplier buttons to processing pattern gui
|
- Added multiplier buttons to processing pattern gui
|
||||||
- Switched crafting terminal JEI search to fuzzy mode. If the recipe uses a damageable item, AE will try to grab it ( damaged tools )
|
- Switched crafting terminal JEI search to fuzzy mode. If the recipe uses a damageable item, AE will try to grab it ( damaged tools )
|
||||||
@@ -39,7 +46,11 @@ QOL:
|
|||||||
- Encoded patterns can be draggred on the interface terminal.
|
- Encoded patterns can be draggred on the interface terminal.
|
||||||
- Storage Monitor and Conversion Monitor now also ccepts fluids
|
- Storage Monitor and Conversion Monitor now also ccepts fluids
|
||||||
- Draggable JEI ghost items (also works on bookmarked items. SHIFT + Click will move the hovered item into the first free target slot)
|
- Draggable JEI ghost items (also works on bookmarked items. SHIFT + Click will move the hovered item into the first free target slot)
|
||||||
-JEI auto switches between crafting and processing patterns
|
- JEI auto switches between crafting and processing patterns
|
||||||
|
- GTCE Blocking mode work through phantom itemfaces
|
||||||
|
- Shift-clicking blank patterns into the pattern terminal will try to fill the blank pattern slots first
|
||||||
|
- Mismached simulated/real item count ( most often due to compacting drawers ) will now tell the player wich item cause the failure when trying to start a craft
|
||||||
|
- Added 'pattern expansion' cards that adds an extra row of patterns to interfaces. up to 3 card on an interface. (each card will increase the interface idle power draw by 4 times)
|
||||||
|
|
||||||
HOTKEYS:
|
HOTKEYS:
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -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
@@ -3,8 +3,8 @@ aechannel=stable
|
|||||||
aebuild=7
|
aebuild=7
|
||||||
aegroup=appeng
|
aegroup=appeng
|
||||||
aebasename=appliedenergistics2
|
aebasename=appliedenergistics2
|
||||||
trousers=omni-fixes-v21b
|
trousers=trousers_edition
|
||||||
|
trousersversion=v49t
|
||||||
#########################################################
|
#########################################################
|
||||||
# Versions #
|
# Versions #
|
||||||
#########################################################
|
#########################################################
|
||||||
|
|||||||
@@ -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 {
|
||||||
@@ -80,7 +80,7 @@ configurations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly "gregtechce:gregtech:1.12.2:1.12.0.662"
|
compileOnly "gregtechce:gregtech:1.12.2:1.15.1.735"
|
||||||
|
|
||||||
// installable runtime dependencies
|
// installable runtime dependencies
|
||||||
mods "mcp.mobius.waila:Hwyla:${hwyla_version}"
|
mods "mcp.mobius.waila:Hwyla:${hwyla_version}"
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ public enum Upgrades
|
|||||||
*/
|
*/
|
||||||
FUZZY( 1 ),
|
FUZZY( 1 ),
|
||||||
SPEED( 1 ),
|
SPEED( 1 ),
|
||||||
INVERTER( 1 );
|
INVERTER( 1 ),
|
||||||
|
PATTERN_EXPANSION(1);
|
||||||
|
|
||||||
private final int tier;
|
private final int tier;
|
||||||
private final Map<ItemStack, Integer> supportedMax = new HashMap<>();
|
private final Map<ItemStack, Integer> supportedMax = new HashMap<>();
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ public interface IMaterials
|
|||||||
|
|
||||||
IItemDefinition cardCapacity();
|
IItemDefinition cardCapacity();
|
||||||
|
|
||||||
|
IItemDefinition cardPatternExpansion();
|
||||||
|
|
||||||
IItemDefinition cardFuzzy();
|
IItemDefinition cardFuzzy();
|
||||||
|
|
||||||
IItemDefinition cardInverter();
|
IItemDefinition cardInverter();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ import net.minecraft.world.World;
|
|||||||
import appeng.api.implementations.ICraftingPatternItem;
|
import appeng.api.implementations.ICraftingPatternItem;
|
||||||
import appeng.api.storage.data.IAEItemStack;
|
import appeng.api.storage.data.IAEItemStack;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* do not implement provided by {@link ICraftingPatternItem}
|
* do not implement provided by {@link ICraftingPatternItem}
|
||||||
@@ -84,6 +87,11 @@ public interface ICraftingPatternDetails
|
|||||||
*/
|
*/
|
||||||
boolean canSubstitute();
|
boolean canSubstitute();
|
||||||
|
|
||||||
|
default List<IAEItemStack> getSubstituteInputs( int slot )
|
||||||
|
{
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow using this INSTANCE of the pattern details to preform the crafting action with performance enhancements.
|
* Allow using this INSTANCE of the pattern details to preform the crafting action with performance enhancements.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -44,10 +44,7 @@ public interface IStackWatcherHost
|
|||||||
/**
|
/**
|
||||||
* Called when a watched item changes amounts.
|
* Called when a watched item changes amounts.
|
||||||
*
|
*
|
||||||
* @param o changed item list
|
|
||||||
* @param fullStack old stack
|
|
||||||
* @param diffStack new stack
|
* @param diffStack new stack
|
||||||
* @param src action source
|
|
||||||
* @param chan storage channel
|
* @param chan storage channel
|
||||||
*/
|
*/
|
||||||
void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan );
|
void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan );
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ public interface IStorageGrid extends IGridCache, IStorageMonitorable
|
|||||||
* @param input injected items
|
* @param input injected items
|
||||||
*/
|
*/
|
||||||
void postAlterationOfStoredItems( IStorageChannel<?> chan, Iterable<? extends IAEStack<?>> input, IActionSource src );
|
void postAlterationOfStoredItems( IStorageChannel<?> chan, Iterable<? extends IAEStack<?>> input, IActionSource src );
|
||||||
|
void postCraftablesChanges( IStorageChannel<?> chan, Iterable<? extends IAEStack<?>> input, IActionSource src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to add a cell provider to the storage system
|
* Used to add a cell provider to the storage system
|
||||||
|
|||||||
@@ -112,4 +112,17 @@ public interface IAEItemStack extends IAEStack<IAEItemStack>
|
|||||||
* @return definition stack
|
* @return definition stack
|
||||||
*/
|
*/
|
||||||
ItemStack getDefinition();
|
ItemStack getDefinition();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare this AE item stack to another item stack, but ignores
|
||||||
|
* the amount. It checks the item type, NBT and damage values.
|
||||||
|
*
|
||||||
|
* @param is An item stack
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
|||||||
+277
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ public class GuiInterface extends GuiUpgradeable
|
|||||||
public GuiInterface( final InventoryPlayer inventoryPlayer, final IInterfaceHost te )
|
public GuiInterface( final InventoryPlayer inventoryPlayer, final IInterfaceHost te )
|
||||||
{
|
{
|
||||||
super( new ContainerInterface( inventoryPlayer, te ) );
|
super( new ContainerInterface( inventoryPlayer, te ) );
|
||||||
this.ySize = 211;
|
this.ySize = 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -62,8 +62,7 @@ public class GuiInterface extends GuiUpgradeable
|
|||||||
this.BlockMode = new GuiImgButton( this.guiLeft - 18, this.guiTop + 8, Settings.BLOCK, YesNo.NO );
|
this.BlockMode = new GuiImgButton( this.guiLeft - 18, this.guiTop + 8, Settings.BLOCK, YesNo.NO );
|
||||||
this.buttonList.add( this.BlockMode );
|
this.buttonList.add( this.BlockMode );
|
||||||
|
|
||||||
this.interfaceMode = new GuiToggleButton( this.guiLeft - 18, this.guiTop + 26, 84, 85, GuiText.InterfaceTerminal
|
this.interfaceMode = new GuiToggleButton( this.guiLeft - 18, this.guiTop + 26, 84, 85, GuiText.InterfaceTerminal.getLocal(), GuiText.InterfaceTerminalHint.getLocal() );
|
||||||
.getLocal(), GuiText.InterfaceTerminalHint.getLocal() );
|
|
||||||
this.buttonList.add( this.interfaceMode );
|
this.buttonList.add( this.interfaceMode );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,13 +85,20 @@ public class GuiInterface extends GuiUpgradeable
|
|||||||
this.fontRenderer.drawString( GuiText.StoredItems.getLocal(), 8, 6 + 60 + 7, 4210752 );
|
this.fontRenderer.drawString( GuiText.StoredItems.getLocal(), 8, 6 + 60 + 7, 4210752 );
|
||||||
this.fontRenderer.drawString( GuiText.Patterns.getLocal(), 8, 6 + 73 + 7, 4210752 );
|
this.fontRenderer.drawString( GuiText.Patterns.getLocal(), 8, 6 + 73 + 7, 4210752 );
|
||||||
|
|
||||||
this.fontRenderer.drawString( GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getBackground()
|
protected String getBackground()
|
||||||
{
|
{
|
||||||
return "guis/interface.png";
|
int upgrades = ( (ContainerInterface) this.cvb ).getPatternUpgrades();
|
||||||
|
if( upgrades == 0 )
|
||||||
|
{
|
||||||
|
return "guis/newinterface.png";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "guis/newinterface" + upgrades + ".png";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -117,4 +123,5 @@ public class GuiInterface extends GuiUpgradeable
|
|||||||
NetworkHandler.instance().sendToServer( new PacketConfigButton( this.BlockMode.getSetting(), backwards ) );
|
NetworkHandler.instance().sendToServer( new PacketConfigButton( this.BlockMode.getSetting(), backwards ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,13 @@ import java.util.*;
|
|||||||
|
|
||||||
import appeng.api.config.ActionItems;
|
import appeng.api.config.ActionItems;
|
||||||
import appeng.api.config.Settings;
|
import appeng.api.config.Settings;
|
||||||
|
import appeng.api.config.Upgrades;
|
||||||
import appeng.client.gui.widgets.GuiImgButton;
|
import appeng.client.gui.widgets.GuiImgButton;
|
||||||
import appeng.core.worlddata.IWorldPlayerMapping;
|
import appeng.core.worlddata.IWorldPlayerMapping;
|
||||||
|
import appeng.helpers.DualityInterface;
|
||||||
|
import appeng.parts.misc.PartInterface;
|
||||||
|
import appeng.tile.inventory.AppEngInternalInventory;
|
||||||
|
import appeng.tile.misc.TileInterface;
|
||||||
import appeng.util.BlockPosUtils;
|
import appeng.util.BlockPosUtils;
|
||||||
import com.google.common.collect.HashMultimap;
|
import com.google.common.collect.HashMultimap;
|
||||||
|
|
||||||
@@ -69,6 +74,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
|||||||
private final HashMultimap<String, ClientDCInternalInv> byName = HashMultimap.create();
|
private final HashMultimap<String, ClientDCInternalInv> byName = HashMultimap.create();
|
||||||
private final HashMap<ClientDCInternalInv,BlockPos> blockPosHashMap = new HashMap<>();
|
private final HashMap<ClientDCInternalInv,BlockPos> blockPosHashMap = new HashMap<>();
|
||||||
private final HashMap<GuiButton,ClientDCInternalInv> guiButtonHashMap = new HashMap<>();
|
private final HashMap<GuiButton,ClientDCInternalInv> guiButtonHashMap = new HashMap<>();
|
||||||
|
private final Map<ClientDCInternalInv,Integer> numUpgradesMap = new HashMap<>();
|
||||||
private final ArrayList<String> names = new ArrayList<>();
|
private final ArrayList<String> names = new ArrayList<>();
|
||||||
private final ArrayList<Object> lines = new ArrayList<>();
|
private final ArrayList<Object> lines = new ArrayList<>();
|
||||||
private final Set<Object> matchedStacks = new HashSet<>();
|
private final Set<Object> matchedStacks = new HashSet<>();
|
||||||
@@ -91,7 +97,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
|||||||
final GuiScrollbar scrollbar = new GuiScrollbar();
|
final GuiScrollbar scrollbar = new GuiScrollbar();
|
||||||
this.setScrollBar( scrollbar );
|
this.setScrollBar( scrollbar );
|
||||||
this.xSize = 208;
|
this.xSize = 208;
|
||||||
this.ySize = 256;
|
this.ySize = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -136,36 +142,43 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
|||||||
this.fontRenderer.drawString( this.getGuiDisplayName( GuiText.InterfaceTerminal.getLocal() ), 8, 6, 4210752 );
|
this.fontRenderer.drawString( this.getGuiDisplayName( GuiText.InterfaceTerminal.getLocal() ), 8, 6, 4210752 );
|
||||||
this.fontRenderer.drawString( GuiText.inventory.getLocal(), this.offsetX + 2, this.ySize - 96 + 3, 4210752 );
|
this.fontRenderer.drawString( GuiText.inventory.getLocal(), this.offsetX + 2, this.ySize - 96 + 3, 4210752 );
|
||||||
|
|
||||||
final int ex = this.getScrollBar().getCurrentScroll();
|
final int currentScroll = this.getScrollBar().getCurrentScroll();
|
||||||
|
|
||||||
this.guiButtonNextAssembler = new GuiImgButton(guiLeft + 123, guiTop + 25,Settings.ACTIONS, ActionItems.FREE_MOLECULAR_SLOT_SHORTCUT);
|
this.guiButtonNextAssembler = new GuiImgButton( guiLeft + 123, guiTop + 25, Settings.ACTIONS, ActionItems.FREE_MOLECULAR_SLOT_SHORTCUT );
|
||||||
this.buttonList.add( guiButtonNextAssembler );
|
this.buttonList.add( guiButtonNextAssembler );
|
||||||
|
|
||||||
guiButtonHide = new GuiImgButton( guiLeft + 141, guiTop + 25,Settings.ACTIONS, this.partInterfaceTerminal.onlyInterfacesWithFreeSlots ?
|
guiButtonHide = new GuiImgButton( guiLeft + 141, guiTop + 25, Settings.ACTIONS, this.partInterfaceTerminal.onlyInterfacesWithFreeSlots ? ActionItems.TOGGLE_SHOW_FULL_INTERFACES_OFF : ActionItems.TOGGLE_SHOW_FULL_INTERFACES_ON );
|
||||||
ActionItems.TOGGLE_SHOW_FULL_INTERFACES_OFF :
|
|
||||||
ActionItems.TOGGLE_SHOW_FULL_INTERFACES_ON);
|
|
||||||
this.buttonList.add( guiButtonHide );
|
this.buttonList.add( guiButtonHide );
|
||||||
|
|
||||||
this.inventorySlots.inventorySlots.removeIf( slot -> slot instanceof SlotDisconnected );
|
this.inventorySlots.inventorySlots.removeIf( slot -> slot instanceof SlotDisconnected );
|
||||||
|
|
||||||
int offset = 51;
|
int offset = 52;
|
||||||
for( int x = 0; x < LINES_ON_PAGE && ex + x < this.lines.size(); x++ )
|
int linesDraw = 0;
|
||||||
|
for( int x = 0; x < LINES_ON_PAGE && linesDraw < LINES_ON_PAGE && currentScroll + x < this.lines.size(); x++ )
|
||||||
{
|
{
|
||||||
final Object lineObj = this.lines.get( ex + x );
|
final Object lineObj = this.lines.get( currentScroll + x );
|
||||||
if( lineObj instanceof ClientDCInternalInv )
|
if( lineObj instanceof ClientDCInternalInv )
|
||||||
{
|
{
|
||||||
final ClientDCInternalInv inv = (ClientDCInternalInv) lineObj;
|
final ClientDCInternalInv inv = (ClientDCInternalInv) lineObj;
|
||||||
for( int z = 0; z < inv.getInventory().getSlots(); z++ )
|
|
||||||
{
|
|
||||||
this.inventorySlots.inventorySlots.add( new SlotDisconnected( inv, z, z * 18 + 22, 1 + offset ) );
|
|
||||||
if (this.matchedStacks.contains(inv.getInventory().getStackInSlot(z)))
|
|
||||||
drawRect( z * 18 + 22, 1 + offset, z * 18 + 22 + 16, 1 + offset + 16, 0x2A00FF00 );
|
|
||||||
}
|
|
||||||
|
|
||||||
GuiButton guiButton = new GuiImgButton(guiLeft + 4, guiTop + offset + 1, Settings.ACTIONS, ActionItems.HIGHLIGHT_INTERFACE);
|
GuiButton guiButton = new GuiImgButton( guiLeft + 4, guiTop + offset, Settings.ACTIONS, ActionItems.HIGHLIGHT_INTERFACE );
|
||||||
guiButtonHashMap.put( guiButton , inv);
|
guiButtonHashMap.put( guiButton, inv );
|
||||||
this.buttonList.add( guiButton );
|
this.buttonList.add( guiButton );
|
||||||
|
int extraLines = numUpgradesMap.get( inv );
|
||||||
|
|
||||||
|
for( int row = 0; row < 1 + extraLines && linesDraw < LINES_ON_PAGE ; ++row )
|
||||||
|
{
|
||||||
|
for( int z = 0; z < 9 ; z++ )
|
||||||
|
{
|
||||||
|
this.inventorySlots.inventorySlots.add( new SlotDisconnected( inv, z + ( row * 9 ), ( z * 18 + 22 ), offset ) );
|
||||||
|
if( this.matchedStacks.contains( inv.getInventory().getStackInSlot( z + ( row * 9 ) ) ) )
|
||||||
|
{
|
||||||
|
drawRect( z * 18 + 22, offset, z * 18 + 22 + 16, offset + 16, 0x2A00FF00 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
linesDraw++;
|
||||||
|
offset += 18;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( lineObj instanceof String )
|
else if( lineObj instanceof String )
|
||||||
{
|
{
|
||||||
@@ -176,17 +189,17 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
|||||||
name = name + " (" + rows + ')';
|
name = name + " (" + rows + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
while( name.length() > 2 && this.fontRenderer.getStringWidth( name ) > 155 )
|
while ( name.length() > 2 && this.fontRenderer.getStringWidth( name ) > 155 )
|
||||||
{
|
{
|
||||||
name = name.substring( 0, name.length() - 1 );
|
name = name.substring( 0, name.length() - 1 );
|
||||||
}
|
}
|
||||||
|
this.fontRenderer.drawString( name, this.offsetX + 2, 5 + offset, 4210752 );
|
||||||
this.fontRenderer.drawString( name, this.offsetX + 2, 6 + offset, 4210752 );
|
linesDraw++;
|
||||||
|
offset += 18;
|
||||||
}
|
}
|
||||||
offset += 18;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( searchFieldInputs.isMouseIn( mouseX , mouseY ) ) drawTooltip( Mouse.getEventX() * this.width / this.mc.displayWidth - offsetX, mouseY - guiTop, "Inputs OR names" );
|
if( searchFieldInputs.isMouseIn( mouseX, mouseY ) ) drawTooltip( Mouse.getEventX() * this.width / this.mc.displayWidth - offsetX, mouseY - guiTop, "Inputs OR names" );
|
||||||
else if( searchFieldOutputs.isMouseIn( mouseX, mouseY ) ) drawTooltip( Mouse.getEventX() * this.width / this.mc.displayWidth - offsetX, mouseY - guiTop, "Outputs OR names" );
|
else if( searchFieldOutputs.isMouseIn( mouseX, mouseY ) ) drawTooltip( Mouse.getEventX() * this.width / this.mc.displayWidth - offsetX, mouseY - guiTop, "Outputs OR names" );
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -224,7 +237,11 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
|||||||
int interfaceDim = dimHashMap.get( guiButtonHashMap.get( this.selectedButton ) );
|
int interfaceDim = dimHashMap.get( guiButtonHashMap.get( this.selectedButton ) );
|
||||||
if( playerDim != interfaceDim )
|
if( playerDim != interfaceDim )
|
||||||
{
|
{
|
||||||
mc.player.sendStatusMessage( new TextComponentString( "Interface located at dimension: " + interfaceDim + " [" + DimensionManager.getWorld( interfaceDim ).provider.getDimensionType().getName() + "] and cant be highlighted" ), false );
|
try {
|
||||||
|
mc.player.sendStatusMessage( new TextComponentString( "Interface located at dimension: " + interfaceDim + " [" + DimensionManager.getWorld( interfaceDim ).provider.getDimensionType().getName() + "] and cant be highlighted" ), false );
|
||||||
|
} catch(Exception e){
|
||||||
|
mc.player.sendStatusMessage( new TextComponentString( "Interface is located in another dimension and cannot be highlighted" ), false );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -264,19 +281,28 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
|||||||
|
|
||||||
int offset = 51;
|
int offset = 51;
|
||||||
final int ex = this.getScrollBar().getCurrentScroll();
|
final int ex = this.getScrollBar().getCurrentScroll();
|
||||||
|
int linesDraw = 0;
|
||||||
for( int x = 0; x < LINES_ON_PAGE && ex + x < this.lines.size(); x++ )
|
for( int x = 0; x < LINES_ON_PAGE && linesDraw < LINES_ON_PAGE && ex + x < this.lines.size(); x++ )
|
||||||
{
|
{
|
||||||
final Object lineObj = this.lines.get( ex + x );
|
final Object lineObj = this.lines.get( ex + x );
|
||||||
if( lineObj instanceof ClientDCInternalInv )
|
if( lineObj instanceof ClientDCInternalInv )
|
||||||
{
|
{
|
||||||
final ClientDCInternalInv inv = (ClientDCInternalInv) lineObj;
|
|
||||||
|
|
||||||
GlStateManager.color( 1, 1, 1, 1 );
|
GlStateManager.color( 1, 1, 1, 1 );
|
||||||
final int width = inv.getInventory().getSlots() * 18;
|
final int width = 9 * 18;
|
||||||
this.drawTexturedModalRect( offsetX + 20, offsetY + offset, 20, 173, width, 18 );
|
|
||||||
|
int extraLines = numUpgradesMap.get( lineObj );
|
||||||
|
|
||||||
|
for( int row = 0; row < 1 + extraLines && linesDraw < LINES_ON_PAGE; ++row )
|
||||||
|
{
|
||||||
|
this.drawTexturedModalRect( offsetX + 20, offsetY + offset , 20, 173, width, 18 );
|
||||||
|
offset += 18;
|
||||||
|
linesDraw++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
offset += 18;
|
||||||
|
linesDraw++;
|
||||||
}
|
}
|
||||||
offset += 18;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( this.searchFieldInputs != null )
|
if( this.searchFieldInputs != null )
|
||||||
@@ -337,6 +363,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
|||||||
final ClientDCInternalInv current = this.getById( id, invData.getLong( "sortBy" ), invData.getString( "un" ) );
|
final ClientDCInternalInv current = this.getById( id, invData.getLong( "sortBy" ), invData.getString( "un" ) );
|
||||||
blockPosHashMap.put( current, NBTUtil.getPosFromTag( invData.getCompoundTag( "pos" )) );
|
blockPosHashMap.put( current, NBTUtil.getPosFromTag( invData.getCompoundTag( "pos" )) );
|
||||||
dimHashMap.put( current, invData.getInteger( "dim" ));
|
dimHashMap.put( current, invData.getInteger( "dim" ));
|
||||||
|
numUpgradesMap.put( current, invData.getInteger("numUpgrades"));
|
||||||
|
|
||||||
for( int x = 0; x < current.getInventory().getSlots(); x++ )
|
for( int x = 0; x < current.getInventory().getSlots(); x++ )
|
||||||
{
|
{
|
||||||
@@ -395,8 +422,12 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
|||||||
// Search if the current inventory holds a pattern containing the search term.
|
// Search if the current inventory holds a pattern containing the search term.
|
||||||
if( !found )
|
if( !found )
|
||||||
{
|
{
|
||||||
|
int slot = 0;
|
||||||
for( final ItemStack itemStack : entry.getInventory() )
|
for( final ItemStack itemStack : entry.getInventory() )
|
||||||
{
|
{
|
||||||
|
if (slot > 8 + numUpgradesMap.get(entry) * 9) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
if( !searchFieldInputs.isEmpty() && !searchFieldOutputs.isEmpty() ) {
|
if( !searchFieldInputs.isEmpty() && !searchFieldOutputs.isEmpty() ) {
|
||||||
if (this.itemStackMatchesSearchTerm(itemStack, searchFieldInputs, 0) || this.itemStackMatchesSearchTerm(itemStack, searchFieldOutputs, 1)) {
|
if (this.itemStackMatchesSearchTerm(itemStack, searchFieldInputs, 0) || this.itemStackMatchesSearchTerm(itemStack, searchFieldOutputs, 1)) {
|
||||||
found = true;
|
found = true;
|
||||||
@@ -418,6 +449,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
|||||||
// If only Interfaces with empty slots should be shown, check that here
|
// If only Interfaces with empty slots should be shown, check that here
|
||||||
if(itemStack.isEmpty())
|
if(itemStack.isEmpty())
|
||||||
interfaceHasFreeSlots = true;
|
interfaceHasFreeSlots = true;
|
||||||
|
slot++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if found, filter skipped or machine name matching the search term, add it
|
// if found, filter skipped or machine name matching the search term, add it
|
||||||
@@ -458,7 +490,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
|||||||
this.lines.addAll( clientInventories );
|
this.lines.addAll( clientInventories );
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getScrollBar().setRange( 0, this.lines.size() - LINES_ON_PAGE, 2 );
|
this.getScrollBar().setRange( 0, this.lines.size() - 1, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean itemStackMatchesSearchTerm( final ItemStack itemStack, final String searchTerm,int pass )
|
private boolean itemStackMatchesSearchTerm( final ItemStack itemStack, final String searchTerm,int pass )
|
||||||
@@ -548,7 +580,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
|
|||||||
|
|
||||||
if( o == null )
|
if( o == null )
|
||||||
{
|
{
|
||||||
this.byId.put( id, o = new ClientDCInternalInv( 9, id, sortBy, string ) );
|
this.byId.put( id, o = new ClientDCInternalInv( DualityInterface.NUMBER_OF_PATTERN_SLOTS, id, sortBy, string ) );
|
||||||
this.refreshList = true;
|
this.refreshList = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -270,12 +270,15 @@ public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients
|
|||||||
@Override
|
@Override
|
||||||
public Rectangle getArea()
|
public Rectangle getArea()
|
||||||
{
|
{
|
||||||
if( slot instanceof SlotFake )
|
if( slot instanceof SlotFake && ( (SlotFake) slot ).isSlotEnabled() )
|
||||||
|
{
|
||||||
return new Rectangle( getGuiLeft() + ( (SlotFake) slot ).xPos, getGuiTop() + ( (SlotFake) slot ).yPos, 16, 16 );
|
return new Rectangle( getGuiLeft() + ( (SlotFake) slot ).xPos, getGuiTop() + ( (SlotFake) slot ).yPos, 16, 16 );
|
||||||
else
|
}
|
||||||
|
else if( slot instanceof GuiFluidSlot && ( (GuiFluidSlot) slot ).isSlotEnabled() )
|
||||||
{
|
{
|
||||||
return new Rectangle( getGuiLeft() + ( (GuiFluidSlot) slot ).xPos(), getGuiTop() + ( (GuiFluidSlot) slot ).yPos(), 16, 16 );
|
return new Rectangle( getGuiLeft() + ( (GuiFluidSlot) slot ).xPos(), getGuiTop() + ( (GuiFluidSlot) slot ).yPos(), 16, 16 );
|
||||||
}
|
}
|
||||||
|
return new Rectangle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -284,7 +287,7 @@ public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients
|
|||||||
PacketInventoryAction p = null;
|
PacketInventoryAction p = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if( slot instanceof SlotFake )
|
if( slot instanceof SlotFake && ( (SlotFake) slot ).isSlotEnabled() )
|
||||||
{
|
{
|
||||||
if( finalItemStack.isEmpty() && finalFluidStack != null )
|
if( finalItemStack.isEmpty() && finalFluidStack != null )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ import net.minecraft.item.ItemStack;
|
|||||||
|
|
||||||
public abstract class GuiCustomSlot extends Gui implements ITooltip
|
public abstract class GuiCustomSlot extends Gui implements ITooltip
|
||||||
{
|
{
|
||||||
private final int x;
|
protected final int x;
|
||||||
private final int y;
|
protected final int y;
|
||||||
private final int id;
|
protected final int id;
|
||||||
|
|
||||||
public GuiCustomSlot( final int id, final int x, final int y )
|
public GuiCustomSlot( final int id, final int x, final int y )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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 )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -159,56 +159,58 @@ public class ContainerCraftingCPU extends AEBaseContainer implements IMEMonitorH
|
|||||||
@Override
|
@Override
|
||||||
public void detectAndSendChanges()
|
public void detectAndSendChanges()
|
||||||
{
|
{
|
||||||
if( Platform.isServer() && this.getMonitor() != null && !this.list.isEmpty() )
|
if( Platform.isServer() && this.getMonitor() != null )
|
||||||
{
|
{
|
||||||
try
|
if( this.getEstimatedTime() >= 0 )
|
||||||
{
|
{
|
||||||
if( this.getEstimatedTime() >= 0 )
|
final long elapsedTime = this.getMonitor().getElapsedTime();
|
||||||
|
final double remainingItems = this.getMonitor().getRemainingItemCount();
|
||||||
|
final double startItems = this.getMonitor().getStartItemCount();
|
||||||
|
final long eta = (long) ( elapsedTime / Math.max( 1d, ( startItems - remainingItems ) ) * remainingItems );
|
||||||
|
this.setEstimatedTime( eta );
|
||||||
|
}
|
||||||
|
if( !this.list.isEmpty() )
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
final long elapsedTime = this.getMonitor().getElapsedTime();
|
final PacketMEInventoryUpdate a = new PacketMEInventoryUpdate( (byte) 0 );
|
||||||
final double remainingItems = this.getMonitor().getRemainingItemCount();
|
final PacketMEInventoryUpdate b = new PacketMEInventoryUpdate( (byte) 1 );
|
||||||
final double startItems = this.getMonitor().getStartItemCount();
|
final PacketMEInventoryUpdate c = new PacketMEInventoryUpdate( (byte) 2 );
|
||||||
final long eta = (long) ( elapsedTime / Math.max( 1d, ( startItems - remainingItems ) ) * remainingItems );
|
|
||||||
this.setEstimatedTime( eta );
|
|
||||||
}
|
|
||||||
|
|
||||||
final PacketMEInventoryUpdate a = new PacketMEInventoryUpdate( (byte) 0 );
|
for( final IAEItemStack out : this.list )
|
||||||
final PacketMEInventoryUpdate b = new PacketMEInventoryUpdate( (byte) 1 );
|
|
||||||
final PacketMEInventoryUpdate c = new PacketMEInventoryUpdate( (byte) 2 );
|
|
||||||
|
|
||||||
for( final IAEItemStack out : this.list )
|
|
||||||
{
|
|
||||||
a.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.STORAGE ) );
|
|
||||||
b.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.ACTIVE ) );
|
|
||||||
c.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.PENDING ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
this.list.resetStatus();
|
|
||||||
|
|
||||||
for( final Object g : this.listeners )
|
|
||||||
{
|
|
||||||
if( g instanceof EntityPlayer )
|
|
||||||
{
|
{
|
||||||
if( !a.isEmpty() )
|
a.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.STORAGE ) );
|
||||||
{
|
b.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.ACTIVE ) );
|
||||||
NetworkHandler.instance().sendTo( a, (EntityPlayerMP) g );
|
c.appendItem( this.getMonitor().getItemStack( out, CraftingItemList.PENDING ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !b.isEmpty() )
|
this.list.resetStatus();
|
||||||
{
|
|
||||||
NetworkHandler.instance().sendTo( b, (EntityPlayerMP) g );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !c.isEmpty() )
|
for( final Object g : this.listeners )
|
||||||
|
{
|
||||||
|
if( g instanceof EntityPlayer )
|
||||||
{
|
{
|
||||||
NetworkHandler.instance().sendTo( c, (EntityPlayerMP) g );
|
if( !a.isEmpty() )
|
||||||
|
{
|
||||||
|
NetworkHandler.instance().sendTo( a, (EntityPlayerMP) g );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !b.isEmpty() )
|
||||||
|
{
|
||||||
|
NetworkHandler.instance().sendTo( b, (EntityPlayerMP) g );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !c.isEmpty() )
|
||||||
|
{
|
||||||
|
NetworkHandler.instance().sendTo( c, (EntityPlayerMP) g );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
catch( final IOException e )
|
||||||
catch( final IOException e )
|
{
|
||||||
{
|
// :P
|
||||||
// :P
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.detectAndSendChanges();
|
super.detectAndSendChanges();
|
||||||
|
|||||||
+528
@@ -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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -19,6 +19,9 @@
|
|||||||
package appeng.container.implementations;
|
package appeng.container.implementations;
|
||||||
|
|
||||||
|
|
||||||
|
import appeng.api.config.Upgrades;
|
||||||
|
import appeng.container.slot.*;
|
||||||
|
import appeng.util.Platform;
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
|
|
||||||
import appeng.api.config.SecurityPermissions;
|
import appeng.api.config.SecurityPermissions;
|
||||||
@@ -26,14 +29,11 @@ import appeng.api.config.Settings;
|
|||||||
import appeng.api.config.YesNo;
|
import appeng.api.config.YesNo;
|
||||||
import appeng.api.util.IConfigManager;
|
import appeng.api.util.IConfigManager;
|
||||||
import appeng.container.guisync.GuiSync;
|
import appeng.container.guisync.GuiSync;
|
||||||
import appeng.container.slot.SlotFake;
|
|
||||||
import appeng.container.slot.SlotNormal;
|
|
||||||
import appeng.container.slot.SlotRestrictedInput;
|
|
||||||
import appeng.helpers.DualityInterface;
|
import appeng.helpers.DualityInterface;
|
||||||
import appeng.helpers.IInterfaceHost;
|
import appeng.helpers.IInterfaceHost;
|
||||||
|
|
||||||
|
|
||||||
public class ContainerInterface extends ContainerUpgradeable
|
public class ContainerInterface extends ContainerUpgradeable implements IOptionalSlotHost
|
||||||
{
|
{
|
||||||
|
|
||||||
private final DualityInterface myDuality;
|
private final DualityInterface myDuality;
|
||||||
@@ -44,16 +44,22 @@ public class ContainerInterface extends ContainerUpgradeable
|
|||||||
@GuiSync( 4 )
|
@GuiSync( 4 )
|
||||||
public YesNo iTermMode = YesNo.YES;
|
public YesNo iTermMode = YesNo.YES;
|
||||||
|
|
||||||
|
@GuiSync( 7 )
|
||||||
|
public int patternExpansions = 0;
|
||||||
|
|
||||||
public ContainerInterface( final InventoryPlayer ip, final IInterfaceHost te )
|
public ContainerInterface( final InventoryPlayer ip, final IInterfaceHost te )
|
||||||
{
|
{
|
||||||
super( ip, te.getInterfaceDuality().getHost() );
|
super( ip, te.getInterfaceDuality().getHost() );
|
||||||
|
|
||||||
this.myDuality = te.getInterfaceDuality();
|
this.myDuality = te.getInterfaceDuality();
|
||||||
|
|
||||||
for( int x = 0; x < DualityInterface.NUMBER_OF_PATTERN_SLOTS; x++ )
|
for (int row = 0 ; row < 4 ; ++row)
|
||||||
{
|
{
|
||||||
this.addSlotToContainer( new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.ENCODED_PATTERN, this.myDuality
|
for( int x = 0; x < 9; x++ )
|
||||||
.getPatterns(), x, 8 + 18 * x, 90 + 7, this.getInventoryPlayer() ).setStackLimit( 1 ) );
|
{
|
||||||
|
this.addSlotToContainer( new OptionalSlotRestrictedInput( SlotRestrictedInput.PlacableItemType.ENCODED_PATTERN, this.myDuality
|
||||||
|
.getPatterns(), this, x + row * 9, 8 + 18 * x, 97 + ( 18 * row ), row, this.getInventoryPlayer() ).setStackLimit( 1 ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for( int x = 0; x < DualityInterface.NUMBER_OF_CONFIG_SLOTS; x++ )
|
for( int x = 0; x < DualityInterface.NUMBER_OF_CONFIG_SLOTS; x++ )
|
||||||
@@ -70,7 +76,7 @@ public class ContainerInterface extends ContainerUpgradeable
|
|||||||
@Override
|
@Override
|
||||||
protected int getHeight()
|
protected int getHeight()
|
||||||
{
|
{
|
||||||
return 211;
|
return 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -82,16 +88,35 @@ public class ContainerInterface extends ContainerUpgradeable
|
|||||||
@Override
|
@Override
|
||||||
public int availableUpgrades()
|
public int availableUpgrades()
|
||||||
{
|
{
|
||||||
return 1;
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSlotEnabled( final int idx )
|
||||||
|
{
|
||||||
|
return myDuality.getInstalledUpgrades(Upgrades.PATTERN_EXPANSION) >= idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void detectAndSendChanges()
|
public void detectAndSendChanges()
|
||||||
{
|
{
|
||||||
this.verifyPermissions( SecurityPermissions.BUILD, false );
|
this.verifyPermissions( SecurityPermissions.BUILD, false );
|
||||||
|
|
||||||
|
if (patternExpansions != getPatternUpgrades())
|
||||||
|
{
|
||||||
|
patternExpansions = getPatternUpgrades();
|
||||||
|
this.myDuality.dropExcessPatterns();
|
||||||
|
}
|
||||||
super.detectAndSendChanges();
|
super.detectAndSendChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdate( final String field, final Object oldValue, final Object newValue ) {
|
||||||
|
super.onUpdate(field, oldValue, newValue);
|
||||||
|
if ( Platform.isClient() && field.equals("patternExpansions"))
|
||||||
|
this.myDuality.dropExcessPatterns();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void loadSettingsFromHost( final IConfigManager cm )
|
protected void loadSettingsFromHost( final IConfigManager cm )
|
||||||
{
|
{
|
||||||
@@ -118,4 +143,9 @@ public class ContainerInterface extends ContainerUpgradeable
|
|||||||
{
|
{
|
||||||
this.iTermMode = iTermMode;
|
this.iTermMode = iTermMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getPatternUpgrades()
|
||||||
|
{
|
||||||
|
return this.myDuality.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import appeng.api.config.Upgrades;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
@@ -405,6 +406,7 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer
|
|||||||
tag.setString( "un", inv.unlocalizedName );
|
tag.setString( "un", inv.unlocalizedName );
|
||||||
tag.setTag( "pos", NBTUtil.createPosTag( inv.pos ) );
|
tag.setTag( "pos", NBTUtil.createPosTag( inv.pos ) );
|
||||||
tag.setInteger( "dim", inv.dim );
|
tag.setInteger( "dim", inv.dim );
|
||||||
|
tag.setInteger( "numUpgrades", inv.numUpgrades );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( int x = 0; x < length; x++ )
|
for( int x = 0; x < length; x++ )
|
||||||
@@ -437,6 +439,7 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer
|
|||||||
private final IItemHandler server;
|
private final IItemHandler server;
|
||||||
private final BlockPos pos;
|
private final BlockPos pos;
|
||||||
private final int dim;
|
private final int dim;
|
||||||
|
private final int numUpgrades;
|
||||||
|
|
||||||
public InvTracker( final DualityInterface dual, final IItemHandler patterns, final String unlocalizedName )
|
public InvTracker( final DualityInterface dual, final IItemHandler patterns, final String unlocalizedName )
|
||||||
{
|
{
|
||||||
@@ -446,6 +449,7 @@ public final class ContainerInterfaceTerminal extends AEBaseContainer
|
|||||||
this.sortBy = dual.getSortValue();
|
this.sortBy = dual.getSortValue();
|
||||||
this.pos = dual.getLocation().getPos();
|
this.pos = dual.getLocation().getPos();
|
||||||
this.dim = dual.getLocation().getWorld().provider.getDimension();
|
this.dim = dual.getLocation().getWorld().provider.getDimension();
|
||||||
|
this.numUpgrades = dual.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -134,14 +134,16 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
|
|||||||
{
|
{
|
||||||
return ItemStack.EMPTY;
|
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.getPatternTerminal().getInventoryByName( "pattern" );
|
final AppEngSlot clickSlot = ( AppEngSlot ) this.inventorySlots.get( idx ); // require AE SLots!
|
||||||
ItemStack remainder = patternInv.insertItem( 0, itemStack, false );
|
ItemStack itemStack = clickSlot.getStack();
|
||||||
clickSlot.putStack( remainder );
|
if( AEApi.instance().definitions().materials().blankPattern().isSameAs( itemStack ) )
|
||||||
|
{
|
||||||
|
IItemHandler patternInv = this.getPatternTerminal().getInventoryByName( "pattern" );
|
||||||
|
ItemStack remainder = patternInv.insertItem( 0, itemStack, false );
|
||||||
|
clickSlot.putStack( remainder );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return super.transferStackInSlot( p, idx );
|
return super.transferStackInSlot( p, idx );
|
||||||
}
|
}
|
||||||
@@ -176,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 );
|
||||||
@@ -503,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;
|
||||||
@@ -525,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() )
|
||||||
{
|
{
|
||||||
@@ -533,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
|
||||||
@@ -561,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() )
|
||||||
{
|
{
|
||||||
@@ -576,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();
|
||||||
|
|
||||||
@@ -822,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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ public class AppEngSlot extends Slot
|
|||||||
{
|
{
|
||||||
if( this.isSlotEnabled() )
|
if( this.isSlotEnabled() )
|
||||||
{
|
{
|
||||||
return !this.itemHandler.extractItem( this.index, 1, true ).isEmpty();
|
return !this.itemHandler.extractItem( this.index, Integer.MAX_VALUE, true ).isEmpty();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -363,6 +363,8 @@ final class Registration
|
|||||||
// Interface
|
// Interface
|
||||||
Upgrades.CRAFTING.registerItem( parts.iface(), 1 );
|
Upgrades.CRAFTING.registerItem( parts.iface(), 1 );
|
||||||
Upgrades.CRAFTING.registerItem( blocks.iface(), 1 );
|
Upgrades.CRAFTING.registerItem( blocks.iface(), 1 );
|
||||||
|
Upgrades.PATTERN_EXPANSION.registerItem( parts.iface(), 3 );
|
||||||
|
Upgrades.PATTERN_EXPANSION.registerItem( blocks.iface(), 3 );
|
||||||
|
|
||||||
// IO Port!
|
// IO Port!
|
||||||
Upgrades.SPEED.registerItem( blocks.iOPort(), 3 );
|
Upgrades.SPEED.registerItem( blocks.iOPort(), 3 );
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ public class ApiStorage implements IStorageHelper
|
|||||||
@Override
|
@Override
|
||||||
public int transferFactor()
|
public int transferFactor()
|
||||||
{
|
{
|
||||||
return 125;
|
return 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ public final class ApiMaterials implements IMaterials
|
|||||||
private final IItemDefinition cardRedstone;
|
private final IItemDefinition cardRedstone;
|
||||||
private final IItemDefinition cardSpeed;
|
private final IItemDefinition cardSpeed;
|
||||||
private final IItemDefinition cardCapacity;
|
private final IItemDefinition cardCapacity;
|
||||||
|
private final IItemDefinition cardPatternExpansion;
|
||||||
private final IItemDefinition cardFuzzy;
|
private final IItemDefinition cardFuzzy;
|
||||||
private final IItemDefinition cardInverter;
|
private final IItemDefinition cardInverter;
|
||||||
private final IItemDefinition cardCrafting;
|
private final IItemDefinition cardCrafting;
|
||||||
@@ -204,6 +205,7 @@ public final class ApiMaterials implements IMaterials
|
|||||||
this.cardRedstone = new DamagedItemDefinition( "material.card.redstone", materials.createMaterial( MaterialType.CARD_REDSTONE ) );
|
this.cardRedstone = new DamagedItemDefinition( "material.card.redstone", materials.createMaterial( MaterialType.CARD_REDSTONE ) );
|
||||||
this.cardSpeed = new DamagedItemDefinition( "material.card.acceleration", materials.createMaterial( MaterialType.CARD_SPEED ) );
|
this.cardSpeed = new DamagedItemDefinition( "material.card.acceleration", materials.createMaterial( MaterialType.CARD_SPEED ) );
|
||||||
this.cardCapacity = new DamagedItemDefinition( "material.card.capacity", materials.createMaterial( MaterialType.CARD_CAPACITY ) );
|
this.cardCapacity = new DamagedItemDefinition( "material.card.capacity", materials.createMaterial( MaterialType.CARD_CAPACITY ) );
|
||||||
|
this.cardPatternExpansion = new DamagedItemDefinition( "material.card.pattern.expansion", materials.createMaterial(MaterialType.CARD_PATTERN_EXPANSION) );
|
||||||
this.cardFuzzy = new DamagedItemDefinition( "material.card.fuzzy", materials.createMaterial( MaterialType.CARD_FUZZY ) );
|
this.cardFuzzy = new DamagedItemDefinition( "material.card.fuzzy", materials.createMaterial( MaterialType.CARD_FUZZY ) );
|
||||||
this.cardInverter = new DamagedItemDefinition( "material.card.inverter", materials.createMaterial( MaterialType.CARD_INVERTER ) );
|
this.cardInverter = new DamagedItemDefinition( "material.card.inverter", materials.createMaterial( MaterialType.CARD_INVERTER ) );
|
||||||
this.cardCrafting = new DamagedItemDefinition( "material.card.crafting", materials.createMaterial( MaterialType.CARD_CRAFTING ) );
|
this.cardCrafting = new DamagedItemDefinition( "material.card.crafting", materials.createMaterial( MaterialType.CARD_CRAFTING ) );
|
||||||
@@ -424,6 +426,9 @@ public final class ApiMaterials implements IMaterials
|
|||||||
return this.cardCapacity;
|
return this.cardCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IItemDefinition cardPatternExpansion(){ return this.cardPatternExpansion;}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IItemDefinition cardFuzzy()
|
public IItemDefinition cardFuzzy()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,12 +23,14 @@ 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 io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
|
|
||||||
@@ -68,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.
|
||||||
@@ -80,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 ));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,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
|
||||||
@@ -192,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
|
||||||
@@ -211,23 +228,21 @@ public class PacketJEIRecipe extends AppEngPacket
|
|||||||
out = Platform.poweredExtraction( energy, storage, request, cct.getActionSource() );
|
out = Platform.poweredExtraction( energy, storage, request, cct.getActionSource() );
|
||||||
if( out == null )
|
if( out == null )
|
||||||
{
|
{
|
||||||
Collection<IAEItemStack> outList = inv.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findFuzzy( request, FuzzyMode.IGNORE_ALL );
|
if( request.getItem().isDamageable() || ( Platform.isModLoaded( "gregtech" ) && request.getItem() instanceof MetaTool ) )
|
||||||
IAEItemStack mostDamaged = null;
|
|
||||||
for( IAEItemStack is : outList )
|
|
||||||
{
|
{
|
||||||
if( !is.isCraftable() )
|
Collection<IAEItemStack> outList = inv.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findFuzzy( request, FuzzyMode.IGNORE_ALL );
|
||||||
|
for( IAEItemStack is : outList )
|
||||||
{
|
{
|
||||||
if( mostDamaged == null || mostDamaged.getItemDamage() < is.getItemDamage() )
|
if( is.getDefinition().getMetadata() == request.getDefinition().getMetadata() )
|
||||||
{
|
{
|
||||||
mostDamaged = is;
|
out = Platform.poweredExtraction( energy, storage, is.copy().setStackSize( 1 ), cct.getActionSource() );
|
||||||
|
}
|
||||||
|
if( out != null )
|
||||||
|
{
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( mostDamaged != null )
|
|
||||||
{
|
|
||||||
mostDamaged.setStackSize( 1 );
|
|
||||||
out = Platform.poweredExtraction( energy, storage, mostDamaged, cct.getActionSource() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -246,7 +261,10 @@ public class PacketJEIRecipe extends AppEngPacket
|
|||||||
|
|
||||||
if( out != null )
|
if( out != null )
|
||||||
{
|
{
|
||||||
out.setStackSize( recipe[x][y].getCount() );
|
if (!cct.useRealItems())
|
||||||
|
{
|
||||||
|
out.setStackSize( recipe.get( x )[y].getCount() );
|
||||||
|
}
|
||||||
currentItem = out.createItemStack();
|
currentItem = out.createItemStack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -258,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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,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 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,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 ) )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
package appeng.core.sync.packets;
|
package appeng.core.sync.packets;
|
||||||
|
|
||||||
|
|
||||||
|
import appeng.fluids.container.ContainerFluidInterface;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
|
|
||||||
@@ -90,5 +91,9 @@ public class PacketTargetFluidStack extends AppEngPacket
|
|||||||
{
|
{
|
||||||
( (ContainerFluidTerminal) player.openContainer ).setTargetStack( this.stack );
|
( (ContainerFluidTerminal) player.openContainer ).setTargetStack( this.stack );
|
||||||
}
|
}
|
||||||
|
else if( player.openContainer instanceof ContainerFluidInterface )
|
||||||
|
{
|
||||||
|
( (ContainerFluidInterface) player.openContainer ).setTargetStack( this.stack );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
private final IItemList<IAEItemStack> missing = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
private final IItemList<IAEItemStack> missing = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
private final HashMap<String, TwoIntegers> opsAndMultiplier = new HashMap<>();
|
private final HashMap<String, TwoIntegers> opsAndMultiplier = new HashMap<>();
|
||||||
private final Object monitor = new Object();
|
private final Object monitor = new Object();
|
||||||
|
private final Stopwatch watch = Stopwatch.createUnstarted();
|
||||||
private CraftingTreeNode tree;
|
private CraftingTreeNode tree;
|
||||||
private final IAEItemStack output;
|
private final IAEItemStack output;
|
||||||
private boolean simulate = false;
|
private boolean simulate = false;
|
||||||
@@ -66,7 +67,10 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
private long bytes = 0;
|
private long bytes = 0;
|
||||||
private final IActionSource actionSrc;
|
private final IActionSource actionSrc;
|
||||||
private final ICraftingCallback callback;
|
private final ICraftingCallback callback;
|
||||||
|
private boolean running = false;
|
||||||
private boolean done = false;
|
private boolean done = false;
|
||||||
|
private int time;
|
||||||
|
private int incTime;
|
||||||
|
|
||||||
private World wrapWorld( final World w )
|
private World wrapWorld( final World w )
|
||||||
{
|
{
|
||||||
@@ -133,6 +137,7 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
TickHandler.INSTANCE.registerCraftingSimulation( this.world, this );
|
TickHandler.INSTANCE.registerCraftingSimulation( this.world, this );
|
||||||
|
this.handlePausing();
|
||||||
|
|
||||||
final Stopwatch timer = Stopwatch.createStarted();
|
final Stopwatch timer = Stopwatch.createStarted();
|
||||||
|
|
||||||
@@ -214,6 +219,41 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
this.finish();
|
this.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handlePausing() throws InterruptedException
|
||||||
|
{
|
||||||
|
if( !this.actionSrc.player().isPresent() && this.incTime > 100 )
|
||||||
|
{
|
||||||
|
this.incTime = 0;
|
||||||
|
synchronized ( this.monitor )
|
||||||
|
{
|
||||||
|
if( this.watch.elapsed( TimeUnit.MICROSECONDS ) > this.time )
|
||||||
|
{
|
||||||
|
this.running = false;
|
||||||
|
this.watch.stop();
|
||||||
|
this.monitor.notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !this.running )
|
||||||
|
{
|
||||||
|
AELog.craftingDebug( "crafting job will now sleep" );
|
||||||
|
|
||||||
|
while ( !this.running )
|
||||||
|
{
|
||||||
|
this.monitor.wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
AELog.craftingDebug( "crafting job now active" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Thread.interrupted() )
|
||||||
|
{
|
||||||
|
throw new InterruptedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.incTime++;
|
||||||
|
}
|
||||||
|
|
||||||
private void finish()
|
private void finish()
|
||||||
{
|
{
|
||||||
if( this.callback != null )
|
if( this.callback != null )
|
||||||
@@ -225,6 +265,7 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
|
|
||||||
synchronized( this.monitor )
|
synchronized( this.monitor )
|
||||||
{
|
{
|
||||||
|
this.running = false;
|
||||||
this.done = true;
|
this.done = true;
|
||||||
this.monitor.notify();
|
this.monitor.notify();
|
||||||
}
|
}
|
||||||
@@ -270,13 +311,25 @@ public class CraftingJob implements Runnable, ICraftingJob
|
|||||||
/**
|
/**
|
||||||
* @return true if this needs more simulation
|
* @return true if this needs more simulation
|
||||||
*/
|
*/
|
||||||
public boolean simulateFor()
|
public boolean simulateFor(final int milli)
|
||||||
{
|
{
|
||||||
synchronized( this.monitor ) {
|
this.time = milli;
|
||||||
if ( this.done ) {
|
|
||||||
|
synchronized ( this.monitor )
|
||||||
|
{
|
||||||
|
if( this.done )
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if( !this.actionSrc.player().isPresent() )
|
||||||
|
{
|
||||||
|
this.watch.reset();
|
||||||
|
this.watch.start();
|
||||||
|
this.monitor.notify();
|
||||||
|
}
|
||||||
|
this.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -119,18 +120,48 @@ public class CraftingTreeNode
|
|||||||
|
|
||||||
IAEItemStack request( final MECraftingInventory inv, long l, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
IAEItemStack request( final MECraftingInventory inv, long l, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
||||||
{
|
{
|
||||||
|
this.job.handlePausing();
|
||||||
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() )
|
||||||
{
|
{
|
||||||
itemList = inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL );
|
final List<IAEItemStack> substitutes = this.parent.details.getSubstituteInputs( this.slot );
|
||||||
|
itemList = new ArrayList<>( substitutes.size() );
|
||||||
|
|
||||||
|
for( IAEItemStack stack : substitutes )
|
||||||
|
{
|
||||||
|
itemList.addAll( inventoryList.findFuzzy( stack, FuzzyMode.IGNORE_ALL ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -151,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 )
|
||||||
{
|
{
|
||||||
@@ -177,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 )
|
||||||
{
|
{
|
||||||
@@ -221,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 );
|
||||||
|
|
||||||
@@ -229,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 )
|
||||||
{
|
{
|
||||||
@@ -253,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 )
|
||||||
{
|
{
|
||||||
@@ -316,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 )
|
||||||
{
|
{
|
||||||
@@ -353,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() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ public class CraftingTreeProcess
|
|||||||
|
|
||||||
void request( final MECraftingInventory inv, final long i, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
void request( final MECraftingInventory inv, final long i, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
||||||
{
|
{
|
||||||
|
this.job.handlePausing();
|
||||||
if( this.fullSimulation )
|
if( this.fullSimulation )
|
||||||
{
|
{
|
||||||
final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
|
final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
|
||||||
@@ -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 )
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ import appeng.api.storage.IStorageChannel;
|
|||||||
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.api.storage.data.IItemList;
|
import appeng.api.storage.data.IItemList;
|
||||||
|
import appeng.me.helpers.PlayerSource;
|
||||||
import appeng.util.inv.ItemListIgnoreCrafting;
|
import appeng.util.inv.ItemListIgnoreCrafting;
|
||||||
|
import net.minecraft.util.text.TextComponentString;
|
||||||
|
|
||||||
|
|
||||||
public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
||||||
@@ -307,8 +309,19 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
|
|||||||
|
|
||||||
if( result == null || result.getStackSize() != extra.getStackSize() )
|
if( result == null || result.getStackSize() != extra.getStackSize() )
|
||||||
{
|
{
|
||||||
|
if( src.player().isPresent() )
|
||||||
|
{
|
||||||
|
if( result == null )
|
||||||
|
{
|
||||||
|
src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getItem().getItemStackDisplayName( extra.getDefinition() ) + " available but could not extract anything" ), false );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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;
|
||||||
break;
|
if( !src.player().isPresent() ) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ package appeng.fluids.client.gui;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import appeng.api.util.IConfigManager;
|
||||||
|
import appeng.client.gui.widgets.GuiCustomSlot;
|
||||||
|
import appeng.util.IConfigManagerHost;
|
||||||
import net.minecraft.client.gui.GuiButton;
|
import net.minecraft.client.gui.GuiButton;
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
|
|
||||||
@@ -38,11 +41,12 @@ import appeng.fluids.helper.IFluidInterfaceHost;
|
|||||||
import appeng.fluids.util.IAEFluidTank;
|
import appeng.fluids.util.IAEFluidTank;
|
||||||
|
|
||||||
|
|
||||||
public class GuiFluidInterface extends GuiUpgradeable
|
public class GuiFluidInterface extends GuiUpgradeable implements IConfigManagerHost
|
||||||
{
|
{
|
||||||
public final static int ID_BUTTON_TANK = 222;
|
public final static int ID_BUTTON_TANK = 222;
|
||||||
|
|
||||||
private final IFluidInterfaceHost host;
|
private final IFluidInterfaceHost host;
|
||||||
|
private final ContainerFluidInterface container;
|
||||||
private GuiTabButton priority;
|
private GuiTabButton priority;
|
||||||
|
|
||||||
public GuiFluidInterface( final InventoryPlayer ip, final IFluidInterfaceHost te )
|
public GuiFluidInterface( final InventoryPlayer ip, final IFluidInterfaceHost te )
|
||||||
@@ -50,6 +54,8 @@ public class GuiFluidInterface extends GuiUpgradeable
|
|||||||
super( new ContainerFluidInterface( ip, te ) );
|
super( new ContainerFluidInterface( ip, te ) );
|
||||||
this.ySize = 231;
|
this.ySize = 231;
|
||||||
this.host = te;
|
this.host = te;
|
||||||
|
( this.container = (ContainerFluidInterface) this.inventorySlots ).setGui( this );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -62,9 +68,7 @@ public class GuiFluidInterface extends GuiUpgradeable
|
|||||||
|
|
||||||
for( int i = 0; i < DualityFluidInterface.NUMBER_OF_TANKS; ++i )
|
for( int i = 0; i < DualityFluidInterface.NUMBER_OF_TANKS; ++i )
|
||||||
{
|
{
|
||||||
final GuiFluidTank guiTank = new GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, this.getGuiLeft() + 35 + 18 * i, this
|
this.guiSlots.add( new GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, 36 + 18 * i, 53, 16, 68 ) );
|
||||||
.getGuiTop() + 53, 16, 68 );
|
|
||||||
this.buttonList.add( guiTank );
|
|
||||||
this.guiSlots.add( new GuiFluidSlot( configFluids, i, i, 35 + 18 * i, 35 ) );
|
this.guiSlots.add( new GuiFluidSlot( configFluids, i, i, 35 + 18 * i, 35 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,9 +108,33 @@ public class GuiFluidInterface extends GuiUpgradeable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void mouseClicked( int xCoord, int yCoord, int btn ) throws IOException
|
||||||
|
{
|
||||||
|
for( GuiCustomSlot slot : this.guiSlots )
|
||||||
|
{
|
||||||
|
if( slot instanceof GuiFluidTank )
|
||||||
|
{
|
||||||
|
if( this.isPointInRegion( slot.xPos(), slot.yPos(), slot.getWidth(), slot.getHeight(), xCoord, yCoord ) && slot.canClick( this.mc.player ) )
|
||||||
|
{
|
||||||
|
this.container.setTargetStack( ( (GuiFluidTank) slot ).getFluidStack() );
|
||||||
|
slot.slotClicked( this.mc.player.inventory.getItemStack(), btn );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.mouseClicked( xCoord, yCoord, btn );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean drawUpgrades()
|
protected boolean drawUpgrades()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSetting( IConfigManager manager, Enum settingName, Enum newValue )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,42 +19,50 @@
|
|||||||
package appeng.fluids.client.gui.widgets;
|
package appeng.fluids.client.gui.widgets;
|
||||||
|
|
||||||
|
|
||||||
|
import appeng.client.gui.widgets.GuiCustomSlot;
|
||||||
|
import appeng.core.sync.network.NetworkHandler;
|
||||||
|
import appeng.core.sync.packets.PacketInventoryAction;
|
||||||
|
import appeng.helpers.InventoryAction;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.GuiButton;
|
|
||||||
import net.minecraft.client.renderer.GlStateManager;
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.client.renderer.texture.TextureMap;
|
import net.minecraft.client.renderer.texture.TextureMap;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
import appeng.api.storage.data.IAEFluidStack;
|
import appeng.api.storage.data.IAEFluidStack;
|
||||||
import appeng.api.util.AEColor;
|
|
||||||
import appeng.client.gui.widgets.ITooltip;
|
import appeng.client.gui.widgets.ITooltip;
|
||||||
import appeng.fluids.util.IAEFluidTank;
|
import appeng.fluids.util.IAEFluidTank;
|
||||||
|
|
||||||
|
|
||||||
@SideOnly( Side.CLIENT )
|
@SideOnly( Side.CLIENT )
|
||||||
public class GuiFluidTank extends GuiButton implements ITooltip
|
public class GuiFluidTank extends GuiCustomSlot implements ITooltip
|
||||||
{
|
{
|
||||||
private final IAEFluidTank tank;
|
private final IAEFluidTank tank;
|
||||||
private final int slot;
|
private final int slot;
|
||||||
|
private final int width;
|
||||||
|
private final int height;
|
||||||
|
|
||||||
public GuiFluidTank( IAEFluidTank tank, int slot, int id, int x, int y, int w, int h )
|
public GuiFluidTank( IAEFluidTank tank, int slot, int id, int x, int y, int w, int h )
|
||||||
{
|
{
|
||||||
super( id, x, y, w, h, "" );
|
super( id, x, y );
|
||||||
this.tank = tank;
|
this.tank = tank;
|
||||||
this.slot = slot;
|
this.slot = slot;
|
||||||
|
this.width = w;
|
||||||
|
this.height = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawButton( final Minecraft mc, final int mouseX, final int mouseY, final float partialTicks )
|
public void drawContent( Minecraft mc, int mouseX, int mouseY, float partialTicks )
|
||||||
{
|
{
|
||||||
if( this.visible )
|
final IAEFluidStack fs = this.getFluidStack();
|
||||||
|
if( fs != null )
|
||||||
{
|
{
|
||||||
GlStateManager.disableBlend();
|
GlStateManager.disableBlend();
|
||||||
GlStateManager.disableLighting();
|
GlStateManager.disableLighting();
|
||||||
|
|
||||||
drawRect( this.x, this.y, this.x + this.width, this.y + this.height, AEColor.GRAY.blackVariant | 0xFF000000 );
|
//drawRect( this.x, this.y, this.x + this.width, this.y + this.height, AEColor.GRAY.blackVariant | 0xFF000000 );
|
||||||
|
|
||||||
final IAEFluidStack fluid = this.tank.getFluidInSlot( this.slot );
|
final IAEFluidStack fluid = this.tank.getFluidInSlot( this.slot );
|
||||||
if( fluid != null && fluid.getStackSize() > 0 )
|
if( fluid != null && fluid.getStackSize() > 0 )
|
||||||
@@ -69,17 +77,16 @@ public class GuiFluidTank extends GuiButton implements ITooltip
|
|||||||
TextureAtlasSprite sprite = mc.getTextureMapBlocks().getAtlasSprite( fluid.getFluid().getStill().toString() );
|
TextureAtlasSprite sprite = mc.getTextureMapBlocks().getAtlasSprite( fluid.getFluid().getStill().toString() );
|
||||||
final int scaledHeight = (int) ( this.height * ( (float) fluid.getStackSize() / this.tank.getTankProperties()[this.slot].getCapacity() ) );
|
final int scaledHeight = (int) ( this.height * ( (float) fluid.getStackSize() / this.tank.getTankProperties()[this.slot].getCapacity() ) );
|
||||||
|
|
||||||
int iconHeightRemainder = scaledHeight % 16;
|
int iconHeightRemainder = scaledHeight % this.getHeight();
|
||||||
if( iconHeightRemainder > 0 )
|
if( iconHeightRemainder > 0 )
|
||||||
{
|
{
|
||||||
this.drawTexturedModalRect( this.x, this.y + this.height - iconHeightRemainder, sprite, 16, iconHeightRemainder );
|
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder, sprite, this.getWidth(), iconHeightRemainder );
|
||||||
}
|
}
|
||||||
for( int i = 0; i < scaledHeight / 16; i++ )
|
for( int i = 0; i < scaledHeight / this.getHeight(); i++ )
|
||||||
{
|
{
|
||||||
this.drawTexturedModalRect( this.x, this.y + this.height - iconHeightRemainder - ( i + 1 ) * 16, sprite, 16, 16 );
|
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder - ( i + 1 ) * 16, sprite, this.getWidth(), this.getHeight() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,25 +107,25 @@ public class GuiFluidTank extends GuiButton implements ITooltip
|
|||||||
@Override
|
@Override
|
||||||
public int xPos()
|
public int xPos()
|
||||||
{
|
{
|
||||||
return this.x - 2;
|
return this.x - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int yPos()
|
public int yPos()
|
||||||
{
|
{
|
||||||
return this.y - 2;
|
return this.y - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getWidth()
|
public int getWidth()
|
||||||
{
|
{
|
||||||
return this.width + 4;
|
return this.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight()
|
public int getHeight()
|
||||||
{
|
{
|
||||||
return this.height + 4;
|
return this.height + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -127,4 +134,24 @@ public class GuiFluidTank extends GuiButton implements ITooltip
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IAEFluidStack getFluidStack()
|
||||||
|
{
|
||||||
|
return this.tank.getFluidInSlot( this.slot );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void slotClicked( ItemStack clickStack, final int mouseButton )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( getFluidStack() != null )
|
||||||
|
{
|
||||||
|
NetworkHandler.instance().sendToServer( new PacketInventoryAction( InventoryAction.FILL_ITEM, slot, 0 ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NetworkHandler.instance().sendToServer( new PacketInventoryAction( InventoryAction.EMPTY_ITEM, slot, 0 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,17 @@
|
|||||||
package appeng.fluids.container;
|
package appeng.fluids.container;
|
||||||
|
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import appeng.core.sync.network.NetworkHandler;
|
||||||
|
import appeng.core.sync.packets.PacketTargetFluidStack;
|
||||||
|
import appeng.fluids.util.AEFluidStack;
|
||||||
|
import appeng.helpers.InventoryAction;
|
||||||
|
import appeng.util.IConfigManagerHost;
|
||||||
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
import net.minecraft.inventory.IContainerListener;
|
import net.minecraft.inventory.IContainerListener;
|
||||||
|
|
||||||
@@ -33,12 +41,19 @@ import appeng.fluids.helper.FluidSyncHelper;
|
|||||||
import appeng.fluids.helper.IFluidInterfaceHost;
|
import appeng.fluids.helper.IFluidInterfaceHost;
|
||||||
import appeng.fluids.util.IAEFluidTank;
|
import appeng.fluids.util.IAEFluidTank;
|
||||||
import appeng.util.Platform;
|
import appeng.util.Platform;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
import net.minecraftforge.fluids.FluidUtil;
|
||||||
|
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
|
||||||
|
|
||||||
|
|
||||||
public class ContainerFluidInterface extends ContainerFluidConfigurable
|
public class ContainerFluidInterface extends ContainerFluidConfigurable implements IConfigManagerHost
|
||||||
{
|
{
|
||||||
private final DualityFluidInterface myDuality;
|
private final DualityFluidInterface myDuality;
|
||||||
private final FluidSyncHelper tankSync;
|
private final FluidSyncHelper tankSync;
|
||||||
|
private IConfigManagerHost gui;
|
||||||
|
// Holds the fluid the client wishes to extract, or null for insert
|
||||||
|
private IAEFluidStack clientRequestedTargetFluid = null;
|
||||||
|
|
||||||
public ContainerFluidInterface( final InventoryPlayer ip, final IFluidInterfaceHost te )
|
public ContainerFluidInterface( final InventoryPlayer ip, final IFluidInterfaceHost te )
|
||||||
{
|
{
|
||||||
@@ -60,6 +75,15 @@ public class ContainerFluidInterface extends ContainerFluidConfigurable
|
|||||||
return this.myDuality.getConfig();
|
return this.myDuality.getConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSetting( IConfigManager manager, Enum settingName, Enum newValue )
|
||||||
|
{
|
||||||
|
if( this.getGui() != null )
|
||||||
|
{
|
||||||
|
this.getGui().updateSetting( manager, settingName, newValue );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void detectAndSendChanges()
|
public void detectAndSendChanges()
|
||||||
{
|
{
|
||||||
@@ -97,6 +121,126 @@ public class ContainerFluidInterface extends ContainerFluidConfigurable
|
|||||||
this.tankSync.readPacket( fluids );
|
this.tankSync.readPacket( fluids );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IConfigManagerHost getGui()
|
||||||
|
{
|
||||||
|
return this.gui;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGui( @Nonnull final IConfigManagerHost gui )
|
||||||
|
{
|
||||||
|
this.gui = gui;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doAction( EntityPlayerMP player, InventoryAction action, int slot, long id )
|
||||||
|
{
|
||||||
|
if( action != InventoryAction.FILL_ITEM && action != InventoryAction.EMPTY_ITEM )
|
||||||
|
{
|
||||||
|
super.doAction( player, action, slot, id );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ItemStack held = player.inventory.getItemStack();
|
||||||
|
ItemStack heldCopy = held.copy();
|
||||||
|
heldCopy.setCount( 1 );
|
||||||
|
IFluidHandlerItem fh = FluidUtil.getFluidHandler( heldCopy );
|
||||||
|
if( fh == null )
|
||||||
|
{
|
||||||
|
// only fluid handlers items
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( action == InventoryAction.FILL_ITEM && this.clientRequestedTargetFluid != null )
|
||||||
|
{
|
||||||
|
final IAEFluidStack stack = this.clientRequestedTargetFluid.copy();
|
||||||
|
|
||||||
|
// Check how much we can store in the item
|
||||||
|
stack.setStackSize( Integer.MAX_VALUE );
|
||||||
|
int amountAllowed = fh.fill( stack.getFluidStack(), false );
|
||||||
|
int heldAmount = held.getCount();
|
||||||
|
for( int i = 0; i < heldAmount; i++ )
|
||||||
|
{
|
||||||
|
ItemStack copiedFluidContainer = held.copy();
|
||||||
|
copiedFluidContainer.setCount( 1 );
|
||||||
|
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
|
||||||
|
|
||||||
|
FluidStack extractableFluid = this.myDuality.getTanks().drain( stack.setStackSize( amountAllowed ).getFluidStack(), false );
|
||||||
|
if( extractableFluid == null || extractableFluid.amount == 0 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fillableAmount = fh.fill( extractableFluid, false );
|
||||||
|
if( fillableAmount > 0 )
|
||||||
|
{
|
||||||
|
FluidStack extractedFluid = this.myDuality.getTanks().drain( extractableFluid, true );
|
||||||
|
fh.fill( extractedFluid, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( held.getCount() == 1 )
|
||||||
|
{
|
||||||
|
player.inventory.setItemStack( fh.getContainer() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player.inventory.getItemStack().shrink( 1 );
|
||||||
|
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
|
||||||
|
{
|
||||||
|
player.dropItem( fh.getContainer(), false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( action == InventoryAction.EMPTY_ITEM )
|
||||||
|
{
|
||||||
|
int heldAmount = held.getCount();
|
||||||
|
for( int i = 0; i < heldAmount; i++ )
|
||||||
|
{
|
||||||
|
ItemStack copiedFluidContainer = held.copy();
|
||||||
|
copiedFluidContainer.setCount( 1 );
|
||||||
|
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
|
||||||
|
|
||||||
|
FluidStack drainable = fh.drain( this.myDuality.getTanks().getTankProperties()[slot].getCapacity(), false );
|
||||||
|
if( drainable != null )
|
||||||
|
{
|
||||||
|
fh.drain( drainable, true );
|
||||||
|
this.myDuality.getTanks().fill( drainable, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( held.getCount() == 1 )
|
||||||
|
{
|
||||||
|
player.inventory.setItemStack( fh.getContainer() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player.inventory.getItemStack().shrink( 1 );
|
||||||
|
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
|
||||||
|
{
|
||||||
|
player.dropItem( fh.getContainer(), false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.updateHeld( player );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetStack( final IAEFluidStack stack )
|
||||||
|
{
|
||||||
|
if( Platform.isClient() )
|
||||||
|
{
|
||||||
|
if( stack == null && this.clientRequestedTargetFluid == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if( stack != null && this.clientRequestedTargetFluid != null && stack.getFluidStack().isFluidEqual( this.clientRequestedTargetFluid.getFluidStack() ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NetworkHandler.instance().sendToServer( new PacketTargetFluidStack( (AEFluidStack) stack ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
this.clientRequestedTargetFluid = stack == null ? null : stack.copy();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean supportCapacity()
|
protected boolean supportCapacity()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ import java.nio.BufferOverflowException;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import appeng.container.slot.AppEngSlot;
|
||||||
|
import appeng.container.slot.SlotPlayerHotBar;
|
||||||
|
import appeng.container.slot.SlotPlayerInv;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
@@ -70,6 +73,7 @@ import appeng.me.helpers.ChannelPowerSrc;
|
|||||||
import appeng.util.ConfigManager;
|
import appeng.util.ConfigManager;
|
||||||
import appeng.util.IConfigManagerHost;
|
import appeng.util.IConfigManagerHost;
|
||||||
import appeng.util.Platform;
|
import appeng.util.Platform;
|
||||||
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -342,6 +346,89 @@ public class ContainerFluidTerminal extends AEBaseContainer implements IConfigMa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack transferStackInSlot( final EntityPlayer p, final int idx )
|
||||||
|
{
|
||||||
|
if( Platform.isClient() )
|
||||||
|
{
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
EntityPlayerMP player = (EntityPlayerMP) p;
|
||||||
|
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();
|
||||||
|
|
||||||
|
ItemStack copy = itemStack.copy();
|
||||||
|
copy.setCount( 1 );
|
||||||
|
IFluidHandlerItem fh = FluidUtil.getFluidHandler( copy );
|
||||||
|
if( fh == null )
|
||||||
|
{
|
||||||
|
// only fluid handlers items
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int heldAmount = itemStack.getCount();
|
||||||
|
for( int i = 0; i < heldAmount; i++ )
|
||||||
|
{
|
||||||
|
copy = itemStack.copy();
|
||||||
|
copy.setCount( 1 );
|
||||||
|
fh = FluidUtil.getFluidHandler( copy );
|
||||||
|
|
||||||
|
final FluidStack extract = fh.drain( Integer.MAX_VALUE, false );
|
||||||
|
if( extract == null || extract.amount < 1 )
|
||||||
|
{
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we can push into the system
|
||||||
|
final IAEFluidStack notStorable = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ), this.getActionSource(), Actionable.SIMULATE );
|
||||||
|
|
||||||
|
if( notStorable != null && notStorable.getStackSize() > 0 )
|
||||||
|
{
|
||||||
|
final int toStore = (int) ( extract.amount - notStorable.getStackSize() );
|
||||||
|
final FluidStack storable = fh.drain( toStore, false );
|
||||||
|
|
||||||
|
if( storable == null || storable.amount == 0 )
|
||||||
|
{
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
extract.amount = storable.amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actually drain
|
||||||
|
final FluidStack drained = fh.drain( extract, true );
|
||||||
|
extract.amount = drained.amount;
|
||||||
|
|
||||||
|
final IAEFluidStack notInserted = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ), this.getActionSource() );
|
||||||
|
|
||||||
|
if( notInserted != null && notInserted.getStackSize() > 0 )
|
||||||
|
{
|
||||||
|
IAEFluidStack spill = this.monitor.injectItems( notInserted, Actionable.MODULATE, this.getActionSource() );
|
||||||
|
if( spill != null && spill.getStackSize() > 0 )
|
||||||
|
{
|
||||||
|
fh.fill( spill.getFluidStack(), true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( notInserted == null )
|
||||||
|
{
|
||||||
|
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
|
||||||
|
{
|
||||||
|
player.dropItem( fh.getContainer(), false );
|
||||||
|
}
|
||||||
|
clickSlot.decrStackSize( 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.detectAndSendChanges();
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
return super.transferStackInSlot( p, idx );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doAction( EntityPlayerMP player, InventoryAction action, int slot, long id )
|
public void doAction( EntityPlayerMP player, InventoryAction action, int slot, long id )
|
||||||
{
|
{
|
||||||
@@ -352,13 +439,9 @@ public class ContainerFluidTerminal extends AEBaseContainer implements IConfigMa
|
|||||||
}
|
}
|
||||||
|
|
||||||
final ItemStack held = player.inventory.getItemStack();
|
final ItemStack held = player.inventory.getItemStack();
|
||||||
if( held.getCount() != 1 )
|
ItemStack heldCopy = held.copy();
|
||||||
{
|
heldCopy.setCount( 1 );
|
||||||
// only support stacksize 1 for now
|
IFluidHandlerItem fh = FluidUtil.getFluidHandler( heldCopy );
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final IFluidHandlerItem fh = FluidUtil.getFluidHandler( held );
|
|
||||||
if( fh == null )
|
if( fh == null )
|
||||||
{
|
{
|
||||||
// only fluid handlers items
|
// only fluid handlers items
|
||||||
@@ -372,84 +455,122 @@ public class ContainerFluidTerminal extends AEBaseContainer implements IConfigMa
|
|||||||
// Check how much we can store in the item
|
// Check how much we can store in the item
|
||||||
stack.setStackSize( Integer.MAX_VALUE );
|
stack.setStackSize( Integer.MAX_VALUE );
|
||||||
int amountAllowed = fh.fill( stack.getFluidStack(), false );
|
int amountAllowed = fh.fill( stack.getFluidStack(), false );
|
||||||
stack.setStackSize( amountAllowed );
|
int heldAmount = held.getCount();
|
||||||
|
for( int i = 0; i < heldAmount; i++ )
|
||||||
// Check if we can pull out of the system
|
|
||||||
final IAEFluidStack canPull = Platform.poweredExtraction( this.getPowerSource(), this.monitor, stack, this.getActionSource(), Actionable.SIMULATE );
|
|
||||||
if( canPull == null || canPull.getStackSize() < 1 )
|
|
||||||
{
|
{
|
||||||
return;
|
ItemStack copiedFluidContainer = held.copy();
|
||||||
}
|
copiedFluidContainer.setCount( 1 );
|
||||||
|
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
|
||||||
|
|
||||||
// How much could fit into the container
|
// Check if we can pull out of the system
|
||||||
final int canFill = fh.fill( canPull.getFluidStack(), false );
|
final IAEFluidStack canPull = Platform.poweredExtraction( this.getPowerSource(), this.monitor, stack.setStackSize( amountAllowed ), this.getActionSource(), Actionable.SIMULATE );
|
||||||
if( canFill == 0 )
|
if( canPull == null || canPull.getStackSize() < 1 )
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now actually pull out of the system
|
|
||||||
stack.setStackSize( canFill );
|
|
||||||
final IAEFluidStack pulled = Platform.poweredExtraction( this.getPowerSource(), this.monitor, stack, this.getActionSource() );
|
|
||||||
if( pulled == null || pulled.getStackSize() < 1 )
|
|
||||||
{
|
|
||||||
// Something went wrong
|
|
||||||
AELog.error( "Unable to pull fluid out of the ME system even though the simulation said yes " );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actually fill
|
|
||||||
final int used = fh.fill( pulled.getFluidStack(), true );
|
|
||||||
|
|
||||||
if( used != canFill )
|
|
||||||
{
|
|
||||||
AELog.error( "Fluid item [%s] reported a different possible amount than it actually accepted.", held.getDisplayName() );
|
|
||||||
}
|
|
||||||
|
|
||||||
player.inventory.setItemStack( fh.getContainer() );
|
|
||||||
this.updateHeld( player );
|
|
||||||
}
|
|
||||||
else if( action == InventoryAction.EMPTY_ITEM )
|
|
||||||
{
|
|
||||||
// See how much we can drain from the item
|
|
||||||
final FluidStack extract = fh.drain( Integer.MAX_VALUE, false );
|
|
||||||
if( extract == null || extract.amount < 1 )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we can push into the system
|
|
||||||
final IAEFluidStack notStorable = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ),
|
|
||||||
this.getActionSource(), Actionable.SIMULATE );
|
|
||||||
|
|
||||||
if( notStorable != null && notStorable.getStackSize() > 0 )
|
|
||||||
{
|
|
||||||
final int toStore = (int) ( extract.amount - notStorable.getStackSize() );
|
|
||||||
final FluidStack storable = fh.drain( toStore, false );
|
|
||||||
|
|
||||||
if( storable == null || storable.amount == 0 )
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// How much could fit into the container
|
||||||
|
final int canFill = fh.fill( canPull.getFluidStack(), false );
|
||||||
|
if( canFill == 0 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now actually pull out of the system
|
||||||
|
final IAEFluidStack pulled = Platform.poweredExtraction( this.getPowerSource(), this.monitor, stack.setStackSize( canFill ), this.getActionSource() );
|
||||||
|
if( pulled == null || pulled.getStackSize() < 1 )
|
||||||
|
{
|
||||||
|
// Something went wrong
|
||||||
|
AELog.error( "Unable to pull fluid out of the ME system even though the simulation said yes " );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actually fill
|
||||||
|
final int used = fh.fill( pulled.getFluidStack(), true );
|
||||||
|
|
||||||
|
if( used != canFill )
|
||||||
|
{
|
||||||
|
AELog.error( "Fluid item [%s] reported a different possible amount than it actually accepted.", held.getDisplayName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( held.getCount() == 1 )
|
||||||
|
{
|
||||||
|
player.inventory.setItemStack( fh.getContainer() );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
extract.amount = storable.amount;
|
player.inventory.getItemStack().shrink( 1 );
|
||||||
|
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
|
||||||
|
{
|
||||||
|
player.dropItem( fh.getContainer(), false );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.updateHeld( player );
|
||||||
|
|
||||||
// Actually drain
|
}
|
||||||
final FluidStack drained = fh.drain( extract, true );
|
else if( action == InventoryAction.EMPTY_ITEM )
|
||||||
extract.amount = drained.amount;
|
{
|
||||||
|
int heldAmount = held.getCount();
|
||||||
final IAEFluidStack notInserted = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ),
|
for( int i = 0; i < heldAmount; i++ )
|
||||||
this.getActionSource() );
|
|
||||||
|
|
||||||
if( notInserted != null && notInserted.getStackSize() > 0 )
|
|
||||||
{
|
{
|
||||||
AELog.error( "Fluid item [%s] reported a different possible amount to drain than it actually provided.", held.getDisplayName() );
|
ItemStack copiedFluidContainer = held.copy();
|
||||||
}
|
copiedFluidContainer.setCount( 1 );
|
||||||
|
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
|
||||||
|
|
||||||
player.inventory.setItemStack( fh.getContainer() );
|
// See how much we can drain from the item
|
||||||
|
final FluidStack extract = fh.drain( Integer.MAX_VALUE, false );
|
||||||
|
if( extract == null || extract.amount < 1 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we can push into the system
|
||||||
|
final IAEFluidStack notStorable = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ), this.getActionSource(), Actionable.SIMULATE );
|
||||||
|
|
||||||
|
if( notStorable != null && notStorable.getStackSize() > 0 )
|
||||||
|
{
|
||||||
|
final int toStore = (int) ( extract.amount - notStorable.getStackSize() );
|
||||||
|
final FluidStack storable = fh.drain( toStore, false );
|
||||||
|
|
||||||
|
if( storable == null || storable.amount == 0 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
extract.amount = storable.amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actually drain
|
||||||
|
final FluidStack drained = fh.drain( extract, true );
|
||||||
|
extract.amount = drained.amount;
|
||||||
|
|
||||||
|
final IAEFluidStack notInserted = Platform.poweredInsert( this.getPowerSource(), this.monitor, AEFluidStack.fromFluidStack( extract ), this.getActionSource() );
|
||||||
|
|
||||||
|
if( notInserted != null && notInserted.getStackSize() > 0 )
|
||||||
|
{
|
||||||
|
IAEFluidStack spill = this.monitor.injectItems( notInserted, Actionable.MODULATE, this.getActionSource() );
|
||||||
|
if( spill != null && spill.getStackSize() > 0 )
|
||||||
|
{
|
||||||
|
fh.fill( spill.getFluidStack(), true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( held.getCount() == 1 )
|
||||||
|
{
|
||||||
|
player.inventory.setItemStack( fh.getContainer() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player.inventory.getItemStack().shrink( 1 );
|
||||||
|
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
|
||||||
|
{
|
||||||
|
player.dropItem( fh.getContainer(), false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
this.updateHeld( player );
|
this.updateHeld( player );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -19,16 +19,15 @@
|
|||||||
package appeng.fluids.parts;
|
package appeng.fluids.parts;
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
import appeng.api.config.AccessRestriction;
|
||||||
import appeng.api.config.Settings;
|
import appeng.api.config.Settings;
|
||||||
import appeng.api.config.StorageFilter;
|
import appeng.api.config.StorageFilter;
|
||||||
import appeng.parts.misc.PartStorageBus;
|
import appeng.api.storage.data.IAEItemStack;
|
||||||
|
import appeng.me.GridAccessException;
|
||||||
|
import appeng.util.inv.ItemSlot;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
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;
|
||||||
@@ -45,7 +44,6 @@ import appeng.api.storage.channels.IFluidStorageChannel;
|
|||||||
import appeng.api.storage.data.IAEFluidStack;
|
import appeng.api.storage.data.IAEFluidStack;
|
||||||
import appeng.api.storage.data.IItemList;
|
import appeng.api.storage.data.IItemList;
|
||||||
import appeng.fluids.util.AEFluidStack;
|
import appeng.fluids.util.AEFluidStack;
|
||||||
import appeng.me.GridAccessException;
|
|
||||||
import appeng.me.helpers.IGridProxyable;
|
import appeng.me.helpers.IGridProxyable;
|
||||||
import appeng.me.storage.ITickingMonitor;
|
import appeng.me.storage.ITickingMonitor;
|
||||||
|
|
||||||
@@ -65,17 +63,20 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
|||||||
private final IGridProxyable proxyable;
|
private final IGridProxyable proxyable;
|
||||||
private final FluidHandlerAdapter.InventoryCache cache;
|
private final FluidHandlerAdapter.InventoryCache cache;
|
||||||
private StorageFilter mode;
|
private StorageFilter mode;
|
||||||
|
private AccessRestriction access;
|
||||||
|
|
||||||
FluidHandlerAdapter( IFluidHandler fluidHandler, IGridProxyable proxy )
|
FluidHandlerAdapter( IFluidHandler fluidHandler, IGridProxyable proxy )
|
||||||
{
|
{
|
||||||
this.fluidHandler = fluidHandler;
|
this.fluidHandler = fluidHandler;
|
||||||
this.proxyable = proxy;
|
this.proxyable = proxy;
|
||||||
if( this.proxyable instanceof PartStorageBus )
|
if( this.proxyable instanceof PartFluidStorageBus )
|
||||||
{
|
{
|
||||||
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
|
PartFluidStorageBus partFluidStorageBus = (PartFluidStorageBus) this.proxyable;
|
||||||
this.mode = ( (StorageFilter) partStorageBus.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
|
this.mode = ( (StorageFilter) partFluidStorageBus.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
|
||||||
|
this.access = ( (AccessRestriction) partFluidStorageBus.getConfigManager().getSetting( Settings.ACCESS ) );
|
||||||
}
|
}
|
||||||
this.cache = new FluidHandlerAdapter.InventoryCache( this.fluidHandler, this.mode);
|
this.cache = new FluidHandlerAdapter.InventoryCache( this.fluidHandler, this.mode );
|
||||||
|
this.cache.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -94,11 +95,14 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
|||||||
|
|
||||||
if( type == Actionable.MODULATE )
|
if( type == Actionable.MODULATE )
|
||||||
{
|
{
|
||||||
|
IAEFluidStack added = input.copy().setStackSize( input.getStackSize() - remaining );
|
||||||
|
this.cache.currentlyCached.add( added );
|
||||||
|
this.postDifference( Collections.singletonList( added ) );
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||||
}
|
}
|
||||||
catch( GridAccessException ignore )
|
catch( GridAccessException ex )
|
||||||
{
|
{
|
||||||
// meh
|
// meh
|
||||||
}
|
}
|
||||||
@@ -123,25 +127,32 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IAEFluidStack gatheredAEFluidstack = AEFluidStack.fromFluidStack( gathered );
|
||||||
if( mode == Actionable.MODULATE )
|
if( mode == Actionable.MODULATE )
|
||||||
{
|
{
|
||||||
|
IAEFluidStack cachedStack = this.cache.currentlyCached.findPrecise( request );
|
||||||
|
if( cachedStack != null )
|
||||||
|
{
|
||||||
|
cachedStack.decStackSize( gatheredAEFluidstack.getStackSize() );
|
||||||
|
this.postDifference( Collections.singletonList( gatheredAEFluidstack.copy().setStackSize( -gatheredAEFluidstack.getStackSize() ) ) );
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||||
}
|
}
|
||||||
catch( GridAccessException ignore )
|
catch( GridAccessException ex )
|
||||||
{
|
{
|
||||||
// meh
|
// meh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return AEFluidStack.fromFluidStack( gathered );
|
return gatheredAEFluidstack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TickRateModulation onTick()
|
public TickRateModulation onTick()
|
||||||
{
|
{
|
||||||
List<IAEFluidStack> changes = this.cache.update();
|
List<IAEFluidStack> changes = this.cache.update();
|
||||||
if( !changes.isEmpty() )
|
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
|
||||||
{
|
{
|
||||||
this.postDifference( changes );
|
this.postDifference( changes );
|
||||||
return TickRateModulation.URGENT;
|
return TickRateModulation.URGENT;
|
||||||
@@ -202,9 +213,9 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
|||||||
|
|
||||||
private static class InventoryCache
|
private static class InventoryCache
|
||||||
{
|
{
|
||||||
private IAEFluidStack[] cachedAeStacks = new IAEFluidStack[0];
|
|
||||||
private final IFluidHandler fluidHandler;
|
private final IFluidHandler fluidHandler;
|
||||||
private final StorageFilter mode;
|
private final StorageFilter mode;
|
||||||
|
IItemList<IAEFluidStack> currentlyCached = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
|
||||||
|
|
||||||
public InventoryCache( IFluidHandler fluidHandler, StorageFilter mode )
|
public InventoryCache( IFluidHandler fluidHandler, StorageFilter mode )
|
||||||
{
|
{
|
||||||
@@ -216,102 +227,46 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
|||||||
{
|
{
|
||||||
final List<IAEFluidStack> changes = new ArrayList<>();
|
final List<IAEFluidStack> changes = new ArrayList<>();
|
||||||
final IFluidTankProperties[] tankProperties = this.fluidHandler.getTankProperties();
|
final IFluidTankProperties[] tankProperties = this.fluidHandler.getTankProperties();
|
||||||
final int slots = tankProperties.length;
|
|
||||||
|
|
||||||
// Make room for new slots
|
IItemList<IAEFluidStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
|
||||||
if( slots > this.cachedAeStacks.length )
|
|
||||||
{
|
|
||||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
|
||||||
}
|
|
||||||
|
|
||||||
for( int slot = 0; slot < slots; slot++ )
|
for( IFluidTankProperties tankProperty : tankProperties )
|
||||||
{
|
{
|
||||||
// Save the old stuff
|
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && this.fluidHandler.drain( 1, false ) == null )
|
||||||
final IAEFluidStack oldAEFS = this.cachedAeStacks[slot];
|
|
||||||
FluidStack newFS = tankProperties[slot].getContents();
|
|
||||||
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && newFS != null )
|
|
||||||
{
|
{
|
||||||
if( this.fluidHandler.drain( 1, false ) == null )
|
continue;
|
||||||
{
|
|
||||||
newFS = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.handlePossibleSlotChanges( slot, oldAEFS, newFS, changes );
|
currentlyOnStorage.add( AEFluidStack.fromFluidStack( tankProperty.getContents() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle cases where the number of slots actually is lower now than before
|
for ( final IAEFluidStack is : currentlyCached )
|
||||||
if( slots < this.cachedAeStacks.length )
|
|
||||||
{
|
{
|
||||||
for( int slot = slots; slot < this.cachedAeStacks.length; slot++ )
|
is.setStackSize( -is.getStackSize() );
|
||||||
{
|
|
||||||
final IAEFluidStack aeStack = this.cachedAeStacks[slot];
|
|
||||||
|
|
||||||
if( aeStack != null )
|
|
||||||
{
|
|
||||||
final IAEFluidStack a = aeStack.copy();
|
|
||||||
a.setStackSize( -a.getStackSize() );
|
|
||||||
changes.add( a );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for ( final IAEFluidStack is : currentlyOnStorage )
|
||||||
|
{
|
||||||
|
currentlyCached.add( is );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( final IAEFluidStack is : currentlyCached )
|
||||||
|
{
|
||||||
|
if( is.getStackSize() != 0 )
|
||||||
|
{
|
||||||
|
changes.add( is );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentlyCached = currentlyOnStorage;
|
||||||
|
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IItemList<IAEFluidStack> getAvailableItems( IItemList<IAEFluidStack> out )
|
public IItemList<IAEFluidStack> getAvailableItems( IItemList<IAEFluidStack> out )
|
||||||
{
|
{
|
||||||
Arrays.stream( this.cachedAeStacks ).forEach( out::add );
|
currentlyCached.iterator().forEachRemaining( out::add );
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePossibleSlotChanges( int slot, IAEFluidStack oldAeFS, FluidStack newFS, List<IAEFluidStack> changes )
|
|
||||||
{
|
|
||||||
if( oldAeFS != null && oldAeFS.getFluidStack().isFluidEqual( newFS ) )
|
|
||||||
{
|
|
||||||
this.handleStackSizeChanged( slot, oldAeFS, newFS, changes );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.handleFluidChanged( slot, oldAeFS, newFS, changes );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleStackSizeChanged( int slot, IAEFluidStack oldAeFS, FluidStack newFS, List<IAEFluidStack> changes )
|
|
||||||
{
|
|
||||||
// Still the same fluid, but amount might have changed
|
|
||||||
final long diff = newFS.amount - oldAeFS.getStackSize();
|
|
||||||
|
|
||||||
if( diff != 0 )
|
|
||||||
{
|
|
||||||
final IAEFluidStack stack = oldAeFS.copy();
|
|
||||||
stack.setStackSize( newFS.amount );
|
|
||||||
|
|
||||||
this.cachedAeStacks[slot] = stack;
|
|
||||||
|
|
||||||
final IAEFluidStack a = stack.copy();
|
|
||||||
a.setStackSize( diff );
|
|
||||||
changes.add( a );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleFluidChanged( int slot, IAEFluidStack oldAeFS, FluidStack newFS, List<IAEFluidStack> changes )
|
|
||||||
{
|
|
||||||
// Completely different fluid
|
|
||||||
this.cachedAeStacks[slot] = AEFluidStack.fromFluidStack( newFS );
|
|
||||||
|
|
||||||
// If we had a stack previously in this slot, notify the network about its disappearance
|
|
||||||
if( oldAeFS != null )
|
|
||||||
{
|
|
||||||
oldAeFS.setStackSize( -oldAeFS.getStackSize() );
|
|
||||||
changes.add( oldAeFS );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify the network about the new stack. Note that this is null if newFS was null
|
|
||||||
if( this.cachedAeStacks[slot] != null )
|
|
||||||
{
|
|
||||||
changes.add( this.cachedAeStacks[slot] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
@@ -204,7 +205,7 @@ public class PartFluidFormationPlane extends PartAbstractFormationPlane<IAEFluid
|
|||||||
@Override
|
@Override
|
||||||
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
|
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
|
||||||
{
|
{
|
||||||
if( this.getProxy().isActive() && channel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
|
if( channel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
|
||||||
{
|
{
|
||||||
final List<IMEInventoryHandler> handler = new ArrayList<>( 1 );
|
final List<IMEInventoryHandler> handler = new ArrayList<>( 1 );
|
||||||
handler.add( this.myHandler );
|
handler.add( this.myHandler );
|
||||||
|
|||||||
@@ -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,9 @@ package appeng.fluids.parts;
|
|||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
import appeng.api.storage.data.IItemList;
|
||||||
import appeng.fluids.helper.IConfigurableFluidInventory;
|
import appeng.fluids.helper.IConfigurableFluidInventory;
|
||||||
|
import appeng.me.cache.NetworkMonitor;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
@@ -34,7 +36,6 @@ import appeng.api.storage.IStorageChannel;
|
|||||||
import appeng.api.storage.channels.IFluidStorageChannel;
|
import appeng.api.storage.channels.IFluidStorageChannel;
|
||||||
import appeng.api.storage.data.IAEFluidStack;
|
import appeng.api.storage.data.IAEFluidStack;
|
||||||
import appeng.api.storage.data.IAEStack;
|
import appeng.api.storage.data.IAEStack;
|
||||||
import appeng.api.storage.data.IItemList;
|
|
||||||
import appeng.api.util.AECableType;
|
import appeng.api.util.AECableType;
|
||||||
import appeng.api.util.AEPartLocation;
|
import appeng.api.util.AEPartLocation;
|
||||||
import appeng.api.util.IConfigManager;
|
import appeng.api.util.IConfigManager;
|
||||||
@@ -127,15 +128,25 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
|
|||||||
this.configureWatchers();
|
this.configureWatchers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@MENetworkEventSubscribe
|
@MENetworkEventSubscribe
|
||||||
public void channelChanged( final MENetworkChannelsChanged c )
|
public void powerRender( final MENetworkPowerStatusChange powerEvent )
|
||||||
{
|
{
|
||||||
|
if (this.getProxy().isActive())
|
||||||
|
{
|
||||||
|
onListUpdate();
|
||||||
|
}
|
||||||
this.updateState();
|
this.updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@MENetworkEventSubscribe
|
@MENetworkEventSubscribe
|
||||||
public void powerChanged( final MENetworkPowerStatusChange c )
|
public void chanRender( final MENetworkChannelsChanged c )
|
||||||
{
|
{
|
||||||
|
if (this.getProxy().isActive())
|
||||||
|
{
|
||||||
|
onListUpdate();
|
||||||
|
}
|
||||||
this.updateState();
|
this.updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,10 +258,9 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
|
|||||||
|
|
||||||
if( myStack == null )
|
if( myStack == null )
|
||||||
{
|
{
|
||||||
this.lastReportedValue = 0;
|
if( monitor instanceof NetworkMonitor )
|
||||||
for( final IAEFluidStack st : monitor.getStorageList() )
|
|
||||||
{
|
{
|
||||||
this.lastReportedValue += st.getStackSize();
|
this.lastReportedValue = ( (NetworkMonitor<IAEFluidStack>) monitor ).getGridCurrentCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,6 @@ package appeng.helpers;
|
|||||||
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
@@ -33,8 +32,6 @@ import de.ellpeck.actuallyadditions.api.tile.IPhantomTile;
|
|||||||
import gregtech.api.block.machines.BlockMachine;
|
import gregtech.api.block.machines.BlockMachine;
|
||||||
import gregtech.api.metatileentity.MetaTileEntity;
|
import gregtech.api.metatileentity.MetaTileEntity;
|
||||||
import gregtech.api.metatileentity.MetaTileEntityHolder;
|
import gregtech.api.metatileentity.MetaTileEntityHolder;
|
||||||
import gregtech.api.metatileentity.TieredMetaTileEntity;
|
|
||||||
import gregtech.api.metatileentity.WorkableTieredMetaTileEntity;
|
|
||||||
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.init.Items;
|
import net.minecraft.init.Items;
|
||||||
@@ -115,7 +112,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
|
|
||||||
public static final int NUMBER_OF_STORAGE_SLOTS = 9;
|
public static final int NUMBER_OF_STORAGE_SLOTS = 9;
|
||||||
public static final int NUMBER_OF_CONFIG_SLOTS = 9;
|
public static final int NUMBER_OF_CONFIG_SLOTS = 9;
|
||||||
public static final int NUMBER_OF_PATTERN_SLOTS = 9;
|
public static final int NUMBER_OF_PATTERN_SLOTS = 36;
|
||||||
|
|
||||||
private static final Collection<Block> BAD_BLOCKS = new HashSet<>( 100 );
|
private static final Collection<Block> BAD_BLOCKS = new HashSet<>( 100 );
|
||||||
private final IAEItemStack[] requireWork = { null, null, null, null, null, null, null, null, null };
|
private final IAEItemStack[] requireWork = { null, null, null, null, null, null, null, null, null };
|
||||||
@@ -143,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, 1 );
|
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 );
|
||||||
|
|
||||||
@@ -179,10 +178,15 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if( inv == this.config && ( !removed.isEmpty() || !added.isEmpty() ) )
|
||||||
if( inv == this.config )
|
|
||||||
{
|
{
|
||||||
|
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() ) )
|
||||||
{
|
{
|
||||||
@@ -279,10 +283,11 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.waitingToSendFacing = null;
|
this.waitingToSendFacing = null;
|
||||||
final NBTTagCompound waitingListSided = data.getCompoundTag("sidedWaitList");
|
final NBTTagCompound waitingListSided = data.getCompoundTag( "sidedWaitList" );
|
||||||
|
|
||||||
for (EnumFacing s : EnumFacing.values())
|
for( EnumFacing s : EnumFacing.values() )
|
||||||
if (waitingListSided.hasKey( s.name() )) {
|
if( waitingListSided.hasKey( s.name() ) )
|
||||||
|
{
|
||||||
NBTTagList w = waitingListSided.getTagList( s.name(), 10 );
|
NBTTagList w = waitingListSided.getTagList( s.name(), 10 );
|
||||||
for( int x = 0; x < w.tagCount(); x++ )
|
for( int x = 0; x < w.tagCount(); x++ )
|
||||||
{
|
{
|
||||||
@@ -290,14 +295,31 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
if( c != null )
|
if( c != null )
|
||||||
{
|
{
|
||||||
final ItemStack is = new ItemStack( c );
|
final ItemStack is = new ItemStack( c );
|
||||||
this.addToSendListFacing( is , EnumFacing.getFront( s.getIndex() ) );
|
this.addToSendListFacing( is, EnumFacing.getFront( s.getIndex() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.craftingTracker.readFromNBT( data );
|
this.craftingTracker.readFromNBT( data );
|
||||||
|
|
||||||
|
// fix upgrade slot size mismatch
|
||||||
|
NBTTagCompound up = data.getCompoundTag( "upgrades" );
|
||||||
|
if( up.hasKey( "Size" ) && up.getInteger( "Size" ) != this.upgrades.getSlots() )
|
||||||
|
{
|
||||||
|
up.setInteger( "Size", this.upgrades.getSlots() );
|
||||||
|
this.upgrades.writeToNBT( up, "upgrades" );
|
||||||
|
}
|
||||||
|
|
||||||
this.upgrades.readFromNBT( data, "upgrades" );
|
this.upgrades.readFromNBT( data, "upgrades" );
|
||||||
this.config.readFromNBT( data, "config" );
|
this.config.readFromNBT( data, "config" );
|
||||||
|
|
||||||
|
NBTTagCompound pa = data.getCompoundTag( "patterns" );
|
||||||
|
if( pa.hasKey( "Size" ) && pa.getInteger( "Size" ) != this.patterns.getSlots() )
|
||||||
|
{
|
||||||
|
pa.setInteger( "Size", this.patterns.getSlots() );
|
||||||
|
this.upgrades.writeToNBT( pa, "patterns" );
|
||||||
|
}
|
||||||
|
|
||||||
this.patterns.readFromNBT( data, "patterns" );
|
this.patterns.readFromNBT( data, "patterns" );
|
||||||
this.storage.readFromNBT( data, "storage" );
|
this.storage.readFromNBT( data, "storage" );
|
||||||
this.priority = data.getInteger( "priority" );
|
this.priority = data.getInteger( "priority" );
|
||||||
@@ -400,9 +422,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
|
|
||||||
private void updateCraftingList()
|
private void updateCraftingList()
|
||||||
{
|
{
|
||||||
final Boolean[] accountedFor = { false, false, false, false, false, false, false, false, false }; // 9...
|
final Boolean[] accountedFor = new Boolean[this.patterns.getSlots()];
|
||||||
|
Arrays.fill( accountedFor, false );
|
||||||
assert ( accountedFor.length == this.patterns.getSlots() );
|
|
||||||
|
|
||||||
if( !this.gridProxy.isReady() )
|
if( !this.gridProxy.isReady() )
|
||||||
{
|
{
|
||||||
@@ -417,7 +438,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
final ICraftingPatternDetails details = i.next();
|
final ICraftingPatternDetails details = i.next();
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
|
|
||||||
for( int x = 0; x < accountedFor.length; x++ )
|
for( int x = 0; x < accountedFor.length ; x++ )
|
||||||
{
|
{
|
||||||
final ItemStack is = this.patterns.getStackInSlot( x );
|
final ItemStack is = this.patterns.getStackInSlot( x );
|
||||||
if( details.getPattern() == is )
|
if( details.getPattern() == is )
|
||||||
@@ -433,7 +454,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for( int x = 0; x < accountedFor.length; x++ )
|
for( int x = 0; x < accountedFor.length ; x++ )
|
||||||
{
|
{
|
||||||
if( !accountedFor[x] )
|
if( !accountedFor[x] )
|
||||||
{
|
{
|
||||||
@@ -586,6 +607,30 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dropExcessPatterns()
|
||||||
|
{
|
||||||
|
IItemHandler patterns = getPatterns();
|
||||||
|
|
||||||
|
List<ItemStack> dropList = new ArrayList<>();
|
||||||
|
for( int invSlot = 0; invSlot < patterns.getSlots(); invSlot++ )
|
||||||
|
{
|
||||||
|
if( invSlot > 8 + this.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION ) * 9 )
|
||||||
|
{
|
||||||
|
ItemStack is = patterns.getStackInSlot( invSlot );
|
||||||
|
if( is.isEmpty() ) continue;
|
||||||
|
dropList.add( patterns.extractItem( invSlot, Integer.MAX_VALUE, false ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( dropList.size() > 0 )
|
||||||
|
{
|
||||||
|
World world = this.getLocation().getWorld();
|
||||||
|
BlockPos blockPos = this.getLocation().getPos();
|
||||||
|
Platform.spawnDrops( world, blockPos, dropList );
|
||||||
|
}
|
||||||
|
|
||||||
|
this.gridProxy.setIdlePowerUsage( Math.pow( 4, ( this.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION ) ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canInsert( final ItemStack stack )
|
public boolean canInsert( final ItemStack stack )
|
||||||
{
|
{
|
||||||
@@ -812,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 )
|
||||||
@@ -936,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;
|
||||||
@@ -1544,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
|
||||||
|
|||||||
@@ -19,21 +19,17 @@
|
|||||||
package appeng.helpers;
|
package appeng.helpers;
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.StringJoiner;
|
|
||||||
|
|
||||||
import net.minecraft.inventory.InventoryCrafting;
|
import net.minecraft.inventory.InventoryCrafting;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.crafting.CraftingManager;
|
import net.minecraft.item.crafting.CraftingManager;
|
||||||
import net.minecraft.item.crafting.IRecipe;
|
import net.minecraft.item.crafting.IRecipe;
|
||||||
|
import net.minecraft.item.crafting.Ingredient;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.nbt.NBTTagList;
|
import net.minecraft.nbt.NBTTagList;
|
||||||
|
import net.minecraft.util.NonNullList;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
import appeng.api.AEApi;
|
||||||
@@ -41,25 +37,32 @@ 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;
|
||||||
|
|
||||||
|
|
||||||
public class PatternHelper implements ICraftingPatternDetails, Comparable<PatternHelper>
|
public class PatternHelper implements ICraftingPatternDetails, Comparable<PatternHelper>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private static final int CRAFTING_GRID_DIMENSION = 3;
|
||||||
|
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;
|
||||||
|
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;
|
||||||
private final IAEItemStack[] condensedOutputs;
|
private final IAEItemStack[] condensedOutputs;
|
||||||
private final IAEItemStack[] inputs;
|
private final IAEItemStack[] inputs;
|
||||||
private final IAEItemStack[] outputs;
|
private final IAEItemStack[] outputs;
|
||||||
|
private final Map<Integer, List<IAEItemStack>> substituteInputs;
|
||||||
private final boolean isCrafting;
|
private final boolean isCrafting;
|
||||||
private final boolean canSubstitute;
|
private final boolean canSubstitute;
|
||||||
private final Set<TestLookup> failCache = new HashSet<>();
|
private final Set<TestLookup> failCache = new HashSet<>();
|
||||||
@@ -80,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 );
|
||||||
@@ -143,9 +149,11 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
final int outputLength = out.size();
|
||||||
|
|
||||||
this.outputs = out.toArray( new IAEItemStack[out.size()] );
|
this.inputs = in.toArray( new IAEItemStack[isCrafting ? CRAFTING_INPUT_LIMIT : PROCESSING_INPUT_LIMIT] );
|
||||||
this.inputs = in.toArray( new IAEItemStack[in.size()] );
|
this.outputs = out.toArray( new IAEItemStack[outputLength] );
|
||||||
|
this.substituteInputs = new HashMap<>( CRAFTING_INPUT_LIMIT );
|
||||||
|
|
||||||
final Map<IAEItemStack, IAEItemStack> tmpOutputs = new HashMap<>();
|
final Map<IAEItemStack, IAEItemStack> tmpOutputs = new HashMap<>();
|
||||||
|
|
||||||
@@ -257,6 +265,14 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
|||||||
|
|
||||||
this.testFrame.setInventorySlotContents( slotIndex, i );
|
this.testFrame.setInventorySlotContents( slotIndex, i );
|
||||||
|
|
||||||
|
// If we cannot substitute, the items must match exactly
|
||||||
|
if (!canSubstitute && slotIndex < inputs.length) {
|
||||||
|
if (!inputs[slotIndex].isSameType(i)) {
|
||||||
|
this.markItemAs(slotIndex, i, TestStatus.DECLINE);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( this.standardRecipe.matches( this.testFrame, w ) )
|
if( this.standardRecipe.matches( this.testFrame, w ) )
|
||||||
{
|
{
|
||||||
final ItemStack testOutput = this.standardRecipe.getCraftingResult( this.testFrame );
|
final ItemStack testOutput = this.standardRecipe.getCraftingResult( this.testFrame );
|
||||||
@@ -268,25 +284,6 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( AEConfig.instance().isFeatureEnabled( AEFeature.CRAFTING_MANAGER_FALLBACK ) )
|
|
||||||
{
|
|
||||||
final ItemStack testOutput = CraftingManager.findMatchingResult( this.testFrame, w );
|
|
||||||
|
|
||||||
if( Platform.itemComparisons().isSameItem( this.correctOutput, testOutput ) )
|
|
||||||
{
|
|
||||||
this.testFrame.setInventorySlotContents( slotIndex, this.crafting.getStackInSlot( slotIndex ) );
|
|
||||||
this.markItemAs( slotIndex, i, TestStatus.ACCEPT );
|
|
||||||
|
|
||||||
if( AELog.isCraftingDebugLogEnabled() )
|
|
||||||
{
|
|
||||||
this.warnAboutCraftingManager( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.warnAboutCraftingManager( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
this.markItemAs( slotIndex, i, TestStatus.DECLINE );
|
this.markItemAs( slotIndex, i, TestStatus.DECLINE );
|
||||||
return false;
|
return false;
|
||||||
@@ -328,6 +325,97 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
|||||||
return this.canSubstitute;
|
return this.canSubstitute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IAEItemStack> getSubstituteInputs(int slot) {
|
||||||
|
if (this.inputs[slot] == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.substituteInputs.computeIfAbsent(slot, value -> {
|
||||||
|
ItemStack[] matchingStacks = getRecipeIngredient(slot).getMatchingStacks();
|
||||||
|
List<IAEItemStack> itemList = new ArrayList<>(matchingStacks.length + 1);
|
||||||
|
for (ItemStack matchingStack : matchingStacks) {
|
||||||
|
itemList.add(AEItemStack.fromItemStack(matchingStack));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that the specific item put in by the user is at the beginning,
|
||||||
|
// so that it takes precedence over substitutions
|
||||||
|
itemList.add(0, this.inputs[slot]);
|
||||||
|
return itemList;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link Ingredient} from the actual used recipe for a given slot-index into {@link #getInputs()}.
|
||||||
|
* <p/>
|
||||||
|
* Conversion is needed for two reasons: our sparse ingredients are always organized in a 3x3 grid, while Vanilla's
|
||||||
|
* ingredient list will be condensed to the actual recipe's grid size. In addition, in our 3x3 grid, the user can
|
||||||
|
* shift the actual recipe input to the right and down.
|
||||||
|
*/
|
||||||
|
private Ingredient getRecipeIngredient(int slot) {
|
||||||
|
|
||||||
|
if (standardRecipe instanceof IShapedRecipe ) {
|
||||||
|
IShapedRecipe shapedRecipe = (IShapedRecipe) standardRecipe;
|
||||||
|
|
||||||
|
return getShapedRecipeIngredient(slot, shapedRecipe.getRecipeWidth());
|
||||||
|
} else {
|
||||||
|
return getShapelessRecipeIngredient(slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Ingredient getShapedRecipeIngredient(int slot, int recipeWidth) {
|
||||||
|
// Compute the offset of the user's input vs. crafting grid origin
|
||||||
|
// Which is >0 if they have empty rows above or to the left of their input
|
||||||
|
int topOffset = 0;
|
||||||
|
if (inputs[0] == null && inputs[1] == null && inputs[2] == null) {
|
||||||
|
topOffset++; // First row is fully empty
|
||||||
|
if (inputs[3] == null && inputs[4] == null && inputs[5] == null) {
|
||||||
|
topOffset++; // Second row is fully empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int leftOffset = 0;
|
||||||
|
if (inputs[0] == null && inputs[3] == null && inputs[6] == null) {
|
||||||
|
leftOffset++; // First column is fully empty
|
||||||
|
if (inputs[1] == null && inputs[4] == null && inputs[7] == null) {
|
||||||
|
leftOffset++; // Second column is fully empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the x,y of the slot, as-if the recipe was anchored to 0,0
|
||||||
|
int slotX = slot % CRAFTING_GRID_DIMENSION - leftOffset;
|
||||||
|
int slotY = slot / CRAFTING_GRID_DIMENSION - topOffset;
|
||||||
|
|
||||||
|
// Compute the index into the recipe's ingredient list now
|
||||||
|
int ingredientIndex = slotY * recipeWidth + slotX;
|
||||||
|
|
||||||
|
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
|
||||||
|
|
||||||
|
if (ingredientIndex < 0 || ingredientIndex > ingredients.size()) {
|
||||||
|
return Ingredient.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ingredients.get(ingredientIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Ingredient getShapelessRecipeIngredient(int slot) {
|
||||||
|
// We map the list of *filled* sparse inputs to the shapeless (ergo unordered)
|
||||||
|
// ingredients. While these do not actually correspond to each other,
|
||||||
|
// since both lists have the same length, the mapping is at least stable.
|
||||||
|
int ingredientIndex = 0;
|
||||||
|
for (int i = 0; i < slot; i++) {
|
||||||
|
if (inputs[i] != null) {
|
||||||
|
ingredientIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
|
||||||
|
if (ingredientIndex < ingredients.size()) {
|
||||||
|
return ingredients.get(ingredientIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ingredient.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getOutput( final InventoryCrafting craftingInv, final World w )
|
public ItemStack getOutput( final InventoryCrafting craftingInv, final World w )
|
||||||
{
|
{
|
||||||
@@ -406,24 +494,6 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
|||||||
return this.pattern.hashCode();
|
return this.pattern.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void warnAboutCraftingManager( boolean foundAlternative )
|
|
||||||
{
|
|
||||||
final String foundAlternativeRecipe = foundAlternative ? "Found alternative recipe." : "NOT FOUND, please report.";
|
|
||||||
|
|
||||||
final StringJoiner joinActualInputs = new StringJoiner( ", " );
|
|
||||||
for( int j = 0; j < this.testFrame.getSizeInventory(); j++ )
|
|
||||||
{
|
|
||||||
final ItemStack stack = this.testFrame.getStackInSlot( j );
|
|
||||||
if( !stack.isEmpty() )
|
|
||||||
{
|
|
||||||
joinActualInputs.add( stack.toString() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AELog.warn( "Using CraftingManager fallback: Recipe <%s> for output <%s> rejected inputs [%s]. %s",
|
|
||||||
this.standardRecipe.getRegistryName(), this.standardRecipe.getRecipeOutput(), joinActualInputs, foundAlternativeRecipe );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals( final Object obj )
|
public boolean equals( final Object obj )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -187,20 +187,15 @@ public class TickHandler
|
|||||||
if( ev.type == Type.WORLD && ev.phase == Phase.END )
|
if( ev.type == Type.WORLD && ev.phase == Phase.END )
|
||||||
{
|
{
|
||||||
final WorldTickEvent wte = (WorldTickEvent) ev;
|
final WorldTickEvent wte = (WorldTickEvent) ev;
|
||||||
synchronized( this.craftingJobs )
|
synchronized ( this.craftingJobs )
|
||||||
{
|
{
|
||||||
final Collection<CraftingJob> jobSet = this.craftingJobs.get( wte.world );
|
final Collection<CraftingJob> jobSet = this.craftingJobs.get( wte.world );
|
||||||
if( !jobSet.isEmpty() )
|
if (!jobSet.isEmpty()) {
|
||||||
{
|
final int jobSize = jobSet.size();
|
||||||
final Iterator<CraftingJob> i = jobSet.iterator();
|
final int microSecondsPerTick = AEConfig.instance().getCraftingCalculationTimePerTick() * 1000;
|
||||||
while( i.hasNext() )
|
final int simTime = Math.max(1, microSecondsPerTick / jobSize);
|
||||||
{
|
|
||||||
final CraftingJob cj = i.next();
|
jobSet.removeIf( cj -> !cj.simulateFor( simTime ) );
|
||||||
if( !cj.simulateFor() )
|
|
||||||
{
|
|
||||||
i.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 )
|
||||||
|
|||||||
@@ -147,8 +147,12 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// prefer pure crystals.
|
// prefer pure crystals.
|
||||||
for( ItemStack stack : ingredient.getAllIngredients() )
|
for ( ItemStack stack : ingredient.getAllIngredients() )
|
||||||
{
|
{
|
||||||
|
if( stack == null )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if( Platform.isRecipePrioritized( stack ) )
|
if( Platform.isRecipePrioritized( stack ) )
|
||||||
{
|
{
|
||||||
list.add( 0, stack );
|
list.add( 0, stack );
|
||||||
@@ -159,7 +163,7 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for( final ItemStack is : list )
|
for ( final ItemStack is : list )
|
||||||
{
|
{
|
||||||
final NBTTagCompound tag = new NBTTagCompound();
|
final NBTTagCompound tag = new NBTTagCompound();
|
||||||
is.writeToNBT( tag );
|
is.writeToNBT( tag );
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|
||||||
|
|||||||
+29
-5
@@ -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 )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -164,6 +164,8 @@ public final class ItemMaterial extends AEBaseItem implements IStorageComponent,
|
|||||||
return Upgrades.INVERTER;
|
return Upgrades.INVERTER;
|
||||||
case CARD_CRAFTING:
|
case CARD_CRAFTING:
|
||||||
return Upgrades.CRAFTING;
|
return Upgrades.CRAFTING;
|
||||||
|
case CARD_PATTERN_EXPANSION:
|
||||||
|
return Upgrades.PATTERN_EXPANSION;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,10 @@ public enum MaterialType
|
|||||||
FLUID_CELL1K_PART( 54, "material_fluid_cell1k_part", EnumSet.of( AEFeature.STORAGE_CELLS ) ),
|
FLUID_CELL1K_PART( 54, "material_fluid_cell1k_part", EnumSet.of( AEFeature.STORAGE_CELLS ) ),
|
||||||
FLUID_CELL4K_PART( 55, "material_fluid_cell4k_part", EnumSet.of( AEFeature.STORAGE_CELLS ) ),
|
FLUID_CELL4K_PART( 55, "material_fluid_cell4k_part", EnumSet.of( AEFeature.STORAGE_CELLS ) ),
|
||||||
FLUID_CELL16K_PART( 56, "material_fluid_cell16k_part", EnumSet.of( AEFeature.STORAGE_CELLS ) ),
|
FLUID_CELL16K_PART( 56, "material_fluid_cell16k_part", EnumSet.of( AEFeature.STORAGE_CELLS ) ),
|
||||||
FLUID_CELL64K_PART( 57, "material_fluid_cell64k_part", EnumSet.of( AEFeature.STORAGE_CELLS ) );
|
FLUID_CELL64K_PART( 57, "material_fluid_cell64k_part", EnumSet.of( AEFeature.STORAGE_CELLS ) ),
|
||||||
|
|
||||||
|
CARD_PATTERN_EXPANSION( 58, "material_card_pattern_expansion", EnumSet.of( AEFeature.ADVANCED_CARDS ) );
|
||||||
|
|
||||||
|
|
||||||
private final Set<AEFeature> features;
|
private final Set<AEFeature> features;
|
||||||
private final ModelResourceLocation model;
|
private final ModelResourceLocation model;
|
||||||
|
|||||||
@@ -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 )
|
||||||
|
|||||||
@@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -633,10 +640,10 @@ public class GridNode implements IGridNode, IPathItem
|
|||||||
this.usedChannels = 0;
|
this.usedChannels = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int idx = this.connections.indexOf( fast );
|
final int idx = this.connections.indexOf( (IGridConnection) fast );
|
||||||
if( idx > 0 )
|
if( idx > 0 )
|
||||||
{
|
{
|
||||||
this.connections.remove( fast );
|
this.connections.remove( (IGridConnection) fast );
|
||||||
this.connections.add( 0, (IGridConnection) fast );
|
this.connections.add( 0, (IGridConnection) fast );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+61
-16
@@ -30,7 +30,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
@@ -42,6 +41,7 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.*;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
import appeng.api.AEApi;
|
||||||
@@ -105,8 +105,8 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
|||||||
private final Set<ICraftingProvider> craftingProviders = new HashSet<>();
|
private final Set<ICraftingProvider> craftingProviders = new HashSet<>();
|
||||||
private final Map<IGridNode, ICraftingWatcher> craftingWatchers = new HashMap<>();
|
private final Map<IGridNode, ICraftingWatcher> craftingWatchers = new HashMap<>();
|
||||||
private final IGrid grid;
|
private final IGrid grid;
|
||||||
private final Map<ICraftingPatternDetails, List<ICraftingMedium>> craftingMethods = new HashMap<>();
|
private final Object2ObjectMap<ICraftingPatternDetails, List<ICraftingMedium>> craftingMethods = new Object2ObjectOpenHashMap<>();
|
||||||
private final Map<IAEItemStack, ImmutableList<ICraftingPatternDetails>> craftableItems = new HashMap<>();
|
private final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> craftableItems = new Object2ObjectOpenHashMap<>();
|
||||||
private final Set<IAEItemStack> emitableItems = new HashSet<>();
|
private final Set<IAEItemStack> emitableItems = new HashSet<>();
|
||||||
private final Map<String, CraftingLinkNexus> craftingLinks = new HashMap<>();
|
private final Map<String, CraftingLinkNexus> craftingLinks = new HashMap<>();
|
||||||
private final Multimap<IAEStack, CraftingWatcher> interests = HashMultimap.create();
|
private final Multimap<IAEStack, CraftingWatcher> interests = HashMultimap.create();
|
||||||
@@ -160,11 +160,11 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
|||||||
{
|
{
|
||||||
if( machine instanceof ICraftingWatcherHost )
|
if( machine instanceof ICraftingWatcherHost )
|
||||||
{
|
{
|
||||||
final ICraftingWatcher craftingWatcher = this.craftingWatchers.get( machine );
|
final ICraftingWatcher craftingWatcher = this.craftingWatchers.get( gridNode );
|
||||||
if( craftingWatcher != null )
|
if( craftingWatcher != null )
|
||||||
{
|
{
|
||||||
craftingWatcher.reset();
|
craftingWatcher.reset();
|
||||||
this.craftingWatchers.remove( machine );
|
this.craftingWatchers.remove( gridNode );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,24 +270,21 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Map<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = 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();
|
||||||
this.craftableItems.clear();
|
this.craftableItems.clear();
|
||||||
this.emitableItems.clear();
|
this.emitableItems.clear();
|
||||||
|
|
||||||
// update the stuff that was in the list...
|
|
||||||
this.storageGrid.postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), oldItems.keySet(),
|
|
||||||
new BaseActionSource() );
|
|
||||||
|
|
||||||
// re-create list..
|
// re-create list..
|
||||||
for( final ICraftingProvider provider : this.craftingProviders )
|
for( final ICraftingProvider provider : this.craftingProviders )
|
||||||
{
|
{
|
||||||
provider.provideCrafting( this );
|
provider.provideCrafting( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
final Map<IAEItemStack, Set<ICraftingPatternDetails>> tmpCraft = new HashMap<>();
|
final Object2ObjectMap<IAEItemStack, ObjectSet<ICraftingPatternDetails>> tmpCraft = new Object2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
// new craftables!
|
// new craftables!
|
||||||
for( final ICraftingPatternDetails details : this.craftingMethods.keySet() )
|
for( final ICraftingPatternDetails details : this.craftingMethods.keySet() )
|
||||||
@@ -298,11 +295,11 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
|||||||
out.reset();
|
out.reset();
|
||||||
out.setCraftable( true );
|
out.setCraftable( true );
|
||||||
|
|
||||||
Set<ICraftingPatternDetails> methods = tmpCraft.get( out );
|
ObjectSet<ICraftingPatternDetails> methods = tmpCraft.get( out );
|
||||||
|
|
||||||
if( methods == null )
|
if( methods == null )
|
||||||
{
|
{
|
||||||
tmpCraft.put( out, methods = new TreeSet<>( COMPARATOR ) );
|
tmpCraft.put( out, methods = new ObjectRBTreeSet<>( COMPARATOR ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
methods.add( details );
|
methods.add( details );
|
||||||
@@ -310,12 +307,56 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make them immutable
|
// make them immutable
|
||||||
for( final Entry<IAEItemStack, Set<ICraftingPatternDetails>> e : tmpCraft.entrySet() )
|
for( final Entry<IAEItemStack, ObjectSet<ICraftingPatternDetails>> e : tmpCraft.entrySet() )
|
||||||
{
|
{
|
||||||
this.craftableItems.put( e.getKey(), ImmutableList.copyOf( e.getValue() ) );
|
this.craftableItems.put( e.getKey(), ImmutableList.copyOf( e.getValue() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
this.storageGrid.postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), this.craftableItems.keySet(),
|
Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> craftablesChanged = new Object2ObjectArrayMap<>();
|
||||||
|
|
||||||
|
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> i = oldItems.entrySet();
|
||||||
|
for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : i) {
|
||||||
|
if (!this.craftableItems.containsKey( ais.getKey() )) {
|
||||||
|
IAEItemStack changedStack = ais.getKey().copy();
|
||||||
|
changedStack.reset();
|
||||||
|
changedStack.setCraftable( false );
|
||||||
|
craftablesChanged.put( changedStack, ais.getValue() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> j = this.craftableItems.entrySet();
|
||||||
|
for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : j) {
|
||||||
|
if (!oldItems.containsKey( ais )){
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.storageGrid.postCraftablesChanges( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), craftablesChanged.keySet(),
|
||||||
new BaseActionSource() );
|
new BaseActionSource() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,7 +676,11 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
|||||||
|
|
||||||
public boolean hasCpu( final ICraftingCPU cpu )
|
public boolean hasCpu( final ICraftingCPU cpu )
|
||||||
{
|
{
|
||||||
return this.craftingCPUClusters.contains( cpu );
|
if (cpu instanceof CraftingCPUCluster)
|
||||||
|
{
|
||||||
|
return this.craftingCPUClusters.contains( (CraftingCPUCluster) cpu );
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GenericInterestManager<CraftingWatcher> getInterestManager()
|
public GenericInterestManager<CraftingWatcher> getInterestManager()
|
||||||
|
|||||||
+176
-40
@@ -30,6 +30,7 @@ import java.util.PriorityQueue;
|
|||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.HashMultiset;
|
import com.google.common.collect.HashMultiset;
|
||||||
import com.google.common.collect.Multiset;
|
import com.google.common.collect.Multiset;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
@@ -63,12 +64,10 @@ import appeng.me.energy.EnergyWatcher;
|
|||||||
public class EnergyGridCache implements IEnergyGrid
|
public class EnergyGridCache implements IEnergyGrid
|
||||||
{
|
{
|
||||||
|
|
||||||
private static final double MAX_BUFFER_STORAGE = 200;
|
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 );
|
||||||
|
|
||||||
@@ -76,9 +75,24 @@ public class EnergyGridCache implements IEnergyGrid
|
|||||||
};
|
};
|
||||||
|
|
||||||
private final NavigableSet<EnergyThreshold> interests = Sets.newTreeSet();
|
private final NavigableSet<EnergyThreshold> interests = Sets.newTreeSet();
|
||||||
|
|
||||||
|
// Should only be modified from the add/remove methods below to guard against
|
||||||
|
// concurrent modifications
|
||||||
private final double averageLength = 40.0;
|
private final double averageLength = 40.0;
|
||||||
private final Set<IAEPowerStorage> providers = new LinkedHashSet<>();
|
private final Set<IAEPowerStorage> providers = new LinkedHashSet<>();
|
||||||
|
// Used to track whether an extraction is currently in progress, to fail fast
|
||||||
|
// when something externally
|
||||||
|
// modifies the energy grid.
|
||||||
|
private boolean ongoingExtractOperation = false;
|
||||||
|
|
||||||
|
// Should only be modified from the add/remove methods below to guard against
|
||||||
|
// concurrent modifications
|
||||||
private final Set<IAEPowerStorage> requesters = new LinkedHashSet<>();
|
private final Set<IAEPowerStorage> requesters = new LinkedHashSet<>();
|
||||||
|
// Used to track whether an injection is currently in progress, to fail fast
|
||||||
|
// when something externally
|
||||||
|
// modifies the energy grid.
|
||||||
|
private boolean ongoingInjectOperation = false;
|
||||||
|
|
||||||
private final Multiset<IEnergyGridProvider> energyGridProviders = HashMultiset.create();
|
private final Multiset<IEnergyGridProvider> energyGridProviders = HashMultiset.create();
|
||||||
private final IGrid myGrid;
|
private final IGrid myGrid;
|
||||||
private final HashMap<IGridNode, IEnergyWatcher> watchers = new HashMap<>();
|
private final HashMap<IGridNode, IEnergyWatcher> watchers = new HashMap<>();
|
||||||
@@ -110,6 +124,10 @@ 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> providerToRemove = new HashSet<>();
|
||||||
|
private Set<IAEPowerStorage> requesterToRemove = new HashSet<>();
|
||||||
|
private Set<IAEPowerStorage> providersToAdd = new HashSet<>();
|
||||||
|
private Set<IAEPowerStorage> requesterToAdd = new HashSet<>();
|
||||||
|
|
||||||
public EnergyGridCache( final IGrid g )
|
public EnergyGridCache( final IGrid g )
|
||||||
{
|
{
|
||||||
@@ -143,20 +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 )
|
||||||
{
|
{
|
||||||
this.providers.add( ev.storage );
|
addProvider( ev.storage );
|
||||||
}
|
}
|
||||||
break;
|
else
|
||||||
case REQUEST_POWER:
|
|
||||||
if( ev.storage.getPowerFlow() != AccessRestriction.READ )
|
|
||||||
{
|
{
|
||||||
this.requesters.add( ev.storage );
|
this.providersToAdd.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
|
||||||
@@ -301,19 +332,56 @@ public class EnergyGridCache implements IEnergyGrid
|
|||||||
{
|
{
|
||||||
double extractedPower = 0;
|
double extractedPower = 0;
|
||||||
|
|
||||||
|
this.providers.addAll( providersToAdd );
|
||||||
|
providersToAdd.clear();
|
||||||
|
providers.removeIf( providerToRemove::contains );
|
||||||
|
this.providerToRemove.clear();
|
||||||
|
|
||||||
final Iterator<IAEPowerStorage> it = this.providers.iterator();
|
final Iterator<IAEPowerStorage> it = this.providers.iterator();
|
||||||
|
|
||||||
while( extractedPower < amt && it.hasNext() )
|
ongoingExtractOperation = true;
|
||||||
|
boolean ls = false;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
final IAEPowerStorage node = it.next();
|
while ( extractedPower < amt && it.hasNext() )
|
||||||
|
|
||||||
final double req = amt - extractedPower;
|
|
||||||
final double newPower = node.extractAEPower( req, mode, PowerMultiplier.ONE );
|
|
||||||
extractedPower += newPower;
|
|
||||||
|
|
||||||
if( newPower < req && mode == Actionable.MODULATE )
|
|
||||||
{
|
{
|
||||||
it.remove();
|
final IAEPowerStorage node = it.next();
|
||||||
|
if( node != null )
|
||||||
|
{
|
||||||
|
if( node == localStorage && mode == Actionable.MODULATE )
|
||||||
|
{
|
||||||
|
ls = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final double req = amt - extractedPower;
|
||||||
|
final double newPower = node.extractAEPower( req, mode, PowerMultiplier.ONE );
|
||||||
|
extractedPower += newPower;
|
||||||
|
|
||||||
|
if( newPower < req && mode == Actionable.MODULATE )
|
||||||
|
{
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,17 +406,37 @@ public class EnergyGridCache implements IEnergyGrid
|
|||||||
{
|
{
|
||||||
final double originalAmount = amt;
|
final double originalAmount = amt;
|
||||||
|
|
||||||
|
this.requesters.addAll( requesterToAdd );
|
||||||
|
requesterToAdd.clear();
|
||||||
|
requesters.removeIf( requesterToRemove::contains );
|
||||||
|
this.requesterToRemove.clear();
|
||||||
|
|
||||||
final Iterator<IAEPowerStorage> it = this.requesters.iterator();
|
final Iterator<IAEPowerStorage> it = this.requesters.iterator();
|
||||||
|
|
||||||
while( amt > 0 && it.hasNext() )
|
ongoingInjectOperation = true;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
final IAEPowerStorage node = it.next();
|
while ( amt > 0 && it.hasNext() )
|
||||||
amt = node.injectAEPower( amt, mode );
|
|
||||||
|
|
||||||
if( amt > 0 && mode == Actionable.MODULATE )
|
|
||||||
{
|
{
|
||||||
it.remove();
|
final IAEPowerStorage node = it.next();
|
||||||
|
|
||||||
|
if( node != null )
|
||||||
|
{
|
||||||
|
amt = node.injectAEPower( amt, mode );
|
||||||
|
|
||||||
|
if( amt > 0 && mode == Actionable.MODULATE )
|
||||||
|
{
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
ongoingInjectOperation = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final double overflow = Math.max( 0.0, amt );
|
final double overflow = Math.max( 0.0, amt );
|
||||||
@@ -367,7 +455,7 @@ public class EnergyGridCache implements IEnergyGrid
|
|||||||
double required = 0;
|
double required = 0;
|
||||||
|
|
||||||
final Iterator<IAEPowerStorage> it = this.requesters.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 )
|
||||||
@@ -428,11 +516,7 @@ public class EnergyGridCache implements IEnergyGrid
|
|||||||
@Override
|
@Override
|
||||||
public double getStoredPower()
|
public double getStoredPower()
|
||||||
{
|
{
|
||||||
if( this.availableTicksSinceUpdate > 90 )
|
this.refreshPower();
|
||||||
{
|
|
||||||
this.refreshPower();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Math.max( 0.0, this.globalAvailablePower );
|
return Math.max( 0.0, this.globalAvailablePower );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,9 +589,22 @@ public class EnergyGridCache implements IEnergyGrid
|
|||||||
this.globalMaxPower -= ps.getAEMaxPower();
|
this.globalMaxPower -= ps.getAEMaxPower();
|
||||||
this.globalAvailablePower -= ps.getAECurrentPower();
|
this.globalAvailablePower -= ps.getAECurrentPower();
|
||||||
}
|
}
|
||||||
|
if( !ongoingExtractOperation )
|
||||||
this.providers.remove( ps );
|
{
|
||||||
this.requesters.remove( ps );
|
removeProvider( ps );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.providerToRemove.add( ps );
|
||||||
|
}
|
||||||
|
if( !ongoingInjectOperation )
|
||||||
|
{
|
||||||
|
removeRequester( ps );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.requesterToRemove.add( ps );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,6 +620,31 @@ public class EnergyGridCache implements IEnergyGrid
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addRequester( IAEPowerStorage requester )
|
||||||
|
{
|
||||||
|
Preconditions.checkState( !ongoingInjectOperation, "Cannot modify energy requesters while energy is being injected." );
|
||||||
|
this.requesters.add( requester );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeRequester( IAEPowerStorage requester )
|
||||||
|
{
|
||||||
|
Preconditions.checkState( !ongoingInjectOperation, "Cannot modify energy requesters while energy is being injected." );
|
||||||
|
this.requesters.remove( requester );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addProvider( IAEPowerStorage provider )
|
||||||
|
{
|
||||||
|
Preconditions.checkState( !ongoingExtractOperation, "Cannot modify energy providers while energy is being extracted." );
|
||||||
|
this.providers.add( 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 )
|
||||||
{
|
{
|
||||||
@@ -554,12 +676,26 @@ public class EnergyGridCache implements IEnergyGrid
|
|||||||
if( current > 0 && ps.getPowerFlow() != AccessRestriction.WRITE )
|
if( current > 0 && ps.getPowerFlow() != AccessRestriction.WRITE )
|
||||||
{
|
{
|
||||||
this.globalAvailablePower += current;
|
this.globalAvailablePower += current;
|
||||||
this.providers.add( ps );
|
if( !ongoingExtractOperation )
|
||||||
|
{
|
||||||
|
addProvider( ps );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.providersToAdd.add( ps );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( current < max && ps.getPowerFlow() != AccessRestriction.READ )
|
if( current < max && ps.getPowerFlow() != AccessRestriction.READ )
|
||||||
{
|
{
|
||||||
this.requesters.add( ps );
|
if( !ongoingInjectOperation )
|
||||||
|
{
|
||||||
|
addRequester( ps );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.requesterToAdd.add( ps );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-10
@@ -94,19 +94,19 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( machine instanceof IStackWatcherHost )
|
if( machine instanceof IStackWatcherHost )
|
||||||
{
|
{
|
||||||
final IStackWatcher myWatcher = this.watchers.get( machine );
|
final IStackWatcher myWatcher = this.watchers.get( node );
|
||||||
|
|
||||||
if( myWatcher != null )
|
if( myWatcher != null )
|
||||||
{
|
{
|
||||||
myWatcher.reset();
|
myWatcher.reset();
|
||||||
this.watchers.remove( machine );
|
this.watchers.remove( node );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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,10 +246,9 @@ public class GridStorageCache implements IStorageGrid
|
|||||||
this.removeCellProvider( cc, tracker );
|
this.removeCellProvider( cc, tracker );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.forceUpdate() );
|
|
||||||
|
|
||||||
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 )
|
||||||
@@ -281,6 +279,12 @@ public class GridStorageCache implements IStorageGrid
|
|||||||
this.storageMonitors.get( chan ).postChange( true, (Iterable) input, src );
|
this.storageMonitors.get( chan ).postChange( true, (Iterable) input, src );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postCraftablesChanges( IStorageChannel<?> chan, Iterable<? extends IAEStack<?>> input, IActionSource src )
|
||||||
|
{
|
||||||
|
this.storageMonitors.get( chan ).updateCraftables( (Iterable) input, src );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerCellProvider( final ICellProvider provider )
|
public void registerCellProvider( final ICellProvider provider )
|
||||||
{
|
{
|
||||||
@@ -324,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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+139
-100
@@ -19,20 +19,9 @@
|
|||||||
package appeng.me.cache;
|
package appeng.me.cache;
|
||||||
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Deque;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
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 com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.Queues;
|
|
||||||
|
|
||||||
import appeng.api.config.AccessRestriction;
|
import appeng.api.config.AccessRestriction;
|
||||||
import appeng.api.config.Actionable;
|
import appeng.api.config.Actionable;
|
||||||
import appeng.api.networking.events.MENetworkStorageEvent;
|
import appeng.api.networking.events.MENetworkStorageEvent;
|
||||||
@@ -41,17 +30,26 @@ import appeng.api.storage.IMEInventoryHandler;
|
|||||||
import appeng.api.storage.IMEMonitor;
|
import appeng.api.storage.IMEMonitor;
|
||||||
import appeng.api.storage.IMEMonitorHandlerReceiver;
|
import appeng.api.storage.IMEMonitorHandlerReceiver;
|
||||||
import appeng.api.storage.IStorageChannel;
|
import appeng.api.storage.IStorageChannel;
|
||||||
|
import appeng.api.storage.channels.IFluidStorageChannel;
|
||||||
|
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 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.*;
|
||||||
|
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;
|
||||||
@@ -63,9 +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;
|
||||||
private boolean hasChanged = false;
|
private long gridItemCount;
|
||||||
@Nonnegative
|
private long gridFluidCount;
|
||||||
private int localDepthSemaphore = 0;
|
public boolean forceUpdate;
|
||||||
|
|
||||||
public NetworkMonitor( final GridStorageCache cache, final IStorageChannel<T> chan )
|
public NetworkMonitor( final GridStorageCache cache, final IStorageChannel<T> chan )
|
||||||
{
|
{
|
||||||
@@ -90,21 +88,7 @@ public class NetworkMonitor<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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
this.localDepthSemaphore++;
|
|
||||||
final T leftover = this.getHandler().extractItems( request, mode, src );
|
|
||||||
this.localDepthSemaphore--;
|
|
||||||
|
|
||||||
if( this.localDepthSemaphore == 0 )
|
|
||||||
{
|
|
||||||
this.monitorDifference( request.copy(), leftover, true, src );
|
|
||||||
}
|
|
||||||
|
|
||||||
return leftover;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -137,38 +121,42 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
|
|||||||
return this.getHandler().getSlot();
|
return this.getHandler().getSlot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getGridCurrentCount()
|
||||||
|
{
|
||||||
|
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
||||||
|
{
|
||||||
|
return gridItemCount;
|
||||||
|
}
|
||||||
|
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
|
||||||
|
{
|
||||||
|
return gridFluidCount;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incGridCurrentCount( long count )
|
||||||
|
{
|
||||||
|
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
||||||
|
{
|
||||||
|
gridItemCount += count;
|
||||||
|
}
|
||||||
|
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
|
||||||
|
{
|
||||||
|
gridFluidCount += count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public IItemList<T> getStorageList()
|
public IItemList<T> getStorageList()
|
||||||
{
|
{
|
||||||
if( hasChanged )
|
|
||||||
{
|
|
||||||
hasChanged = false;
|
|
||||||
this.cachedList.resetStatus();
|
|
||||||
return this.getAvailableItems( this.cachedList );
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.cachedList;
|
return this.cachedList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
this.localDepthSemaphore++;
|
|
||||||
final T leftover = this.getHandler().injectItems( input, mode, src );
|
|
||||||
this.localDepthSemaphore--;
|
|
||||||
|
|
||||||
if( this.localDepthSemaphore == 0 )
|
|
||||||
{
|
|
||||||
this.monitorDifference( input.copy(), leftover, false, src );
|
|
||||||
}
|
|
||||||
|
|
||||||
return leftover;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -200,36 +188,15 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
|
|||||||
return this.listeners.entrySet().iterator();
|
return this.listeners.entrySet().iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
private T monitorDifference( final IAEStack<T> original, final T leftOvers, final boolean extraction, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void notifyListenersOfChange( final Iterable<T> diff, final IActionSource src )
|
private void notifyListenersOfChange( final Iterable<T> diff, final IActionSource src )
|
||||||
{
|
{
|
||||||
this.hasChanged = true;
|
|
||||||
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
|
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
|
||||||
|
|
||||||
while( i.hasNext() )
|
while( i.hasNext() )
|
||||||
{
|
{
|
||||||
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 );
|
||||||
@@ -241,46 +208,57 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void postChangesToListeners( final Iterable<T> changes, final IActionSource src )
|
protected void updateCraftables( Iterable<T> input, IActionSource src )
|
||||||
{
|
{
|
||||||
this.postChange( true, changes, src );
|
for( final T changedItem : input )
|
||||||
|
{
|
||||||
|
if (changedItem.isCraftable()) {
|
||||||
|
this.cachedList.add( changedItem );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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( this.localDepthSemaphore > 0 || 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.localDepthSemaphore++;
|
|
||||||
|
|
||||||
this.sendEvent = true;
|
this.sendEvent = true;
|
||||||
|
|
||||||
this.notifyListenersOfChange( changes, src );
|
for( final T change : changes )
|
||||||
|
|
||||||
for( final T changedItem : changes )
|
|
||||||
{
|
{
|
||||||
T difference = changedItem;
|
//T change = changed;
|
||||||
|
if( !add && change != null )
|
||||||
if( !add && changedItem != null )
|
|
||||||
{
|
{
|
||||||
difference = changedItem.copy();
|
//change = changed.copy();
|
||||||
difference.setStackSize( -changedItem.getStackSize() );
|
change.setStackSize( -change.getStackSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( this.myGridCache.getInterestManager().containsKey( changedItem ) )
|
incGridCurrentCount( change.getStackSize() );
|
||||||
|
this.cachedList.addStorage( change );
|
||||||
|
|
||||||
|
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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,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, difference, src, this.getChannel() );
|
iw.getHost().onStackChange( this.getStorageList(), fullStack, change, src, this.getChannel() );
|
||||||
}
|
}
|
||||||
|
|
||||||
this.myGridCache.getInterestManager().disableTransactions();
|
this.myGridCache.getInterestManager().disableTransactions();
|
||||||
@@ -296,21 +274,78 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final NetworkMonitor<?> last = GLOBAL_DEPTH.pop();
|
this.notifyListenersOfChange( changes, src );
|
||||||
this.localDepthSemaphore--;
|
|
||||||
|
|
||||||
if( last != this )
|
if( src2MonitorsMap.get( src ).getFirst() == 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()
|
void forceUpdate()
|
||||||
{
|
{
|
||||||
this.hasChanged = true;
|
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();
|
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
|
||||||
while( i.hasNext() )
|
while ( i.hasNext() )
|
||||||
{
|
{
|
||||||
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();
|
||||||
@@ -328,6 +363,10 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
|
|||||||
|
|
||||||
void onTick()
|
void onTick()
|
||||||
{
|
{
|
||||||
|
if( forceUpdate )
|
||||||
|
{
|
||||||
|
forceUpdate();
|
||||||
|
}
|
||||||
if( this.sendEvent )
|
if( this.sendEvent )
|
||||||
{
|
{
|
||||||
this.sendEvent = false;
|
this.sendEvent = false;
|
||||||
|
|||||||
+56
-17
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -314,7 +314,7 @@ public class PathGridCache implements IPathingGrid
|
|||||||
int depth = 0;
|
int depth = 0;
|
||||||
for( final IGridNode nodes : this.requireChannels )
|
for( final IGridNode nodes : this.requireChannels )
|
||||||
{
|
{
|
||||||
if( !this.semiOpen.contains( nodes ) )
|
if( !this.semiOpen.contains( (IPathItem) nodes ) )
|
||||||
{
|
{
|
||||||
final IGridBlock gb = nodes.getGridBlock();
|
final IGridBlock gb = nodes.getGridBlock();
|
||||||
final EnumSet<GridFlags> flags = gb.getFlags();
|
final EnumSet<GridFlags> flags = gb.getFlags();
|
||||||
|
|||||||
@@ -138,7 +138,6 @@ public class TickManagerCache implements ITickManager
|
|||||||
tt.addEntityCrashInfo( crashreportcategory );
|
tt.addEntityCrashInfo( crashreportcategory );
|
||||||
throw new ReportedException( crashreport );
|
throw new ReportedException( crashreport );
|
||||||
}
|
}
|
||||||
PartLevelEmitter.wipeCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addToQueue( final TickTracker tt )
|
private void addToQueue( final TickTracker tt )
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ import java.util.*;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import appeng.api.config.Upgrades;
|
||||||
|
import appeng.helpers.DualityInterface;
|
||||||
|
import appeng.helpers.PatternHelper;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
import net.minecraft.inventory.InventoryCrafting;
|
import net.minecraft.inventory.InventoryCrafting;
|
||||||
@@ -233,8 +237,9 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
|
|
||||||
public IAEItemStack injectItems( final IAEItemStack input, final Actionable type, final IActionSource src )
|
public IAEItemStack injectItems( final IAEItemStack input, final Actionable type, final IActionSource src )
|
||||||
{
|
{
|
||||||
if( !( input instanceof IAEItemStack ) )
|
// also stop accepting items when the job is complete, i.e. to prevent re-insertion when pushing out
|
||||||
{
|
// items during storeItems
|
||||||
|
if (input == null || isComplete) {
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,7 +297,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
{
|
{
|
||||||
is.decStackSize( what.getStackSize() );
|
is.decStackSize( what.getStackSize() );
|
||||||
|
|
||||||
this.updateElapsedTime( what );
|
this.updateRemainingItemCount( what );
|
||||||
this.markDirty();
|
this.markDirty();
|
||||||
this.postCraftingStatusChange( what.copy().setStackSize( -what.getStackSize() ) );
|
this.postCraftingStatusChange( what.copy().setStackSize( -what.getStackSize() ) );
|
||||||
|
|
||||||
@@ -431,6 +436,11 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
AELog.crafting( LOG_MARK_AS_COMPLETE, logStack );
|
AELog.crafting( LOG_MARK_AS_COMPLETE, logStack );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Waiting for can potentially contain items at this point, if the user has a 64xplank->64xbutton processing
|
||||||
|
// recipe for example, but only requested 1xbutton. We just ignore the rest since it will be dumped
|
||||||
|
// back into the network inventory regardless. For this to work it's important that injectItems in this CPU
|
||||||
|
// does not accept any further items if isComplete is true.
|
||||||
|
this.waitingFor.resetStatus();
|
||||||
this.remainingItemCount = 0;
|
this.remainingItemCount = 0;
|
||||||
this.startItemCount = 0;
|
this.startItemCount = 0;
|
||||||
this.lastTime = 0;
|
this.lastTime = 0;
|
||||||
@@ -485,22 +495,87 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean canCraft( final ICraftingPatternDetails details, final IAEItemStack[] condensedInputs )
|
private boolean canCraft(final ICraftingPatternDetails details, final IAEItemStack[] condensedInputs)
|
||||||
{
|
{
|
||||||
for( IAEItemStack g : condensedInputs )
|
if( !details.isCraftable() )
|
||||||
{
|
{
|
||||||
|
// Processing patterns are relatively easy
|
||||||
|
for ( IAEItemStack input : condensedInputs )
|
||||||
|
{
|
||||||
|
final IAEItemStack ais = this.inventory.extractItems( input.copy(), Actionable.SIMULATE,
|
||||||
|
this.machineSrc );
|
||||||
|
|
||||||
if( details.isCraftable() )
|
if( ais == null || ais.getStackSize() < input.getStackSize() )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( details.canSubstitute() )
|
||||||
|
{
|
||||||
|
// When substitutions are allowed, we have to keep track of which items we've reserved
|
||||||
|
IAEItemStack[] inputs = details.getInputs();
|
||||||
|
Map<IAEItemStack, Integer> consumedCount = new HashMap<>();
|
||||||
|
for ( int i = 0; i < inputs.length; i++ )
|
||||||
|
{
|
||||||
|
List<IAEItemStack> substitutes = details.getSubstituteInputs( i );
|
||||||
|
if( substitutes.isEmpty() )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for ( IAEItemStack substitute : substitutes )
|
||||||
|
{
|
||||||
|
for ( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( substitute, FuzzyMode.IGNORE_ALL ) )
|
||||||
|
{
|
||||||
|
int alreadyConsumed = consumedCount.getOrDefault( fuzz, 0 );
|
||||||
|
if( fuzz.getStackSize() - alreadyConsumed <= 0 )
|
||||||
|
{
|
||||||
|
continue; // Already fully consumed by a previous slot of this recipe
|
||||||
|
}
|
||||||
|
|
||||||
|
fuzz = fuzz.copy();
|
||||||
|
fuzz.setStackSize( 1 ); // We're iterating over non condensed inputs which means there's 1 of each needed
|
||||||
|
final IAEItemStack ais = this.inventory.extractItems( fuzz, Actionable.SIMULATE,
|
||||||
|
this.machineSrc );
|
||||||
|
|
||||||
|
if( ais != null && ais.getStackSize() > 0 )
|
||||||
|
{
|
||||||
|
// Mark 1 of the stack as consumed
|
||||||
|
consumedCount.merge( fuzz, 1, Integer::sum );
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( found )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !found )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// When no substitutions can occur, we can simply check that all items are accounted since
|
||||||
|
// each type of item should only occur once
|
||||||
|
for ( IAEItemStack g : condensedInputs )
|
||||||
{
|
{
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
|
|
||||||
for( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( g, FuzzyMode.IGNORE_ALL ) )
|
for ( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( g, FuzzyMode.IGNORE_ALL ) )
|
||||||
{
|
{
|
||||||
fuzz = fuzz.copy();
|
fuzz = fuzz.copy();
|
||||||
fuzz.setStackSize( g.getStackSize() );
|
fuzz.setStackSize( g.getStackSize() );
|
||||||
final IAEItemStack ais = this.inventory.extractItems( fuzz, Actionable.SIMULATE, this.machineSrc );
|
final IAEItemStack ais = this.inventory.extractItems( fuzz, Actionable.SIMULATE, this.machineSrc );
|
||||||
|
|
||||||
if (ais != null && ais.getStackSize() == g.getStackSize())
|
if( ais != null && ais.getStackSize() >= g.getStackSize() )
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@@ -517,15 +592,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
final IAEItemStack ais = this.inventory.extractItems( g.copy(), Actionable.SIMULATE, this.machineSrc );
|
|
||||||
|
|
||||||
if (ais == null || ais.getStackSize() < g.getStackSize())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -676,8 +743,15 @@ 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++ )
|
||||||
@@ -692,59 +766,59 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
|
|
||||||
if( details.canSubstitute() )
|
if( details.canSubstitute() )
|
||||||
{
|
{
|
||||||
itemList = this.inventory.getItemList().findFuzzy( input[x], FuzzyMode.IGNORE_ALL );
|
final List<IAEItemStack> substitutes = details.getSubstituteInputs( x );
|
||||||
}
|
itemList = new ArrayList<>( substitutes.size() );
|
||||||
else
|
|
||||||
{
|
|
||||||
itemList = new ArrayList<>( 1 );
|
|
||||||
|
|
||||||
final IAEItemStack item = this.inventory.getItemList().findPrecise( input[x] );
|
for( IAEItemStack stack : substitutes )
|
||||||
|
|
||||||
if( item != null )
|
|
||||||
{
|
{
|
||||||
itemList.add( item );
|
itemList.addAll( this.inventory.getItemList().findFuzzy( stack, FuzzyMode.IGNORE_ALL ) );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
itemList = new ArrayList<>(1);
|
||||||
|
|
||||||
|
final IAEItemStack item = this.inventory.getItemList()
|
||||||
|
.findPrecise(input[x]);
|
||||||
|
|
||||||
|
if (item != null) {
|
||||||
|
itemList.add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for( IAEItemStack fuzz : itemList )
|
for (IAEItemStack fuzz : itemList) {
|
||||||
{
|
|
||||||
fuzz = fuzz.copy();
|
fuzz = fuzz.copy();
|
||||||
fuzz.setStackSize( input[x].getStackSize() );
|
fuzz.setStackSize(input[x].getStackSize());
|
||||||
|
|
||||||
if( details.isValidItemForSlot( x, fuzz.createItemStack(), this.getWorld() ) )
|
if (details.isValidItemForSlot(x, fuzz.createItemStack(),
|
||||||
{
|
this.getWorld())) {
|
||||||
final IAEItemStack ais = this.inventory.extractItems( fuzz, Actionable.MODULATE, this.machineSrc );
|
final IAEItemStack ais = this.inventory.extractItems(fuzz,
|
||||||
final ItemStack is = ais == null ? ItemStack.EMPTY : ais.createItemStack();
|
Actionable.MODULATE, this.machineSrc);
|
||||||
|
final ItemStack is = ais == null ? ItemStack.EMPTY
|
||||||
|
: ais.createItemStack();
|
||||||
|
|
||||||
if( !is.isEmpty() )
|
if (!is.isEmpty()) {
|
||||||
{
|
this.postChange(AEItemStack.fromItemStack(is), this.machineSrc);
|
||||||
this.postChange( AEItemStack.fromItemStack( is ), this.machineSrc );
|
ic.setInventorySlotContents(x, is);
|
||||||
ic.setInventorySlotContents( x, is );
|
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
final IAEItemStack ais = this.inventory.extractItems(input[x].copy(),
|
||||||
{
|
Actionable.MODULATE, this.machineSrc);
|
||||||
final IAEItemStack ais = this.inventory.extractItems( input[x].copy(), Actionable.MODULATE, this.machineSrc );
|
|
||||||
final ItemStack is = ais == null ? ItemStack.EMPTY : ais.createItemStack();
|
final ItemStack is = ais == null ? ItemStack.EMPTY : ais.createItemStack();
|
||||||
|
|
||||||
if( !is.isEmpty() )
|
if (!is.isEmpty()) {
|
||||||
{
|
this.postChange(input[x], this.machineSrc);
|
||||||
this.postChange( input[x], this.machineSrc );
|
ic.setInventorySlotContents(x, is);
|
||||||
ic.setInventorySlotContents( x, is );
|
if (is.getCount() == input[x].getStackSize()) {
|
||||||
if( is.getCount() == input[x].getStackSize() )
|
|
||||||
{
|
|
||||||
found = true;
|
found = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !found )
|
if (!found) {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -828,6 +902,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
|
|
||||||
private void storeItems()
|
private void storeItems()
|
||||||
{
|
{
|
||||||
|
Preconditions.checkState(isComplete, "CPU should be complete to prevent re-insertion when dumping items");
|
||||||
final IGrid g = this.getGrid();
|
final IGrid g = this.getGrid();
|
||||||
|
|
||||||
if( g == null )
|
if( g == null )
|
||||||
@@ -838,23 +913,24 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
final IStorageGrid sg = g.getCache( IStorageGrid.class );
|
final IStorageGrid sg = g.getCache( IStorageGrid.class );
|
||||||
final IMEInventory<IAEItemStack> ii = sg.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
final IMEInventory<IAEItemStack> ii = sg.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||||
|
|
||||||
for( IAEItemStack is : this.inventory.getItemList() )
|
IItemList<IAEItemStack> itemList = this.inventory.getItemList();
|
||||||
|
for( IAEItemStack is : itemList )
|
||||||
{
|
{
|
||||||
is = this.inventory.extractItems( is.copy(), Actionable.MODULATE, this.machineSrc );
|
this.postChange( is, this.machineSrc );
|
||||||
|
IAEItemStack remainder = ii.injectItems( is.copy(), Actionable.MODULATE, this.machineSrc );
|
||||||
|
|
||||||
if( is != null )
|
// The network was unable to receive all of the items, i.e. no or not enough storage space left
|
||||||
|
if( remainder != null )
|
||||||
{
|
{
|
||||||
this.postChange( is, this.machineSrc );
|
is.setStackSize( remainder.getStackSize() );
|
||||||
is = ii.injectItems( is, Actionable.MODULATE, this.machineSrc );
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if( is != null )
|
|
||||||
{
|
{
|
||||||
this.inventory.injectItems( is, Actionable.MODULATE, this.machineSrc );
|
is.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( this.inventory.getItemList().isEmpty() )
|
if( itemList.isEmpty() )
|
||||||
{
|
{
|
||||||
this.inventory = new MECraftingInventory();
|
this.inventory = new MECraftingInventory();
|
||||||
}
|
}
|
||||||
@@ -939,14 +1015,13 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
@Override
|
@Override
|
||||||
public boolean isBusy()
|
public boolean isBusy()
|
||||||
{
|
{
|
||||||
final Iterator<Entry<ICraftingPatternDetails, TaskProgress>> i = this.tasks.entrySet().iterator();
|
|
||||||
|
|
||||||
while( i.hasNext() )
|
this.tasks.entrySet().removeIf(
|
||||||
|
taskProgressEntry -> taskProgressEntry.getValue().value <= 0 );
|
||||||
|
|
||||||
|
if( !this.waitingFor.isEmpty() || !this.tasks.isEmpty() )
|
||||||
{
|
{
|
||||||
if( i.next().getValue().value <= 0 )
|
this.updateElapsedTime();
|
||||||
{
|
|
||||||
i.remove();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return !this.tasks.isEmpty() || !this.waitingFor.isEmpty();
|
return !this.tasks.isEmpty() || !this.waitingFor.isEmpty();
|
||||||
@@ -1338,12 +1413,16 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
this.remainingItemCount = itemCount;
|
this.remainingItemCount = itemCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateElapsedTime( final IAEItemStack is )
|
private void updateRemainingItemCount( final IAEItemStack is )
|
||||||
|
{
|
||||||
|
this.remainingItemCount = this.getRemainingItemCount() - is.getStackSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateElapsedTime()
|
||||||
{
|
{
|
||||||
final long nextStartTime = System.nanoTime();
|
final long nextStartTime = System.nanoTime();
|
||||||
this.elapsedTime = this.getElapsedTime() + nextStartTime - this.lastTime;
|
this.elapsedTime = this.getElapsedTime() + nextStartTime - this.lastTime;
|
||||||
this.lastTime = nextStartTime;
|
this.lastTime = nextStartTime;
|
||||||
this.remainingItemCount = this.getRemainingItemCount() - is.getStackSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getElapsedTime()
|
public long getElapsedTime()
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ public abstract class AbstractCellInventory<T extends IAEStack<T>> implements IC
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clean any old crusty stuff...
|
// clean any old crusty stuff...
|
||||||
for( ; x < oldStoredItems && x < this.maxItemTypes; x++ )
|
for( ; x >= oldStoredItems && x < this.maxItemTypes; x++ )
|
||||||
{
|
{
|
||||||
this.tagCompound.removeTag( ITEM_SLOT_KEYS[x] );
|
this.tagCompound.removeTag( ITEM_SLOT_KEYS[x] );
|
||||||
this.tagCompound.removeTag( ITEM_SLOT_COUNT_KEYS[x] );
|
this.tagCompound.removeTag( ITEM_SLOT_COUNT_KEYS[x] );
|
||||||
|
|||||||
@@ -277,6 +277,7 @@ public class BasicCellInventory<T extends IAEStack<T>> extends AbstractCellInven
|
|||||||
}
|
}
|
||||||
|
|
||||||
t.setStackSize( stackSize );
|
t.setStackSize( stackSize );
|
||||||
|
t.setCraftable( false );
|
||||||
|
|
||||||
if( stackSize > 0 )
|
if( stackSize > 0 )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,15 +19,20 @@
|
|||||||
package appeng.me.storage;
|
package appeng.me.storage;
|
||||||
|
|
||||||
|
|
||||||
|
import appeng.core.features.registries.cell.CreativeCellHandler;
|
||||||
|
import appeng.me.GridAccessException;
|
||||||
|
import appeng.me.helpers.MachineSource;
|
||||||
|
import appeng.tile.storage.TileDrive;
|
||||||
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>
|
||||||
{
|
{
|
||||||
@@ -35,14 +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;
|
||||||
|
|
||||||
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( drive );
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStatus()
|
public int getStatus()
|
||||||
@@ -55,38 +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;
|
||||||
}
|
}
|
||||||
|
if (this.drive.getProxy().isActive() && !(handler instanceof CreativeCellHandler))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
{
|
||||||
|
this.drive.getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), Collections.singletonList( request.copy().setStackSize( -extractable.getStackSize() ) ), this.source );
|
||||||
|
} catch ( GridAccessException e )
|
||||||
|
{
|
||||||
|
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T
|
|||||||
final IItemList<T> after = this.getInternal() == null ? this.getWrappedChannel().createList() : this.getInternal()
|
final IItemList<T> after = this.getInternal() == null ? this.getWrappedChannel().createList() : this.getInternal()
|
||||||
.getAvailableItems( new ItemListIgnoreCrafting( this.getWrappedChannel().createList() ) );
|
.getAvailableItems( new ItemListIgnoreCrafting( this.getWrappedChannel().createList() ) );
|
||||||
|
|
||||||
if( this.monitor != null )
|
if( this.monitor != null && this.listeners.size() > 0 )
|
||||||
{
|
{
|
||||||
this.monitor.addListener( this, this.monitor );
|
this.monitor.addListener( this, this.monitor );
|
||||||
}
|
}
|
||||||
@@ -90,6 +90,13 @@ public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T
|
|||||||
@Override
|
@Override
|
||||||
public void addListener( final IMEMonitorHandlerReceiver<T> l, final Object verificationToken )
|
public void addListener( final IMEMonitorHandlerReceiver<T> l, final Object verificationToken )
|
||||||
{
|
{
|
||||||
|
if( this.listeners.size() == 0 )
|
||||||
|
{
|
||||||
|
if( this.monitor != null )
|
||||||
|
{
|
||||||
|
this.monitor.addListener( this, this.monitor );
|
||||||
|
}
|
||||||
|
}
|
||||||
this.listeners.put( l, verificationToken );
|
this.listeners.put( l, verificationToken );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,4 +171,5 @@ public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T
|
|||||||
{
|
{
|
||||||
this.changeSource = changeSource;
|
this.changeSource = changeSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class MEPassThrough<T extends IAEStack<T>> implements IMEInventoryHandler
|
|||||||
this.setInternal( i );
|
this.setInternal( i );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IMEInventory<T> getInternal()
|
public IMEInventory<T> getInternal()
|
||||||
{
|
{
|
||||||
return this.internal;
|
return this.internal;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -180,7 +180,10 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.pushItemIntoTarget( destination, energy, inv, ais );
|
if( inv.getStorageList().findPrecise( ais ) != null )
|
||||||
|
{
|
||||||
|
this.pushItemIntoTarget( destination, energy, inv, ais );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( this.itemToSend == before && this.isCraftingEnabled() )
|
if( this.itemToSend == before && this.isCraftingEnabled() )
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
@@ -206,7 +207,7 @@ public class PartFormationPlane extends PartAbstractFormationPlane<IAEItemStack>
|
|||||||
@Override
|
@Override
|
||||||
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
|
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
|
||||||
{
|
{
|
||||||
if( this.getProxy().isActive() && channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
if( channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
||||||
{
|
{
|
||||||
final List<IMEInventoryHandler> handler = new ArrayList<>( 1 );
|
final List<IMEInventoryHandler> handler = new ArrayList<>( 1 );
|
||||||
handler.add( this.myHandler );
|
handler.add( this.myHandler );
|
||||||
|
|||||||
@@ -283,12 +283,12 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
|||||||
final ItemStack simResult;
|
final ItemStack simResult;
|
||||||
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
||||||
{
|
{
|
||||||
simResult = myAdaptor.simulateSimilarRemove( toSend, itemStackToImport, fzMode, this );
|
simResult = myAdaptor.simulateSimilarRemove( toSend, itemStackToImport, fzMode, null );
|
||||||
itemAmountNotStorable = inv.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
|
itemAmountNotStorable = inv.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
simResult = myAdaptor.simulateRemove( toSend, itemStackToImport, this );
|
simResult = myAdaptor.simulateRemove( toSend, itemStackToImport, null );
|
||||||
itemAmountNotStorable = inv.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
|
itemAmountNotStorable = inv.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,40 +19,9 @@
|
|||||||
package appeng.parts.automation;
|
package appeng.parts.automation;
|
||||||
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import appeng.me.Grid;
|
|
||||||
import appeng.me.GridNode;
|
|
||||||
import appeng.util.item.AEItemStack;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraft.inventory.InventoryCrafting;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
|
||||||
import net.minecraft.util.EnumHand;
|
|
||||||
import net.minecraft.util.EnumParticleTypes;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraftforge.items.IItemHandler;
|
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
import appeng.api.AEApi;
|
||||||
import appeng.api.config.FuzzyMode;
|
import appeng.api.config.*;
|
||||||
import appeng.api.config.LevelType;
|
import appeng.api.networking.crafting.*;
|
||||||
import appeng.api.config.RedstoneMode;
|
|
||||||
import appeng.api.config.Settings;
|
|
||||||
import appeng.api.config.Upgrades;
|
|
||||||
import appeng.api.config.YesNo;
|
|
||||||
import appeng.api.networking.crafting.ICraftingGrid;
|
|
||||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
|
||||||
import appeng.api.networking.crafting.ICraftingProvider;
|
|
||||||
import appeng.api.networking.crafting.ICraftingProviderHelper;
|
|
||||||
import appeng.api.networking.crafting.ICraftingWatcher;
|
|
||||||
import appeng.api.networking.crafting.ICraftingWatcherHost;
|
|
||||||
import appeng.api.networking.energy.IEnergyGrid;
|
import appeng.api.networking.energy.IEnergyGrid;
|
||||||
import appeng.api.networking.energy.IEnergyWatcher;
|
import appeng.api.networking.energy.IEnergyWatcher;
|
||||||
import appeng.api.networking.energy.IEnergyWatcherHost;
|
import appeng.api.networking.energy.IEnergyWatcherHost;
|
||||||
@@ -81,10 +50,28 @@ import appeng.core.sync.GuiBridge;
|
|||||||
import appeng.helpers.Reflected;
|
import appeng.helpers.Reflected;
|
||||||
import appeng.items.parts.PartModels;
|
import appeng.items.parts.PartModels;
|
||||||
import appeng.me.GridAccessException;
|
import appeng.me.GridAccessException;
|
||||||
|
import appeng.me.cache.NetworkMonitor;
|
||||||
import appeng.parts.PartModel;
|
import appeng.parts.PartModel;
|
||||||
import appeng.tile.inventory.AppEngInternalAEInventory;
|
import appeng.tile.inventory.AppEngInternalAEInventory;
|
||||||
import appeng.util.Platform;
|
import appeng.util.Platform;
|
||||||
import appeng.util.inv.InvOperation;
|
import appeng.util.inv.InvOperation;
|
||||||
|
import appeng.util.item.OreHelper;
|
||||||
|
import appeng.util.item.OreReference;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.inventory.InventoryCrafting;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.EnumHand;
|
||||||
|
import net.minecraft.util.EnumParticleTypes;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
|
||||||
public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherHost, IStackWatcherHost, ICraftingWatcherHost, IMEMonitorHandlerReceiver<IAEItemStack>, ICraftingProvider
|
public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherHost, IStackWatcherHost, ICraftingWatcherHost, IMEMonitorHandlerReceiver<IAEItemStack>, ICraftingProvider
|
||||||
@@ -123,9 +110,6 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
|
|||||||
private double centerX;
|
private double centerX;
|
||||||
private double centerY;
|
private double centerY;
|
||||||
private double centerZ;
|
private double centerZ;
|
||||||
static Object2LongMap<Grid> gridItemCount = new Object2LongOpenHashMap<>();
|
|
||||||
static Object2ObjectOpenHashMap<Grid, Object2LongMap<AEItemStack>> fuzzyAEItemStackCount = new Object2ObjectOpenHashMap<>();
|
|
||||||
static Object2ObjectOpenHashMap<Grid, Object2LongMap<AEItemStack>> preciseAEItemStackCount = new Object2ObjectOpenHashMap<>();
|
|
||||||
|
|
||||||
@Reflected
|
@Reflected
|
||||||
public PartLevelEmitter( final ItemStack is )
|
public PartLevelEmitter( final ItemStack is )
|
||||||
@@ -156,12 +140,6 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@MENetworkEventSubscribe
|
|
||||||
public void powerChanged( final MENetworkPowerStatusChange c )
|
|
||||||
{
|
|
||||||
this.updateState();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateState()
|
private void updateState()
|
||||||
{
|
{
|
||||||
final boolean isOn = this.isLevelEmitterOn();
|
final boolean isOn = this.isLevelEmitterOn();
|
||||||
@@ -206,9 +184,25 @@ 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 channelChanged( final MENetworkChannelsChanged c )
|
public void powerRender( final MENetworkPowerStatusChange powerEvent )
|
||||||
{
|
{
|
||||||
|
if (this.getProxy().isActive())
|
||||||
|
{
|
||||||
|
onListUpdate();
|
||||||
|
}
|
||||||
|
this.updateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@MENetworkEventSubscribe
|
||||||
|
public void chanRender( final MENetworkChannelsChanged c )
|
||||||
|
{
|
||||||
|
if (this.getProxy().isActive())
|
||||||
|
{
|
||||||
|
onListUpdate();
|
||||||
|
}
|
||||||
this.updateState();
|
this.updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,90 +317,29 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateReportingValue( final IMEMonitor<IAEItemStack> monitor )
|
private void updateReportingValue( final IMEMonitor<IAEItemStack> monitor )
|
||||||
{
|
|
||||||
updateReportingValue( monitor,null );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateReportingValue( final IMEMonitor<IAEItemStack> monitor, Iterable<IAEItemStack> change )
|
|
||||||
{
|
{
|
||||||
final IAEItemStack myStack = this.config.getAEStackInSlot( 0 );
|
final IAEItemStack myStack = this.config.getAEStackInSlot( 0 );
|
||||||
|
|
||||||
GridNode node = (GridNode) (this.getGridNode());
|
if( myStack == null )
|
||||||
|
|
||||||
if( node != null )
|
|
||||||
{
|
{
|
||||||
|
if( monitor instanceof NetworkMonitor )
|
||||||
final Grid g = node.getInternalGrid();
|
|
||||||
|
|
||||||
if( myStack == null )
|
|
||||||
{
|
{
|
||||||
if( change != null )
|
this.lastReportedValue = ( (NetworkMonitor<IAEItemStack>) monitor ).getGridCurrentCount();
|
||||||
{
|
|
||||||
if( gridItemCount.containsKey( g ) )
|
|
||||||
{
|
|
||||||
change.forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gridItemCount.computeIfAbsent( g, ( aLong ) -> {
|
|
||||||
this.lastReportedValue = 0;
|
|
||||||
monitor.getStorageList().forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
|
|
||||||
return ( lastReportedValue );
|
|
||||||
} );
|
|
||||||
this.lastReportedValue = gridItemCount.get( g );
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
else if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
||||||
{
|
{
|
||||||
final FuzzyMode fzMode = (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE );
|
final FuzzyMode fzMode = (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE );
|
||||||
if( change != null )
|
|
||||||
{
|
|
||||||
if( fuzzyAEItemStackCount.containsKey( g ) )
|
|
||||||
{
|
|
||||||
change.forEach( iaeItemStack -> {
|
|
||||||
if( iaeItemStack.sameOre( myStack ) ) lastReportedValue += iaeItemStack.getStackSize();
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fuzzyAEItemStackCount.computeIfAbsent( g, ( grid -> new Object2LongOpenHashMap<>() ) );
|
this.lastReportedValue = 0;
|
||||||
fuzzyAEItemStackCount.get( g ).computeIfAbsent( (AEItemStack) myStack, ( aLong -> {
|
monitor.getStorageList().findFuzzy( myStack, fzMode ).forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
|
||||||
this.lastReportedValue = 0;
|
}
|
||||||
monitor.getStorageList().findFuzzy( myStack, fzMode ).forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
|
else
|
||||||
return ( lastReportedValue );
|
{
|
||||||
} ) );
|
this.lastReportedValue = 0;
|
||||||
|
IAEItemStack precise = monitor.getStorageList().findPrecise( myStack );
|
||||||
this.lastReportedValue = fuzzyAEItemStackCount.get( g ).get( myStack );
|
if( precise != null ) lastReportedValue = precise.getStackSize();
|
||||||
if( this.lastReportedValue == 0 )
|
|
||||||
{
|
|
||||||
fuzzyAEItemStackCount.get( g ).remove( myStack );
|
|
||||||
fuzzyAEItemStackCount.trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( change != null )
|
|
||||||
{
|
|
||||||
if( preciseAEItemStackCount.containsKey( g ) )
|
|
||||||
{
|
|
||||||
change.forEach( iaeItemStack -> {
|
|
||||||
if( iaeItemStack.isSameType( myStack ) ) lastReportedValue += iaeItemStack.getStackSize();
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
preciseAEItemStackCount.computeIfAbsent( g, ( grid -> new Object2LongOpenHashMap<>() ) );
|
|
||||||
preciseAEItemStackCount.get( g ).computeIfAbsent( (AEItemStack) myStack, ( aLong -> {
|
|
||||||
this.lastReportedValue = 0;
|
|
||||||
IAEItemStack precise = monitor.getStorageList().findPrecise( myStack );
|
|
||||||
if( precise != null ) lastReportedValue = precise.getStackSize();
|
|
||||||
return ( lastReportedValue );
|
|
||||||
} ) );
|
|
||||||
this.lastReportedValue = preciseAEItemStackCount.get( g ).get( myStack );
|
|
||||||
if( this.lastReportedValue == 0 )
|
|
||||||
{
|
|
||||||
preciseAEItemStackCount.get( g ).remove( myStack );
|
|
||||||
preciseAEItemStackCount.trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.updateState();
|
this.updateState();
|
||||||
}
|
}
|
||||||
@@ -421,8 +354,7 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
|
|||||||
@Override
|
@Override
|
||||||
public void onStackChange( final IItemList o, final IAEStack fullStack, final IAEStack diffStack, final IActionSource src, final 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 ) && fullStack.equals( this.config.getAEStackInSlot( 0 ) ) && this
|
if( chan == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) && fullStack.equals( this.config.getAEStackInSlot( 0 ) ) && this.getInstalledUpgrades( Upgrades.FUZZY ) == 0 )
|
||||||
.getInstalledUpgrades( Upgrades.FUZZY ) == 0 )
|
|
||||||
{
|
{
|
||||||
this.lastReportedValue = fullStack.getStackSize();
|
this.lastReportedValue = fullStack.getStackSize();
|
||||||
this.updateState();
|
this.updateState();
|
||||||
@@ -459,7 +391,7 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
|
|||||||
@Override
|
@Override
|
||||||
public void postChange( final IBaseMonitor<IAEItemStack> monitor, final Iterable<IAEItemStack> change, final IActionSource actionSource )
|
public void postChange( final IBaseMonitor<IAEItemStack> monitor, final Iterable<IAEItemStack> change, final IActionSource actionSource )
|
||||||
{
|
{
|
||||||
this.updateReportingValue( (IMEMonitor<IAEItemStack>) monitor, change );
|
this.updateReportingValue( (IMEMonitor<IAEItemStack>) monitor );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -552,6 +484,7 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
|
|||||||
public void upgradesChanged()
|
public void upgradesChanged()
|
||||||
{
|
{
|
||||||
this.configureWatchers();
|
this.configureWatchers();
|
||||||
|
this.updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -636,9 +569,4 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void wipeCache(){
|
|
||||||
fuzzyAEItemStackCount.clear();
|
|
||||||
preciseAEItemStackCount.clear();
|
|
||||||
gridItemCount.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,20 @@
|
|||||||
package appeng.parts.automation;
|
package appeng.parts.automation;
|
||||||
|
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import appeng.api.AEApi;
|
||||||
|
import appeng.container.slot.SlotRestrictedInput;
|
||||||
|
import appeng.core.Api;
|
||||||
|
import appeng.helpers.DualityInterface;
|
||||||
|
import appeng.util.inv.ItemHandlerIterator;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.init.Items;
|
import net.minecraft.init.Items;
|
||||||
|
import net.minecraft.inventory.Slot;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
import appeng.api.config.Upgrades;
|
import appeng.api.config.Upgrades;
|
||||||
@@ -33,6 +43,9 @@ import appeng.util.inv.IAEAppEngInventory;
|
|||||||
import appeng.util.inv.InvOperation;
|
import appeng.util.inv.InvOperation;
|
||||||
import appeng.util.inv.filter.IAEItemFilter;
|
import appeng.util.inv.filter.IAEItemFilter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
public abstract class UpgradeInventory extends AppEngInternalInventory implements IAEAppEngInventory
|
public abstract class UpgradeInventory extends AppEngInternalInventory implements IAEAppEngInventory
|
||||||
{
|
{
|
||||||
@@ -45,6 +58,7 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
|
|||||||
private int capacityUpgrades = 0;
|
private int capacityUpgrades = 0;
|
||||||
private int inverterUpgrades = 0;
|
private int inverterUpgrades = 0;
|
||||||
private int craftingUpgrades = 0;
|
private int craftingUpgrades = 0;
|
||||||
|
private int patternExpansionUpgrades = 0;
|
||||||
|
|
||||||
public UpgradeInventory( final IAEAppEngInventory parent, final int s )
|
public UpgradeInventory( final IAEAppEngInventory parent, final int s )
|
||||||
{
|
{
|
||||||
@@ -81,6 +95,8 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
|
|||||||
return this.inverterUpgrades;
|
return this.inverterUpgrades;
|
||||||
case CRAFTING:
|
case CRAFTING:
|
||||||
return this.craftingUpgrades;
|
return this.craftingUpgrades;
|
||||||
|
case PATTERN_EXPANSION:
|
||||||
|
return this.patternExpansionUpgrades;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -91,7 +107,7 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
|
|||||||
private void updateUpgradeInfo()
|
private void updateUpgradeInfo()
|
||||||
{
|
{
|
||||||
this.cached = true;
|
this.cached = true;
|
||||||
this.inverterUpgrades = this.capacityUpgrades = this.redstoneUpgrades = this.speedUpgrades = this.fuzzyUpgrades = this.craftingUpgrades = 0;
|
this.patternExpansionUpgrades = this.inverterUpgrades = this.capacityUpgrades = this.redstoneUpgrades = this.speedUpgrades = this.fuzzyUpgrades = this.craftingUpgrades = 0;
|
||||||
|
|
||||||
for( final ItemStack is : this )
|
for( final ItemStack is : this )
|
||||||
{
|
{
|
||||||
@@ -121,6 +137,9 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
|
|||||||
case CRAFTING:
|
case CRAFTING:
|
||||||
this.craftingUpgrades++;
|
this.craftingUpgrades++;
|
||||||
break;
|
break;
|
||||||
|
case PATTERN_EXPANSION:
|
||||||
|
this.patternExpansionUpgrades++;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -132,6 +151,7 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
|
|||||||
this.speedUpgrades = Math.min( this.speedUpgrades, this.getMaxInstalled( Upgrades.SPEED ) );
|
this.speedUpgrades = Math.min( this.speedUpgrades, this.getMaxInstalled( Upgrades.SPEED ) );
|
||||||
this.inverterUpgrades = Math.min( this.inverterUpgrades, this.getMaxInstalled( Upgrades.INVERTER ) );
|
this.inverterUpgrades = Math.min( this.inverterUpgrades, this.getMaxInstalled( Upgrades.INVERTER ) );
|
||||||
this.craftingUpgrades = Math.min( this.craftingUpgrades, this.getMaxInstalled( Upgrades.CRAFTING ) );
|
this.craftingUpgrades = Math.min( this.craftingUpgrades, this.getMaxInstalled( Upgrades.CRAFTING ) );
|
||||||
|
this.patternExpansionUpgrades = Math.min( this.patternExpansionUpgrades, this.getMaxInstalled( Upgrades.PATTERN_EXPANSION ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -160,6 +180,13 @@ public abstract class UpgradeInventory extends AppEngInternalInventory implement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public ItemStack extractItem( int slot, int amount, boolean simulate )
|
||||||
|
{
|
||||||
|
return super.extractItem( slot, amount, simulate );
|
||||||
|
}
|
||||||
|
|
||||||
private class UpgradeInvFilter implements IAEItemFilter
|
private class UpgradeInvFilter implements IAEItemFilter
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -19,17 +19,12 @@
|
|||||||
package appeng.parts.misc;
|
package appeng.parts.misc;
|
||||||
|
|
||||||
|
|
||||||
import java.util.*;
|
import javax.annotation.Nullable;
|
||||||
|
import appeng.api.AEApi;
|
||||||
|
import appeng.api.config.AccessRestriction;
|
||||||
|
import appeng.api.config.Actionable;
|
||||||
import appeng.api.config.Settings;
|
import appeng.api.config.Settings;
|
||||||
import appeng.api.config.StorageFilter;
|
import appeng.api.config.StorageFilter;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraftforge.items.IItemHandler;
|
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
|
||||||
import appeng.api.config.Actionable;
|
|
||||||
import appeng.api.networking.security.IActionSource;
|
import appeng.api.networking.security.IActionSource;
|
||||||
import appeng.api.networking.storage.IBaseMonitor;
|
import appeng.api.networking.storage.IBaseMonitor;
|
||||||
import appeng.api.networking.ticking.TickRateModulation;
|
import appeng.api.networking.ticking.TickRateModulation;
|
||||||
@@ -39,11 +34,19 @@ import appeng.api.storage.channels.IItemStorageChannel;
|
|||||||
import appeng.api.storage.data.IAEItemStack;
|
import appeng.api.storage.data.IAEItemStack;
|
||||||
import appeng.api.storage.data.IItemList;
|
import appeng.api.storage.data.IItemList;
|
||||||
import appeng.core.AELog;
|
import appeng.core.AELog;
|
||||||
|
import appeng.me.GridAccessException;
|
||||||
import appeng.me.helpers.IGridProxyable;
|
import appeng.me.helpers.IGridProxyable;
|
||||||
import appeng.me.storage.ITickingMonitor;
|
import appeng.me.storage.ITickingMonitor;
|
||||||
import appeng.util.Platform;
|
import appeng.util.inv.ItemHandlerIterator;
|
||||||
|
import appeng.util.inv.ItemSlot;
|
||||||
import appeng.util.item.AEItemStack;
|
import appeng.util.item.AEItemStack;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import com.google.common.primitives.Ints;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,6 +60,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
private final IGridProxyable proxyable;
|
private final IGridProxyable proxyable;
|
||||||
private final InventoryCache cache;
|
private final InventoryCache cache;
|
||||||
private StorageFilter mode;
|
private StorageFilter mode;
|
||||||
|
private AccessRestriction access;
|
||||||
|
|
||||||
ItemHandlerAdapter( IItemHandler itemHandler, IGridProxyable proxy )
|
ItemHandlerAdapter( IItemHandler itemHandler, IGridProxyable proxy )
|
||||||
{
|
{
|
||||||
@@ -66,35 +70,45 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
{
|
{
|
||||||
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
|
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
|
||||||
this.mode = ( (StorageFilter) partStorageBus.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
|
this.mode = ( (StorageFilter) partStorageBus.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
|
||||||
|
this.access = ( (AccessRestriction) partStorageBus.getConfigManager().getSetting( Settings.ACCESS ) );
|
||||||
}
|
}
|
||||||
this.cache = new InventoryCache( this.itemHandler, this.mode );
|
this.cache = new InventoryCache( this.itemHandler, this.mode );
|
||||||
|
this.cache.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
|
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
|
||||||
{
|
{
|
||||||
|
// Try to reuse the cached stack
|
||||||
|
@Nullable ItemStack currentCached = iox.getCachedItemStack();
|
||||||
|
iox.setCachedItemStack(null);
|
||||||
|
|
||||||
|
ItemStack orgInput;
|
||||||
|
int slotCount = this.itemHandler.getSlots();
|
||||||
|
|
||||||
|
if( currentCached != null && iox.isSameType( currentCached ) )
|
||||||
|
{
|
||||||
|
// Cache is suitable, just update the count
|
||||||
|
orgInput = currentCached;
|
||||||
|
currentCached.setCount( Ints.saturatedCast( iox.getStackSize() ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We need a new stack :-(
|
||||||
|
orgInput = iox.createItemStack();
|
||||||
|
}
|
||||||
|
|
||||||
ItemStack orgInput = iox.createItemStack();
|
|
||||||
ItemStack remaining = orgInput;
|
ItemStack remaining = orgInput;
|
||||||
|
|
||||||
int slotCount = this.itemHandler.getSlots();
|
|
||||||
boolean simulate = ( type == Actionable.SIMULATE );
|
|
||||||
List<Pair<Integer, Integer>> injectedList = new ArrayList<>();
|
|
||||||
// This uses a brute force approach and tries to jam it in every slot the inventory exposes.
|
|
||||||
for( int i = 0; i < slotCount && !remaining.isEmpty(); i++ )
|
for( int i = 0; i < slotCount && !remaining.isEmpty(); i++ )
|
||||||
{
|
{
|
||||||
int countPre = remaining.getCount();
|
remaining = this.itemHandler.insertItem( i, remaining, type == Actionable.SIMULATE );
|
||||||
remaining = this.itemHandler.insertItem( i, remaining, simulate );
|
}
|
||||||
int countPos = remaining.getCount();
|
|
||||||
if( remaining.isEmpty() )
|
// Store the stack in the cache for next time.
|
||||||
{
|
if( !remaining.isEmpty() )
|
||||||
injectedList.add( Pair.of( i, countPre ) );
|
{
|
||||||
break;
|
iox.setCachedItemStack( remaining );
|
||||||
}
|
|
||||||
else if( countPos < countPre )
|
|
||||||
{
|
|
||||||
injectedList.add( Pair.of( i, countPre - countPos ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point, we still have some items left...
|
// At this point, we still have some items left...
|
||||||
@@ -106,30 +120,17 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
|
|
||||||
if( type == Actionable.MODULATE )
|
if( type == Actionable.MODULATE )
|
||||||
{
|
{
|
||||||
if( this.cache.cachedAeStacks.length == 0 )
|
IAEItemStack added = iox.copy().setStackSize( iox.getStackSize() - remaining.getCount() );
|
||||||
|
this.cache.currentlyCached.add( added );
|
||||||
|
this.postDifference( Collections.singletonList( added ) );
|
||||||
|
try
|
||||||
{
|
{
|
||||||
this.cache.update();
|
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||||
}
|
}
|
||||||
else
|
catch( GridAccessException ex )
|
||||||
{
|
{
|
||||||
for( Pair<Integer, Integer> pair : injectedList )
|
// meh
|
||||||
{
|
|
||||||
if( pair.getKey() >= this.cache.cachedAeStacks.length )
|
|
||||||
{
|
|
||||||
this.cache.update();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if( this.cache.cachedAeStacks[pair.getKey()] == null )
|
|
||||||
{
|
|
||||||
this.cache.cachedAeStacks[pair.getKey()] = iox.copy().setStackSize( pair.getValue() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.cache.cachedAeStacks[pair.getKey()].incStackSize( pair.getValue() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return AEItemStack.fromItemStack( remaining );
|
return AEItemStack.fromItemStack( remaining );
|
||||||
@@ -138,21 +139,17 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
@Override
|
@Override
|
||||||
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
|
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
|
||||||
{
|
{
|
||||||
ItemStack requestedItemStack = request.createItemStack();
|
int remainingSize = Ints.saturatedCast( request.getStackSize() );
|
||||||
int remainingSize = requestedItemStack.getCount();
|
|
||||||
|
|
||||||
// Use this to gather the requested items
|
// Use this to gather the requested items
|
||||||
ItemStack gathered = ItemStack.EMPTY;
|
ItemStack gathered = ItemStack.EMPTY;
|
||||||
|
|
||||||
final boolean simulate = ( mode == Actionable.SIMULATE );
|
final boolean simulate = ( mode == Actionable.SIMULATE );
|
||||||
List<Pair<Integer, Integer>> extractedList = new ArrayList<>();
|
|
||||||
|
|
||||||
|
|
||||||
for ( int i = 0; i < this.itemHandler.getSlots(); i++ )
|
for ( int i = 0; i < this.itemHandler.getSlots(); i++ )
|
||||||
{
|
{
|
||||||
ItemStack stackInInventorySlot = this.itemHandler.getStackInSlot( i );
|
ItemStack stackInInventorySlot = this.itemHandler.getStackInSlot( i );
|
||||||
|
|
||||||
if( !Platform.itemComparisons().isSameItem( stackInInventorySlot, requestedItemStack ) )
|
if( !request.isSameType( stackInInventorySlot ) )
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -191,16 +188,10 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
}
|
}
|
||||||
remainingCurrentSlot -= extracted.getCount();
|
remainingCurrentSlot -= extracted.getCount();
|
||||||
}
|
}
|
||||||
}
|
} while ( !extracted.isEmpty() && remainingCurrentSlot > 0 );
|
||||||
while ( !extracted.isEmpty() && remainingCurrentSlot > 0 );
|
|
||||||
|
|
||||||
remainingSize -= stackSizeCurrentSlot - remainingCurrentSlot;
|
remainingSize -= stackSizeCurrentSlot - remainingCurrentSlot;
|
||||||
|
|
||||||
if (!gathered.isEmpty())
|
|
||||||
{
|
|
||||||
extractedList.add( Pair.of( i, gathered.getCount() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Done?
|
// Done?
|
||||||
if( remainingSize <= 0 )
|
if( remainingSize <= 0 )
|
||||||
{
|
{
|
||||||
@@ -210,29 +201,26 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
|
|
||||||
if( !gathered.isEmpty() )
|
if( !gathered.isEmpty() )
|
||||||
{
|
{
|
||||||
|
IAEItemStack gatheredAEItemStack = AEItemStack.fromItemStack( gathered );
|
||||||
if( mode == Actionable.MODULATE )
|
if( mode == Actionable.MODULATE )
|
||||||
{
|
{
|
||||||
if( this.cache.cachedAeStacks.length == 0 )
|
IAEItemStack cachedStack = this.cache.currentlyCached.findPrecise( request );
|
||||||
|
if( cachedStack != null )
|
||||||
{
|
{
|
||||||
this.cache.update();
|
cachedStack.decStackSize( gatheredAEItemStack.getStackSize() );
|
||||||
|
this.postDifference( Collections.singletonList( gatheredAEItemStack.copy().setStackSize( -gatheredAEItemStack.getStackSize() ) ) );
|
||||||
}
|
}
|
||||||
else
|
try
|
||||||
{
|
{
|
||||||
for( Pair<Integer, Integer> pair : extractedList )
|
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||||
{
|
}
|
||||||
if( this.cache.cachedAeStacks[pair.getKey()] != null )
|
catch( GridAccessException ex )
|
||||||
{
|
{
|
||||||
this.cache.cachedAeStacks[pair.getKey()].decStackSize( pair.getValue() );
|
// meh
|
||||||
if( this.cache.cachedAeStacks[pair.getKey()].getStackSize() == 0 )
|
|
||||||
{
|
|
||||||
this.cache.cachedAeStacks[pair.getKey()] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return AEItemStack.fromItemStack( gathered );
|
return gatheredAEItemStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -242,7 +230,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
public TickRateModulation onTick()
|
public TickRateModulation onTick()
|
||||||
{
|
{
|
||||||
List<IAEItemStack> changes = this.cache.update();
|
List<IAEItemStack> changes = this.cache.update();
|
||||||
if( !changes.isEmpty() )
|
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
|
||||||
{
|
{
|
||||||
this.postDifference( changes );
|
this.postDifference( changes );
|
||||||
return TickRateModulation.URGENT;
|
return TickRateModulation.URGENT;
|
||||||
@@ -286,7 +274,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
private void postDifference( Iterable<IAEItemStack> a )
|
private void postDifference( Iterable<IAEItemStack> a )
|
||||||
{
|
{
|
||||||
final Iterator<Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
|
final Iterator<Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
|
||||||
while( i.hasNext() )
|
while ( i.hasNext() )
|
||||||
{
|
{
|
||||||
final Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
|
final Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
|
||||||
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
|
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
|
||||||
@@ -301,11 +289,11 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class InventoryCache
|
private static class InventoryCache implements Iterable<ItemSlot>
|
||||||
{
|
{
|
||||||
private IAEItemStack[] cachedAeStacks = new IAEItemStack[0];
|
|
||||||
private final IItemHandler itemHandler;
|
private final IItemHandler itemHandler;
|
||||||
private final StorageFilter mode;
|
private final StorageFilter mode;
|
||||||
|
IItemList<IAEItemStack> currentlyCached = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
|
|
||||||
public InventoryCache( IItemHandler itemHandler, StorageFilter mode )
|
public InventoryCache( IItemHandler itemHandler, StorageFilter mode )
|
||||||
{
|
{
|
||||||
@@ -315,106 +303,58 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
|
|
||||||
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
|
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
|
||||||
{
|
{
|
||||||
Arrays.stream( this.cachedAeStacks ).forEach( out::add );
|
currentlyCached.iterator().forEachRemaining( out::add );
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private StorageFilter getMode()
|
||||||
|
{
|
||||||
|
return this.mode;
|
||||||
|
}
|
||||||
|
|
||||||
public List<IAEItemStack> update()
|
public List<IAEItemStack> update()
|
||||||
{
|
{
|
||||||
final List<IAEItemStack> changes = new ArrayList<>();
|
final List<IAEItemStack> changes = new ArrayList<>();
|
||||||
final int slots = this.itemHandler.getSlots();
|
|
||||||
|
|
||||||
// Make room for new slots
|
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
if( slots > this.cachedAeStacks.length )
|
|
||||||
{
|
|
||||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
|
||||||
}
|
|
||||||
|
|
||||||
for( int slot = 0; slot < slots; slot++ )
|
for( final ItemSlot is : this )
|
||||||
{
|
{
|
||||||
// Save the old stuff
|
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && !is.isExtractable() )
|
||||||
final IAEItemStack oldAeIS = this.cachedAeStacks[slot];
|
|
||||||
ItemStack newIS = this.itemHandler.getStackInSlot( slot );
|
|
||||||
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && !newIS.isEmpty() )
|
|
||||||
{
|
{
|
||||||
if( this.itemHandler.extractItem( slot, 1, true ).isEmpty() )
|
continue;
|
||||||
{
|
|
||||||
newIS = ItemStack.EMPTY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.handlePossibleSlotChanges( slot, oldAeIS, newIS, changes );
|
currentlyOnStorage.add( is.getAEItemStack() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle cases where the number of slots actually is lower now than before
|
for ( final IAEItemStack is : currentlyCached )
|
||||||
if( slots < this.cachedAeStacks.length )
|
|
||||||
{
|
{
|
||||||
for( int slot = slots; slot < this.cachedAeStacks.length; slot++ )
|
is.setStackSize( -is.getStackSize() );
|
||||||
{
|
|
||||||
final IAEItemStack aeStack = this.cachedAeStacks[slot];
|
|
||||||
|
|
||||||
if( aeStack != null )
|
|
||||||
{
|
|
||||||
final IAEItemStack a = aeStack.copy();
|
|
||||||
a.setStackSize( -a.getStackSize() );
|
|
||||||
changes.add( a );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reduce the cache size
|
|
||||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for ( final IAEItemStack is : currentlyOnStorage )
|
||||||
|
{
|
||||||
|
currentlyCached.add( is );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( final IAEItemStack is : currentlyCached )
|
||||||
|
{
|
||||||
|
if( is.getStackSize() != 0 )
|
||||||
|
{
|
||||||
|
changes.add( is );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentlyCached = currentlyOnStorage;
|
||||||
|
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePossibleSlotChanges( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
|
@Override
|
||||||
|
public Iterator<ItemSlot> iterator()
|
||||||
{
|
{
|
||||||
if( oldAeIS != null && oldAeIS.isSameType( newIS ) )
|
return new ItemHandlerIterator( this.itemHandler );
|
||||||
{
|
|
||||||
this.handleStackSizeChanged( slot, oldAeIS, newIS, changes );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.handleItemChanged( slot, oldAeIS, newIS, changes );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleStackSizeChanged( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
|
|
||||||
{
|
|
||||||
// Still the same item, but amount might have changed
|
|
||||||
final long diff = newIS.getCount() - oldAeIS.getStackSize();
|
|
||||||
|
|
||||||
if( diff != 0 )
|
|
||||||
{
|
|
||||||
final IAEItemStack stack = oldAeIS.copy();
|
|
||||||
stack.setStackSize( newIS.getCount() );
|
|
||||||
|
|
||||||
this.cachedAeStacks[slot] = stack;
|
|
||||||
|
|
||||||
final IAEItemStack a = stack.copy();
|
|
||||||
a.setStackSize( diff );
|
|
||||||
changes.add( a );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleItemChanged( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
|
|
||||||
{
|
|
||||||
// Completely different item
|
|
||||||
this.cachedAeStacks[slot] = AEItemStack.fromItemStack( newIS );
|
|
||||||
|
|
||||||
// If we had a stack previously in this slot, notify the network about its disappearance
|
|
||||||
if( oldAeIS != null )
|
|
||||||
{
|
|
||||||
oldAeIS.setStackSize( -oldAeIS.getStackSize() );
|
|
||||||
changes.add( oldAeIS );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify the network about the new stack. Note that this is null if newIS was null
|
|
||||||
if( this.cachedAeStacks[slot] != null )
|
|
||||||
{
|
|
||||||
changes.add( this.cachedAeStacks[slot] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
package appeng.parts.misc;
|
package appeng.parts.misc;
|
||||||
|
|
||||||
import java.util.*;
|
import javax.annotation.Nullable;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import appeng.api.storage.IStorageChannel;
|
|
||||||
|
|
||||||
import appeng.core.AELog;
|
|
||||||
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
import appeng.api.AEApi;
|
||||||
|
import appeng.api.config.AccessRestriction;
|
||||||
import appeng.api.config.Actionable;
|
import appeng.api.config.Actionable;
|
||||||
|
import appeng.api.config.Settings;
|
||||||
import appeng.api.networking.security.IActionSource;
|
import appeng.api.networking.security.IActionSource;
|
||||||
import appeng.api.networking.storage.IBaseMonitor;
|
import appeng.api.networking.storage.IBaseMonitor;
|
||||||
import appeng.api.networking.ticking.TickRateModulation;
|
import appeng.api.networking.ticking.TickRateModulation;
|
||||||
import appeng.api.storage.IMEInventory;
|
import appeng.api.storage.IMEInventory;
|
||||||
import appeng.api.storage.IMEMonitorHandlerReceiver;
|
import appeng.api.storage.IMEMonitorHandlerReceiver;
|
||||||
|
import appeng.api.storage.IStorageChannel;
|
||||||
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.api.storage.data.IItemList;
|
import appeng.api.storage.data.IItemList;
|
||||||
|
import appeng.core.AELog;
|
||||||
import appeng.me.GridAccessException;
|
import appeng.me.GridAccessException;
|
||||||
import appeng.me.helpers.IGridProxyable;
|
import appeng.me.helpers.IGridProxyable;
|
||||||
import appeng.me.storage.ITickingMonitor;
|
import appeng.me.storage.ITickingMonitor;
|
||||||
import appeng.util.item.AEItemStack;
|
import appeng.util.item.AEItemStack;
|
||||||
|
import com.google.common.primitives.Ints;
|
||||||
|
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps an Item Repository in such a way that it can be used as an IMEInventory for items.
|
* Wraps an Item Repository in such a way that it can be used as an IMEInventory for items.
|
||||||
@@ -40,24 +40,49 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
|||||||
private final IItemRepository itemRepository;
|
private final IItemRepository itemRepository;
|
||||||
private final IGridProxyable proxyable;
|
private final IGridProxyable proxyable;
|
||||||
private final InventoryCache cache;
|
private final InventoryCache cache;
|
||||||
|
private AccessRestriction access;
|
||||||
|
|
||||||
|
private ItemStack stackCache;
|
||||||
|
|
||||||
ItemRepositoryAdapter( IItemRepository itemRepository, IGridProxyable proxy )
|
ItemRepositoryAdapter( IItemRepository itemRepository, IGridProxyable proxy )
|
||||||
{
|
{
|
||||||
this.itemRepository = itemRepository;
|
this.itemRepository = itemRepository;
|
||||||
this.proxyable = proxy;
|
this.proxyable = proxy;
|
||||||
this.cache = new InventoryCache( this.itemRepository );
|
this.cache = new InventoryCache( this.itemRepository );
|
||||||
|
if( this.proxyable instanceof PartStorageBus )
|
||||||
|
{
|
||||||
|
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
|
||||||
|
this.access = ( (AccessRestriction) partStorageBus.getConfigManager().getSetting( Settings.ACCESS ) );
|
||||||
|
}
|
||||||
|
this.cache.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
|
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
|
||||||
{
|
{
|
||||||
ItemStack orgInput = iox.createItemStack();
|
// Try to reuse the cached stack
|
||||||
ItemStack remaining = orgInput;
|
@Nullable ItemStack currentCached = stackCache;
|
||||||
|
stackCache = null;
|
||||||
|
|
||||||
boolean simulate = ( type == Actionable.SIMULATE );
|
ItemStack orgInput;
|
||||||
|
if( currentCached != null && iox.isSameType( currentCached ) )
|
||||||
|
{
|
||||||
|
// Cache is suitable, just update the count
|
||||||
|
orgInput = currentCached;
|
||||||
|
currentCached.setCount( Ints.saturatedCast( iox.getStackSize() ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We need a new stack :-(
|
||||||
|
orgInput = iox.createItemStack();
|
||||||
|
}
|
||||||
|
ItemStack remaining = this.itemRepository.insertItem( orgInput, type == Actionable.SIMULATE );
|
||||||
|
|
||||||
remaining = this.itemRepository.insertItem( remaining, simulate );
|
// Store the stack in the cache for next time.
|
||||||
|
if( !remaining.isEmpty() && remaining != orgInput )
|
||||||
|
{
|
||||||
|
stackCache = remaining;
|
||||||
|
}
|
||||||
|
|
||||||
// At this point, we still have some items left...
|
// At this point, we still have some items left...
|
||||||
if( remaining == orgInput )
|
if( remaining == orgInput )
|
||||||
@@ -68,6 +93,9 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
|||||||
|
|
||||||
if( type == Actionable.MODULATE )
|
if( type == Actionable.MODULATE )
|
||||||
{
|
{
|
||||||
|
IAEItemStack added = iox.copy().setStackSize( iox.getStackSize() - remaining.getCount() );
|
||||||
|
this.cache.currentlyCached.add( added );
|
||||||
|
this.postDifference( Collections.singletonList( added ) );
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||||
@@ -85,12 +113,11 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
|||||||
@Override
|
@Override
|
||||||
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
|
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
|
||||||
{
|
{
|
||||||
ItemStack requestedItemStack = request.getDefinition();
|
int remainingSize = Ints.saturatedCast( request.getStackSize() );
|
||||||
int remainingSize = (int) Math.min( Integer.MAX_VALUE, request.getStackSize());
|
|
||||||
|
|
||||||
final boolean simulate = ( mode == Actionable.SIMULATE );
|
final boolean simulate = ( mode == Actionable.SIMULATE );
|
||||||
|
|
||||||
ItemStack extracted = this.itemRepository.extractItem( requestedItemStack, remainingSize, simulate );
|
ItemStack extracted = this.itemRepository.extractItem( request.getDefinition(), remainingSize, simulate );
|
||||||
|
|
||||||
if( extracted.getCount() > remainingSize )
|
if( extracted.getCount() > remainingSize )
|
||||||
{
|
{
|
||||||
@@ -103,8 +130,15 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
|||||||
|
|
||||||
if( !extracted.isEmpty() )
|
if( !extracted.isEmpty() )
|
||||||
{
|
{
|
||||||
|
IAEItemStack extractedAEItemStack = AEItemStack.fromItemStack( extracted );
|
||||||
if( mode == Actionable.MODULATE )
|
if( mode == Actionable.MODULATE )
|
||||||
{
|
{
|
||||||
|
IAEItemStack cachedStack = this.cache.currentlyCached.findPrecise( request );
|
||||||
|
if (cachedStack != null)
|
||||||
|
{
|
||||||
|
cachedStack.decStackSize( extractedAEItemStack.getStackSize() );
|
||||||
|
this.postDifference( Collections.singletonList( extractedAEItemStack.copy().setStackSize( -extractedAEItemStack.getStackSize() ) ) );
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||||
@@ -114,7 +148,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
|||||||
// meh
|
// meh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return AEItemStack.fromItemStack( extracted );
|
return extractedAEItemStack;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -146,7 +180,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
|||||||
private void postDifference( Iterable<IAEItemStack> a )
|
private void postDifference( Iterable<IAEItemStack> a )
|
||||||
{
|
{
|
||||||
final Iterator<Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
|
final Iterator<Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
|
||||||
while( i.hasNext() )
|
while ( i.hasNext() )
|
||||||
{
|
{
|
||||||
final Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
|
final Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
|
||||||
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
|
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
|
||||||
@@ -164,17 +198,15 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
|||||||
@Override
|
@Override
|
||||||
public TickRateModulation onTick()
|
public TickRateModulation onTick()
|
||||||
{
|
{
|
||||||
|
List<IAEItemStack> changes = this.cache.update();
|
||||||
|
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
|
||||||
{
|
{
|
||||||
List<IAEItemStack> changes = this.cache.update();
|
this.postDifference( changes );
|
||||||
if( !changes.isEmpty() )
|
return TickRateModulation.URGENT;
|
||||||
{
|
}
|
||||||
this.postDifference( changes );
|
else
|
||||||
return TickRateModulation.URGENT;
|
{
|
||||||
}
|
return TickRateModulation.SLOWER;
|
||||||
else
|
|
||||||
{
|
|
||||||
return TickRateModulation.SLOWER;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +218,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
|||||||
|
|
||||||
private static class InventoryCache
|
private static class InventoryCache
|
||||||
{
|
{
|
||||||
private IAEItemStack[] cachedAeStacks = new IAEItemStack[0];
|
private IItemList<IAEItemStack> currentlyCached = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
private final IItemRepository iItemRepository;
|
private final IItemRepository iItemRepository;
|
||||||
|
|
||||||
public InventoryCache( IItemRepository iItemRepository )
|
public InventoryCache( IItemRepository iItemRepository )
|
||||||
@@ -196,7 +228,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
|||||||
|
|
||||||
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
|
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
|
||||||
{
|
{
|
||||||
Arrays.stream( this.cachedAeStacks ).forEach( out::add );
|
currentlyCached.iterator().forEachRemaining( out::add );
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,94 +236,31 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
|||||||
{
|
{
|
||||||
final List<IAEItemStack> changes = new ArrayList<>();
|
final List<IAEItemStack> changes = new ArrayList<>();
|
||||||
|
|
||||||
List<IAEItemStack> out = this.iItemRepository.getAllItems().stream().map( s -> AEItemStack.fromItemStack( s.itemPrototype ).setStackSize( s.count ) ).collect(Collectors.toList() );
|
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
|
this.iItemRepository.getAllItems().stream().map( s -> AEItemStack.fromItemStack( s.itemPrototype ).setStackSize( s.count ) ).forEach( currentlyOnStorage::add );
|
||||||
|
|
||||||
final int size = out.size();
|
for ( final IAEItemStack is : currentlyCached )
|
||||||
|
|
||||||
// Make room for new slots
|
|
||||||
if( size > this.cachedAeStacks.length )
|
|
||||||
{
|
{
|
||||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, size );
|
is.setStackSize( -is.getStackSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( int x = 0; x < size; x++ )
|
for ( final IAEItemStack is : currentlyOnStorage )
|
||||||
{
|
{
|
||||||
// Save the old stuff
|
currentlyCached.add( is );
|
||||||
final IAEItemStack oldAeIS = this.cachedAeStacks[x];
|
|
||||||
final IAEItemStack newIS = out.get( x );
|
|
||||||
|
|
||||||
this.handlePossibleSlotChanges( x, oldAeIS, newIS, changes );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle cases where the number of slots actually is lower now than before
|
for ( final IAEItemStack is : currentlyCached )
|
||||||
if( size < this.cachedAeStacks.length )
|
|
||||||
{
|
{
|
||||||
for( int x = 0; x < this.cachedAeStacks.length; x++ )
|
if( is.getStackSize() != 0 )
|
||||||
{
|
{
|
||||||
final IAEItemStack aeStack = this.cachedAeStacks[x];
|
changes.add( is );
|
||||||
|
|
||||||
if( aeStack != null )
|
|
||||||
{
|
|
||||||
final IAEItemStack a = aeStack.copy();
|
|
||||||
a.setStackSize( -a.getStackSize() );
|
|
||||||
changes.add( a );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reduce the cache size
|
|
||||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, size );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentlyCached = currentlyOnStorage;
|
||||||
|
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePossibleSlotChanges( int slot, IAEItemStack oldAeIS, IAEItemStack newIS, List<IAEItemStack> changes )
|
|
||||||
{
|
|
||||||
if( oldAeIS != null && oldAeIS.isSameType( newIS ) )
|
|
||||||
{
|
|
||||||
this.handleStackSizeChanged( slot, oldAeIS, newIS, changes );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.handleItemChanged( slot, oldAeIS, newIS, changes );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleStackSizeChanged( int slot, IAEItemStack oldAeIS, IAEItemStack newIS, List<IAEItemStack> changes )
|
|
||||||
{
|
|
||||||
// Still the same item, but amount might have changed
|
|
||||||
final long diff = newIS.getStackSize() - oldAeIS.getStackSize();
|
|
||||||
|
|
||||||
if( diff != 0 )
|
|
||||||
{
|
|
||||||
final IAEItemStack stack = oldAeIS.copy();
|
|
||||||
stack.setStackSize( newIS.getStackSize() );
|
|
||||||
|
|
||||||
this.cachedAeStacks[slot] = stack;
|
|
||||||
|
|
||||||
final IAEItemStack a = stack.copy();
|
|
||||||
a.setStackSize( diff );
|
|
||||||
changes.add( a );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleItemChanged( int slot, IAEItemStack oldAeIS, IAEItemStack newIS, List<IAEItemStack> changes )
|
|
||||||
{
|
|
||||||
// Completely different item
|
|
||||||
this.cachedAeStacks[slot] = newIS ;
|
|
||||||
|
|
||||||
// If we had a stack previously in this slot, notify the network about its disappearance
|
|
||||||
if( oldAeIS != null )
|
|
||||||
{
|
|
||||||
oldAeIS.setStackSize( -oldAeIS.getStackSize() );
|
|
||||||
changes.add( oldAeIS );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify the network about the new stack. Note that this is null if newIS was null
|
|
||||||
if( this.cachedAeStacks[slot] != null )
|
|
||||||
{
|
|
||||||
changes.add( this.cachedAeStacks[slot] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,195 +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 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;
|
|
||||||
|
|
||||||
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 )
|
|
||||||
{
|
|
||||||
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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user