Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e09f74cb5f | |||
| facc1b4ef4 | |||
| 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 | |||
| 24750f00b1 |
+13
-2
@@ -15,6 +15,10 @@ Fixes:
|
||||
- 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
|
||||
- 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:
|
||||
|
||||
@@ -24,6 +28,9 @@ Performance:
|
||||
- Count items set in interfaces before queuing crafting for them needlessly
|
||||
- Backported b7ca98d ( Avoid copying items on simulated item extraction )
|
||||
- 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:
|
||||
|
||||
@@ -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 )
|
||||
- Shortcut to molecular assemblers with free slots on the terminal interface by @Theisyat
|
||||
- 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. )
|
||||
- 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 )
|
||||
@@ -39,7 +46,11 @@ QOL:
|
||||
- Encoded patterns can be draggred on the interface terminal.
|
||||
- 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)
|
||||
-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:
|
||||
|
||||
|
||||
@@ -44,10 +44,7 @@ public interface IStackWatcherHost
|
||||
/**
|
||||
* Called when a watched item changes amounts.
|
||||
*
|
||||
* @param o changed item list
|
||||
* @param fullStack old stack
|
||||
* @param diffStack new stack
|
||||
* @param src action source
|
||||
* @param chan storage channel
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -22,10 +22,9 @@ package appeng.client.render;
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.renderer.*;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.RenderItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
@@ -33,7 +32,6 @@ import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.util.IWideReadableNumberConverter;
|
||||
import appeng.util.ReadableNumberConverter;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
|
||||
/**
|
||||
@@ -123,49 +121,6 @@ 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.
|
||||
*
|
||||
@@ -192,9 +147,9 @@ public class TesrRenderHelper
|
||||
|
||||
public static void renderFluid2dWithAmount( IAEFluidStack fluidStack, float scale, float spacing )
|
||||
{
|
||||
final FluidStack renderStack = fluidStack.getFluidStack();
|
||||
final ItemStack renderStack = fluidStack.asItemStackRepresentation();
|
||||
|
||||
TesrRenderHelper.renderFluid2d( renderStack, scale );
|
||||
TesrRenderHelper.renderItem2d( renderStack, scale );
|
||||
|
||||
final long stackSize = fluidStack.getStackSize() / 1000;
|
||||
final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm( stackSize ) + "B";
|
||||
|
||||
@@ -22,6 +22,7 @@ package appeng.crafting;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import appeng.me.cache.CraftingGridCache;
|
||||
import com.google.common.base.Stopwatch;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -71,6 +72,8 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
private boolean done = false;
|
||||
private int time;
|
||||
private int incTime;
|
||||
private final ICraftingGrid cc;
|
||||
private final IStorageGrid sg;
|
||||
|
||||
private World wrapWorld( final World w )
|
||||
{
|
||||
@@ -84,10 +87,9 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
this.actionSrc = actionSrc;
|
||||
|
||||
this.callback = callback;
|
||||
final ICraftingGrid cc = grid.getCache( ICraftingGrid.class );
|
||||
final IStorageGrid sg = grid.getCache( IStorageGrid.class );
|
||||
this.original = new MECraftingInventory( sg
|
||||
.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ), actionSrc, false, false, false );
|
||||
this.cc = grid.getCache( ICraftingGrid.class );
|
||||
this.sg = grid.getCache( IStorageGrid.class );
|
||||
this.original = new MECraftingInventory( sg.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ), actionSrc, false, false, false );
|
||||
|
||||
this.setTree( this.getCraftingTree( cc, what ) );
|
||||
this.availableCheck = null;
|
||||
@@ -325,25 +327,9 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
{
|
||||
this.watch.reset();
|
||||
this.watch.start();
|
||||
this.running = true;
|
||||
|
||||
AELog.craftingDebug( "main thread is now going to sleep" );
|
||||
|
||||
this.monitor.notify();
|
||||
|
||||
while ( this.running )
|
||||
{
|
||||
try
|
||||
{
|
||||
this.monitor.wait();
|
||||
}
|
||||
catch( final InterruptedException ignored )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
AELog.craftingDebug( "main thread is now active" );
|
||||
}
|
||||
this.running = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -396,6 +382,11 @@ public class CraftingJob implements Runnable, ICraftingJob
|
||||
}
|
||||
}
|
||||
|
||||
public void addIncompletablePattern( ICraftingPatternDetails details, IAEItemStack stack )
|
||||
{
|
||||
( (CraftingGridCache) cc ).getPatternStatusManager().put( details, stack );
|
||||
}
|
||||
|
||||
private static class TwoIntegers
|
||||
{
|
||||
private final long perOp = 0;
|
||||
|
||||
@@ -22,7 +22,10 @@ package appeng.crafting;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import appeng.util.item.OreHelper;
|
||||
import appeng.util.item.OreReference;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
@@ -117,6 +120,11 @@ public class CraftingTreeNode
|
||||
return this.parent.notRecursive( details );
|
||||
}
|
||||
|
||||
public CraftingTreeProcess getParent()
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
IAEItemStack request( final MECraftingInventory inv, long l, final IActionSource src ) throws CraftBranchFailure, InterruptedException
|
||||
{
|
||||
this.job.handlePausing();
|
||||
@@ -318,6 +326,7 @@ public class CraftingTreeNode
|
||||
if( this.missing > 0 )
|
||||
{
|
||||
job.addMissing( this.getStack( this.missing ) );
|
||||
addMissingIAEStack();
|
||||
}
|
||||
// missing = 0;
|
||||
|
||||
@@ -329,6 +338,29 @@ public class CraftingTreeNode
|
||||
}
|
||||
}
|
||||
|
||||
void addMissingIAEStack()
|
||||
{
|
||||
if( parent != null )
|
||||
{
|
||||
parent.addMissingIAEStack();
|
||||
if( missing > 0 )
|
||||
{
|
||||
if( this.parent.details.canSubstitute() && this.getSlot() >= 0 )
|
||||
{
|
||||
final List<IAEItemStack> substitutes = this.parent.details.getSubstituteInputs( this.slot );
|
||||
for( IAEItemStack stack : substitutes )
|
||||
{
|
||||
job.addIncompletablePattern( this.getParent().details, stack.copy().setStackSize( this.missing ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
job.addIncompletablePattern( this.getParent().details, this.getStack( this.missing ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IAEItemStack getStack( final long size )
|
||||
{
|
||||
final IAEItemStack is = this.what.copy();
|
||||
|
||||
@@ -23,11 +23,10 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import appeng.me.cache.CraftingGridCache;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.Actionable;
|
||||
@@ -66,7 +65,7 @@ public class CraftingTreeProcess
|
||||
this.depth = depth;
|
||||
final World world = job.getWorld();
|
||||
|
||||
if( details.isCraftable() )
|
||||
if( !( (CraftingGridCache) cc ).getPatternStatusManager().containsIncompletablePattern( details ) && details.isCraftable() )
|
||||
{
|
||||
final IAEItemStack[] list = details.getInputs();
|
||||
|
||||
@@ -174,6 +173,11 @@ public class CraftingTreeProcess
|
||||
return this.parent == null || this.parent.notRecursive( details );
|
||||
}
|
||||
|
||||
public CraftingTreeNode getParent()
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
long getTimes( final long remaining, final long stackSize )
|
||||
{
|
||||
if( this.limitQty || this.fullSimulation )
|
||||
@@ -305,7 +309,7 @@ public class CraftingTreeProcess
|
||||
|
||||
void getPlan( final IItemList<IAEItemStack> plan )
|
||||
{
|
||||
for( IAEItemStack i : this.details.getOutputs() )
|
||||
for( IAEItemStack i : this.details.getCondensedOutputs() )
|
||||
{
|
||||
i = i.copy();
|
||||
i.setCountRequestable( i.getStackSize() * this.crafts );
|
||||
@@ -317,4 +321,12 @@ public class CraftingTreeProcess
|
||||
pro.getPlan( plan );
|
||||
}
|
||||
}
|
||||
|
||||
public void addMissingIAEStack()
|
||||
{
|
||||
if( parent != null )
|
||||
{
|
||||
parent.addMissingIAEStack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,16 +19,15 @@
|
||||
package appeng.fluids.parts;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Settings;
|
||||
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.capability.IFluidHandler;
|
||||
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.IItemList;
|
||||
import appeng.fluids.util.AEFluidStack;
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.me.helpers.IGridProxyable;
|
||||
import appeng.me.storage.ITickingMonitor;
|
||||
|
||||
@@ -65,17 +63,20 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
||||
private final IGridProxyable proxyable;
|
||||
private final FluidHandlerAdapter.InventoryCache cache;
|
||||
private StorageFilter mode;
|
||||
private AccessRestriction access;
|
||||
|
||||
FluidHandlerAdapter( IFluidHandler fluidHandler, IGridProxyable proxy )
|
||||
{
|
||||
this.fluidHandler = fluidHandler;
|
||||
this.proxyable = proxy;
|
||||
if( this.proxyable instanceof PartStorageBus )
|
||||
if( this.proxyable instanceof PartFluidStorageBus )
|
||||
{
|
||||
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
|
||||
this.mode = ( (StorageFilter) partStorageBus.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
|
||||
PartFluidStorageBus partFluidStorageBus = (PartFluidStorageBus) this.proxyable;
|
||||
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
|
||||
@@ -94,11 +95,14 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
||||
|
||||
if( type == Actionable.MODULATE )
|
||||
{
|
||||
IAEFluidStack added = input.copy().setStackSize( input.getStackSize() - remaining );
|
||||
this.cache.currentlyCached.add( added );
|
||||
this.postDifference( Collections.singletonList( added ) );
|
||||
try
|
||||
{
|
||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||
}
|
||||
catch( GridAccessException ignore )
|
||||
catch( GridAccessException ex )
|
||||
{
|
||||
// meh
|
||||
}
|
||||
@@ -123,25 +127,32 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
||||
return null;
|
||||
}
|
||||
|
||||
IAEFluidStack gatheredAEFluidstack = AEFluidStack.fromFluidStack( gathered );
|
||||
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
|
||||
{
|
||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||
}
|
||||
catch( GridAccessException ignore )
|
||||
catch( GridAccessException ex )
|
||||
{
|
||||
// meh
|
||||
}
|
||||
}
|
||||
return AEFluidStack.fromFluidStack( gathered );
|
||||
return gatheredAEFluidstack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TickRateModulation onTick()
|
||||
{
|
||||
List<IAEFluidStack> changes = this.cache.update();
|
||||
if( !changes.isEmpty() )
|
||||
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
|
||||
{
|
||||
this.postDifference( changes );
|
||||
return TickRateModulation.URGENT;
|
||||
@@ -202,9 +213,9 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
||||
|
||||
private static class InventoryCache
|
||||
{
|
||||
private IAEFluidStack[] cachedAeStacks = new IAEFluidStack[0];
|
||||
private final IFluidHandler fluidHandler;
|
||||
private final StorageFilter mode;
|
||||
IItemList<IAEFluidStack> currentlyCached = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
|
||||
|
||||
public InventoryCache( IFluidHandler fluidHandler, StorageFilter mode )
|
||||
{
|
||||
@@ -216,19 +227,12 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
||||
{
|
||||
final List<IAEFluidStack> changes = new ArrayList<>();
|
||||
final IFluidTankProperties[] tankProperties = this.fluidHandler.getTankProperties();
|
||||
final int slots = tankProperties.length;
|
||||
|
||||
// Make room for new slots
|
||||
if( slots > this.cachedAeStacks.length )
|
||||
{
|
||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
||||
}
|
||||
IItemList<IAEFluidStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
|
||||
|
||||
for( int slot = 0; slot < slots; slot++ )
|
||||
for( IFluidTankProperties tankProperty : tankProperties )
|
||||
{
|
||||
// Save the old stuff
|
||||
final IAEFluidStack oldAEFS = this.cachedAeStacks[slot];
|
||||
FluidStack newFS = tankProperties[slot].getContents();
|
||||
FluidStack newFS = tankProperty.getContents();
|
||||
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && newFS != null )
|
||||
{
|
||||
if( this.fluidHandler.drain( 1, false ) == null )
|
||||
@@ -236,82 +240,40 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
|
||||
newFS = null;
|
||||
}
|
||||
}
|
||||
this.handlePossibleSlotChanges( slot, oldAEFS, newFS, changes );
|
||||
}
|
||||
|
||||
// Handle cases where the number of slots actually is lower now than before
|
||||
if( slots < this.cachedAeStacks.length )
|
||||
{
|
||||
for( int slot = slots; slot < this.cachedAeStacks.length; slot++ )
|
||||
if( newFS != null )
|
||||
{
|
||||
final IAEFluidStack aeStack = this.cachedAeStacks[slot];
|
||||
|
||||
if( aeStack != null )
|
||||
{
|
||||
final IAEFluidStack a = aeStack.copy();
|
||||
a.setStackSize( -a.getStackSize() );
|
||||
changes.add( a );
|
||||
}
|
||||
currentlyOnStorage.add( AEFluidStack.fromFluidStack( newFS ) );
|
||||
}
|
||||
|
||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
||||
}
|
||||
|
||||
for ( final IAEFluidStack is : currentlyCached )
|
||||
{
|
||||
is.setStackSize( -is.getStackSize() );
|
||||
}
|
||||
|
||||
for ( final IAEFluidStack is : currentlyOnStorage )
|
||||
{
|
||||
currentlyCached.add( is );
|
||||
}
|
||||
|
||||
for ( final IAEFluidStack is : currentlyCached )
|
||||
{
|
||||
if( is.getStackSize() != 0 )
|
||||
{
|
||||
changes.add( is );
|
||||
}
|
||||
}
|
||||
|
||||
currentlyCached = currentlyOnStorage;
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
public IItemList<IAEFluidStack> getAvailableItems( IItemList<IAEFluidStack> out )
|
||||
{
|
||||
Arrays.stream( this.cachedAeStacks ).forEach( out::add );
|
||||
currentlyCached.iterator().forEachRemaining( out::add );
|
||||
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] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ public class PartFluidFormationPlane extends PartAbstractFormationPlane<IAEFluid
|
||||
@Override
|
||||
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 );
|
||||
handler.add( this.myHandler );
|
||||
|
||||
@@ -4,7 +4,10 @@ package appeng.fluids.parts;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import appeng.api.networking.events.MENetworkChannelChanged;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.fluids.helper.IConfigurableFluidInventory;
|
||||
import appeng.me.cache.NetworkMonitor;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
@@ -34,7 +37,6 @@ import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.channels.IFluidStorageChannel;
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.api.util.AECableType;
|
||||
import appeng.api.util.AEPartLocation;
|
||||
import appeng.api.util.IConfigManager;
|
||||
@@ -114,9 +116,9 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
|
||||
@Override
|
||||
public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan )
|
||||
{
|
||||
if( chan == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) && fullStack.equals( this.config.getFluidInSlot( 0 ) ) )
|
||||
if( chan == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) && diffStack.equals( this.config.getFluidInSlot( 0 ) ) )
|
||||
{
|
||||
this.lastReportedValue = fullStack.getStackSize();
|
||||
this.lastReportedValue += diffStack.getStackSize();
|
||||
this.updateState();
|
||||
}
|
||||
}
|
||||
@@ -128,14 +130,22 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void channelChanged( final MENetworkChannelsChanged c )
|
||||
public void powerStatusChange( final MENetworkPowerStatusChange powerEvent )
|
||||
{
|
||||
if (this.getProxy().isActive())
|
||||
{
|
||||
onListUpdate();
|
||||
}
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void powerChanged( final MENetworkPowerStatusChange c )
|
||||
public void channelChanged( final MENetworkChannelsChanged c )
|
||||
{
|
||||
if (this.getProxy().isActive())
|
||||
{
|
||||
onListUpdate();
|
||||
}
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
@@ -247,10 +257,9 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
|
||||
|
||||
if( myStack == null )
|
||||
{
|
||||
this.lastReportedValue = 0;
|
||||
for( final IAEFluidStack st : monitor.getStorageList() )
|
||||
if( monitor instanceof NetworkMonitor )
|
||||
{
|
||||
this.lastReportedValue += st.getStackSize();
|
||||
this.lastReportedValue = ( (NetworkMonitor<IAEFluidStack>) monitor ).getGridCurrentCount();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.Objects;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import appeng.fluids.helper.IConfigurableFluidInventory;
|
||||
import appeng.util.ConfigManager;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
@@ -167,11 +168,28 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
|
||||
final boolean fullReset = this.resetCacheLogic == 2;
|
||||
this.resetCacheLogic = 0;
|
||||
|
||||
final IMEInventory<IAEFluidStack> in = this.getInternalHandler();
|
||||
final MEInventoryHandler<IAEFluidStack> in = this.getInternalHandler();
|
||||
IItemList<IAEFluidStack> before = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
|
||||
boolean denyRead = false;
|
||||
if( in != null )
|
||||
{
|
||||
before = in.getAvailableItems( before );
|
||||
if( accessChanged )
|
||||
{
|
||||
AccessRestriction currentAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS );
|
||||
AccessRestriction oldAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getOldSetting( Settings.ACCESS );
|
||||
if( oldAccess.hasPermission( AccessRestriction.READ ) && !currentAccess.hasPermission( AccessRestriction.READ ) )
|
||||
{
|
||||
denyRead = true;
|
||||
}
|
||||
in.setBaseAccess( oldAccess );
|
||||
before = in.getAvailableItems( before );
|
||||
in.setBaseAccess( currentAccess );
|
||||
accessChanged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
before = in.getAvailableItems( before );
|
||||
}
|
||||
}
|
||||
|
||||
this.cached = false;
|
||||
@@ -180,15 +198,17 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
|
||||
this.handlerHash = 0;
|
||||
}
|
||||
|
||||
final IMEInventory<IAEFluidStack> out = this.getInternalHandler();
|
||||
final MEInventoryHandler<IAEFluidStack> out = this.getInternalHandler();
|
||||
|
||||
if( in != out )
|
||||
if( in != out || denyRead )
|
||||
{
|
||||
IItemList<IAEFluidStack> after = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
|
||||
if( out != null )
|
||||
|
||||
if( out != null && !denyRead )
|
||||
{
|
||||
after = out.getAvailableItems( after );
|
||||
}
|
||||
|
||||
Platform.postListChanges( before, after, this, this.source );
|
||||
}
|
||||
}
|
||||
@@ -264,20 +284,25 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
|
||||
@Override
|
||||
public void postChange( final IBaseMonitor<IAEFluidStack> monitor, final Iterable<IAEFluidStack> change, final IActionSource source )
|
||||
{
|
||||
if( source == this.source || source.machine().map( machine -> machine == this ).orElse( false ) )
|
||||
if( this.source.machine().map( machine -> machine == this ).orElse( false ) && monitor != null )
|
||||
{
|
||||
try
|
||||
AccessRestriction currentAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS );
|
||||
if( !currentAccess.hasPermission( AccessRestriction.READ ) )
|
||||
{
|
||||
if( this.getProxy().isActive() )
|
||||
{
|
||||
this.getProxy().getStorage().postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ), change, this.source );
|
||||
}
|
||||
return;
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
}
|
||||
try
|
||||
{
|
||||
if( this.getProxy().isActive() )
|
||||
{
|
||||
// :(
|
||||
this.getProxy().getStorage().postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ), change, this.source );
|
||||
}
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
{
|
||||
// :(
|
||||
}
|
||||
}
|
||||
|
||||
public MEInventoryHandler<IAEFluidStack> getInternalHandler()
|
||||
@@ -415,7 +440,7 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
|
||||
{
|
||||
if( channel == this.getStorageChannel() )
|
||||
{
|
||||
final IMEInventoryHandler<IAEFluidStack> out = this.getProxy().isActive() ? this.getInternalHandler() : null;
|
||||
final IMEInventoryHandler<IAEFluidStack> out = this.getInternalHandler();
|
||||
if( out != null )
|
||||
{
|
||||
return Collections.singletonList( out );
|
||||
|
||||
@@ -24,9 +24,12 @@ import java.util.*;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import appeng.api.definitions.IItemDefinition;
|
||||
import appeng.api.networking.crafting.*;
|
||||
import appeng.integration.modules.gregtech.GTCEInventoryAdaptor;
|
||||
import appeng.me.cache.CraftingGridCache;
|
||||
import appeng.util.*;
|
||||
import appeng.util.inv.*;
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import de.ellpeck.actuallyadditions.api.tile.IPhantomTile;
|
||||
@@ -65,10 +68,6 @@ import appeng.api.implementations.tiles.ICraftingMachine;
|
||||
import appeng.api.networking.GridFlags;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.crafting.ICraftingLink;
|
||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||
import appeng.api.networking.crafting.ICraftingProvider;
|
||||
import appeng.api.networking.crafting.ICraftingProviderHelper;
|
||||
import appeng.api.networking.energy.IEnergySource;
|
||||
import appeng.api.networking.events.MENetworkCraftingPatternChange;
|
||||
import appeng.api.networking.security.IActionHost;
|
||||
@@ -110,7 +109,6 @@ import static gregtech.api.block.machines.BlockMachine.getMetaTileEntity;
|
||||
|
||||
public class DualityInterface implements IGridTickable, IStorageMonitorable, IInventoryDestination, IAEAppEngInventory, IConfigManagerHost, ICraftingProvider, IUpgradeableHost
|
||||
{
|
||||
private int[] failedCraftTriesSlot = {0,0,0,0,0,0,0,0,0};
|
||||
|
||||
public static final int NUMBER_OF_STORAGE_SLOTS = 9;
|
||||
public static final int NUMBER_OF_CONFIG_SLOTS = 9;
|
||||
@@ -931,17 +929,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
{
|
||||
if( this.getInstalledUpgrades( Upgrades.CRAFTING ) > 0 && itemStack != null )
|
||||
{
|
||||
if (this.failedCraftTriesSlot[x] <= 0)
|
||||
{
|
||||
boolean crafted = this.craftingTracker.handleCrafting( x, itemStack.getStackSize(), itemStack, d, this.iHost.getTileEntity().getWorld(),
|
||||
this.gridProxy.getGrid(), this.gridProxy.getCrafting(), this.mySource );
|
||||
|
||||
if (crafted) this.failedCraftTriesSlot[x] = 0;
|
||||
else{
|
||||
this.failedCraftTriesSlot[x] += 2;
|
||||
}
|
||||
}
|
||||
this.failedCraftTriesSlot[x] -= 1;
|
||||
return this.craftingTracker.handleCrafting( x, itemStack.getStackSize(), itemStack, d, this.iHost.getTileEntity().getWorld(), this.gridProxy.getGrid(), this.gridProxy.getCrafting(), this.mySource );
|
||||
}
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
|
||||
@@ -22,6 +22,9 @@ package appeng.helpers;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import appeng.api.networking.crafting.*;
|
||||
import appeng.me.cache.CraftingGridCache;
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
@@ -29,10 +32,6 @@ import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
import appeng.api.networking.crafting.ICraftingJob;
|
||||
import appeng.api.networking.crafting.ICraftingLink;
|
||||
import appeng.api.networking.crafting.ICraftingRequester;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.util.InventoryAdaptor;
|
||||
@@ -132,6 +131,17 @@ public class MultiCraftingTracker
|
||||
final IAEItemStack aisC = ais.copy();
|
||||
aisC.setStackSize( itemToCraft );
|
||||
|
||||
CraftingGridCache cgc = (CraftingGridCache) cg;
|
||||
|
||||
ImmutableCollection<ICraftingPatternDetails> cl = cgc.getCraftingFor( aisC, null, x, w );
|
||||
for( ICraftingPatternDetails craftingPatternDetails : cl )
|
||||
{
|
||||
if( cgc.getPatternStatusManager().containsIncompletablePattern( craftingPatternDetails ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
this.setJob( x, cg.beginCraftingJob( w, g, mySrc, aisC, null ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
|
||||
}
|
||||
}
|
||||
}
|
||||
final int outputLength = out.size();
|
||||
final int outputLength = this.isCrafting ? CRAFTING_OUTPUT_LIMIT : PROCESSING_OUTPUT_LIMIT;
|
||||
|
||||
this.inputs = in.toArray(new IAEItemStack[ALL_INPUT_LIMIT]);
|
||||
this.outputs = out.toArray(new IAEItemStack[outputLength]);
|
||||
|
||||
@@ -225,7 +225,7 @@ public class ItemEncodedPattern extends AEBaseItem implements ICraftingPatternIt
|
||||
|
||||
final ICraftingPatternDetails details = this.getPatternForItem( item, w );
|
||||
|
||||
out = details != null ? details.getOutputs()[0].createItemStack() : ItemStack.EMPTY;
|
||||
out = details != null ? details.getCondensedOutputs()[0].createItemStack() : ItemStack.EMPTY;
|
||||
|
||||
SIMPLE_CACHE.put( item, out );
|
||||
return out;
|
||||
|
||||
+29
-14
@@ -30,22 +30,19 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import appeng.me.helpers.PatternStatusManager;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
||||
import it.unimi.dsi.fastutil.objects.*;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
@@ -270,20 +267,17 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
// coalesce change events during a grid traversal to a single rebuild
|
||||
if (pauseRebuilds != 0)
|
||||
{
|
||||
rebuildNeeded.add(this);
|
||||
rebuildNeeded.add( this );
|
||||
return;
|
||||
}
|
||||
|
||||
final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = this.craftableItems;
|
||||
final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = new Object2ObjectOpenHashMap<>( this.craftableItems );
|
||||
|
||||
// erase list.
|
||||
this.craftingMethods.clear();
|
||||
this.craftableItems.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() );
|
||||
( (GridStorageCache) this.storageGrid ).clearPatternStatus();
|
||||
|
||||
// re-create list..
|
||||
for( final ICraftingProvider provider : this.craftingProviders )
|
||||
@@ -296,7 +290,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
// new craftables!
|
||||
for( final ICraftingPatternDetails details : this.craftingMethods.keySet() )
|
||||
{
|
||||
for( IAEItemStack out : details.getOutputs() )
|
||||
for( IAEItemStack out : details.getCondensedOutputs() )
|
||||
{
|
||||
out = out.copy();
|
||||
out.reset();
|
||||
@@ -319,7 +313,23 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
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() )) {
|
||||
craftablesChanged.put( ais.getKey().setCraftable( false ), ais.getValue() );
|
||||
}
|
||||
}
|
||||
|
||||
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> j = this.craftableItems.entrySet();
|
||||
for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : j) {
|
||||
if (!oldItems.containsKey( ais )){
|
||||
craftablesChanged.put( ais.getKey().setCraftable( true ), ais.getValue() );
|
||||
}
|
||||
}
|
||||
|
||||
this.storageGrid.postCraftablesChanges( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), craftablesChanged.keySet(),
|
||||
new BaseActionSource() );
|
||||
}
|
||||
|
||||
@@ -639,7 +649,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
|
||||
public boolean hasCpu( final ICraftingCPU cpu )
|
||||
{
|
||||
if (cpu instanceof CraftingCPUCluster)
|
||||
if( cpu instanceof CraftingCPUCluster )
|
||||
{
|
||||
return this.craftingCPUClusters.contains( (CraftingCPUCluster) cpu );
|
||||
}
|
||||
@@ -651,6 +661,11 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
|
||||
return this.interestManager;
|
||||
}
|
||||
|
||||
public PatternStatusManager getPatternStatusManager()
|
||||
{
|
||||
return ( (GridStorageCache) this.storageGrid ).getPatternStatusManager();
|
||||
}
|
||||
|
||||
private static class ActiveCpuIterator implements Iterator<ICraftingCPU>
|
||||
{
|
||||
|
||||
|
||||
+215
-55
@@ -19,20 +19,10 @@
|
||||
package appeng.me.cache;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import com.google.common.collect.HashMultiset;
|
||||
import com.google.common.collect.Multiset;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.*;
|
||||
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Actionable;
|
||||
@@ -63,8 +53,9 @@ import appeng.me.energy.EnergyWatcher;
|
||||
public class EnergyGridCache implements IEnergyGrid
|
||||
{
|
||||
|
||||
private static final double MAX_BUFFER_STORAGE = 200;
|
||||
private static final Comparator<IEnergyGridProvider> COMPARATOR_HIGHEST_AMOUNT_STORED_FIRST = ( o1, o2 ) -> Double.compare( o2.getProviderStoredEnergy(), o1.getProviderStoredEnergy() );
|
||||
private static final double MAX_BUFFER_STORAGE = 800;
|
||||
private static final Comparator<IEnergyGridProvider> COMPARATOR_HIGHEST_AMOUNT_STORED_FIRST = ( o1, o2 ) -> Double.compare( o2.getProviderStoredEnergy(),
|
||||
o1.getProviderStoredEnergy() );
|
||||
|
||||
private static final Comparator<IEnergyGridProvider> COMPARATOR_LOWEST_PERCENTAGE_FIRST = ( o1, o2 ) ->
|
||||
{
|
||||
@@ -75,9 +66,24 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
};
|
||||
|
||||
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 Set<IAEPowerStorage> providers = new LinkedHashSet<>();
|
||||
private final Set<IAEPowerStorage> requesters = new LinkedHashSet<>();
|
||||
private final Multimap<Integer,IAEPowerStorage> providers = HashMultimap.create();
|
||||
// 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 Multimap<Integer,IAEPowerStorage> requesters = HashMultimap.create();
|
||||
// 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 IGrid myGrid;
|
||||
private final HashMap<IGridNode, IEnergyWatcher> watchers = new HashMap<>();
|
||||
@@ -109,12 +115,16 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
private double lastStoredPower = -1;
|
||||
|
||||
private final GridPowerStorage localStorage = new GridPowerStorage();
|
||||
private Set<IAEPowerStorage> providersToRemove = new HashSet<>();
|
||||
private Set<IAEPowerStorage> requestersToRemove = new HashSet<>();
|
||||
private Set<IAEPowerStorage> providersToAdd = new HashSet<>();
|
||||
private Set<IAEPowerStorage> requestersToAdd = new HashSet<>();
|
||||
|
||||
public EnergyGridCache( final IGrid g )
|
||||
{
|
||||
this.myGrid = g;
|
||||
this.requesters.add( this.localStorage );
|
||||
this.providers.add( this.localStorage );
|
||||
this.requesters.put( 0, this.localStorage );
|
||||
this.providers.put( 1, this.localStorage );
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
@@ -147,13 +157,27 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
case PROVIDE_POWER:
|
||||
if( ev.storage.getPowerFlow() != AccessRestriction.WRITE )
|
||||
{
|
||||
this.providers.add( ev.storage );
|
||||
if( !ongoingExtractOperation )
|
||||
{
|
||||
addProvider( ev.storage );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.providersToAdd.add( ev.storage );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case REQUEST_POWER:
|
||||
if( ev.storage.getPowerFlow() != AccessRestriction.READ )
|
||||
{
|
||||
this.requesters.add( ev.storage );
|
||||
if( !ongoingInjectOperation )
|
||||
{
|
||||
addRequester( ev.storage );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.requestersToAdd.add( ev.storage );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -283,7 +307,7 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
{
|
||||
this.availableTicksSinceUpdate = 0;
|
||||
this.globalAvailablePower = 0;
|
||||
for( final IAEPowerStorage p : this.providers )
|
||||
for( final IAEPowerStorage p : this.providers.values() )
|
||||
{
|
||||
this.globalAvailablePower += p.getAECurrentPower();
|
||||
}
|
||||
@@ -300,20 +324,50 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
{
|
||||
double extractedPower = 0;
|
||||
|
||||
final Iterator<IAEPowerStorage> it = this.providers.iterator();
|
||||
|
||||
while ( extractedPower < amt && it.hasNext() )
|
||||
{
|
||||
final IAEPowerStorage node = it.next();
|
||||
|
||||
final double req = amt - extractedPower;
|
||||
final double newPower = node.extractAEPower( req, mode, PowerMultiplier.ONE );
|
||||
extractedPower += newPower;
|
||||
|
||||
if( newPower < req && mode == Actionable.MODULATE )
|
||||
providersToAdd.forEach( provider -> {
|
||||
if( provider instanceof GridPowerStorage )
|
||||
{
|
||||
it.remove();
|
||||
providers.put( 1, provider );
|
||||
}
|
||||
else
|
||||
{
|
||||
providers.put( 0, provider );
|
||||
}
|
||||
} );
|
||||
providersToAdd.clear();
|
||||
|
||||
final Iterator<IAEPowerStorage> it = this.providers.values().iterator();
|
||||
|
||||
ongoingExtractOperation = true;
|
||||
try
|
||||
{
|
||||
while ( extractedPower < amt && it.hasNext() )
|
||||
{
|
||||
final IAEPowerStorage node = it.next();
|
||||
|
||||
final double req = amt - extractedPower;
|
||||
final double newPower = node.extractAEPower( req, mode, PowerMultiplier.ONE );
|
||||
extractedPower += newPower;
|
||||
|
||||
if( newPower < req && mode == Actionable.MODULATE )
|
||||
{
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
} finally
|
||||
{
|
||||
providersToRemove.forEach( provider -> {
|
||||
if( provider instanceof GridPowerStorage )
|
||||
{
|
||||
providers.remove( 1, provider );
|
||||
}
|
||||
else
|
||||
{
|
||||
providers.remove( 0, provider );
|
||||
}
|
||||
} );
|
||||
this.providersToRemove.clear();
|
||||
ongoingExtractOperation = false;
|
||||
}
|
||||
|
||||
final double result = Math.min( extractedPower, amt );
|
||||
@@ -337,17 +391,48 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
{
|
||||
final double originalAmount = amt;
|
||||
|
||||
final Iterator<IAEPowerStorage> it = this.requesters.iterator();
|
||||
|
||||
while ( amt > 0 && it.hasNext() )
|
||||
{
|
||||
final IAEPowerStorage node = it.next();
|
||||
amt = node.injectAEPower( amt, mode );
|
||||
|
||||
if( amt > 0 && mode == Actionable.MODULATE )
|
||||
requestersToAdd.forEach( requester -> {
|
||||
if( requester instanceof GridPowerStorage )
|
||||
{
|
||||
it.remove();
|
||||
requesters.put( 0, requester );
|
||||
}
|
||||
else
|
||||
{
|
||||
requesters.put( 1, requester );
|
||||
}
|
||||
} );
|
||||
requestersToAdd.clear();
|
||||
|
||||
final Iterator<IAEPowerStorage> it = this.requesters.values().iterator();
|
||||
|
||||
ongoingInjectOperation = true;
|
||||
try
|
||||
{
|
||||
while ( amt > 0 && it.hasNext() )
|
||||
{
|
||||
final IAEPowerStorage node = it.next();
|
||||
|
||||
amt = node.injectAEPower( amt, mode );
|
||||
|
||||
if( amt > 0 && mode == Actionable.MODULATE )
|
||||
{
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
} finally
|
||||
{
|
||||
requestersToRemove.forEach( requester -> {
|
||||
if( requester instanceof GridPowerStorage )
|
||||
{
|
||||
requesters.remove( 0, requester );
|
||||
}
|
||||
else
|
||||
{
|
||||
requesters.remove( 1, requester );
|
||||
}
|
||||
} );
|
||||
this.requestersToRemove.clear();
|
||||
ongoingInjectOperation = false;
|
||||
}
|
||||
|
||||
final double overflow = Math.max( 0.0, amt );
|
||||
@@ -365,7 +450,7 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
{
|
||||
double required = 0;
|
||||
|
||||
final Iterator<IAEPowerStorage> it = this.requesters.iterator();
|
||||
final Iterator<IAEPowerStorage> it = this.requesters.values().iterator();
|
||||
while( required < maxRequired && it.hasNext() )
|
||||
{
|
||||
final IAEPowerStorage node = it.next();
|
||||
@@ -427,11 +512,7 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
@Override
|
||||
public double getStoredPower()
|
||||
{
|
||||
if( this.availableTicksSinceUpdate > 90 )
|
||||
{
|
||||
this.refreshPower();
|
||||
}
|
||||
|
||||
this.refreshPower();
|
||||
return Math.max( 0.0, this.globalAvailablePower );
|
||||
}
|
||||
|
||||
@@ -504,9 +585,22 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
this.globalMaxPower -= ps.getAEMaxPower();
|
||||
this.globalAvailablePower -= ps.getAECurrentPower();
|
||||
}
|
||||
|
||||
this.providers.remove( ps );
|
||||
this.requesters.remove( ps );
|
||||
if( !ongoingExtractOperation )
|
||||
{
|
||||
removeProvider( ps );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.providersToRemove.add( ps );
|
||||
}
|
||||
if( !ongoingInjectOperation )
|
||||
{
|
||||
removeRequester( ps );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.requestersToRemove.add( ps );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,6 +616,58 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
}
|
||||
}
|
||||
|
||||
private void addRequester(IAEPowerStorage requester) {
|
||||
Preconditions.checkState(!ongoingInjectOperation,
|
||||
"Cannot modify energy requesters while energy is being injected.");
|
||||
if( requester instanceof GridPowerStorage )
|
||||
{
|
||||
requesters.put( 0, requester );
|
||||
}
|
||||
else
|
||||
{
|
||||
requesters.put( 1, requester );
|
||||
}
|
||||
}
|
||||
|
||||
private void removeRequester(IAEPowerStorage requester) {
|
||||
Preconditions.checkState(!ongoingInjectOperation,
|
||||
"Cannot modify energy requesters while energy is being injected.");
|
||||
if( requester instanceof GridPowerStorage )
|
||||
{
|
||||
requesters.remove( 0, requester );
|
||||
}
|
||||
else
|
||||
{
|
||||
requesters.remove( 1, requester );
|
||||
}
|
||||
}
|
||||
|
||||
private void addProvider(IAEPowerStorage provider) {
|
||||
Preconditions.checkState(!ongoingExtractOperation,
|
||||
"Cannot modify energy providers while energy is being extracted.");
|
||||
if( provider instanceof GridPowerStorage )
|
||||
{
|
||||
providers.put( 1, provider );
|
||||
}
|
||||
else
|
||||
{
|
||||
providers.put( 0, provider );
|
||||
}
|
||||
}
|
||||
|
||||
private void removeProvider(IAEPowerStorage provider)
|
||||
{
|
||||
Preconditions.checkState( !ongoingExtractOperation, "Cannot modify energy providers while energy is being extracted." );
|
||||
if( provider instanceof GridPowerStorage )
|
||||
{
|
||||
providers.remove( 1, provider );
|
||||
}
|
||||
else
|
||||
{
|
||||
providers.remove( 0, provider );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNode( final IGridNode node, final IGridHost machine )
|
||||
{
|
||||
@@ -553,12 +699,26 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
if( current > 0 && ps.getPowerFlow() != AccessRestriction.WRITE )
|
||||
{
|
||||
this.globalAvailablePower += current;
|
||||
this.providers.add( ps );
|
||||
if( !ongoingExtractOperation )
|
||||
{
|
||||
addProvider( ps );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.providersToAdd.add( ps );
|
||||
}
|
||||
}
|
||||
|
||||
if( current < max && ps.getPowerFlow() != AccessRestriction.READ )
|
||||
{
|
||||
this.requesters.add( ps );
|
||||
if( !ongoingInjectOperation )
|
||||
{
|
||||
addRequester( ps );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.requestersToAdd.add( ps );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -685,4 +845,4 @@ public class EnergyGridCache implements IEnergyGrid
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+25
-2
@@ -26,7 +26,10 @@ import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||
import appeng.me.helpers.PatternStatusManager;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
@@ -65,6 +68,10 @@ public class GridStorageCache implements IStorageGrid
|
||||
private final HashSet<ICellProvider> inactiveCellProviders = new HashSet<>();
|
||||
private final SetMultimap<IAEStack, ItemWatcher> interests = HashMultimap.create();
|
||||
private final GenericInterestManager<ItemWatcher> interestManager = new GenericInterestManager<>( this.interests );
|
||||
private final Multimap<ICraftingPatternDetails, IAEStack> patternDetails2IAEStackMultimap = HashMultimap.create();
|
||||
private final Multimap<IAEStack, ICraftingPatternDetails> iaeStack2PatternDetailsMultimap = HashMultimap.create();
|
||||
private final PatternStatusManager patternStatusManager = new PatternStatusManager( this.patternDetails2IAEStackMultimap, this.iaeStack2PatternDetailsMultimap );
|
||||
|
||||
private final HashMap<IGridNode, IStackWatcher> watchers = new HashMap<>();
|
||||
private Map<IStorageChannel<? extends IAEStack>, NetworkInventoryHandler<?>> storageNetworks;
|
||||
private Map<IStorageChannel<? extends IAEStack>, NetworkMonitor<?>> storageMonitors;
|
||||
@@ -248,8 +255,6 @@ public class GridStorageCache implements IStorageGrid
|
||||
}
|
||||
}
|
||||
|
||||
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.forceUpdate() );
|
||||
|
||||
tracker.applyChanges();
|
||||
}
|
||||
|
||||
@@ -281,6 +286,12 @@ public class GridStorageCache implements IStorageGrid
|
||||
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
|
||||
public void registerCellProvider( final ICellProvider provider )
|
||||
{
|
||||
@@ -300,6 +311,18 @@ public class GridStorageCache implements IStorageGrid
|
||||
return this.interestManager;
|
||||
}
|
||||
|
||||
public PatternStatusManager getPatternStatusManager()
|
||||
{
|
||||
return this.patternStatusManager;
|
||||
}
|
||||
|
||||
public void clearPatternStatus()
|
||||
{
|
||||
System.out.println( "reseting pattern status due to pattern changes" );
|
||||
this.patternDetails2IAEStackMultimap.clear();
|
||||
this.iaeStack2PatternDetailsMultimap.clear();
|
||||
}
|
||||
|
||||
IGrid getGrid()
|
||||
{
|
||||
return this.myGrid;
|
||||
|
||||
+123
-104
@@ -19,34 +19,35 @@
|
||||
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.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Queues;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||
import appeng.api.networking.events.MENetworkStorageEvent;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.storage.IMEInventoryHandler;
|
||||
import appeng.api.storage.IMEMonitor;
|
||||
import appeng.api.storage.IMEMonitorHandlerReceiver;
|
||||
import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.channels.IFluidStorageChannel;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.me.storage.ItemWatcher;
|
||||
import com.google.common.collect.Queues;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Deque;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
||||
public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
|
||||
{
|
||||
@@ -63,9 +64,10 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
|
||||
private final Object2ObjectMap<IMEMonitorHandlerReceiver<T>, Object> listeners;
|
||||
|
||||
private boolean sendEvent = false;
|
||||
private boolean hasChanged = false;
|
||||
@Nonnegative
|
||||
private int localDepthSemaphore = 0;
|
||||
private long gridItemCount;
|
||||
private long gridFluidCount;
|
||||
|
||||
public NetworkMonitor( final GridStorageCache cache, final IStorageChannel<T> chan )
|
||||
{
|
||||
@@ -90,21 +92,7 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
|
||||
@Override
|
||||
public T extractItems( final T request, final Actionable mode, final IActionSource src )
|
||||
{
|
||||
if( mode == Actionable.SIMULATE )
|
||||
{
|
||||
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;
|
||||
return this.getHandler().extractItems( request, mode, src );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -137,38 +125,43 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
|
||||
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 long incGridCurrentCount(long count)
|
||||
{
|
||||
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
||||
{
|
||||
return gridItemCount += count;
|
||||
}
|
||||
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
|
||||
{
|
||||
return gridFluidCount += count;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IItemList<T> getStorageList()
|
||||
{
|
||||
if( hasChanged )
|
||||
{
|
||||
hasChanged = false;
|
||||
this.cachedList.resetStatus();
|
||||
return this.getAvailableItems( this.cachedList );
|
||||
}
|
||||
|
||||
return this.cachedList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T injectItems( final T input, final Actionable mode, final IActionSource src )
|
||||
{
|
||||
if( mode == Actionable.SIMULATE )
|
||||
{
|
||||
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;
|
||||
return this.getHandler().injectItems( input, mode, src );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -200,30 +193,8 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
|
||||
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 )
|
||||
{
|
||||
this.hasChanged = true;
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
|
||||
|
||||
while( i.hasNext() )
|
||||
@@ -241,35 +212,41 @@ 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.copy().setCraftable( true ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.cachedList.findPrecise( changedItem ).setCraftable( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void postChange( final boolean add, final Iterable<T> changes, final IActionSource src )
|
||||
{
|
||||
if( this.localDepthSemaphore > 0 || GLOBAL_DEPTH.contains( this ) )
|
||||
if( GLOBAL_DEPTH.contains( this ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GLOBAL_DEPTH.push( this );
|
||||
this.localDepthSemaphore++;
|
||||
|
||||
this.sendEvent = true;
|
||||
|
||||
this.notifyListenersOfChange( changes, src );
|
||||
|
||||
for( final T changedItem : changes )
|
||||
{
|
||||
T difference = changedItem;
|
||||
|
||||
if( !add && changedItem != null )
|
||||
{
|
||||
difference = changedItem.copy();
|
||||
difference.setStackSize( -changedItem.getStackSize() );
|
||||
changedItem.setStackSize( -changedItem.getStackSize() );
|
||||
}
|
||||
|
||||
incGridCurrentCount( changedItem.getStackSize() );
|
||||
this.cachedList.add( changedItem );
|
||||
|
||||
if( this.myGridCache.getInterestManager().containsKey( changedItem ) )
|
||||
{
|
||||
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( changedItem );
|
||||
@@ -288,16 +265,78 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
|
||||
|
||||
for( final ItemWatcher iw : list )
|
||||
{
|
||||
iw.getHost().onStackChange( this.getStorageList(), fullStack, difference, src, this.getChannel() );
|
||||
iw.getHost().onStackChange( this.getStorageList(), fullStack, changedItem, src, this.getChannel() );
|
||||
}
|
||||
|
||||
this.myGridCache.getInterestManager().disableTransactions();
|
||||
}
|
||||
}
|
||||
if( changedItem instanceof IAEItemStack )
|
||||
{
|
||||
if( this.myGridCache.getPatternStatusManager().containsMissingIAEStack( changedItem ) )
|
||||
{
|
||||
this.myGridCache.getPatternStatusManager().enableTransactions();
|
||||
|
||||
for( ICraftingPatternDetails craftingPatternDetails : this.myGridCache.getPatternStatusManager().getIncompletablePattern( changedItem ) )
|
||||
{
|
||||
for( IAEStack stack : this.myGridCache.getPatternStatusManager().getMissingIAEStack( craftingPatternDetails ) )
|
||||
{
|
||||
if( craftingPatternDetails.canSubstitute() )
|
||||
{
|
||||
if( ( (IAEItemStack) stack ).getItem().isDamageable() )
|
||||
{
|
||||
if( ( (IAEStack) changedItem ).fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) )
|
||||
{
|
||||
if( changedItem.getStackSize() > 0 )
|
||||
{
|
||||
this.myGridCache.getPatternStatusManager().remove( craftingPatternDetails, stack );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ( (IAEItemStack) stack ).sameOre( (IAEItemStack) changedItem ) )
|
||||
{
|
||||
if( changedItem.getStackSize() > 0 )
|
||||
{
|
||||
if( changedItem.getStackSize() >= stack.getStackSize() )
|
||||
{
|
||||
this.myGridCache.getPatternStatusManager().remove( craftingPatternDetails, stack );
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.decStackSize( changedItem.getStackSize() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( stack.equals( changedItem ) )
|
||||
{
|
||||
if( changedItem.getStackSize() > 0 )
|
||||
{
|
||||
if( changedItem.getStackSize() >= stack.getStackSize() )
|
||||
{
|
||||
this.myGridCache.getPatternStatusManager().remove( craftingPatternDetails, stack );
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.decStackSize( changedItem.getStackSize() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.myGridCache.getPatternStatusManager().disableTransactions();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.notifyListenersOfChange( changes, src );
|
||||
|
||||
final NetworkMonitor<?> last = GLOBAL_DEPTH.pop();
|
||||
this.localDepthSemaphore--;
|
||||
|
||||
if( last != this )
|
||||
{
|
||||
@@ -305,27 +344,6 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
|
||||
}
|
||||
}
|
||||
|
||||
void forceUpdate()
|
||||
{
|
||||
this.hasChanged = true;
|
||||
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
|
||||
while( i.hasNext() )
|
||||
{
|
||||
final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
|
||||
final IMEMonitorHandlerReceiver<T> receiver = o.getKey();
|
||||
|
||||
if( receiver.isValid( o.getValue() ) )
|
||||
{
|
||||
receiver.onListUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onTick()
|
||||
{
|
||||
if( this.sendEvent )
|
||||
@@ -333,5 +351,6 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
|
||||
this.sendEvent = false;
|
||||
this.myGridCache.getGrid().postEvent( new MENetworkStorageEvent( this, this.myChannel ) );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,6 @@ public class TickManagerCache implements ITickManager
|
||||
tt.addEntityCrashInfo( crashreportcategory );
|
||||
throw new ReportedException( crashreport );
|
||||
}
|
||||
PartLevelEmitter.wipeCache();
|
||||
}
|
||||
|
||||
private void addToQueue( final TickTracker tt )
|
||||
|
||||
@@ -23,9 +23,10 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
|
||||
public class GenericInterestManager<T>
|
||||
@@ -101,12 +102,30 @@ public class GenericInterestManager<T>
|
||||
|
||||
public boolean containsKey( final IAEStack stack )
|
||||
{
|
||||
if( stack.isItem() && ( ( AEItemStack ) stack ).getItem().isDamageable() )
|
||||
{
|
||||
return this.container.keySet().stream().filter( s -> s.isItem() )
|
||||
.anyMatch( s -> s.fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) );
|
||||
}
|
||||
return this.container.containsKey( stack );
|
||||
}
|
||||
|
||||
public Collection<T> get( final IAEStack stack )
|
||||
{
|
||||
return this.container.get( stack );
|
||||
Collection<T> watchers = new ArrayList<>();
|
||||
if( stack.isItem() && ( ( AEItemStack ) stack ).getItem().isDamageable() )
|
||||
{
|
||||
this.container.keySet().stream().filter( s -> s.isItem() )
|
||||
.filter( k -> k.fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) )
|
||||
.forEach( key ->
|
||||
watchers.addAll( this.container.get( key ) )
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.container.get( stack );
|
||||
}
|
||||
return watchers;
|
||||
}
|
||||
|
||||
private class SavedTransactions
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, 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.me.helpers;
|
||||
|
||||
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class PatternStatusManager
|
||||
{
|
||||
|
||||
private final Multimap<ICraftingPatternDetails, IAEStack> patternDetailsIAEStackMultimap;
|
||||
private final Multimap<IAEStack, ICraftingPatternDetails> iaeStackPatternDetailsMultimap;
|
||||
|
||||
private List<SavedTransactions> transactions = null;
|
||||
private int transDepth = 0;
|
||||
|
||||
public PatternStatusManager( final Multimap<ICraftingPatternDetails, IAEStack> interests, final Multimap<IAEStack, ICraftingPatternDetails> interested )
|
||||
{
|
||||
this.patternDetailsIAEStackMultimap = interests;
|
||||
this.iaeStackPatternDetailsMultimap = interested;
|
||||
}
|
||||
|
||||
public void enableTransactions()
|
||||
{
|
||||
if( this.transDepth == 0 )
|
||||
{
|
||||
this.transactions = new ArrayList<>();
|
||||
}
|
||||
|
||||
this.transDepth++;
|
||||
}
|
||||
|
||||
public void disableTransactions()
|
||||
{
|
||||
this.transDepth--;
|
||||
|
||||
if( this.transDepth == 0 )
|
||||
{
|
||||
final List<SavedTransactions> myActions = this.transactions;
|
||||
this.transactions = null;
|
||||
|
||||
for( final SavedTransactions t : myActions )
|
||||
{
|
||||
if( t.put )
|
||||
{
|
||||
this.put( t.patternDetails, t.stack );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.remove( t.patternDetails, t.stack );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean put( final ICraftingPatternDetails craftingPatternDetails, final IAEStack debtStack )
|
||||
{
|
||||
if( this.transactions != null )
|
||||
{
|
||||
this.transactions.add( new SavedTransactions( true, craftingPatternDetails, debtStack ) );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.iaeStackPatternDetailsMultimap.put( debtStack, craftingPatternDetails );
|
||||
return this.patternDetailsIAEStackMultimap.put( craftingPatternDetails, debtStack );
|
||||
}
|
||||
}
|
||||
|
||||
public boolean remove( final ICraftingPatternDetails craftingPatternDetails, final IAEStack debtStack )
|
||||
{
|
||||
if( this.transactions != null )
|
||||
{
|
||||
this.transactions.add( new SavedTransactions( false, craftingPatternDetails, debtStack ) );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.iaeStackPatternDetailsMultimap.remove( debtStack, craftingPatternDetails );
|
||||
return this.patternDetailsIAEStackMultimap.remove( craftingPatternDetails, debtStack );
|
||||
}
|
||||
}
|
||||
|
||||
public boolean containsIncompletablePattern( final ICraftingPatternDetails craftingPatternDetails )
|
||||
{
|
||||
return this.patternDetailsIAEStackMultimap.containsKey( craftingPatternDetails );
|
||||
}
|
||||
|
||||
public boolean containsMissingIAEStack( final IAEStack stack )
|
||||
{
|
||||
if( ( (IAEItemStack) stack ).getItem().isDamageable() )
|
||||
{
|
||||
for( IAEStack i : iaeStackPatternDetailsMultimap.keySet() )
|
||||
{
|
||||
if( i.fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return this.iaeStackPatternDetailsMultimap.containsKey( stack );
|
||||
}
|
||||
|
||||
public Collection<IAEStack> getMissingIAEStack( final ICraftingPatternDetails patternDetails )
|
||||
{
|
||||
return this.patternDetailsIAEStackMultimap.get( patternDetails );
|
||||
}
|
||||
|
||||
public Collection<ICraftingPatternDetails> getIncompletablePattern( final IAEStack stack )
|
||||
{
|
||||
Collection<ICraftingPatternDetails> a = new ArrayList<>();
|
||||
if( ( (IAEItemStack) stack ).getItem().isDamageable() )
|
||||
{
|
||||
for( IAEStack i : iaeStackPatternDetailsMultimap.keySet() )
|
||||
{
|
||||
if( i.fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) )
|
||||
{
|
||||
a.addAll( this.iaeStackPatternDetailsMultimap.get( i ) );
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
return this.iaeStackPatternDetailsMultimap.get( stack );
|
||||
}
|
||||
|
||||
private class SavedTransactions
|
||||
{
|
||||
|
||||
private final boolean put;
|
||||
private final ICraftingPatternDetails patternDetails;
|
||||
private final IAEStack stack;
|
||||
|
||||
public SavedTransactions( final boolean putOperation, final ICraftingPatternDetails myPatternDetails, final IAEStack stack )
|
||||
{
|
||||
this.put = putOperation;
|
||||
this.patternDetails = myPatternDetails;
|
||||
this.stack = stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,10 @@
|
||||
package appeng.me.storage;
|
||||
|
||||
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.me.helpers.MachineSource;
|
||||
import appeng.tile.storage.TileDrive;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import appeng.api.config.Actionable;
|
||||
@@ -36,6 +40,7 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
|
||||
private final ItemStack is;
|
||||
private final ICellHandler handler;
|
||||
private final IChestOrDrive cord;
|
||||
private IActionSource source;
|
||||
|
||||
public DriveWatcher( final ICellInventoryHandler<T> i, final ItemStack is, final ICellHandler han, final IChestOrDrive cod )
|
||||
{
|
||||
@@ -43,6 +48,7 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
|
||||
this.is = is;
|
||||
this.handler = han;
|
||||
this.cord = cod;
|
||||
this.source = new MachineSource( cod );
|
||||
}
|
||||
|
||||
public int getStatus()
|
||||
@@ -66,6 +72,14 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
|
||||
this.cord.blinkCell( this.getSlot() );
|
||||
this.oldStatus = newStatus;
|
||||
}
|
||||
try
|
||||
{
|
||||
( (TileDrive) this.cord ).getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), ImmutableList.of( input.copy().setStackSize( input.getStackSize() - ( a == null ? 0 : a.getStackSize() ) ) ), this.source );
|
||||
}
|
||||
catch( GridAccessException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
@@ -85,6 +99,15 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
|
||||
this.cord.blinkCell( this.getSlot() );
|
||||
this.oldStatus = newStatus;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
( (TileDrive) this.cord ).getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), ImmutableList.of( request.copy().setStackSize( -a.getStackSize() ) ), this.source );
|
||||
}
|
||||
catch( GridAccessException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
|
||||
@@ -90,6 +90,13 @@ public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T
|
||||
@Override
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ public class MEPassThrough<T extends IAEStack<T>> implements IMEInventoryHandler
|
||||
this.setInternal( i );
|
||||
}
|
||||
|
||||
protected IMEInventory<T> getInternal()
|
||||
public IMEInventory<T> getInternal()
|
||||
{
|
||||
return this.internal;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
package appeng.parts.automation;
|
||||
|
||||
|
||||
import appeng.api.networking.crafting.ICraftingPatternDetails;
|
||||
import appeng.me.cache.CraftingGridCache;
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
@@ -150,18 +153,14 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
|
||||
|
||||
final IAEItemStack ais = this.getConfig().getAEStackInSlot( slotToExport );
|
||||
|
||||
if( ais == null || this.itemToSend <= 0 ) continue;
|
||||
if( ais == null || this.itemToSend <= 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( this.craftOnly() ) {
|
||||
if (this.failedCraftTriesSlot[x] <= 0) {
|
||||
|
||||
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(),
|
||||
this.getProxy().getGrid(), cg, this.mySrc) || this.didSomething;
|
||||
|
||||
if (this.didSomething) this.failedCraftTriesSlot[x] = 0;
|
||||
else this.failedCraftTriesSlot[x] += 2;
|
||||
}
|
||||
this.failedCraftTriesSlot[x] -= 1;
|
||||
if( this.craftOnly() )
|
||||
{
|
||||
this.didSomething = this.craftingTracker.handleCrafting( slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(), this.getProxy().getGrid(), cg, this.mySrc ) || this.didSomething;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -188,15 +187,7 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
|
||||
|
||||
if( this.itemToSend == before && this.isCraftingEnabled() )
|
||||
{
|
||||
if (this.failedCraftTriesSlot[x] <= 0) {
|
||||
|
||||
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(),
|
||||
this.getProxy().getGrid(), cg, this.mySrc) || this.didSomething;
|
||||
|
||||
if (this.didSomething) this.failedCraftTriesSlot[x] = 0;
|
||||
else this.failedCraftTriesSlot[x] += 2;
|
||||
}
|
||||
this.failedCraftTriesSlot[x] -= 1;
|
||||
this.didSomething = this.craftingTracker.handleCrafting( slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(), this.getProxy().getGrid(), cg, this.mySrc ) || this.didSomething;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ public class PartFormationPlane extends PartAbstractFormationPlane<IAEItemStack>
|
||||
@Override
|
||||
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 );
|
||||
handler.add( this.myHandler );
|
||||
|
||||
@@ -19,40 +19,9 @@
|
||||
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.config.FuzzyMode;
|
||||
import appeng.api.config.LevelType;
|
||||
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.config.*;
|
||||
import appeng.api.networking.crafting.*;
|
||||
import appeng.api.networking.energy.IEnergyGrid;
|
||||
import appeng.api.networking.energy.IEnergyWatcher;
|
||||
import appeng.api.networking.energy.IEnergyWatcherHost;
|
||||
@@ -81,10 +50,28 @@ import appeng.core.sync.GuiBridge;
|
||||
import appeng.helpers.Reflected;
|
||||
import appeng.items.parts.PartModels;
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.me.cache.NetworkMonitor;
|
||||
import appeng.parts.PartModel;
|
||||
import appeng.tile.inventory.AppEngInternalAEInventory;
|
||||
import appeng.util.Platform;
|
||||
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
|
||||
@@ -123,9 +110,6 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
|
||||
private double centerX;
|
||||
private double centerY;
|
||||
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
|
||||
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()
|
||||
{
|
||||
final boolean isOn = this.isLevelEmitterOn();
|
||||
@@ -206,9 +184,23 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
|
||||
return flipState ? this.reportingValue >= this.lastReportedValue + 1 : this.reportingValue < this.lastReportedValue + 1;
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void powerStatusChange( final MENetworkPowerStatusChange powerEvent )
|
||||
{
|
||||
if (this.getProxy().isActive())
|
||||
{
|
||||
onListUpdate();
|
||||
}
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void channelChanged( final MENetworkChannelsChanged c )
|
||||
{
|
||||
if (this.getProxy().isActive())
|
||||
{
|
||||
onListUpdate();
|
||||
}
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
@@ -296,24 +288,37 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
|
||||
|
||||
try
|
||||
{
|
||||
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 || myStack == null )
|
||||
|
||||
if( myStack == null )
|
||||
{
|
||||
this.getProxy()
|
||||
.getStorage()
|
||||
.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
||||
.addListener( this,
|
||||
this.getProxy().getGrid() );
|
||||
this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).addListener( this, this.getProxy().getGrid() );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).removeListener( this );
|
||||
|
||||
if( this.myWatcher != null )
|
||||
{
|
||||
this.myWatcher.add( myStack );
|
||||
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
||||
{
|
||||
Optional<OreReference> ores = OreHelper.INSTANCE.getOre( myStack.getDefinition() );
|
||||
if( ores.isPresent() )
|
||||
{
|
||||
for( IAEItemStack iaeItemStack : ores.get().getAEEquivalents() )
|
||||
{
|
||||
this.myWatcher.add( iaeItemStack );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.myWatcher.add( myStack );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.myWatcher.add( myStack );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
@@ -323,90 +328,29 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
|
||||
}
|
||||
|
||||
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 );
|
||||
|
||||
GridNode node = (GridNode) (this.getGridNode());
|
||||
|
||||
if( node != null )
|
||||
if( myStack == null )
|
||||
{
|
||||
|
||||
final Grid g = node.getInternalGrid();
|
||||
|
||||
if( myStack == null )
|
||||
if( monitor instanceof NetworkMonitor )
|
||||
{
|
||||
if( change != null )
|
||||
{
|
||||
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 );
|
||||
this.lastReportedValue = ( (NetworkMonitor<IAEItemStack>) monitor ).getGridCurrentCount();
|
||||
}
|
||||
}
|
||||
|
||||
else if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
||||
{
|
||||
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();
|
||||
} );
|
||||
}
|
||||
}
|
||||
else if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
||||
{
|
||||
final FuzzyMode fzMode = (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE );
|
||||
|
||||
fuzzyAEItemStackCount.computeIfAbsent( g, ( grid -> new Object2LongOpenHashMap<>() ) );
|
||||
fuzzyAEItemStackCount.get( g ).computeIfAbsent( (AEItemStack) myStack, ( aLong -> {
|
||||
this.lastReportedValue = 0;
|
||||
monitor.getStorageList().findFuzzy( myStack, fzMode ).forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
|
||||
return ( lastReportedValue );
|
||||
} ) );
|
||||
|
||||
this.lastReportedValue = fuzzyAEItemStackCount.get( g ).get( myStack );
|
||||
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.lastReportedValue = 0;
|
||||
monitor.getStorageList().findFuzzy( myStack, fzMode ).forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.lastReportedValue = 0;
|
||||
IAEItemStack precise = monitor.getStorageList().findPrecise( myStack );
|
||||
if( precise != null ) lastReportedValue = precise.getStackSize();
|
||||
}
|
||||
this.updateState();
|
||||
}
|
||||
@@ -419,12 +363,23 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStackChange( final IItemList o, final IAEStack fullStack, final IAEStack diffStack, final IActionSource src, final IStorageChannel chan )
|
||||
public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan )
|
||||
{
|
||||
if( chan == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) && fullStack.equals( this.config.getAEStackInSlot( 0 ) ) && this
|
||||
.getInstalledUpgrades( Upgrades.FUZZY ) == 0 )
|
||||
if( chan == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
||||
{
|
||||
this.lastReportedValue = fullStack.getStackSize();
|
||||
IAEItemStack myStack = this.config.getAEStackInSlot( 0 );
|
||||
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
||||
{
|
||||
final FuzzyMode fzMode = (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE );
|
||||
if( Platform.itemComparisons().isFuzzyEqualItem( myStack.getDefinition(), ( (IAEItemStack) diffStack ).getDefinition(), fzMode ) )
|
||||
{
|
||||
this.lastReportedValue += diffStack.getStackSize();
|
||||
}
|
||||
}
|
||||
else if( diffStack.equals( myStack ) )
|
||||
{
|
||||
this.lastReportedValue += diffStack.getStackSize();
|
||||
}
|
||||
this.updateState();
|
||||
}
|
||||
}
|
||||
@@ -459,7 +414,7 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
|
||||
@Override
|
||||
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
|
||||
@@ -636,9 +591,4 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
|
||||
}
|
||||
}
|
||||
|
||||
public static void wipeCache(){
|
||||
fuzzyAEItemStackCount.clear();
|
||||
preciseAEItemStackCount.clear();
|
||||
gridItemCount.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ package appeng.parts.misc;
|
||||
|
||||
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.StorageFilter;
|
||||
@@ -44,7 +45,6 @@ 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 net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -60,6 +60,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
private final IGridProxyable proxyable;
|
||||
private final InventoryCache cache;
|
||||
private StorageFilter mode;
|
||||
private AccessRestriction access;
|
||||
|
||||
private ItemStack stackCache = null;
|
||||
|
||||
@@ -71,8 +72,10 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
{
|
||||
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
|
||||
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.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,6 +86,8 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
stackCache = null;
|
||||
|
||||
ItemStack orgInput;
|
||||
int slotCount = this.itemHandler.getSlots();
|
||||
|
||||
if( currentCached != null && iox.isSameType( currentCached ) )
|
||||
{
|
||||
// Cache is suitable, just update the count
|
||||
@@ -94,10 +99,16 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
// We need a new stack :-(
|
||||
orgInput = iox.createItemStack();
|
||||
}
|
||||
ItemStack remaining = ItemHandlerHelper.insertItem( this.itemHandler, orgInput, type == Actionable.SIMULATE );
|
||||
|
||||
ItemStack remaining = orgInput;
|
||||
|
||||
for( int i = 0; i < slotCount && !remaining.isEmpty(); i++ )
|
||||
{
|
||||
remaining = this.itemHandler.insertItem( i, remaining, type == Actionable.SIMULATE );
|
||||
}
|
||||
|
||||
// Store the stack in the cache for next time.
|
||||
if (!remaining.isEmpty() && remaining != orgInput)
|
||||
if( !remaining.isEmpty() && remaining != orgInput )
|
||||
{
|
||||
stackCache = remaining;
|
||||
}
|
||||
@@ -111,6 +122,9 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
|
||||
if( type == Actionable.MODULATE )
|
||||
{
|
||||
IAEItemStack added = iox.copy().setStackSize( iox.getStackSize() - remaining.getCount() );
|
||||
this.cache.currentlyCached.add( added );
|
||||
this.postDifference( Collections.singletonList( added ) );
|
||||
try
|
||||
{
|
||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||
@@ -119,7 +133,6 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
{
|
||||
// meh
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return AEItemStack.fromItemStack( remaining );
|
||||
@@ -128,18 +141,17 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
@Override
|
||||
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
|
||||
{
|
||||
int remainingSize = Ints.saturatedCast(request.getStackSize());
|
||||
int remainingSize = Ints.saturatedCast( request.getStackSize() );
|
||||
|
||||
// Use this to gather the requested items
|
||||
ItemStack gathered = ItemStack.EMPTY;
|
||||
|
||||
final boolean simulate = ( mode == Actionable.SIMULATE );
|
||||
|
||||
for( int i = 0; i < this.itemHandler.getSlots(); i++ )
|
||||
for ( int i = 0; i < this.itemHandler.getSlots(); i++ )
|
||||
{
|
||||
ItemStack stackInInventorySlot = this.itemHandler.getStackInSlot( i );
|
||||
|
||||
if (!request.isSameType(stackInInventorySlot))
|
||||
if( !request.isSameType( stackInInventorySlot ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -191,8 +203,15 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
|
||||
if( !gathered.isEmpty() )
|
||||
{
|
||||
IAEItemStack gatheredAEItemStack = AEItemStack.fromItemStack( gathered );
|
||||
if( mode == Actionable.MODULATE )
|
||||
{
|
||||
IAEItemStack cachedStack = this.cache.currentlyCached.findPrecise( request );
|
||||
if( cachedStack != null )
|
||||
{
|
||||
cachedStack.decStackSize( gatheredAEItemStack.getStackSize() );
|
||||
this.postDifference( Collections.singletonList( gatheredAEItemStack.copy().setStackSize( -gatheredAEItemStack.getStackSize() ) ) );
|
||||
}
|
||||
try
|
||||
{
|
||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||
@@ -203,7 +222,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
}
|
||||
}
|
||||
|
||||
return AEItemStack.fromItemStack( gathered );
|
||||
return gatheredAEItemStack;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -213,7 +232,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
public TickRateModulation onTick()
|
||||
{
|
||||
List<IAEItemStack> changes = this.cache.update();
|
||||
if( !changes.isEmpty() )
|
||||
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
|
||||
{
|
||||
this.postDifference( changes );
|
||||
return TickRateModulation.URGENT;
|
||||
@@ -274,9 +293,9 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
|
||||
private static class InventoryCache implements Iterable<ItemSlot>
|
||||
{
|
||||
private IAEItemStack[] cachedAeStacks = new IAEItemStack[0];
|
||||
private final IItemHandler itemHandler;
|
||||
private final StorageFilter mode;
|
||||
IItemList<IAEItemStack> currentlyCached = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
|
||||
public InventoryCache( IItemHandler itemHandler, StorageFilter mode )
|
||||
{
|
||||
@@ -286,7 +305,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
|
||||
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
|
||||
{
|
||||
Arrays.stream( this.cachedAeStacks ).forEach( out::add );
|
||||
currentlyCached.iterator().forEachRemaining( out::add );
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -298,93 +317,41 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
||||
public List<IAEItemStack> update()
|
||||
{
|
||||
final List<IAEItemStack> changes = new ArrayList<>();
|
||||
final int slots = this.itemHandler.getSlots();
|
||||
|
||||
// Make room for new slots
|
||||
if( slots > this.cachedAeStacks.length )
|
||||
{
|
||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
||||
}
|
||||
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
|
||||
for( final ItemSlot is : this )
|
||||
for ( final ItemSlot is : this )
|
||||
{
|
||||
// Save the old stuff
|
||||
final IAEItemStack oldAeIS = this.cachedAeStacks[is.getSlot()];
|
||||
final ItemStack newIS = !is.isExtractable() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? ItemStack.EMPTY : is.getItemStack();
|
||||
|
||||
this.handlePossibleSlotChanges( is.getSlot(), oldAeIS, newIS, changes );
|
||||
}
|
||||
// Handle cases where the number of slots actually is lower now than before
|
||||
if( slots < this.cachedAeStacks.length )
|
||||
{
|
||||
for( int slot = slots; slot < this.cachedAeStacks.length; slot++ )
|
||||
if( !newIS.isEmpty() )
|
||||
{
|
||||
final IAEItemStack aeStack = this.cachedAeStacks[slot];
|
||||
|
||||
if( aeStack != null )
|
||||
{
|
||||
final IAEItemStack a = aeStack.copy();
|
||||
a.setStackSize( -a.getStackSize() );
|
||||
changes.add( a );
|
||||
}
|
||||
currentlyOnStorage.add( is.getAEItemStack() );
|
||||
}
|
||||
|
||||
// Reduce the cache size
|
||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
||||
}
|
||||
|
||||
for ( final IAEItemStack is : currentlyCached )
|
||||
{
|
||||
is.setStackSize( -is.getStackSize() );
|
||||
}
|
||||
|
||||
for ( final IAEItemStack is : currentlyOnStorage )
|
||||
{
|
||||
currentlyCached.add( is );
|
||||
}
|
||||
|
||||
for ( final IAEItemStack is : currentlyCached )
|
||||
{
|
||||
if( is.getStackSize() != 0 )
|
||||
{
|
||||
changes.add( is );
|
||||
}
|
||||
}
|
||||
|
||||
currentlyCached = currentlyOnStorage;
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
private void handlePossibleSlotChanges( int slot, IAEItemStack oldAeIS, ItemStack 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, 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] );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ItemSlot> iterator()
|
||||
{
|
||||
|
||||
@@ -2,7 +2,9 @@ package appeng.parts.misc;
|
||||
|
||||
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.networking.security.IActionSource;
|
||||
import appeng.api.networking.storage.IBaseMonitor;
|
||||
import appeng.api.networking.ticking.TickRateModulation;
|
||||
@@ -24,7 +26,6 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
@@ -39,6 +40,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
||||
private final IItemRepository itemRepository;
|
||||
private final IGridProxyable proxyable;
|
||||
private final InventoryCache cache;
|
||||
private AccessRestriction access;
|
||||
|
||||
private ItemStack stackCache;
|
||||
|
||||
@@ -47,6 +49,12 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
||||
this.itemRepository = itemRepository;
|
||||
this.proxyable = proxy;
|
||||
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
|
||||
@@ -71,7 +79,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
||||
ItemStack remaining = this.itemRepository.insertItem( orgInput, type == Actionable.SIMULATE );
|
||||
|
||||
// Store the stack in the cache for next time.
|
||||
if (!remaining.isEmpty() && remaining != orgInput)
|
||||
if( !remaining.isEmpty() && remaining != orgInput )
|
||||
{
|
||||
stackCache = remaining;
|
||||
}
|
||||
@@ -85,6 +93,9 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
||||
|
||||
if( type == Actionable.MODULATE )
|
||||
{
|
||||
IAEItemStack added = iox.copy().setStackSize( iox.getStackSize() - remaining.getCount() );
|
||||
this.cache.currentlyCached.add( added );
|
||||
this.postDifference( Collections.singletonList( added ) );
|
||||
try
|
||||
{
|
||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||
@@ -102,7 +113,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
||||
@Override
|
||||
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
|
||||
{
|
||||
int remainingSize = Ints.saturatedCast(request.getStackSize());
|
||||
int remainingSize = Ints.saturatedCast( request.getStackSize() );
|
||||
|
||||
final boolean simulate = ( mode == Actionable.SIMULATE );
|
||||
|
||||
@@ -119,8 +130,15 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
||||
|
||||
if( !extracted.isEmpty() )
|
||||
{
|
||||
IAEItemStack extractedAEItemStack = AEItemStack.fromItemStack( extracted );
|
||||
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
|
||||
{
|
||||
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||
@@ -130,7 +148,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
||||
// meh
|
||||
}
|
||||
}
|
||||
return AEItemStack.fromItemStack( extracted );
|
||||
return extractedAEItemStack;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -180,17 +198,15 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
||||
@Override
|
||||
public TickRateModulation onTick()
|
||||
{
|
||||
List<IAEItemStack> changes = this.cache.update();
|
||||
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
|
||||
{
|
||||
List<IAEItemStack> changes = this.cache.update();
|
||||
if( !changes.isEmpty() )
|
||||
{
|
||||
this.postDifference( changes );
|
||||
return TickRateModulation.URGENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TickRateModulation.SLOWER;
|
||||
}
|
||||
this.postDifference( changes );
|
||||
return TickRateModulation.URGENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TickRateModulation.SLOWER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +218,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
||||
|
||||
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;
|
||||
|
||||
public InventoryCache( IItemRepository iItemRepository )
|
||||
@@ -212,7 +228,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
||||
|
||||
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
|
||||
{
|
||||
Arrays.stream( this.cachedAeStacks ).forEach( out::add );
|
||||
currentlyCached.iterator().forEachRemaining( out::add );
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -220,95 +236,31 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
|
||||
{
|
||||
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();
|
||||
|
||||
// Make room for new slots
|
||||
if( size > this.cachedAeStacks.length )
|
||||
for ( final IAEItemStack is : currentlyCached )
|
||||
{
|
||||
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
|
||||
final IAEItemStack oldAeIS = this.cachedAeStacks[x];
|
||||
final IAEItemStack newIS = out.get( x );
|
||||
|
||||
this.handlePossibleSlotChanges( x, oldAeIS, newIS, changes );
|
||||
currentlyCached.add( is );
|
||||
}
|
||||
|
||||
// Handle cases where the number of slots actually is lower now than before
|
||||
if( size < this.cachedAeStacks.length )
|
||||
for ( final IAEItemStack is : currentlyCached )
|
||||
{
|
||||
for( int x = 0; x < this.cachedAeStacks.length; x++ )
|
||||
if( is.getStackSize() != 0 )
|
||||
{
|
||||
final IAEItemStack aeStack = this.cachedAeStacks[x];
|
||||
|
||||
if( aeStack != null )
|
||||
{
|
||||
final IAEItemStack a = aeStack.copy();
|
||||
a.setStackSize( -a.getStackSize() );
|
||||
changes.add( a );
|
||||
}
|
||||
changes.add( is );
|
||||
}
|
||||
|
||||
// Reduce the cache size
|
||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, size );
|
||||
}
|
||||
|
||||
currentlyCached = currentlyOnStorage;
|
||||
|
||||
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] );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ package appeng.parts.misc;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@@ -55,6 +56,7 @@ public abstract class PartSharedStorageBus extends PartUpgradeable implements IG
|
||||
{
|
||||
private boolean wasActive = false;
|
||||
private int priority = 0;
|
||||
protected boolean accessChanged;
|
||||
|
||||
public PartSharedStorageBus( ItemStack is )
|
||||
{
|
||||
@@ -146,6 +148,10 @@ public abstract class PartSharedStorageBus extends PartUpgradeable implements IG
|
||||
@Override
|
||||
public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue )
|
||||
{
|
||||
if( settingName instanceof AccessRestriction )
|
||||
{
|
||||
this.accessChanged = true;
|
||||
}
|
||||
this.resetCache( true );
|
||||
this.getHost().markForSave();
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import appeng.fluids.parts.FluidHandlerAdapter;
|
||||
import appeng.me.storage.MEPassThrough;
|
||||
import appeng.util.ConfigManager;
|
||||
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -121,6 +124,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
private int handlerHash = 0;
|
||||
private boolean wasActive = false;
|
||||
private byte resetCacheLogic = 0;
|
||||
private boolean accessChanged;
|
||||
|
||||
@Reflected
|
||||
public PartStorageBus( final ItemStack is )
|
||||
@@ -172,6 +176,10 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
@Override
|
||||
public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue )
|
||||
{
|
||||
if( settingName instanceof AccessRestriction )
|
||||
{
|
||||
this.accessChanged = true;
|
||||
}
|
||||
this.resetCache( true );
|
||||
this.getHost().markForSave();
|
||||
}
|
||||
@@ -258,20 +266,25 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
@Override
|
||||
public void postChange( final IBaseMonitor<IAEItemStack> monitor, final Iterable<IAEItemStack> change, final IActionSource source )
|
||||
{
|
||||
if( source == this.mySrc || source.machine().map( machine -> machine == this ).orElse( false ) )
|
||||
if( this.mySrc.machine().map( machine -> machine == this ).orElse( false ) && monitor != null )
|
||||
{
|
||||
try
|
||||
AccessRestriction currentAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS );
|
||||
if( !currentAccess.hasPermission( AccessRestriction.READ ) )
|
||||
{
|
||||
if( this.getProxy().isActive() )
|
||||
{
|
||||
this.getProxy().getStorage().postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), change, this.mySrc );
|
||||
}
|
||||
return;
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
}
|
||||
try
|
||||
{
|
||||
if( this.getProxy().isActive() )
|
||||
{
|
||||
// :(
|
||||
this.getProxy().getStorage().postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), change, this.mySrc );
|
||||
}
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
{
|
||||
// :(
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -351,11 +364,28 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
final boolean fullReset = this.resetCacheLogic == 2;
|
||||
this.resetCacheLogic = 0;
|
||||
|
||||
final IMEInventory<IAEItemStack> in = this.getInternalHandler();
|
||||
final MEInventoryHandler<IAEItemStack> in = this.getInternalHandler();
|
||||
IItemList<IAEItemStack> before = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
boolean denyRead = false;
|
||||
if( in != null )
|
||||
{
|
||||
before = in.getAvailableItems( before );
|
||||
if( accessChanged )
|
||||
{
|
||||
AccessRestriction currentAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS );
|
||||
AccessRestriction oldAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getOldSetting( Settings.ACCESS );
|
||||
if( oldAccess.hasPermission( AccessRestriction.READ ) && !currentAccess.hasPermission( AccessRestriction.READ ) )
|
||||
{
|
||||
denyRead = true;
|
||||
}
|
||||
in.setBaseAccess( oldAccess );
|
||||
before = in.getAvailableItems( before );
|
||||
in.setBaseAccess( currentAccess );
|
||||
accessChanged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
before = in.getAvailableItems( before );
|
||||
}
|
||||
}
|
||||
|
||||
this.cached = false;
|
||||
@@ -364,16 +394,19 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
this.handlerHash = 0;
|
||||
}
|
||||
|
||||
final IMEInventory<IAEItemStack> out = this.getInternalHandler();
|
||||
final MEInventoryHandler<IAEItemStack> out = this.getInternalHandler();
|
||||
|
||||
if( in != out )
|
||||
if( in != out || denyRead )
|
||||
{
|
||||
IItemList<IAEItemStack> after = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
if( out != null )
|
||||
|
||||
if( out != null && !denyRead )
|
||||
{
|
||||
after = out.getAvailableItems( after );
|
||||
}
|
||||
|
||||
Platform.postListChanges( before, after, this, this.mySrc );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,7 +621,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
||||
{
|
||||
if( channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
||||
{
|
||||
final IMEInventoryHandler<IAEItemStack> out = this.getProxy().isActive() ? this.getInternalHandler() : null;
|
||||
final IMEInventoryHandler<IAEItemStack> out = this.getInternalHandler();
|
||||
if( out != null )
|
||||
{
|
||||
return Collections.singletonList( out );
|
||||
|
||||
@@ -21,10 +21,14 @@ package appeng.parts.reporting;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import appeng.api.networking.events.MENetworkChannelsChanged;
|
||||
import appeng.api.networking.events.MENetworkEventSubscribe;
|
||||
import appeng.api.networking.events.MENetworkPowerStatusChange;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.storage.channels.IFluidStorageChannel;
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.fluids.util.AEFluidStack;
|
||||
import appeng.util.item.AEStack;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
@@ -43,7 +47,6 @@ import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.implementations.parts.IPartStorageMonitor;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.networking.storage.IStackWatcher;
|
||||
import appeng.api.networking.storage.IStackWatcherHost;
|
||||
import appeng.api.parts.IPartModel;
|
||||
@@ -52,7 +55,6 @@ import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.client.render.TesrRenderHelper;
|
||||
import appeng.core.localization.PlayerMessages;
|
||||
import appeng.helpers.Reflected;
|
||||
@@ -206,17 +208,10 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
|
||||
fluidInTank = fluidHandlerItem.drain( Integer.MAX_VALUE, false );
|
||||
}
|
||||
|
||||
if( fluidInTank == null )
|
||||
if (fluidInTank == null)
|
||||
{
|
||||
this.configuredFluid = null;
|
||||
if( !eq.isEmpty() )
|
||||
{
|
||||
this.configuredItem = AEItemStack.fromItemStack( eq ).setStackSize( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.configuredItem = null;
|
||||
}
|
||||
this.configuredItem = AEItemStack.fromItemStack( eq );
|
||||
}
|
||||
else if( fluidInTank.amount > 0 )
|
||||
{
|
||||
@@ -392,19 +387,87 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
|
||||
this.configureWatchers();
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void powerStatusChange( final MENetworkPowerStatusChange ev )
|
||||
{
|
||||
if( !this.getProxy().isPowered() )
|
||||
{
|
||||
if( this.myWatcher != null )
|
||||
{
|
||||
if( this.configuredItem != null )
|
||||
{
|
||||
this.configuredItem.setStackSize( 0 );
|
||||
}
|
||||
if( this.configuredFluid != null )
|
||||
{
|
||||
this.configuredFluid.setStackSize( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
if( this.configuredItem != null )
|
||||
{
|
||||
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
|
||||
}
|
||||
if( this.configuredFluid != null )
|
||||
{
|
||||
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ) );
|
||||
}
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
{
|
||||
// ;P
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void channelChanged( final MENetworkChannelsChanged c )
|
||||
{
|
||||
if( !this.getProxy().isPowered() )
|
||||
{
|
||||
if( this.myWatcher != null )
|
||||
{
|
||||
if( this.configuredItem != null )
|
||||
{
|
||||
this.configuredItem.setStackSize( 0 );
|
||||
}
|
||||
if( this.configuredFluid != null )
|
||||
{
|
||||
this.configuredFluid.setStackSize( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
if( this.configuredItem != null )
|
||||
{
|
||||
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
|
||||
}
|
||||
if( this.configuredFluid != null )
|
||||
{
|
||||
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ) );
|
||||
}
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
{
|
||||
// ;P
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStackChange( final IItemList o, final IAEStack fullStack, final IAEStack diffStack, final IActionSource src, final IStorageChannel chan )
|
||||
public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan )
|
||||
{
|
||||
if( this.configuredItem != null )
|
||||
{
|
||||
if( fullStack == null )
|
||||
{
|
||||
this.configuredItem.setStackSize( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.configuredItem.setStackSize( fullStack.getStackSize() );
|
||||
}
|
||||
long diff = this.configuredItem.getStackSize() + diffStack.getStackSize();
|
||||
this.configuredItem.setStackSize( diff >= 0 ? this.configuredItem.getStackSize() + diffStack.getStackSize() : 0 );
|
||||
|
||||
final long stackSize = this.configuredItem.getStackSize();
|
||||
final String humanReadableText = NUMBER_CONVERTER.toWideReadableForm( stackSize );
|
||||
@@ -417,14 +480,8 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
|
||||
}
|
||||
else if( this.configuredFluid != null )
|
||||
{
|
||||
if( fullStack == null )
|
||||
{
|
||||
this.configuredFluid.setStackSize( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.configuredFluid.setStackSize( fullStack.getStackSize() );
|
||||
}
|
||||
long diff = this.configuredFluid.getStackSize() + diffStack.getStackSize();
|
||||
this.configuredFluid.setStackSize( diff >= 0 ? this.configuredFluid.getStackSize() + diffStack.getStackSize() : 0 );
|
||||
|
||||
final long stackSize = this.configuredFluid.getStackSize() / 1000;
|
||||
final String humanReadableText = NUMBER_CONVERTER.toWideReadableForm( stackSize ) + "B";
|
||||
|
||||
@@ -170,7 +170,8 @@ public class PartConversionMonitor extends AbstractPartMonitor
|
||||
this.insertItem( player, hand, false );
|
||||
}
|
||||
}
|
||||
return super.onPartActivate( player, hand, pos );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -554,14 +554,10 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
|
||||
@Override
|
||||
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
|
||||
{
|
||||
if( this.getProxy().isActive() )
|
||||
this.updateHandler();
|
||||
if( this.cellHandler != null && this.cellHandler.getChannel() == channel )
|
||||
{
|
||||
this.updateHandler();
|
||||
|
||||
if( this.cellHandler != null && this.cellHandler.getChannel() == channel )
|
||||
{
|
||||
return Collections.singletonList( this.cellHandler );
|
||||
}
|
||||
return Collections.singletonList( this.cellHandler );
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -692,21 +688,16 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
|
||||
@Override
|
||||
public void postChange( final IBaseMonitor<T> monitor, final Iterable<T> change, final IActionSource source )
|
||||
{
|
||||
if( source == TileChest.this.mySrc || source.machine().map( machine -> machine == TileChest.this ).orElse( false ) )
|
||||
try
|
||||
{
|
||||
try
|
||||
if( TileChest.this.getProxy().isActive() )
|
||||
{
|
||||
if( TileChest.this.getProxy().isActive() )
|
||||
{
|
||||
TileChest.this.getProxy().getStorage().postAlterationOfStoredItems( this.chan, change, TileChest.this.mySrc );
|
||||
}
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
{
|
||||
// :(
|
||||
TileChest.this.getProxy().getStorage().postAlterationOfStoredItems( this.chan, change, TileChest.this.mySrc );
|
||||
}
|
||||
} catch ( final GridAccessException e )
|
||||
{
|
||||
// :(
|
||||
}
|
||||
|
||||
TileChest.this.blinkCell( 0 );
|
||||
}
|
||||
|
||||
|
||||
@@ -334,13 +334,8 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior
|
||||
@Override
|
||||
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
|
||||
{
|
||||
if( this.getProxy().isActive() )
|
||||
{
|
||||
this.updateState();
|
||||
|
||||
return this.inventoryHandlers.get( channel );
|
||||
}
|
||||
return Collections.emptyList();
|
||||
this.updateState();
|
||||
return this.inventoryHandlers.get( channel );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -418,10 +418,12 @@ public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IC
|
||||
|
||||
if( possible > 0 )
|
||||
{
|
||||
possible = Math.min( possible, itemsToMove );
|
||||
s.setStackSize( possible );
|
||||
IAEStack injectable = s.copy();
|
||||
|
||||
final IAEStack extracted = src.extractItems( s, Actionable.MODULATE, this.mySrc );
|
||||
possible = Math.min( possible, itemsToMove );
|
||||
injectable.setStackSize( possible );
|
||||
|
||||
final IAEStack extracted = src.extractItems( injectable, Actionable.MODULATE, this.mySrc );
|
||||
if( extracted != null )
|
||||
{
|
||||
possible = extracted.getStackSize();
|
||||
@@ -500,8 +502,9 @@ public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IC
|
||||
final IAEStack test = myList.getFirstItem();
|
||||
if( test != null )
|
||||
{
|
||||
test.setStackSize( 1 );
|
||||
return src.injectItems( test, Actionable.SIMULATE, this.mySrc ) != null;
|
||||
IAEStack testCopy = test.copy();
|
||||
testCopy.setStackSize( 1 );
|
||||
return src.injectItems( testCopy, Actionable.SIMULATE, this.mySrc ) != null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ public final class ConfigManager implements IConfigManager
|
||||
{
|
||||
private final Map<Settings, Enum<?>> settings = new EnumMap<>( Settings.class );
|
||||
private final IConfigManagerHost target;
|
||||
private Map<Settings, Enum<?>> oldSettings = new EnumMap<>( Settings.class );
|
||||
|
||||
public ConfigManager( final IConfigManagerHost tile )
|
||||
{
|
||||
@@ -72,10 +73,15 @@ public final class ConfigManager implements IConfigManager
|
||||
{
|
||||
final Enum<?> oldValue = this.getSetting( settingName );
|
||||
this.settings.put( settingName, newValue );
|
||||
this.oldSettings.put( settingName, oldValue );
|
||||
this.target.updateSetting( this, settingName, newValue );
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
public Enum<?> getOldSetting(final Settings settingName){
|
||||
return this.oldSettings.get( settingName );
|
||||
}
|
||||
|
||||
/**
|
||||
* save all settings using config manager.
|
||||
*
|
||||
|
||||
@@ -43,7 +43,7 @@ public class OreReference
|
||||
return this.otherOptions;
|
||||
}
|
||||
|
||||
List<IAEItemStack> getAEEquivalents()
|
||||
public List<IAEItemStack> getAEEquivalents()
|
||||
{
|
||||
if( this.aeOtherOptions == null )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user