E.V.C Nearly Done

Added E.V.C GUI.
API Change: Tile whitelist now requires capacity, and includes a dual
add method.
This commit is contained in:
Chris committed 2015-07-22 07:38:06 -04:00
1 parent 6eff3b98ab
commit 4ccbe8f623
14 files changed
+743 -205

No files matched your search

+5 -2
View File
@@ -1,7 +1,10 @@
7/21/2015 0.8.10.8
7/22/2015 0.8.10.8
Added E.V.C GUI.
API Change: Tile whitelist now requires capacity, and includes a dual add method.
7/21/2015 0.8.10.8
Added Essentia Vibration Chamber recipe & research.
Preliminary work on Vibration Chamber GUI.
TODO: Add to export whitelist
7/10/2015 0.8.10.8
Fixes #214: Empty jars can again be filled in Essentia Terminal.
@@ -134,7 +134,7 @@ public class ThaumicEnergistics
long startTime = ThELog.beginSection( "PostInit" );
// Register the standard thaumcraft container items and tiles
EssentiaTileContainerHelper.INSTANCE.registerThaumcraftContainers();
EssentiaTileContainerHelper.INSTANCE.registerDefaultContainers();
EssentiaItemContainerHelper.INSTANCE.registerThaumcraftContainers();
// Register features
@@ -16,23 +16,35 @@ import thaumcraft.api.aspects.IEssentiaContainerItem;
public interface IThETransportPermissions
{
/**
* Adds a tile entity to both inject & extract whitelists.
* The tile must implement the interface {@link IAspectContainer}<br />
* Capacity is required to function properly.
*
* @param tileClass
* @return True if added to the lists, False if not.
*/
public <T extends TileEntity & IAspectContainer> boolean addAspectContainerTileToBothPermissions( Class<T> tileClass, int capacity );
/**
* Adds a tile entity to the extract whitelist.
* The tile must implement the interface {@link IAspectContainer}
* The tile must implement the interface {@link IAspectContainer} <br />
* Note: Capacity can be 0 if the tile doesn't truely 'contain' essentia.
*
* @param tileClass
* @return True if added to the list or already present, False otherwise.
*/
public <T extends TileEntity & IAspectContainer> boolean addAspectContainerTileToExtractPermissions( Class<T> tileClass );
public <T extends TileEntity & IAspectContainer> boolean addAspectContainerTileToExtractPermissions( Class<T> tileClass, int capacity );
/**
* Adds a tile entity to the inject whitelist.
* The tile must implement the interface {@link IAspectContainer}
* The tile must implement the interface {@link IAspectContainer}<br />
* Capacity is required to function properly.
*
* @param tileClass
* @return True if added to the list, False if not.
*/
public <T extends TileEntity & IAspectContainer> boolean addAspectContainerTileToInjectPermissions( Class<T> tileClass );
public <T extends TileEntity & IAspectContainer> boolean addAspectContainerTileToInjectPermissions( Class<T> tileClass, int capacity );
/**
* Adds an item to the whitelist that must match the specified damage
@@ -61,7 +73,7 @@ public interface IThETransportPermissions
* @param container
* @return
*/
public boolean canExtractFromAspectContainerTile( IAspectContainer container );
public boolean canExtractFromAspectContainerTile( final IAspectContainer container );
/**
* Checks if the container can be injected into
@@ -71,6 +83,14 @@ public interface IThETransportPermissions
*/
public boolean canInjectToAspectContainerTile( IAspectContainer container );
/**
* Returns the registered capacity of the specified container.
*
* @param container
* @return Registered capacity, or -1 if not registered.
*/
public int getAspectContainerTileCapacity( IAspectContainer container );
/**
* Gets the information about the container as it was registered to the
* whitelist.
@@ -11,7 +11,6 @@ import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.common.util.ForgeDirection;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.ThaumicEnergistics;
@@ -20,6 +19,7 @@ import thaumicenergistics.registries.BlockEnum;
import thaumicenergistics.texture.BlockTextureManager;
import thaumicenergistics.tileentities.TileEssentiaVibrationChamber;
import thaumicenergistics.tileentities.abstraction.TileEVCBase;
import thaumicenergistics.util.EffectiveSide;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -45,14 +45,22 @@ public class BlockEssentiaVibrationChamber
@Override
protected boolean onBlockActivated( final World world, final int x, final int y, final int z, final EntityPlayer player )
{
// Ignore fake players
if( player instanceof FakePlayer )
// Ignore if player is sneaking
if( player.isSneaking() )
{
return false;
}
// Launch the GUI
ThEGuiHandler.launchGui( ThEGuiHandler.ESSENTIA_VIBRATION_CHAMBER, player, world, x, y, z );
// Server side?
if( EffectiveSide.isServerSide() )
{
// Is the tile valid?
if( world.getTileEntity( x, y, z ) instanceof TileEssentiaVibrationChamber )
{
// Launch the GUI
ThEGuiHandler.launchGui( ThEGuiHandler.ESSENTIA_VIBRATION_CHAMBER, player, world, x, y, z );
}
}
return true;
}
@@ -91,7 +99,7 @@ public class BlockEssentiaVibrationChamber
if( ( chamber.getForward() != null ) && ( side == chamber.getForward().ordinal() ) )
{
// Get the aspect in the chamber
Aspect aspect = chamber.processingAspect;
Aspect aspect = chamber.getProcessingAspect();
if( aspect == Aspect.ENERGY )
{
@@ -6,20 +6,37 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.FakePlayer;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.aspect.AspectStack;
import thaumicenergistics.network.packet.client.PacketClientEssentiaVibrationChamber;
import thaumicenergistics.tileentities.TileEssentiaVibrationChamber;
import thaumicenergistics.tileentities.abstraction.TileEVCBase;
import thaumicenergistics.util.EffectiveSide;
public class ContainerEssentiaVibrationChamber
extends Container
{
/**
* The number of items to average.
*/
private static final int TICK_AVG_COUNT = 4;
/**
* The essentia vibration chamber.
*/
private final TileEssentiaVibrationChamber chamber;
/**
* Player who has this container open.
*/
private final EntityPlayer player;
private float powerPerTick = 0, powerPercent = 1.0F, ticksPercent = 1.0F, ticksRemaningMovingAverage = 0.0F;
private int averageTicksRemaning;
public ContainerEssentiaVibrationChamber( final EntityPlayer player, final World world, final int x, final int y, final int z )
{
// Set the player
this.player = player;
// Get the tile entity
TileEntity te = world.getTileEntity( x, y, z );
@@ -33,7 +50,19 @@ public class ContainerEssentiaVibrationChamber
{
// Invalid tile entity
this.chamber = null;
return;
}
// Client side?
if( EffectiveSide.isClientSide() )
{
// Nothing to do client side.
return;
}
// Register for updates
this.chamber.registerListener( this );
}
@Override
@@ -42,24 +71,163 @@ public class ContainerEssentiaVibrationChamber
return !( player instanceof FakePlayer );
}
public int getPowerLevel()
/**
* Gets the power level as a percentage.
*
* @return
*/
public float getPowerPercent()
{
return 5;
return this.powerPercent;
}
/**
* Gets the power produced per tick.
*
* @return
*/
public float getPowerPerTick()
{
return this.powerPerTick;
}
/**
* Gets the aspect being processed by the EVC, can be null.
*
* @return
*/
public Aspect getProcessingAspect()
{
return Aspect.FIRE;
}
if( this.chamber != null )
{
return this.chamber.getProcessingAspect();
}
public float getRemainingPercent()
{
return 0.5F;
}
public AspectStack getStoredEssentia()
{
return null;
}
/**
* Gets the amount of essentia stored in the EVC.
*
* @return
*/
public int getStoredEssentiaAmount()
{
if( this.chamber != null )
{
return this.chamber.getEssentiaAmount( null );
}
return 0;
}
/**
* Gets the aspect stored in the EVC, can be null.
*
* @return
*/
public Aspect getStoredEssentiaAspect()
{
if( this.chamber != null )
{
return this.chamber.getEssentiaType( null );
}
return null;
}
/**
* Gets the amount of essentia stored in the EVC as a percentage.
*
* @return
*/
public float getStoredEssentiaPercent()
{
return 1.0F - ( this.getStoredEssentiaAmount() / (float)TileEVCBase.MAX_ESSENTIA_STORED );
}
/**
* Gets the number of ticks left for processing.
*
* @return
*/
public int getTicksRemaining()
{
return this.averageTicksRemaning;
}
/**
* Gets the time remaining as a percentage.
*
* @return
*/
public float getTicksRemainingPercent()
{
return this.ticksPercent;
}
/**
* Called server side when the EVC updates; client side when an update packet arrives.
*
* @param powerPerTick
* @param ticksRemaining
* @param totalTicks
*/
public void onChamberUpdate( final float powerPerTick, final float maxPowerPerTick, final int ticksRemaining, final int totalTicks )
{
// Server side?
if( EffectiveSide.isServerSide() )
{
// Send update packet
PacketClientEssentiaVibrationChamber updatePacket = new PacketClientEssentiaVibrationChamber();
updatePacket.createUpdatePacket( this.player, powerPerTick, maxPowerPerTick, ticksRemaining, totalTicks ).sendPacketToPlayer();
}
else
{
// Set power per tick
this.powerPerTick = powerPerTick;
// Calculate power percent
this.powerPercent = 1.0F - ( maxPowerPerTick > 0 ? ( powerPerTick / maxPowerPerTick ) : 0 );
// First tick?
if( this.ticksRemaningMovingAverage == 0 )
{
this.ticksRemaningMovingAverage = ticksRemaining;
}
// Update tick average
else
{
float invertedWeight = 1;
if( ticksRemaining > this.ticksRemaningMovingAverage )
{
invertedWeight = 0.3F;
}
this.ticksRemaningMovingAverage -= this.ticksRemaningMovingAverage /
( ContainerEssentiaVibrationChamber.TICK_AVG_COUNT * invertedWeight );
this.ticksRemaningMovingAverage += ticksRemaining / ( ContainerEssentiaVibrationChamber.TICK_AVG_COUNT * invertedWeight );
}
// Cast to int
this.averageTicksRemaning = (int)this.ticksRemaningMovingAverage;
// Calculate time percent
this.ticksPercent = 1.0F - ( totalTicks > 0 ? ( ticksRemaining / (float)totalTicks ) : 0 );
}
}
@Override
public void onContainerClosed( final EntityPlayer player )
{
// Call super
super.onContainerClosed( player );
// Server side?
if( EffectiveSide.isServerSide() && ( this.chamber != null ) )
{
this.chamber.removeListener( this );
}
}
}
@@ -5,96 +5,193 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import org.lwjgl.opengl.GL11;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.container.ContainerEssentiaVibrationChamber;
import thaumicenergistics.gui.abstraction.AbstractGuiBase;
import thaumicenergistics.texture.GuiTextureManager;
import thaumicenergistics.util.GuiHelper;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class GuiEssentiaVibrationChamber
extends AbstractGuiBase
{
/**
* The width of the gui
* The width & height of the gui
*/
private static final int GUI_WIDTH = 176;
private static final int GUI_WIDTH = 176, GUI_HEIGHT = 82;
/**
* The height of the gui
* Dimensions and location of the power bar.
*/
private static final int GUI_HEIGHT = 82;
private static final int POWER_POS_X = 96, POWER_POS_Y = 32, POWER_TEX_X = 51, POWER_TEX_Y = 83, POWER_WIDTH = 6, POWER_HEIGHT = 18;
/**
* Dimensions and location of the essentia storage level bar.
*/
private static final int STORED_POS_X = 62, STORED_POS_Y = 16, STORED_TEX_X = 200, STORED_WIDTH = 8, STORED_HEIGHT = 48;
/**
* Dimensions and location of the essentia storage vial.
*/
private static final int VIAL_POS_X = 61, VIAL_POS_Y = 12, VIAL_TEX_X = 232, VIAL_WIDTH = 11, VIAL_HEIGHT = 56;
/**
* Dimensions and location of the progress fire.
*/
private static final int FIRE_POS_X = 78, FIRE_POS_Y = 30, FIRE_TEX_X = 177, FIRE_WIDTH = 15, FIRE_HEIGHT = 20;
/**
* Thaumcraft's alchemy furnace GUI texture
*/
private static final ResourceLocation alchemyFurnaceTexture = new ResourceLocation( "Thaumcraft", "textures/gui/gui_alchemyfurnace.png" );
private static final ResourceLocation alchemyFurnaceTexture = new ResourceLocation( "thaumcraft", "textures/gui/gui_alchemyfurnace.png" );
/**
* Reference to the container.
*/
private final ContainerEssentiaVibrationChamber container;
public GuiEssentiaVibrationChamber( final EntityPlayer player, final World world, final int x, final int y, final int z )
{
// Create the container and call super
super( new ContainerEssentiaVibrationChamber( player, world, x, y, z ) );
this.container = (ContainerEssentiaVibrationChamber)this.inventorySlots;
// Set the width and height
this.xSize = GuiEssentiaVibrationChamber.GUI_WIDTH;
this.ySize = GuiEssentiaVibrationChamber.GUI_HEIGHT;
}
/**
* Draws elements from the Thaumcraft texture.
*/
private void drawTC_Textures()
{
// Bind the alchemy furnace gui texture
Minecraft.getMinecraft().renderEngine.bindTexture( GuiEssentiaVibrationChamber.alchemyFurnaceTexture );
// Draw stored essentia amount underlay
int storedHeightOffset = (int)( GuiEssentiaVibrationChamber.STORED_HEIGHT * this.container.getStoredEssentiaPercent() );
this.drawTexturedModalRect( this.guiLeft + GuiEssentiaVibrationChamber.STORED_POS_X, this.guiTop + GuiEssentiaVibrationChamber.STORED_POS_Y +
storedHeightOffset, GuiEssentiaVibrationChamber.STORED_TEX_X, storedHeightOffset, GuiEssentiaVibrationChamber.STORED_WIDTH,
GuiEssentiaVibrationChamber.STORED_HEIGHT - storedHeightOffset );
// Enable alpha blending
GL11.glEnable( GL11.GL_BLEND );
// Set the blending mode
GL11.glBlendFunc( GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA );
// Draw stored essentia amount overlay (Vial)
this.drawTexturedModalRect( this.guiLeft + GuiEssentiaVibrationChamber.VIAL_POS_X, this.guiTop + GuiEssentiaVibrationChamber.VIAL_POS_Y,
GuiEssentiaVibrationChamber.VIAL_TEX_X, 0, GuiEssentiaVibrationChamber.VIAL_WIDTH, GuiEssentiaVibrationChamber.VIAL_HEIGHT );
// Draw fire/progress
int progressHeightOffset = (int)( GuiEssentiaVibrationChamber.FIRE_HEIGHT * this.container.getTicksRemainingPercent() );
this.drawTexturedModalRect( this.guiLeft + GuiEssentiaVibrationChamber.FIRE_POS_X, this.guiTop + GuiEssentiaVibrationChamber.FIRE_POS_Y +
progressHeightOffset, GuiEssentiaVibrationChamber.FIRE_TEX_X, progressHeightOffset, GuiEssentiaVibrationChamber.FIRE_WIDTH,
GuiEssentiaVibrationChamber.FIRE_HEIGHT - progressHeightOffset );
// Disable blending
GL11.glDisable( GL11.GL_BLEND );
}
/**
* Draws elements from the Thaumic Energistics texture.
*/
private void drawThE_Textures()
{
// Bind the chamber gui texture
Minecraft.getMinecraft().renderEngine.bindTexture( GuiTextureManager.ESSENTIA_VIBRATION_CHAMBER.getTexture() );
// Draw the GUI
this.drawTexturedModalRect( this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize );
// Calculate the height
int powerBarHeightOffset = (int)( GuiEssentiaVibrationChamber.POWER_HEIGHT * this.container.getPowerPercent() );
// Draw the power bar
this.drawTexturedModalRect( this.guiLeft + GuiEssentiaVibrationChamber.POWER_POS_X, this.guiTop + GuiEssentiaVibrationChamber.POWER_POS_Y +
powerBarHeightOffset, GuiEssentiaVibrationChamber.POWER_TEX_X,
GuiEssentiaVibrationChamber.POWER_TEX_Y + powerBarHeightOffset, GuiEssentiaVibrationChamber.POWER_WIDTH,
GuiEssentiaVibrationChamber.POWER_HEIGHT - powerBarHeightOffset );
}
@Override
protected void drawGuiContainerBackgroundLayer( final float alpha, final int mouseX, final int mouseY )
{
// No tint + no cutout
GL11.glColor4f( 1.0F, 1.0F, 1.0F, 1.0F );
// Bind the chamber gui texture
Minecraft.getMinecraft().renderEngine.bindTexture( GuiTextureManager.ESSENTIA_VIBRATION_CHAMBER.getTexture() );
// Draw from the thaumic energistics texture
this.drawThE_Textures();
// Draw the GUI
this.drawTexturedModalRect( this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize );
int powerOffset = mouseY % 18;
// Draw the power bar
if( powerOffset > 0 )
{
this.drawTexturedModalRect( this.guiLeft + 96, this.guiTop + 32 + powerOffset, 51, 83 + powerOffset, 6, 18 - powerOffset );
}
// Bind the alchemy furnace gui texture
Minecraft.getMinecraft().renderEngine.bindTexture( new ResourceLocation( "thaumcraft", "textures/gui/gui_alchemyfurnace.png" ) );
int storedOffset = 48 - ( ( mouseX / 20 ) % 48 );
// Draw stored essentia amount underlay
if( storedOffset > 0 )
{
this.drawTexturedModalRect( this.guiLeft + 62, this.guiTop + 16 + storedOffset, 200, storedOffset, 8, 48 - storedOffset );
}
// Enable blending
GL11.glEnable( GL11.GL_BLEND );
// Set the blending mode
GL11.glBlendFunc( GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA );
// Draw stored essentia amount overlay
this.drawTexturedModalRect( this.guiLeft + 61, this.guiTop + 12, 232, 0, 11, 56 );
int progressOffset = 20 - ( mouseX % 20 );
// Draw fire/progress
if( progressOffset > 0 )
{
this.drawTexturedModalRect( this.guiLeft + 78, this.guiTop + 30 + progressOffset, 177, progressOffset, 15, 20 - progressOffset );
}
// Disable blending
GL11.glDisable( GL11.GL_BLEND );
// Draw from the thaumcraft texture
this.drawTC_Textures();
}
@Override
public void drawGuiContainerForegroundLayer( final int mouseX, final int mouseY )
{
// Is the mouse over the essentia storage?
if( GuiHelper.INSTANCE.isPointInGuiRegion( GuiEssentiaVibrationChamber.VIAL_POS_Y, GuiEssentiaVibrationChamber.VIAL_POS_X,
GuiEssentiaVibrationChamber.VIAL_HEIGHT, GuiEssentiaVibrationChamber.VIAL_WIDTH, mouseX, mouseY, this.guiLeft, this.guiTop ) )
{
// Get the stored Aspect
Aspect storedAspect = this.container.getStoredEssentiaAspect();
// Get the stored amount
int storedAmount = this.container.getStoredEssentiaAmount();
// Anything stored?
if( ( storedAmount > 0 ) && ( storedAspect != null ) )
{
// Add stored info
this.tooltip.add( String.format( "%s x %d", storedAspect.getName(), storedAmount ) );
}
else
{
// Empty
this.tooltip.add( "Empty" );
}
}
// Is the mouse over the fire?
else if( GuiHelper.INSTANCE.isPointInGuiRegion( GuiEssentiaVibrationChamber.FIRE_POS_Y, GuiEssentiaVibrationChamber.FIRE_POS_X,
GuiEssentiaVibrationChamber.FIRE_HEIGHT, GuiEssentiaVibrationChamber.FIRE_WIDTH, mouseX, mouseY, this.guiLeft, this.guiTop ) )
{
// Get the aspect being processed
Aspect processingAspect = this.container.getProcessingAspect();
// Anything being processed?
if( processingAspect != null )
{
// Calculate the seconds remaining
float secondsRemaining = ( this.container.getTicksRemaining() / 20.0F );
// Add the aspect
this.tooltip.add( String.format( "Processing: %s", processingAspect.getName() ) );
// Add the time
this.tooltip.add( String.format( "Time Remaining: %.0fs", secondsRemaining ) );
}
}
// Is the mouse over the power bar?
else if( GuiHelper.INSTANCE.isPointInGuiRegion( GuiEssentiaVibrationChamber.POWER_POS_Y, GuiEssentiaVibrationChamber.POWER_POS_X,
GuiEssentiaVibrationChamber.POWER_HEIGHT, GuiEssentiaVibrationChamber.POWER_WIDTH, mouseX, mouseY, this.guiLeft, this.guiTop ) )
{
// Add the power per tick
this.tooltip.add( String.format( "%.0f AE/t", this.container.getPowerPerTick() ) );
}
// Draw the tooltip
this.drawTooltip( mouseX - this.guiLeft, mouseY - this.guiTop, true );
}
@Override
@@ -1,8 +1,8 @@
package thaumicenergistics.implementaion;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
@@ -113,27 +113,40 @@ class ThETransportPermissions
/**
* Holds a list of tiles that we are allowed to extract from.
*/
private final List<Class<? extends TileEntity>> tileExtractWhiteList = new ArrayList<Class<? extends TileEntity>>();
private final Set<Class<? extends IAspectContainer>> tileExtractWhiteList = new HashSet<Class<? extends IAspectContainer>>();
/**
* Holds a list of tiles that we are allowed to inject into.
*/
private final List<Class<? extends TileEntity>> tileInjectWhiteList = new ArrayList<Class<? extends TileEntity>>();
private final Set<Class<? extends IAspectContainer>> tileInjectWhiteList = new HashSet<Class<? extends IAspectContainer>>();
/**
* Holds the capacities for each registered tile.
*/
private final HashMap<Class<? extends IAspectContainer>, Integer> tileCapacities = new HashMap<Class<? extends IAspectContainer>, Integer>();
@Override
public <T extends TileEntity & IAspectContainer> boolean addAspectContainerTileToExtractPermissions( final Class<T> tileClass )
public <T extends TileEntity & IAspectContainer> boolean addAspectContainerTileToBothPermissions( final Class<T> tileClass, final int capacity )
{
// Add to both
return( this.addAspectContainerTileToInjectPermissions( tileClass, capacity ) | this.addAspectContainerTileToExtractPermissions( tileClass,
capacity ) );
}
@Override
public <T extends TileEntity & IAspectContainer> boolean addAspectContainerTileToExtractPermissions( final Class<T> tileClass, final int capacity )
{
// Ensure we have a tile
if( tileClass != null )
{
// Is it already registered?
if( !this.tileExtractWhiteList.contains( tileClass ) )
{
// Add to the list
this.tileExtractWhiteList.add( tileClass );
// Set capacity
this.tileCapacities.put( tileClass, capacity );
// Is it not already registered?
if( this.tileExtractWhiteList.add( tileClass ) )
{
// Log the addition
ThELog.info( "Added %s to extraction whitelist.", tileClass.toString() );
ThELog.info( "Added %s with capacity %d to extraction whitelist.", tileClass.toString(), capacity );
}
return true;
@@ -143,19 +156,19 @@ class ThETransportPermissions
}
@Override
public <T extends TileEntity & IAspectContainer> boolean addAspectContainerTileToInjectPermissions( final Class<T> tileClass )
public <T extends TileEntity & IAspectContainer> boolean addAspectContainerTileToInjectPermissions( final Class<T> tileClass, final int capacity )
{
// Ensure we have a tile
if( tileClass != null )
{
// Is it already registered?
if( !this.tileInjectWhiteList.contains( tileClass ) )
{
// Add to the list
this.tileInjectWhiteList.add( tileClass );
// Set capacity
this.tileCapacities.put( tileClass, capacity );
// Is it not already registered?
if( this.tileInjectWhiteList.add( tileClass ) )
{
// Log the addition
ThELog.info( "Added %s to injection whitelist.", tileClass.toString() );
ThELog.info( "Added %s with capacity %d to injection whitelist.", tileClass.toString(), capacity );
}
return true;
@@ -211,49 +224,27 @@ class ThETransportPermissions
@Override
public boolean canExtractFromAspectContainerTile( final IAspectContainer container )
{
// Ensure the container is a tile.
if( !( container instanceof TileEntity ) )
{
return false;
}
// Loop over blacklist
for( Class<? extends TileEntity> whiteClass : this.tileExtractWhiteList )
{
// Is the container an instance of this whitelisted class?
if( whiteClass.isInstance( container ) )
{
// Return that we can extract
return true;
}
}
// Return that we can not extract
return false;
// Return if it is whitelisted or not
return( this.tileExtractWhiteList.contains( container.getClass() ) );
}
@Override
public boolean canInjectToAspectContainerTile( final IAspectContainer container )
{
// Ensure the container is a tile.
if( !( container instanceof TileEntity ) )
// Return if it is whitelisted or not
return( this.tileInjectWhiteList.contains( container.getClass() ) );
}
@Override
public int getAspectContainerTileCapacity( final IAspectContainer container )
{
// Is the capacity registered?
if( this.tileCapacities.containsKey( container.getClass() ) )
{
return false;
return this.tileCapacities.get( container.getClass() );
}
// Loop over blacklist
for( Class<? extends TileEntity> whiteClass : this.tileInjectWhiteList )
{
// Is the container an instance of this whitelisted class?
if( whiteClass.isInstance( container ) )
{
// Return that we can inject
return true;
}
}
// Return that we can not inject
return false;
return -1;
}
@Override
@@ -18,6 +18,8 @@ import thaumicenergistics.api.IThETransportPermissions;
import thaumicenergistics.api.ThEApi;
import thaumicenergistics.aspect.AspectStack;
import thaumicenergistics.fluids.GaseousEssentia;
import thaumicenergistics.tileentities.TileEssentiaVibrationChamber;
import thaumicenergistics.tileentities.abstraction.TileEVCBase;
import appeng.api.config.Actionable;
import appeng.api.storage.data.IAEFluidStack;
@@ -228,24 +230,15 @@ public final class EssentiaTileContainerHelper
}
/**
* Returns the capacity of the specified container.
*
* @param container
* @return Capacity or -1 if unknown capacity.
*/
public int getContainerCapacity( final IAspectContainer container )
{
int capacity = 0;
if( container instanceof TileJarFillable )
{
capacity = ( (TileJarFillable)container ).maxAmount;
}
else if( container instanceof TileAlembic )
{
capacity = ( (TileAlembic)container ).maxAmount;
}
else if( container instanceof TileEssentiaReservoir )
{
capacity = ( (TileEssentiaReservoir)container ).maxAmount;
}
return capacity;
return this.perms.getAspectContainerTileCapacity( container );
}
public int getContainerStoredAmount( final IAspectContainer container )
@@ -381,27 +374,28 @@ public final class EssentiaTileContainerHelper
/**
* Setup the standard white list
*/
public void registerThaumcraftContainers()
public void registerDefaultContainers()
{
// Alembic
this.perms.addAspectContainerTileToExtractPermissions( TileAlembic.class );
this.perms.addAspectContainerTileToExtractPermissions( TileAlembic.class, 32 );
// Centrifuge
this.perms.addAspectContainerTileToExtractPermissions( TileCentrifuge.class );
this.perms.addAspectContainerTileToExtractPermissions( TileCentrifuge.class, 0 );
// Jars
this.perms.addAspectContainerTileToExtractPermissions( TileJarFillable.class );
this.perms.addAspectContainerTileToInjectPermissions( TileJarFillable.class );
this.perms.addAspectContainerTileToBothPermissions( TileJarFillable.class, 64 );
// Essentia buffer
this.perms.addAspectContainerTileToExtractPermissions( TileTubeBuffer.class );
this.perms.addAspectContainerTileToExtractPermissions( TileTubeBuffer.class, 8 );
// Essentia reservoir
this.perms.addAspectContainerTileToExtractPermissions( TileEssentiaReservoir.class );
this.perms.addAspectContainerTileToInjectPermissions( TileEssentiaReservoir.class );
this.perms.addAspectContainerTileToBothPermissions( TileEssentiaReservoir.class, 256 );
// Advanced alchemical furnace
this.perms.addAspectContainerTileToExtractPermissions( TileAlchemyFurnaceAdvancedNozzle.class );
this.perms.addAspectContainerTileToExtractPermissions( TileAlchemyFurnaceAdvancedNozzle.class, 0 );
// Essentia vibration chamber
this.perms.addAspectContainerTileToInjectPermissions( TileEssentiaVibrationChamber.class, TileEVCBase.MAX_ESSENTIA_STORED );
}
}
@@ -7,6 +7,7 @@ import thaumicenergistics.network.handlers.HandlerAreaParticleFX;
import thaumicenergistics.network.handlers.HandlerClientAspectSlot;
import thaumicenergistics.network.handlers.HandlerClientEssentiaCellTerminal;
import thaumicenergistics.network.handlers.HandlerClientEssentiaStorageBus;
import thaumicenergistics.network.handlers.HandlerClientEssentiaVibrationChamber;
import thaumicenergistics.network.handlers.HandlerClientKnowledgeInscriber;
import thaumicenergistics.network.handlers.HandlerClientPriority;
import thaumicenergistics.network.handlers.HandlerServerAspectSlot;
@@ -31,6 +32,7 @@ import thaumicenergistics.network.packet.client.PacketClientEssentiaCellTerminal
import thaumicenergistics.network.packet.client.PacketClientEssentiaEmitter;
import thaumicenergistics.network.packet.client.PacketClientEssentiaIOBus;
import thaumicenergistics.network.packet.client.PacketClientEssentiaStorageBus;
import thaumicenergistics.network.packet.client.PacketClientEssentiaVibrationChamber;
import thaumicenergistics.network.packet.client.PacketClientKnowledgeInscriber;
import thaumicenergistics.network.packet.client.PacketClientPriority;
import thaumicenergistics.network.packet.server.PacketServerArcaneCraftingTerminal;
@@ -102,6 +104,9 @@ public class ChannelHandler
// Wrench Focus
wrapper.registerMessage( HandlerServerWrenchFocus.class, PacketServerWrenchFocus.class, discriminator++ , Side.SERVER );
// Essentia Vibration Chamber
wrapper.registerMessage( HandlerClientEssentiaVibrationChamber.class, PacketClientEssentiaVibrationChamber.class, discriminator++ ,
Side.CLIENT );
}
public static void sendPacketToAllAround( final AbstractPacket packet, final int dimension, final double x, final double y, final double z,
@@ -0,0 +1,19 @@
package thaumicenergistics.network.handlers;
import thaumicenergistics.network.packet.client.PacketClientEssentiaVibrationChamber;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
public class HandlerClientEssentiaVibrationChamber
implements IMessageHandler<PacketClientEssentiaVibrationChamber, IMessage>
{
@Override
public IMessage onMessage( final PacketClientEssentiaVibrationChamber message, final MessageContext ctx )
{
message.execute();
return null;
}
}
@@ -0,0 +1,109 @@
package thaumicenergistics.network.packet.client;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import thaumicenergistics.container.ContainerEssentiaVibrationChamber;
import thaumicenergistics.gui.GuiEssentiaVibrationChamber;
import thaumicenergistics.network.packet.AbstractClientPacket;
public class PacketClientEssentiaVibrationChamber
extends AbstractClientPacket
{
private static final byte MODE_UPDATE = 1;
private float powerPerTick, maxPowerPerTick;
private int ticksRemaining, totalTicks;
@Override
protected void readData( final ByteBuf stream )
{
if( this.mode == PacketClientEssentiaVibrationChamber.MODE_UPDATE )
{
// Read PPT
this.powerPerTick = stream.readFloat();
// Read MPPT
this.maxPowerPerTick = stream.readFloat();
// Read TR
this.ticksRemaining = stream.readInt();
// Read TT
this.totalTicks = stream.readInt();
}
}
@Override
protected void wrappedExecute()
{
// Get the gui
Gui gui = Minecraft.getMinecraft().currentScreen;
// Ensure the gui is the EVC
if( !( gui instanceof GuiEssentiaVibrationChamber ) )
{
return;
}
// Get the container
Container container = ( (GuiEssentiaVibrationChamber)gui ).inventorySlots;
if( this.mode == PacketClientEssentiaVibrationChamber.MODE_UPDATE )
{
// Call update
( (ContainerEssentiaVibrationChamber)container ).onChamberUpdate( this.powerPerTick, this.maxPowerPerTick, this.ticksRemaining,
this.totalTicks );
}
}
@Override
protected void writeData( final ByteBuf stream )
{
if( this.mode == PacketClientEssentiaVibrationChamber.MODE_UPDATE )
{
// Write PPT
stream.writeFloat( this.powerPerTick );
// Write MPPT
stream.writeFloat( this.maxPowerPerTick );
// Write TR
stream.writeInt( this.ticksRemaining );
// Write TT
stream.writeInt( this.totalTicks );
}
}
/**
* Creates an update packet.
*
* @param player
* @param powerPerTick
* @param ticksRemaining
* @param totalTicks
* @return
*/
public PacketClientEssentiaVibrationChamber createUpdatePacket( final EntityPlayer player, final float powerPerTick, final float maxPowerPerTick,
final int ticksRemaining, final int totalTicks )
{
// Set the player
this.player = player;
// Set the mode
this.mode = PacketClientEssentiaVibrationChamber.MODE_UPDATE;
// Set values
this.powerPerTick = powerPerTick;
this.maxPowerPerTick = maxPowerPerTick;
this.ticksRemaining = ticksRemaining;
this.totalTicks = totalTicks;
return this;
}
}
@@ -1,13 +1,16 @@
package thaumicenergistics.tileentities;
import io.netty.buffer.ByteBuf;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntityFurnace;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.aspect.AspectStack;
import thaumicenergistics.container.ContainerEssentiaVibrationChamber;
import thaumicenergistics.integration.IWailaSource;
import thaumicenergistics.integration.tc.EssentiaTransportHelper;
import thaumicenergistics.network.packet.AbstractPacket;
@@ -34,25 +37,20 @@ public class TileEssentiaVibrationChamber
private static String NBTKEY_TIME_REMAINING = "TRemain", NBTKEY_PROCESSING_SPEED = "ProcSpeed", NBTKEY_POWER_PER_TICK = "PwrPerTick",
NBTKEY_PROCESSING_ASPECT = "ProcAspect";
/**
* How long it takes coal to burn
*/
private static int coalBurnTime = 0;
/**
* How much power is produced per tick
*/
private static double basePowerProducedPerTick = 5.0;
private static final double BASE_POWER_PER_TICK = 5.0;
/**
* Half second.
*/
private static int TICKRATE_MIN = 10;
private static final int TICKRATE_MIN = 10;
/**
* Two seconds.
*/
private static int TICKRATE_MAX = 40;
private static final int TICKRATE_MAX = 40;
/**
* Min and Max processing speed
@@ -60,9 +58,24 @@ public class TileEssentiaVibrationChamber
private static final int PROCESS_SPEED_MAX = 200, PROCESS_SPEED_MIN = 20;
/**
* How much longer the essentia will be processed.
* Adjusts processing speed.
*/
private int timeRemaining = 0;
private static final double DILATATION_DIVISOR = 100;
/**
* How long it takes coal to burn
*/
private static int coalBurnTime = 0;
/**
* Time dilation amount
*/
private double dilation = 1.0F;
/**
* How much longer the essentia will be processed, in ticks.
*/
private int processingTicksRemaining = 0;
/**
* How fast processing is occurring.
@@ -77,12 +90,29 @@ public class TileEssentiaVibrationChamber
/**
* What aspect is currently being processed.
*/
public Aspect processingAspect = null;
private Aspect processingAspect = null;
/**
* Set true when the aspect changed.
*/
public boolean processingChanged = false;
private boolean processingChanged = false;
/**
* The total amount of processing ticks for the current aspect.
* Used for GUI.
*/
private int sync_totalProcessingTicks = 0;
/**
* How much power is being produced per tick.
* Used for GUI.
*/
private double sync_powerPerTick = 0;
/**
* Players who have the GUI open.
*/
private final Set<ContainerEssentiaVibrationChamber> listeners = new HashSet<ContainerEssentiaVibrationChamber>();
/**
* Adjusts processing time and power production based on essentia type.
@@ -104,17 +134,29 @@ public class TileEssentiaVibrationChamber
if( this.storedEssentia.aspect == Aspect.FIRE )
{
pTime = TileEssentiaVibrationChamber.coalBurnTime / 2;
this.powerProducedPerProcessingTick = TileEssentiaVibrationChamber.basePowerProducedPerTick * 1.0D;
this.powerProducedPerProcessingTick = TileEssentiaVibrationChamber.BASE_POWER_PER_TICK * 1.0D;
}
else if( this.storedEssentia.aspect == Aspect.ENERGY )
{
pTime = (int)( TileEssentiaVibrationChamber.coalBurnTime / 1.6F );
this.powerProducedPerProcessingTick = TileEssentiaVibrationChamber.basePowerProducedPerTick * 1.6D;
this.powerProducedPerProcessingTick = TileEssentiaVibrationChamber.BASE_POWER_PER_TICK * 1.6D;
}
// Set the total
this.sync_totalProcessingTicks = pTime;
return pTime;
}
/**
* Clamps the processing speed to the min-max constants.
*/
private void clampProcessingSpeed()
{
this.processingSpeed = Math.max( TileEssentiaVibrationChamber.PROCESS_SPEED_MIN,
Math.min( TileEssentiaVibrationChamber.PROCESS_SPEED_MAX, this.processingSpeed ) );
}
/**
* Converts an essentia to processing time.
*
@@ -141,7 +183,7 @@ public class TileEssentiaVibrationChamber
this.markForUpdate();
// Add to processing time
this.timeRemaining += pTime;
this.processingTicksRemaining += pTime;
return true;
}
@@ -159,32 +201,34 @@ public class TileEssentiaVibrationChamber
private TickRateModulation doProcessingTick( final int ticksSinceLastCall )
{
// Is there any processing time remaining?
if( this.timeRemaining == 0 )
if( this.processingTicksRemaining == 0 )
{
return TickRateModulation.IDLE;
}
// Bounds check processing speed
this.processingSpeed = Math.max( TileEssentiaVibrationChamber.PROCESS_SPEED_MIN,
Math.min( TileEssentiaVibrationChamber.PROCESS_SPEED_MAX, this.processingSpeed ) );
// Clap the processing speed
clampProcessingSpeed();
// Calculate dilation
double dilation = this.processingSpeed / 100.0;
this.dilation = this.processingSpeed / TileEssentiaVibrationChamber.DILATATION_DIVISOR;
// Calculate number of processing ticks
double processingTicks = ticksSinceLastCall * dilation;
double processingTicks = ticksSinceLastCall * this.dilation;
// Adjust time remaining
this.timeRemaining -= processingTicks;
this.processingTicksRemaining -= processingTicks;
// Calculate the goal produced power
this.sync_powerPerTick = ( processingTicks * this.powerProducedPerProcessingTick ) / ticksSinceLastCall;
// Finished?
if( this.timeRemaining <= 0 )
if( this.processingTicksRemaining <= 0 )
{
// Adjust processing time
processingTicks += this.timeRemaining;
processingTicks += this.processingTicksRemaining;
// Reset time
this.timeRemaining = 0;
this.processingTicksRemaining = 0;
// Clear the aspect
this.processingAspect = null;
@@ -195,7 +239,7 @@ public class TileEssentiaVibrationChamber
this.markDirty();
}
// Calculate the produced power
// Calculate the actual produced power
double producedPower = processingTicks * this.powerProducedPerProcessingTick;
// Assume slower
@@ -242,6 +286,39 @@ public class TileEssentiaVibrationChamber
}
/**
* Updates all listening containers.
*/
private void updateListeners()
{
// Fast exit check
if( this.listeners.isEmpty() )
{
return;
}
// Cast power per tick
float powerPerTick = (float)this.sync_powerPerTick;
// Calculate the maximum power per tick
float maxPowerPerTick = (float)( this.powerProducedPerProcessingTick * ( TileEssentiaVibrationChamber.PROCESS_SPEED_MAX / TileEssentiaVibrationChamber.DILATATION_DIVISOR ) );
// Clamp the processing speed
clampProcessingSpeed();
// Calculate ticks remaining
int ticksRemaining = (int)( this.processingTicksRemaining / this.dilation );
// Calculate total ticks
int totalTicks = (int)( this.sync_totalProcessingTicks / this.dilation );
// Update listeners
for( ContainerEssentiaVibrationChamber listener : this.listeners )
{
listener.onChamberUpdate( powerPerTick, maxPowerPerTick, ticksRemaining, totalTicks );
}
}
/**
* Adds essentia to the buffer.
*
@@ -303,10 +380,10 @@ public class TileEssentiaVibrationChamber
// Read time remaining
if( data.hasKey( TileEssentiaVibrationChamber.NBTKEY_TIME_REMAINING ) )
{
this.timeRemaining = data.getInteger( TileEssentiaVibrationChamber.NBTKEY_TIME_REMAINING );
this.processingTicksRemaining = data.getInteger( TileEssentiaVibrationChamber.NBTKEY_TIME_REMAINING );
}
if( this.timeRemaining > 0 )
if( this.processingTicksRemaining > 0 )
{
// Read processing speed
if( data.hasKey( TileEssentiaVibrationChamber.NBTKEY_PROCESSING_SPEED ) )
@@ -342,9 +419,9 @@ public class TileEssentiaVibrationChamber
protected void NBTWrite( final NBTTagCompound data )
{
// Write time remaining
data.setInteger( TileEssentiaVibrationChamber.NBTKEY_TIME_REMAINING, this.timeRemaining );
data.setInteger( TileEssentiaVibrationChamber.NBTKEY_TIME_REMAINING, this.processingTicksRemaining );
if( this.timeRemaining > 0 )
if( this.processingTicksRemaining > 0 )
{
// Write processing speed
data.setInteger( TileEssentiaVibrationChamber.NBTKEY_PROCESSING_SPEED, this.processingSpeed );
@@ -420,6 +497,16 @@ public class TileEssentiaVibrationChamber
}
}
/**
* Returns what aspect is currently being processed.
*
* @return
*/
public Aspect getProcessingAspect()
{
return this.processingAspect;
}
/**
* How often to tick?
*
@@ -434,6 +521,26 @@ public class TileEssentiaVibrationChamber
}
/**
* Registers a listener with the EVC
*
* @param listener
*/
public void registerListener( final ContainerEssentiaVibrationChamber listener )
{
this.listeners.add( listener );
}
/**
* Un-registers a listener with the EVC.
*
* @param listener
*/
public void removeListener( final ContainerEssentiaVibrationChamber listener )
{
this.listeners.remove( listener );
}
/**
* Called when the network ticks.
*
@@ -449,17 +556,25 @@ public class TileEssentiaVibrationChamber
TickRateModulation rate = TickRateModulation.IDLE;
// Is there any processing time remaining?
if( this.timeRemaining > 0 )
if( this.processingTicksRemaining > 0 )
{
// Process the essentia
rate = this.doProcessingTick( ticksSinceLastCall );
}
else
{
// No longer producing power
this.sync_powerPerTick = 0;
// Reset speed
this.processingSpeed = TileEssentiaVibrationChamber.PROCESS_SPEED_MIN;
}
// Is there anything stored?
if( this.hasStoredEssentia() )
{
// Is the chamber idle?
if( this.timeRemaining == 0 )
if( this.processingTicksRemaining == 0 )
{
// Can essentia be consumed?
if( this.consumeEssentia() )
@@ -477,9 +592,6 @@ public class TileEssentiaVibrationChamber
}
else
{
// Nothing is stored, keep moving the rotation timer
this.suctionRotationTimer += ticksSinceLastCall;
// Replenish if possible
replenish = true;
}
@@ -491,6 +603,9 @@ public class TileEssentiaVibrationChamber
EssentiaTransportHelper.INSTANCE.takeEssentiaFromTransportNeighbors( this, this.worldObj, this.xCoord, this.yCoord, this.zCoord );
}
// Update listeners
this.updateListeners();
return rate;
}
@@ -5,6 +5,7 @@ import java.io.IOException;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.MinecraftServer;
import net.minecraftforge.common.util.ForgeDirection;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
@@ -38,7 +39,7 @@ public abstract class TileEVCBase
/**
* The maximum amount of stored essentia.
*/
protected static final int MAX_ESSENTIA_STORED = 64;
public static final int MAX_ESSENTIA_STORED = 64;
/**
* Stored Essentia
@@ -48,7 +49,7 @@ public abstract class TileEVCBase
/**
* 1-100: Ignis, 100-200: Potentia
*/
protected int suctionRotationTimer = 1;
//protected int suctionRotationTimer = 1;
protected abstract int addEssentia( final Aspect aspect, final int amount, final Actionable mode );
@@ -220,10 +221,20 @@ public abstract class TileEVCBase
{
int suction = 0;
// Not full?
if( ( this.storedEssentia == null ) || ( this.storedEssentia.stackSize < TileEVCBase.MAX_ESSENTIA_STORED ) )
// Is there anything stored?
if( this.storedEssentia != null )
{
suction = 128;
// Not Full?
if( this.storedEssentia.stackSize < TileEVCBase.MAX_ESSENTIA_STORED )
{
// Full suction when stored but not full.
suction = 128;
}
}
else
{
// Less suction when nothing stored.
suction = 100;
}
return suction;
@@ -232,28 +243,26 @@ public abstract class TileEVCBase
@Override
public Aspect getSuctionType( final ForgeDirection side )
{
// Default to Ignis
Aspect suction = Aspect.FIRE;
// Is there anything stored?
if( this.hasStoredEssentia() )
{
// Suction type must match what is stored
return this.storedEssentia.aspect;
suction = this.storedEssentia.aspect;
}
// Is the timer over 100?
if( this.suctionRotationTimer > 100 )
else
{
// Does the timer need to be reset?
if( this.suctionRotationTimer > 200 )
// Rotate into Potentia?
if( ( MinecraftServer.getServer().getTickCounter() % 200 ) > 100 )
{
this.suctionRotationTimer = 0;
// Set to Potentia
suction = Aspect.ENERGY;
}
// Potentia
return Aspect.ENERGY;
}
// Ignis
return Aspect.FIRE;
return suction;
}
@Override
@@ -13,7 +13,7 @@ thaumicenergistics.block.golem.gear.box.name=Thaumium Gear Box
thaumicenergistics.block.essentia.cell.workbench.name=Essentia Cell Workbench
thaumicenergistics.block.arcane.assembler.name=Arcane Assembler
thaumicenergistics.block.knowledge.inscriber.name=Knowledge Inscriber
thaumicenergistics.block.essentia.vibration.chamber.name=[WIP]Essentia Vibration Chamber
thaumicenergistics.block.essentia.vibration.chamber.name=Essentia Vibration Chamber
#Cable parts
thaumicenergistics.aeparts.essentia.ImportBus.name=Essentia Import Bus