Storage Bus & Conversion Monitor fixes

Bugfix: Essentia Storage Bus updates AE network if contents are
externally changed.
Bugfix: Essentia Terminal sync issue if a cell is removed/added while
viewing terminal.
Bugfix: Essentia Conversion Monitor crash.
Bugfix: Essentia Conversion Monitor no longer eats stacks.
Essentia Conversion Monitor: When shift-double-rightclicking the monitor
only takes essentia matching the input aspect, instead of any essentia
in the players inventory.
Bugfix: Priority tab icon size corrected.
Essentia storage bus can now be attached to a ME Condenser.
This commit is contained in:
Chris committed 2015-05-19 09:58:13 -04:00
1 parent 88582ec974
commit 911a40e417
20 files changed
+582 -141

No files matched your search

+10 -1
View File
@@ -1,4 +1,13 @@
5/16/2015 0.8.10.1
5/19/2015 0.8.10.2
Bugfix: Essentia Storage Bus updates AE network if contents are externally changed.
Bugfix: Essentia Terminal sync issue if a cell is removed/added while viewing terminal.
Bugfix: Essentia Conversion Monitor crash.
Bugfix: Essentia Conversion Monitor no longer eats stacks.
Essentia Conversion Monitor: When shift-double-rightclicking the monitor only takes essentia matching the input aspect, instead of any essentia in the players inventory.
Bugfix: Priority tab icon size corrected.
Essentia storage bus can now be attached to a ME Condenser.
5/16/2015 0.8.10.1
Redundant code cleanup.
Added Essentia Conversion Monitor.
+4
View File
@@ -6,6 +6,10 @@
Export essentia in response to suction.
Export essentia in response to infusion requests.
###Vis Transportation
Use P2P tunnel to move vis through the AE network.
Recharges wand stored in crafting terminal.
###Storage
Store essentia in digital format using disks.
Use existing jars as network storage.
+1 -1
View File
@@ -17,7 +17,7 @@ buildscript {
apply plugin: 'forge'
version = "0.8.10.1"
version = "0.8.10.2"
group= "thaumicenergistics" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "thaumicenergistics"
@@ -33,7 +33,7 @@ public class ThaumicEnergistics
/**
* Current version of the mod.
*/
public static final String VERSION = "0.8.10.1"; // Note: don't forget to change the build.gradle file as well
public static final String VERSION = "0.8.10.2"; // Note: don't forget to change the build.gradle file as well
/**
* Singleton instance
@@ -46,12 +46,12 @@ public class ThaumicEnergistics
public static CommonProxy proxy;
/**
* Mod configuration
* Configuration.
*/
public static IConfig config;
/**
* Creative tab that displays this mods items
* Creative tab.
*/
public static CreativeTabs ThETab = new CreativeTabs( "ThaumicEnergistics" )
{
@@ -162,8 +162,7 @@ public class ThaumicEnergistics
ThELog.endSection( "PreInit", startTime );
}
// TODO: Sync server configs
// TODO: Knowledge Inscriber GUI, add particles like focal manipulator
// TODO: Use area packets over tile sync when possible
// TODO: General: Sync server configs
// TODO: General: Use area packets over tile sync when possible
}
@@ -23,7 +23,7 @@ public interface ITransportPermissions
* @param tileClass
* @return True if added to the list or already present, False otherwise.
*/
public boolean addAspectContainerTileToExtractPermissions( Class<? extends TileEntity> tileClass );
public <T extends TileEntity & IAspectContainer> boolean addAspectContainerTileToExtractPermissions( Class<T> tileClass );
/**
* Adds a tile entity to the inject whitelist.
@@ -32,7 +32,7 @@ public interface ITransportPermissions
* @param tileClass
* @return True if added to the list, False if not.
*/
public boolean addAspectContainerTileToInjectPermissions( Class<? extends TileEntity> tileClass );
public <T extends TileEntity & IAspectContainer> boolean addAspectContainerTileToInjectPermissions( Class<T> tileClass );
/**
* Adds an item to the whitelist that must match the specified damage
@@ -967,7 +967,11 @@ public abstract class AbstractContainerCellTerminalBase
@Override
public final void onListUpdate()
{
// Ignored.
// Update our cached list of aspects
this.aspectStackList = EssentiaConversionHelper.instance.convertIIAEFluidStackListToAspectStackList( this.monitor.getStorageList() );
// Send a full update
this.onClientRequestFullUpdate();
}
/**
@@ -15,6 +15,8 @@ import thaumicenergistics.network.packet.server.PacketServerKnowledgeInscriber;
import thaumicenergistics.registries.ThEStrings;
import thaumicenergistics.texture.GuiTextureManager;
// TODO: Knowledge Inscriber GUI: add particles like focal manipulator
public class GuiKnowledgeInscriber
extends AbstractGuiBase
{
@@ -117,27 +117,24 @@ public abstract class AbstractStateGuiButton
* Draws an icon to the screen.
*
* @param minecraftInstance
* @param iconSpriteSheet
* @param iconU
* @param iconV
* @param iconWidth
* @param iconHeight
* @param width
* @param height
* @param icon
* @param xPos
* @param yPos
* @param iconWidth
* @param iconHeight
*/
protected void drawIcon( final Minecraft minecraftInstance, final IStateIconTexture icon, final int xPos, final int yPos )
protected void drawIcon( final Minecraft minecraftInstance, final IStateIconTexture icon, final int xPos, final int yPos, final int iconWidth,
final int iconHeight )
{
// Bind the sheet
minecraftInstance.getTextureManager().bindTexture( icon.getTexture() );
// Draw the icon
this.drawScaledTexturedModalRect( xPos, yPos, icon.getU(), icon.getV(), this.width, this.height, icon.getWidth(), icon.getHeight() );
this.drawScaledTexturedModalRect( xPos, yPos, icon.getU(), icon.getV(), iconWidth, iconHeight, icon.getWidth(), icon.getHeight() );
}
@Override
public final void drawButton( final Minecraft minecraftInstance, final int x, final int y )
public void drawButton( final Minecraft minecraftInstance, final int x, final int y )
{
// Full white
GL11.glColor4f( 1.0F, 1.0F, 1.0F, 1.0F );
@@ -145,13 +142,14 @@ public abstract class AbstractStateGuiButton
if( this.backgroundIcon != null )
{
// Draw the background
this.drawIcon( minecraftInstance, this.backgroundIcon, this.xPosition, this.yPosition );
this.drawIcon( minecraftInstance, this.backgroundIcon, this.xPosition, this.yPosition, this.width, this.height );
}
if( this.stateIcon != null )
{
// Draw the overlay icon
this.drawIcon( minecraftInstance, this.stateIcon, this.xPosition + this.iconXOffset, this.yPosition + this.iconYOffset );
this.drawIcon( minecraftInstance, this.stateIcon, this.xPosition + this.iconXOffset, this.yPosition + this.iconYOffset, this.width,
this.height );
}
}
@@ -1,8 +1,11 @@
package thaumicenergistics.gui.buttons;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.util.StatCollector;
import org.lwjgl.opengl.GL11;
import thaumicenergistics.texture.AEStateIconsEnum;
import thaumicenergistics.texture.IStateIconTexture;
public class GuiButtonAETab
extends AbstractStateGuiButton
@@ -28,7 +31,7 @@ public class GuiButtonAETab
*/
protected AEStateIconsEnum icon;
public GuiButtonAETab( final int ID, final int xPosition, final int yPosition, final AEStateIconsEnum icon, final String unlocalizedTooltip )
public GuiButtonAETab( final int ID, final int xPosition, final int yPosition, final IStateIconTexture icon, final String unlocalizedTooltip )
{
// Call super
super( ID, xPosition, yPosition, GuiButtonAETab.BUTTON_WIDTH, GuiButtonAETab.BUTTON_HEIGHT, icon, GuiButtonAETab.ICON_X_POSITION,
@@ -38,6 +41,24 @@ public class GuiButtonAETab
this.tooltipMessageUnlocalized = unlocalizedTooltip;
}
@Override
public void drawButton( final Minecraft minecraftInstance, final int x, final int y )
{
// Full white
GL11.glColor4f( 1.0F, 1.0F, 1.0F, 1.0F );
// Draw the tab background
this.drawIcon( minecraftInstance, AEStateIconsEnum.TAB_BUTTON, this.xPosition, this.yPosition, this.width, this.height );
if( this.stateIcon != null )
{
// Draw the overlay icon
this.drawIcon( minecraftInstance, this.stateIcon, this.xPosition + this.iconXOffset, this.yPosition + this.iconYOffset,
AEStateIconsEnum.STANDARD_ICON_SIZE, AEStateIconsEnum.STANDARD_ICON_SIZE );
}
}
@Override
public void getTooltip( final List<String> tooltip )
{
@@ -121,52 +121,44 @@ class ThETransportPermissions
private final List<Class<? extends TileEntity>> tileInjectWhiteList = new ArrayList<Class<? extends TileEntity>>();
@Override
public boolean addAspectContainerTileToExtractPermissions( final Class<? extends TileEntity> tileClass )
public <T extends TileEntity & IAspectContainer> boolean addAspectContainerTileToExtractPermissions( final Class<T> tileClass )
{
// Ensure we have a tile
if( tileClass != null )
{
// Ensure it is a container
if( IAspectContainer.class.isAssignableFrom( tileClass ) )
// Is it already registered?
if( !this.tileExtractWhiteList.contains( tileClass ) )
{
// Is it already registered?
if( !this.tileExtractWhiteList.contains( tileClass ) )
{
// Add to the list
this.tileExtractWhiteList.add( tileClass );
// Add to the list
this.tileExtractWhiteList.add( tileClass );
// Log the addition
ThELog.info( "Added %s to extraction whitelist.", tileClass.toString() );
}
return true;
// Log the addition
ThELog.info( "Added %s to extraction whitelist.", tileClass.toString() );
}
return true;
}
return false;
}
@Override
public boolean addAspectContainerTileToInjectPermissions( final Class<? extends TileEntity> tileClass )
public <T extends TileEntity & IAspectContainer> boolean addAspectContainerTileToInjectPermissions( final Class<T> tileClass )
{
// Ensure we have a tile
if( tileClass != null )
{
// Ensure it is a container
if( IAspectContainer.class.isAssignableFrom( tileClass ) )
// Is it already registered?
if( !this.tileInjectWhiteList.contains( tileClass ) )
{
// Is it already registered?
if( !this.tileInjectWhiteList.contains( tileClass ) )
{
// Add to the list
this.tileInjectWhiteList.add( tileClass );
// Add to the list
this.tileInjectWhiteList.add( tileClass );
// Log the addition
ThELog.info( "Added %s to injection whitelist.", tileClass.toString() );
}
return true;
// Log the addition
ThELog.info( "Added %s to injection whitelist.", tileClass.toString() );
}
return true;
}
return false;
@@ -296,6 +296,15 @@ public final class EssentiaTileContainerHelper
return stored;
}
/**
* Attempts to inject the fluid into the container.
* Returns the amount that was injected in milibuckets.
*
* @param container
* @param fluidStack
* @param mode
* @return
*/
public long injectIntoContainer( final IAspectContainer container, final IAEFluidStack fluidStack, final Actionable mode )
{
// Do we have an input?
@@ -332,6 +341,16 @@ public final class EssentiaTileContainerHelper
return this.injectIntoContainer( container, (int)amountToFill, gasAspect, mode );
}
/**
* Attempts to inject the fluid into the container.
* Returns the amount that was injected in milibuckets.
*
* @param container
* @param amountToFillInEssentiaUnits
* @param aspectToFill
* @param mode
* @return
*/
public long injectIntoContainer( final IAspectContainer container, int amountToFillInEssentiaUnits, final Aspect aspectToFill,
final Actionable mode )
{
@@ -82,6 +82,27 @@ public abstract class AbstractHandlerEssentiaStorageBus
}
}
/**
* Returns true if there are no filters.
*
* @return
*/
protected boolean allowAny()
{
// Are all filters null?
for( Aspect filteredAspect : this.filteredAspects )
{
if( filteredAspect != null )
{
// There is a filter
return false;
}
}
// No filters
return true;
}
/**
* Verifies that the requested fluidstack to insert/extract is both an
* Essentia Gas and white-listed, or not black-listed.
@@ -92,6 +113,13 @@ public abstract class AbstractHandlerEssentiaStorageBus
*/
protected boolean canTransferGas( final GaseousEssentia essentiaGas )
{
// Can any aspect be transfered?
if( this.allowAny() )
{
// Allow the transfer
return true;
}
/*
* Validate based on if the aspect is filtered and the storage bus is
* inverted. See explanation below.
@@ -293,10 +321,10 @@ public abstract class AbstractHandlerEssentiaStorageBus
public abstract IAEFluidStack injectItems( final IAEFluidStack input, final Actionable mode, final BaseActionSource source );
/**
* Checks if the specified fluid is allowed to be transfered.
* Checks if the specified is prioritized.
*/
@Override
public boolean isPrioritized( final IAEFluidStack fluidStack )
public final boolean isPrioritized( final IAEFluidStack fluidStack )
{
// Ensure the fluid stack is an essentia gas
if( !this.isFluidEssentiaGas( fluidStack ) )
@@ -305,8 +333,15 @@ public abstract class AbstractHandlerEssentiaStorageBus
return false;
}
// Can the bus transfer this gas?
return this.canTransferGas( (GaseousEssentia)fluidStack.getFluidStack().getFluid() );
// Is the aspect prioritized?
try
{
return this.filteredAspects.contains( ( (GaseousEssentia)fluidStack.getFluidStack().getFluid() ).getAspect() );
}
catch( Exception e )
{
return false;
}
}
/**
@@ -0,0 +1,151 @@
package thaumicenergistics.inventory;
import net.minecraft.tileentity.TileEntity;
import thaumicenergistics.fluids.GaseousEssentia;
import thaumicenergistics.integration.tc.EssentiaConversionHelper;
import thaumicenergistics.parts.AEPartEssentiaStorageBus;
import appeng.api.config.Actionable;
import appeng.api.networking.IGridNode;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IItemList;
import appeng.tile.misc.TileCondenser;
import com.google.common.collect.ImmutableList;
public class HandlerEssentiaStorageBusCondenser
extends AbstractHandlerEssentiaStorageBus
{
private TileCondenser condenser = null;
public HandlerEssentiaStorageBusCondenser( final AEPartEssentiaStorageBus part )
{
super( part );
}
@Override
public boolean canAccept( final IAEFluidStack fluidStack )
{
// Ensure there is a condenser
if( this.condenser == null )
{
return false;
}
// Ensure the bus has security access
if( !hasSecurityPermission() )
{
// The bus does not have security access.
return false;
}
// Ensure the fluid is an essentia gas
if( !this.isFluidEssentiaGas( fluidStack ) )
{
// Not essentia gas.
return false;
}
// Ensure we are allowed to transfer this fluid
if( !this.canTransferGas( (GaseousEssentia)fluidStack.getFluid() ) )
{
/*
* Either: Not on whitelist or is on blacklist
*/
return false;
}
// Can accept the fluid.
return true;
}
@Override
public IAEFluidStack extractItems( final IAEFluidStack request, final Actionable mode, final BaseActionSource source )
{
// Nothing comes out of the condenser.
return null;
}
@Override
public IItemList<IAEFluidStack> getAvailableItems( final IItemList<IAEFluidStack> out )
{
// Nothing is stored in the condenser.
return out;
}
@Override
public IAEFluidStack injectItems( final IAEFluidStack input, final Actionable mode, final BaseActionSource source )
{
// Ensure input and output
if( ( this.condenser == null ) || ( input == null ) || ( !this.canAccept( input ) ) )
{
return input;
}
// Ignore if simulation
if( mode == Actionable.SIMULATE )
{
// Condenser can accept all.
return null;
}
// Create the fluidstack
IAEFluidStack injectStack = input.copy();
// Set the amount to the Essentia units, NOT the fluid units
injectStack.setStackSize( 500 * EssentiaConversionHelper.instance.convertFluidAmountToEssentiaAmount( input.getStackSize() ) );
// Inject the fluid
this.condenser.fill( this.partStorageBus.getSide().getOpposite(), injectStack.getFluidStack(), ( mode == Actionable.MODULATE ) );
// Since the fluid is being voided, update the network so it doesn't think its stored
injectStack.setStackSize( -input.getStackSize() );
this.postAlterationToHostGrid( ImmutableList.of( injectStack ) );
// All fluid accepted.
return null;
}
@Override
public boolean onNeighborChange()
{
// Get the facing tile
TileEntity te = this.getFaceingTile();
// Is it a condenser?
if( te instanceof TileCondenser )
{
this.condenser = (TileCondenser)te;
}
else
{
this.condenser = null;
}
// Nothing to update
return false;
}
@Override
public void tickingRequest( final IGridNode node, final int TicksSinceLastCall )
{
// Ignored.
}
/**
* Only valid for pass 2
*
* @return
*/
@Override
public boolean validForPass( final int pass )
{
if( this.condenser != null )
{
return pass == 2;
}
return false;
}
}
@@ -1,6 +1,8 @@
package thaumicenergistics.inventory;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.fluids.FluidStack;
@@ -29,36 +31,72 @@ class HandlerEssentiaStorageBusContainer
*/
private IAspectContainer aspectContainer;
/**
* Cached contents of the container.
*/
Hashtable<Aspect, Long> cachedContainerAspects = new Hashtable<Aspect, Long>();
public HandlerEssentiaStorageBusContainer( final AEPartEssentiaStorageBus part )
{
super( part );
}
/**
* Returns true if there are no filters.
* Adds a list of aspects stacks to a <Aspect,Long> dictionary.
*
* @return
* @param essentiaList
*/
private boolean allowAny()
private void addListToDictionary( final List<AspectStack> essentiaList, final Hashtable<Aspect, Long> dictionary )
{
// Are all filters null?
for( Aspect filteredAspect : this.filteredAspects )
// Add each essentia
if( essentiaList != null )
{
if( filteredAspect != null )
for( AspectStack stack : essentiaList )
{
// There is a filter
return false;
dictionary.put( stack.aspect, stack.amount );
}
}
}
// No filters
return true;
/**
* Adjusts the cached aspect amount based on the specified delta.
* Positive diff adds to the amount, negative diff removes from the
* amount.
*
* @param aspect
* @param diff
*/
private void adjustCache( final Aspect aspect, final long diff )
{
long cachedAmount = 0;
// Does the cache have this aspect?
if( this.cachedContainerAspects.containsKey( aspect ) )
{
cachedAmount = this.cachedContainerAspects.get( aspect );
}
// Change the amount
long newAmount = cachedAmount + diff;
// Is there any amount left?
if( newAmount > 0 )
{
// Update the cache
this.cachedContainerAspects.put( aspect, newAmount );
}
// None left, was there some?
else if( cachedAmount > 0 )
{
// Remove from the cache
this.cachedContainerAspects.remove( aspect );
}
}
/**
* Gets essentia stored in the container.
*/
private List<AspectStack> getAvailableEssentia()
private List<AspectStack> getContainerEssentia()
{
// Ensure there is a container
if( this.aspectContainer == null )
@@ -90,19 +128,19 @@ class HandlerEssentiaStorageBusContainer
boolean skipFilterCheck = this.allowAny();
// Add the essentia
for( AspectStack essentia : containerStacks )
for( AspectStack essentiaStack : containerStacks )
{
// Is the aspect in the filter?
if( skipFilterCheck || ( this.filteredAspects.contains( essentia.aspect ) ) )
if( skipFilterCheck || ( this.filteredAspects.contains( essentiaStack.aspect ) ) )
{
// Convert to fluid
GaseousEssentia gas = GaseousEssentia.getGasFromAspect( essentia.aspect );
GaseousEssentia gas = GaseousEssentia.getGasFromAspect( essentiaStack.aspect );
// Is there a fluid form of the aspect?
if( gas != null )
{
// Add to the list
essentiaList.add( new AspectStack( essentia.aspect, essentia.amount ) );
essentiaList.add( essentiaStack );
}
}
}
@@ -110,20 +148,6 @@ class HandlerEssentiaStorageBusContainer
return essentiaList;
}
@Override
protected boolean canTransferGas( final GaseousEssentia essentiaGas )
{
// Are there no filters set?
if( this.allowAny() )
{
// Allow the storage bus to store anything when no filters set.
return true;
}
// Pass to super
return super.canTransferGas( essentiaGas );
}
@Override
public boolean canAccept( final IAEFluidStack fluidStack )
{
@@ -246,6 +270,9 @@ class HandlerEssentiaStorageBusContainer
// Take power
this.partStorageBus.extractPowerForEssentiaTransfer( drainedAmount_EU, Actionable.MODULATE );
// Update cache
this.adjustCache( ( (GaseousEssentia)toDrain.getFluid() ).getAspect(), -drainedAmount_EU );
}
// Copy the request
@@ -265,7 +292,12 @@ class HandlerEssentiaStorageBusContainer
{
if( this.aspectContainer != null )
{
List<AspectStack> essentiaList = this.getAvailableEssentia();
// Get the contents of the container
List<AspectStack> essentiaList = this.getContainerEssentia();
// Update the cache
this.cachedContainerAspects.clear();
this.addListToDictionary( essentiaList, this.cachedContainerAspects );
if( essentiaList != null )
{
@@ -299,13 +331,6 @@ class HandlerEssentiaStorageBusContainer
// Get the fluid stack from the input
FluidStack toFill = input.getFluidStack();
// Ensure the bus can transfer the gas.
if( !this.canTransferGas( (GaseousEssentia)toFill.getFluid() ) )
{
// Can not inject this gas.
return input;
}
// Is void allowed, and we are attached to a void jar?
boolean canVoid = this.isVoidAllowed() && ( this.aspectContainer instanceof TileJarFillableVoid );
@@ -352,6 +377,9 @@ class HandlerEssentiaStorageBusContainer
// Convert the actual amount injected into Essentia units.
filled_EU = (int)EssentiaConversionHelper.instance.convertFluidAmountToEssentiaAmount( filled_FU );
// Update the cache
this.adjustCache( ( (GaseousEssentia)toFill.getFluid() ).getAspect(), filled_EU );
}
// Calculate how much was left over
@@ -400,14 +428,26 @@ class HandlerEssentiaStorageBusContainer
{
// Set the container
this.aspectContainer = (IAspectContainer)tileEntity;
// Clear the cache
this.cachedContainerAspects.clear();
// Container changed
return true;
}
return true;
return false;
}
// Was the bus facing a container?
if( this.aspectContainer != null )
{
// Clear the reference
this.aspectContainer = null;
// Send one last tick
this.tickingRequest( null, 0 );
return true;
}
@@ -420,7 +460,80 @@ class HandlerEssentiaStorageBusContainer
@Override
public void tickingRequest( final IGridNode node, final int TicksSinceLastCall )
{
// Ignored
// Alteration list
List<IAEFluidStack> alterations = null;
// Create the checklist
HashSet<Aspect> aspectsToCheck = new HashSet<Aspect>();
// Get the current contents of the container
List<AspectStack> currentContainerContents = this.getContainerEssentia();
// Convert to dictionary
Hashtable<Aspect, Long> currentContainerAspects = new Hashtable<Aspect, Long>();
if( currentContainerContents != null )
{
this.addListToDictionary( currentContainerContents, currentContainerAspects );
// Add the current aspects to check list
aspectsToCheck.addAll( currentContainerAspects.keySet() );
}
// Add the cached aspects to check list
aspectsToCheck.addAll( this.cachedContainerAspects.keySet() );
// Is there anything to check?
if( aspectsToCheck.size() == 0 )
{
// Nothing to check.
return;
}
// Compare all amounts
for( Aspect aspect : aspectsToCheck )
{
// Value cached
long cachedAmount = 0;
if( this.cachedContainerAspects.containsKey( aspect ) )
{
cachedAmount = this.cachedContainerAspects.get( aspect );
}
// Current value
long currentAmount = 0;
if( currentContainerAspects.containsKey( aspect ) )
{
currentAmount = currentContainerAspects.get( aspect );
}
// Calculate the difference
long diff = currentAmount - cachedAmount;
// Do they differ?
if( diff != 0 )
{
// First alteration?
if( alterations == null )
{
// Create the list
alterations = new ArrayList<IAEFluidStack>();
}
// Create the alteration
alterations.add( EssentiaConversionHelper.instance.createAEFluidStackInEssentiaUnits( aspect, diff ) );
// Update the cache
this.adjustCache( aspect, diff );
}
}
// Any alterations?
if( alterations != null )
{
// Post the changes
this.postAlterationToHostGrid( alterations );
}
}
/**
@@ -11,6 +11,7 @@ import appeng.api.parts.IPartHost;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IItemList;
import appeng.parts.misc.PartInterface;
import appeng.tile.misc.TileCondenser;
import appeng.tile.misc.TileInterface;
/**
@@ -37,6 +38,11 @@ public class HandlerEssentiaStorageBusDuality
*/
private HandlerEssentiaStorageBusInterface interfaceHandler;
/**
* Handler used when facing a condenser.
*/
private HandlerEssentiaStorageBusCondenser condenserHandler;
/**
* Creates the handler.
*
@@ -176,18 +182,35 @@ public class HandlerEssentiaStorageBusDuality
newHandler = this.interfaceHandler;
}
}
// Has the handler changed?
if( ( this.internalHandler != null ) && ( this.internalHandler != newHandler ) )
else if( tileEntity instanceof TileCondenser )
{
// Let the old handler know the neighbor changed
doUpdate |= this.internalHandler.onNeighborChange();
// Create the interface if needed
if( this.condenserHandler == null )
{
// Create the handler
this.condenserHandler = new HandlerEssentiaStorageBusCondenser( this.partStorageBus );
}
// Set the new handler
newHandler = this.condenserHandler;
}
// Set the handler
this.internalHandler = newHandler;
// Has the handler changed?
if( this.internalHandler != newHandler )
{
// Was there a previous handler?
if( this.internalHandler != null )
{
// Let the old handler know the neighbor changed
doUpdate |= this.internalHandler.onNeighborChange();
}
// Pass to handler if has one
// Set the new handler
this.internalHandler = newHandler;
}
// Pass to internal handler
if( this.internalHandler != null )
{
// Update it
@@ -11,6 +11,7 @@ import net.minecraftforge.common.util.ForgeDirection;
import org.apache.commons.lang3.tuple.ImmutablePair;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.aspect.AspectStack;
import thaumicenergistics.fluids.GaseousEssentia;
import thaumicenergistics.integration.tc.EssentiaConversionHelper;
import thaumicenergistics.integration.tc.EssentiaItemContainerHelper;
import thaumicenergistics.registries.AEPartsEnum;
@@ -28,11 +29,25 @@ import appeng.util.Platform;
public class AEPartEssentiaConversionMonitor
extends AEPartEssentiaStorageMonitor
{
/**
* The number of ticks considered to be a double click.
*/
private static long DOUBLE_CLICK_TICKS = 2 * 20;
private int lastPlayerSneakInteractionID = -1;
/**
* The last player ID that deposited essentia
*/
private int depositedPlayerID = -1;
private int lastPlayerSneakInteractionTick = 0;
/**
* The tick count of the last deposited essentia
*/
private int depositedTick = 0;
/**
* The aspect that was last deposited.
*/
private Aspect depositedAspect = null;
/**
* Network source representing this part.
@@ -52,9 +67,10 @@ public class AEPartEssentiaConversionMonitor
*
* @param player
* @param slotIndex
* @param mustMatchAspect
* @return
*/
private boolean drainEssentiaContainer( final EntityPlayer player, final int slotIndex )
private boolean drainEssentiaContainer( final EntityPlayer player, final int slotIndex, final Aspect mustMatchAspect )
{
// Get the container
ItemStack container = player.inventory.getStackInSlot( slotIndex );
@@ -68,6 +84,20 @@ public class AEPartEssentiaConversionMonitor
return false;
}
// Get the aspect
Aspect containerAspect = ( (GaseousEssentia)request.getFluid() ).getAspect();
// Is there a must match aspect?
if( mustMatchAspect != null )
{
// Do the aspects match?
if( containerAspect != mustMatchAspect )
{
// Mismatch
return false;
}
}
// Calculate how much to take from the container
int drainAmount_E = (int)EssentiaConversionHelper.instance.convertFluidAmountToEssentiaAmount( request.getStackSize() );
@@ -82,7 +112,11 @@ public class AEPartEssentiaConversionMonitor
IAEFluidStack rejected = this.injectFluid( request, Actionable.MODULATE );
// How much is left over?
int rejectedAmount_E = (int)EssentiaConversionHelper.instance.convertFluidAmountToEssentiaAmount( rejected.getStackSize() );
int rejectedAmount_E = 0;
if( rejected != null )
{
rejectedAmount_E = (int)EssentiaConversionHelper.instance.convertFluidAmountToEssentiaAmount( rejected.getStackSize() );
}
// Update the drain amount
drainAmount_E = drainAmount_E - rejectedAmount_E;
@@ -93,14 +127,21 @@ public class AEPartEssentiaConversionMonitor
return false;
}
// Extract power
this.extractPowerForEssentiaTransfer( drainAmount_E, Actionable.MODULATE );
// Drain the container
ImmutablePair<Integer, ItemStack> drained = EssentiaItemContainerHelper.instance.extractFromContainer( container, drainAmount_E );
// Update the player inventory
player.inventory.setInventorySlotContents( slotIndex, drained.right );
player.inventory.decrStackSize( slotIndex, 1 );
if( drained != null )
{
player.inventory.addItemStackToInventory( drained.right );
}
// Extract power
this.extractPowerForEssentiaTransfer( drainAmount_E, Actionable.MODULATE );
// Set the last aspect
this.depositedAspect = containerAspect;
return true;
@@ -239,9 +280,38 @@ public class AEPartEssentiaConversionMonitor
*/
private void insertAllEssentiaIntoNetwork( final EntityPlayer player )
{
ItemStack tracking = null;
int prevStackSize = 0;
for( int slotIndex = 0; slotIndex < player.inventory.getSizeInventory(); ++slotIndex )
{
this.drainEssentiaContainer( player, slotIndex );
// Get the stack
tracking = player.inventory.getStackInSlot( slotIndex );
// Is it null or empty?
if( ( tracking == null ) || ( ( prevStackSize = tracking.stackSize ) == 0 ) )
{
// Empty slot
continue;
}
// Attempt to drain
this.drainEssentiaContainer( player, slotIndex, this.depositedAspect );
// Get the updated stack
tracking = player.inventory.getStackInSlot( slotIndex );
// Is there anything left
if( ( tracking != null ) && ( tracking.stackSize > 0 ) )
{
// Did the stack size change?
if( prevStackSize != tracking.stackSize )
{
// Visit this slot again
--slotIndex;
}
}
}
}
@@ -253,10 +323,10 @@ public class AEPartEssentiaConversionMonitor
private void markFirstClick( final EntityPlayer player )
{
// Set the ID
this.lastPlayerSneakInteractionID = WorldSettings.getInstance().getPlayerID( player.getGameProfile() );
this.depositedPlayerID = WorldSettings.getInstance().getPlayerID( player.getGameProfile() );
// Set the time
this.lastPlayerSneakInteractionTick = MinecraftServer.getServer().getTickCounter();
this.depositedTick = MinecraftServer.getServer().getTickCounter();
}
/**
@@ -268,15 +338,14 @@ public class AEPartEssentiaConversionMonitor
private boolean wasDoubleClick( final EntityPlayer player )
{
// Is this the same player that just used the monitor?
if( ( this.lastPlayerSneakInteractionID != -1 ) &&
( this.lastPlayerSneakInteractionID == WorldSettings.getInstance().getPlayerID( player.getGameProfile() ) ) )
if( ( this.depositedPlayerID != -1 ) && ( this.depositedPlayerID == WorldSettings.getInstance().getPlayerID( player.getGameProfile() ) ) )
{
// Was it a double click?
if( MinecraftServer.getServer().getTickCounter() - this.lastPlayerSneakInteractionTick <= AEPartEssentiaConversionMonitor.DOUBLE_CLICK_TICKS )
if( MinecraftServer.getServer().getTickCounter() - this.depositedTick <= AEPartEssentiaConversionMonitor.DOUBLE_CLICK_TICKS )
{
// Reset last interaction trackers
this.lastPlayerSneakInteractionID = -1;
this.lastPlayerSneakInteractionTick = 0;
this.depositedPlayerID = -1;
this.depositedTick = 0;
return true;
}
}
@@ -304,7 +373,7 @@ public class AEPartEssentiaConversionMonitor
return monitor.extractItems( toExtract, mode, this.asMachineSource );
}
// TODO: This should be generalized
// TODO: This should be generalized/abstracted better
/**
* Injects fluid into the ME network.
* Returns what was not stored.
@@ -393,7 +462,7 @@ public class AEPartEssentiaConversionMonitor
}
// Drain the container
boolean didDrain = this.drainEssentiaContainer( player, player.inventory.currentItem );
boolean didDrain = this.drainEssentiaContainer( player, player.inventory.currentItem, null );
if( didDrain )
{
this.markFirstClick( player );
@@ -116,26 +116,6 @@ public class AEPartEssentiaStorageBus
}
}
/**
* Notifies the grid that the storage bus "contents" have changed.
*/
private void postGridUpdateEvent()
{
// Does the storage bus have a grid node?
if( this.node != null )
{
// Get the grid.
IGrid grid = this.node.getGrid();
// Does the grid node have a grid?
if( grid != null )
{
// Post an update to the grid
grid.postEvent( new MENetworkCellArrayUpdate() );
}
}
}
/**
* Adds a new filter from the specified itemstack.
*
@@ -424,6 +404,26 @@ public class AEPartEssentiaStorageBus
}
}
/**
* Notifies the grid that the storage bus contents have changed.
*/
public void postGridUpdateEvent()
{
// Does the storage bus have a grid node?
if( this.node != null )
{
// Get the grid.
IGrid grid = this.node.getGrid();
// Does the grid node have a grid?
if( grid != null )
{
// Post an update to the grid
grid.postEvent( new MENetworkCellArrayUpdate() );
}
}
}
/**
* /**
* Reads the part data from NBT
@@ -62,7 +62,7 @@ public enum AEStateIconsEnum
/**
* Width and height of standard icons.
*/
private static final int STANDARD_ICON_SIZE = 16;
public static final int STANDARD_ICON_SIZE = 16;
/**
* X position in the texture this icon is located at.
@@ -286,6 +286,8 @@ public class TileGearBox
*/
public boolean crank()
{
// TODO: Thaumium Gearbox: Should golem strength play a factor here?
// Don't do work on client side
if( EffectiveSide.isClientSide() )
{
@@ -95,7 +95,7 @@ thaumicenergistics.research_page.TESTORAGE.2=§lComponents§r<BR>Stores the esse
tc.research_name.thaumicenergistics.TEIO=Digi-sentia Transportation
tc.research_text.thaumicenergistics.TEIO=Moving Essentia Digitally!
thaumicenergistics.research_page.TEIO.1=Now that you know how to digitize essentia, it's time to put that knowledge to work.<LINE>§lImport & Export§r<BR>By binding the appropriate core to an essentia tube and chamber, you are able to move essentia in and out of the storage network. The use of a filter tube allows you to specify what aspects are allowed to be transferred.
thaumicenergistics.research_page.TEIO.2=§lStorage Bus§r<BR>Combining the import and export buses into a single device allows you to use external essentia containers as network storage. Due to the lack of a chamber, it's unlikely to work with anything but warded jars.
thaumicenergistics.research_page.TEIO.2=§lStorage Bus§r<BR>Combining the import and export buses into a single device allows you to use external essentia containers as network storage.<BR>As well as storage, the bus can also be used to remove excess essentia from the network by using a void jar or ME Condenser. If using a void jar, you must select the allow void button in the GUI. Setting a low priority on the storage bus is recommended here.
# Research Arcane crafting terminal
tc.research_name.thaumicenergistics.TEARCANETERM=Arcane Crafting Terminal