mirror of
https://github.com/GTNewHorizons/ThaumicEnergistics.git
synced 2026-10-25 20:32:27 +00:00
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:
1 parent
88582ec974
commit
911a40e417
20 files changed
+582
-141
No files matched your search
+10
-1
@@ -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.
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+152
-39
@@ -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
|
||||
|
||||
Reference in new issue
Block a user